root/branches/ppalmers-streaming/src/libstreaming/StreamProcessorManager.cpp

Revision 714, 46.3 kB (checked in by ppalmers, 15 years ago)

- cleanup of streaming interfaces
- doesn't work yet

Line 
1 /*
2  * Copyright (C) 2005-2007 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software Foundation;
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02110-1301 USA
22  */
23
24 #include "StreamProcessorManager.h"
25 #include "generic/StreamProcessor.h"
26 #include "generic/Port.h"
27 #include "util/cycletimer.h"
28
29 #include <errno.h>
30 #include <assert.h>
31
32 #define RUNNING_TIMEOUT_MSEC 4000
33 #define PREPARE_TIMEOUT_MSEC 4000
34 #define ENABLE_TIMEOUT_MSEC 4000
35
36 namespace Streaming {
37
38 IMPL_DEBUG_MODULE( StreamProcessorManager, StreamProcessorManager, DEBUG_LEVEL_VERBOSE );
39
40 StreamProcessorManager::StreamProcessorManager(unsigned int period, unsigned int nb_buffers)
41     : m_is_slave( false )
42     , m_SyncSource(NULL)
43     , m_nb_buffers(nb_buffers)
44     , m_period(period)
45     , m_xruns(0)
46     , m_isoManager(0)
47     , m_nbperiods(0)
48 {
49     addOption(Util::OptionContainer::Option("slaveMode",false));
50 }
51
52 StreamProcessorManager::~StreamProcessorManager() {
53     if (m_isoManager) delete m_isoManager;
54
55 }
56
57 /**
58  * Registers \ref processor with this manager.
59  *
60  * also registers it with the isohandlermanager
61  *
62  * be sure to call isohandlermanager->init() first!
63  * and be sure that the processors are also ->init()'ed
64  *
65  * @param processor
66  * @return true if successfull
67  */
68 bool StreamProcessorManager::registerProcessor(StreamProcessor *processor)
69 {
70     debugOutput( DEBUG_LEVEL_VERBOSE, "Registering processor (%p)\n",processor);
71     assert(processor);
72     assert(m_isoManager);
73
74     if (processor->getType() == StreamProcessor::ePT_Receive) {
75         processor->setVerboseLevel(getDebugLevel()); // inherit debug level
76
77         m_ReceiveProcessors.push_back(processor);
78         processor->setManager(this);
79         return true;
80     }
81
82     if (processor->getType() == StreamProcessor::ePT_Transmit) {
83         processor->setVerboseLevel(getDebugLevel()); // inherit debug level
84
85         m_TransmitProcessors.push_back(processor);
86         processor->setManager(this);
87         return true;
88     }
89
90     debugFatal("Unsupported processor type!\n");
91
92     return false;
93 }
94
95 bool StreamProcessorManager::unregisterProcessor(StreamProcessor *processor)
96 {
97     debugOutput( DEBUG_LEVEL_VERBOSE, "Unregistering processor (%p)\n",processor);
98     assert(processor);
99
100     if (processor->getType()==StreamProcessor::ePT_Receive) {
101
102         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
103             it != m_ReceiveProcessors.end();
104             ++it ) {
105
106             if ( *it == processor ) {
107                     m_ReceiveProcessors.erase(it);
108
109                     processor->clearManager();
110
111                     if(!m_isoManager->unregisterStream(processor)) {
112                         debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister receive stream processor from the Iso manager\n");
113
114                         return false;
115
116                     }
117
118                     return true;
119                 }
120         }
121     }
122
123     if (processor->getType()==StreamProcessor::ePT_Transmit) {
124         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
125             it != m_TransmitProcessors.end();
126             ++it ) {
127
128             if ( *it == processor ) {
129                     m_TransmitProcessors.erase(it);
130
131                     processor->clearManager();
132
133                     if(!m_isoManager->unregisterStream(processor)) {
134                         debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister transmit stream processor from the Iso manager\n");
135
136                         return false;
137
138                     }
139
140                     return true;
141                 }
142         }
143     }
144
145     debugFatal("Processor (%p) not found!\n",processor);
146
147     return false; //not found
148
149 }
150
151 bool StreamProcessorManager::setSyncSource(StreamProcessor *s) {
152     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting sync source to (%p)\n", s);
153
154     m_SyncSource=s;
155     return true;
156 }
157
158 bool StreamProcessorManager::init()
159 {
160     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
161
162     m_isoManager = new IsoHandlerManager(m_thread_realtime, m_thread_priority + 1);
163
164     if(!m_isoManager) {
165         debugFatal("Could not create IsoHandlerManager\n");
166         return false;
167     }
168
169     // propagate the debug level
170     m_isoManager->setVerboseLevel(getDebugLevel());
171
172     if(!m_isoManager->init()) {
173         debugFatal("Could not initialize IsoHandlerManager\n");
174         return false;
175     }
176
177     m_xrun_happened=false;
178
179     return true;
180 }
181
182 bool StreamProcessorManager::prepare() {
183
184     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
185
186     m_is_slave=false;
187     if(!getOption("slaveMode", m_is_slave)) {
188         debugWarning("Could not retrieve slaveMode parameter, defaulting to false\n");
189     }
190
191     // if no sync source is set, select one here
192     if(m_SyncSource == NULL) {
193        debugWarning("Sync Source is not set. Defaulting to first StreamProcessor.\n");
194     }
195
196     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
197         it != m_ReceiveProcessors.end();
198         ++it ) {
199             if(m_SyncSource == NULL) {
200                 debugWarning(" => Sync Source is %p.\n", *it);
201                 m_SyncSource = *it;
202             }
203     }
204
205     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
206         it != m_TransmitProcessors.end();
207         ++it ) {
208             if(m_SyncSource == NULL) {
209                 debugWarning(" => Sync Source is %p.\n", *it);
210                 m_SyncSource = *it;
211             }
212     }
213
214     // now do the actual preparation
215     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepare Receive processors...\n");
216     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
217         it != m_ReceiveProcessors.end();
218         ++it ) {
219
220         if(!(*it)->setOption("slaveMode", m_is_slave)) {
221             debugOutput(DEBUG_LEVEL_VERBOSE, " note: could not set slaveMode option for (%p)...\n",(*it));
222         }
223
224         if(!(*it)->prepare()) {
225             debugFatal(  " could not prepare (%p)...\n",(*it));
226             return false;
227         }
228     }
229
230     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepare Transmit processors...\n");
231     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
232         it != m_TransmitProcessors.end();
233         ++it ) {
234         if(!(*it)->setOption("slaveMode", m_is_slave)) {
235             debugOutput(DEBUG_LEVEL_VERBOSE, " note: could not set slaveMode option for (%p)...\n",(*it));
236         }
237         if(!(*it)->prepare()) {
238             debugFatal( " could not prepare (%p)...\n",(*it));
239             return false;
240         }
241     }
242
243     // if there are no stream processors registered,
244     // fail
245     if (m_ReceiveProcessors.size() + m_TransmitProcessors.size() == 0) {
246         debugFatal("No stream processors registered, can't do anything usefull\n");
247         return false;
248     }
249
250     return true;
251 }
252
253 bool StreamProcessorManager::syncStartAll() {
254
255     debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for StreamProcessor streams to start running...\n");
256     // we have to wait until all streamprocessors indicate that they are running
257     // i.e. that there is actually some data stream flowing
258     int wait_cycles=RUNNING_TIMEOUT_MSEC; // two seconds
259     bool notRunning=true;
260     while (notRunning && wait_cycles) {
261         wait_cycles--;
262         notRunning=false;
263
264         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
265                 it != m_ReceiveProcessors.end();
266                 ++it ) {
267             if(!(*it)->isRunning()) notRunning=true;
268         }
269
270         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
271                 it != m_TransmitProcessors.end();
272                 ++it ) {
273             if(!(*it)->isRunning()) notRunning=true;
274         }
275
276         usleep(1000);
277         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Running check: %d\n", notRunning);
278     }
279
280     if(!wait_cycles) { // timout has occurred
281         debugFatal("One or more streams are not starting up (timeout):\n");
282
283         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
284                 it != m_ReceiveProcessors.end();
285                 ++it ) {
286             if(!(*it)->isRunning()) {
287                 debugFatal(" receive stream %p not running\n",*it);
288             } else {
289                 debugFatal(" receive stream %p running\n",*it);
290             }
291         }
292
293         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
294                 it != m_TransmitProcessors.end();
295                 ++it ) {
296             if(!(*it)->isRunning()) {
297                 debugFatal(" transmit stream %p not running\n",*it);
298             } else {
299                 debugFatal(" transmit stream %p running\n",*it);
300             }
301         }
302         return false;
303     }
304
305     debugOutput( DEBUG_LEVEL_VERBOSE, " StreamProcessor streams running...\n");
306
307     // now find out how long we have to delay the wait operation such that
308     // the received frames will all be presented to the SP
309     debugOutput( DEBUG_LEVEL_VERBOSE, "Finding minimal sync delay...\n");
310     int max_of_min_delay=0;
311     int min_delay=0;
312     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
313             it != m_ReceiveProcessors.end();
314             ++it ) {
315         min_delay=(*it)->getMaxFrameLatency();
316         if(min_delay>max_of_min_delay) max_of_min_delay=min_delay;
317     }
318
319     debugOutput( DEBUG_LEVEL_VERBOSE, "  %d ticks (%03us %04uc %04ut)...\n",
320         max_of_min_delay,
321         (unsigned int)TICKS_TO_SECS(max_of_min_delay),
322         (unsigned int)TICKS_TO_CYCLES(max_of_min_delay),
323         (unsigned int)TICKS_TO_OFFSET(max_of_min_delay));
324     m_SyncSource->setSyncDelay(max_of_min_delay);
325
326     debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for device to indicate clock sync lock...\n");
327     //sleep(2); // FIXME: be smarter here
328    
329     debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting StreamProcessors...\n");
330     // now we reset the frame counters
331     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
332             it != m_ReceiveProcessors.end();
333             ++it ) {
334         // get the receive SP's going at receiving data
335         (*it)->m_data_buffer->setTransparent(false);
336         (*it)->reset();
337     }
338
339     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
340             it != m_TransmitProcessors.end();
341             ++it ) {
342         // make sure the SP retains it's prefilled data
343         (*it)->m_data_buffer->setTransparent(false);
344         (*it)->reset();
345     }
346    
347     dumpInfo();
348     // All buffers are prefilled and set-up, the only thing
349     // that remains a mistery is the timestamp information.
350 //     m_SyncSource->m_data_buffer->setTransparent(false);
351 //     debugShowBackLog();
352
353 //     m_SyncSource->setVerboseLevel(DEBUG_LEVEL_ULTRA_VERBOSE);
354    
355     debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for sync...\n");
356     // in order to obtain that, we wait for the first periods to be
357     // received.
358     int nb_sync_runs=20;
359     while(nb_sync_runs--) { // or while not sync-ed?
360         waitForPeriod();
361         // drop the frames for all receive SP's
362         dryRun(StreamProcessor::ePT_Receive);
363        
364         // we don't have to dryrun for the xmit SP's since they
365         // are not sending data yet.
366        
367         // sync the xmit SP's buffer head timestamps
368         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
369                 it != m_TransmitProcessors.end();
370                 ++it ) {
371             // FIXME: encapsulate
372             (*it)->m_data_buffer->setBufferHeadTimestamp(m_time_of_transfer);
373         }
374     }
375 //     m_SyncSource->setVerboseLevel(DEBUG_LEVEL_VERBOSE);
376
377     debugOutput( DEBUG_LEVEL_VERBOSE, " sync at TS=%011llu (%03us %04uc %04ut)...\n",
378         m_time_of_transfer,
379         (unsigned int)TICKS_TO_SECS(m_time_of_transfer),
380         (unsigned int)TICKS_TO_CYCLES(m_time_of_transfer),
381         (unsigned int)TICKS_TO_OFFSET(m_time_of_transfer));
382     // FIXME: xruns can screw up the framecounter accounting. do something more sane here
383     resetXrunCounters();
384     // lock the isohandlermanager such that things freeze
385 //     debugShowBackLog();
386
387     // we now should have decent sync info
388     // the buffers of the receive streams should be (approx) empty
389     // the buffers of the xmit streams should be full
390    
391     // note what should the timestamp of the first sample be?
392    
393     // at this point the buffer head timestamp of the transmit buffers can be
394     // set properly since we know the sync source's timestamp of the last
395     // buffer transfer. we also know the rate.
396    
397     debugOutput( DEBUG_LEVEL_VERBOSE, " propagate sync info...\n");
398     // FIXME: in the SPM it would be nice to have system time instead of
399     //        1394 time
400 //     float rate=m_SyncSource->getTicksPerFrame();
401 //     int64_t one_ringbuffer_in_ticks=(int64_t)(((float)(m_nb_buffers*m_period))*rate);
402 //     // the data at the front of the buffer is intended to be transmitted
403 //     // nb_periods*period_size after the last received period
404 //     int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks);
405
406     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
407             it != m_TransmitProcessors.end();
408             ++it ) {
409         // FIXME: encapsulate
410         (*it)->m_data_buffer->setBufferHeadTimestamp(m_time_of_transfer);
411         //(*it)->m_data_buffer->setNominalRate(rate); //CHECK!!!
412     }
413    
414     dumpInfo();
415    
416     // this is the place were we should be syncing the received streams too
417     // check how much they differ
418    
419    
420     debugOutput( DEBUG_LEVEL_VERBOSE, "Enabling StreamProcessors...\n");
421
422     // FIXME: this should not be in cycles, but in 'time'
423     // FIXME: remove the timestamp
424     if (!enableStreamProcessors(0)) {
425         debugFatal("Could not enable StreamProcessors...\n");
426         return false;
427     }
428
429     debugOutput( DEBUG_LEVEL_VERBOSE, "Running dry for a while...\n");
430     #define MAX_DRYRUN_CYCLES               40
431     #define MIN_SUCCESSFUL_DRYRUN_CYCLES    4
432     // run some cycles 'dry' such that everything can stabilize
433     int nb_dryrun_cycles_left = MAX_DRYRUN_CYCLES;
434     int nb_succesful_cycles = 0;
435     while(nb_dryrun_cycles_left > 0 &&
436           nb_succesful_cycles < MIN_SUCCESSFUL_DRYRUN_CYCLES ) {
437
438         waitForPeriod();
439
440         if (dryRun()) {
441             nb_succesful_cycles++;
442         } else {
443             debugOutput( DEBUG_LEVEL_VERBOSE, " This dry-run was not xrun free...\n" );
444             resetXrunCounters();
445             // reset the transmit SP's such that there is no issue with accumulating buffers
446             // FIXME: what about receive SP's
447             for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
448                     it != m_TransmitProcessors.end();
449                     ++it ) {
450                 // FIXME: encapsulate
451                 (*it)->reset(); //CHECK!!!
452                 (*it)->m_data_buffer->setBufferHeadTimestamp(m_time_of_transfer);
453             }
454            
455             nb_succesful_cycles = 0;
456             // FIXME: xruns can screw up the framecounter accounting. do something more sane here
457         }
458         nb_dryrun_cycles_left--;
459     }
460
461     if(nb_dryrun_cycles_left == 0) {
462         debugOutput( DEBUG_LEVEL_VERBOSE, " max # dry-run cycles achieved without steady-state...\n" );
463         return false;
464     }
465     debugOutput( DEBUG_LEVEL_VERBOSE, " dry-run resulted in steady-state...\n" );
466
467     // now we should clear the xrun flags
468     resetXrunCounters();
469
470 /*    debugOutput( DEBUG_LEVEL_VERBOSE, "Aligning streams...\n");
471     // run some cycles 'dry' such that everything can stabilize
472     nb_dryrun_cycles_left = MAX_DRYRUN_CYCLES;
473     nb_succesful_cycles = 0;
474     while(nb_dryrun_cycles_left > 0 &&
475           nb_succesful_cycles < MIN_SUCCESSFUL_DRYRUN_CYCLES ) {
476
477         waitForPeriod();
478
479         // align the received streams
480         int64_t sp_lag;
481         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
482                 it != m_ReceiveProcessors.end();
483                 ++it ) {
484             uint64_t ts_sp=(*it)->getTimeAtPeriod();
485             uint64_t ts_sync=m_SyncSource->getTimeAtPeriod();
486
487             sp_lag = diffTicks(ts_sp, ts_sync);
488             debugOutput( DEBUG_LEVEL_VERBOSE, "  SP(%p) TS=%011llu - TS=%011llu = %04lld\n",
489                 (*it), ts_sp, ts_sync, sp_lag);
490             // sync the other receive SP's to the sync source
491 //             if((*it) != m_SyncSource) {
492 //                 if(!(*it)->m_data_buffer->syncCorrectLag(sp_lag)) {
493 //                         debugOutput(DEBUG_LEVEL_VERBOSE,"could not syncCorrectLag(%11lld) for stream processor (%p)\n",
494 //                                 sp_lag, *it);
495 //                 }
496 //             }
497         }
498
499
500         if (dryRun()) {
501             nb_succesful_cycles++;
502         } else {
503             debugOutput( DEBUG_LEVEL_VERBOSE, " This dry-run was not xrun free...\n" );
504             resetXrunCounters();
505             nb_succesful_cycles = 0;
506             // FIXME: xruns can screw up the framecounter accounting. do something more sane here
507         }
508         nb_dryrun_cycles_left--;
509     }
510
511     if(nb_dryrun_cycles_left == 0) {
512         debugOutput( DEBUG_LEVEL_VERBOSE, " max # dry-run cycles achieved without aligned steady-state...\n" );
513         return false;
514     }
515     debugOutput( DEBUG_LEVEL_VERBOSE, " dry-run resulted in aligned steady-state...\n" );*/
516    
517     // now we should clear the xrun flags
518     resetXrunCounters();
519     // and off we go
520     return true;
521 }
522
523 void StreamProcessorManager::resetXrunCounters(){
524     debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting xrun flags...\n");
525     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
526         it != m_ReceiveProcessors.end();
527         ++it )
528     {
529         (*it)->resetXrunCounter();
530     }
531
532     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
533         it != m_TransmitProcessors.end();
534         ++it )
535     {
536         (*it)->resetXrunCounter();
537     }
538 }
539
540 bool StreamProcessorManager::start() {
541     debugOutput( DEBUG_LEVEL_VERBOSE, "Starting Processors...\n");
542     assert(m_isoManager);
543
544     debugOutput( DEBUG_LEVEL_VERBOSE, "Creating handlers for the StreamProcessors...\n");
545     debugOutput( DEBUG_LEVEL_VERBOSE, " Receive processors...\n");
546     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
547         it != m_ReceiveProcessors.end();
548         ++it ) {
549             if (!(*it)->prepareForStart()) {
550                 debugOutput(DEBUG_LEVEL_VERBOSE,"Receive stream processor (%p) failed to prepare for start\n", *it);
551                 return false;
552             }
553             if (!m_isoManager->registerStream(*it)) {
554                 debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register receive stream processor (%p) with the Iso manager\n",*it);
555                 return false;
556             }
557         }
558
559     debugOutput( DEBUG_LEVEL_VERBOSE, " Transmit processors...\n");
560     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
561         it != m_TransmitProcessors.end();
562         ++it ) {
563             if (!(*it)->prepareForStart()) {
564                 debugOutput(DEBUG_LEVEL_VERBOSE,"Transmit stream processor (%p) failed to prepare for start\n", *it);
565                 return false;
566             }
567             if (!m_isoManager->registerStream(*it)) {
568                 debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register transmit stream processor (%p) with the Iso manager\n",*it);
569                 return false;
570             }
571         }
572
573     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing IsoHandlerManager...\n");
574     if (!m_isoManager->prepare()) {
575         debugFatal("Could not prepare isoManager\n");
576         return false;
577     }
578
579     debugOutput( DEBUG_LEVEL_VERBOSE, "Disabling StreamProcessors...\n");
580         if (!disableStreamProcessors()) {
581         debugFatal("Could not disable StreamProcessors...\n");
582         return false;
583     }
584
585     debugOutput( DEBUG_LEVEL_VERBOSE, "Starting IsoHandlers...\n");
586     if (!m_isoManager->startHandlers(-1)) {
587         debugFatal("Could not start handlers...\n");
588         return false;
589     }
590
591     // start all SP's synchonized
592     if (!syncStartAll()) {
593         debugFatal("Could not syncStartAll...\n");
594         return false;
595     }
596
597     // dump the iso stream information when in verbose mode
598     if(getDebugLevel()>=DEBUG_LEVEL_VERBOSE) {
599         m_isoManager->dumpInfo();
600     }
601
602     return true;
603
604 }
605
606 bool StreamProcessorManager::stop() {
607     debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping...\n");
608     assert(m_isoManager);
609
610     debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for all StreamProcessors to prepare to stop...\n");
611     // Most stream processors can just stop without special treatment.  However, some
612     // (like the MOTU) need to do a few things before it's safe to turn off the iso
613     // handling.
614     int wait_cycles=PREPARE_TIMEOUT_MSEC; // two seconds ought to be sufficient
615     bool allReady = false;
616     while (!allReady && wait_cycles) {
617         wait_cycles--;
618         allReady = true;
619
620         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
621             it != m_ReceiveProcessors.end();
622             ++it ) {
623             if(!(*it)->prepareForStop()) allReady = false;
624         }
625
626         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
627             it != m_TransmitProcessors.end();
628             ++it ) {
629             if(!(*it)->prepareForStop()) allReady = false;
630         }
631         usleep(1000);
632     }
633
634     debugOutput( DEBUG_LEVEL_VERBOSE, "Disabling StreamProcessors...\n");
635         if (!disableStreamProcessors()) {
636         debugFatal("Could not disable StreamProcessors...\n");
637         return false;
638     }
639
640     debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping handlers...\n");
641     if(!m_isoManager->stopHandlers()) {
642        debugFatal("Could not stop ISO handlers\n");
643        return false;
644     }
645
646     debugOutput( DEBUG_LEVEL_VERBOSE, "Unregistering processors from handlers...\n");
647     // now unregister all streams from iso manager
648     debugOutput( DEBUG_LEVEL_VERBOSE, " Receive processors...\n");
649     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
650         it != m_ReceiveProcessors.end();
651         ++it ) {
652             if (!m_isoManager->unregisterStream(*it)) {
653                 debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister receive stream processor (%p) from the Iso manager\n",*it);
654                 return false;
655             }
656
657         }
658
659     debugOutput( DEBUG_LEVEL_VERBOSE, " Transmit processors...\n");
660     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
661         it != m_TransmitProcessors.end();
662         ++it ) {
663             if (!m_isoManager->unregisterStream(*it)) {
664                 debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister transmit stream processor (%p) from the Iso manager\n",*it);
665                 return false;
666             }
667
668         }
669
670     return true;
671
672 }
673
674 /**
675  * Enables the registered StreamProcessors
676  * @return true if successful, false otherwise
677  */
678 bool StreamProcessorManager::enableStreamProcessors(uint64_t time_to_enable_at) {
679     debugOutput( DEBUG_LEVEL_VERBOSE, "Enabling StreamProcessors at %llu...\n", time_to_enable_at);
680
681     debugOutput( DEBUG_LEVEL_VERBOSE, " Sync Source StreamProcessor (%p)...\n",m_SyncSource);
682     debugOutput( DEBUG_LEVEL_VERBOSE, "  Prepare...\n");
683     if (!m_SyncSource->prepareForEnable(time_to_enable_at)) {
684             debugFatal("Could not prepare Sync Source StreamProcessor for enable()...\n");
685         return false;
686     }
687
688     debugOutput( DEBUG_LEVEL_VERBOSE, "  Enable...\n");
689     m_SyncSource->enable(time_to_enable_at);
690
691     debugOutput( DEBUG_LEVEL_VERBOSE, " Other StreamProcessors...\n");
692
693     // we prepare the streamprocessors for enable
694     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
695             it != m_ReceiveProcessors.end();
696             ++it ) {
697         if(*it != m_SyncSource) {
698             debugOutput( DEBUG_LEVEL_VERBOSE, " Prepare Receive SP (%p)...\n",*it);
699             (*it)->prepareForEnable(time_to_enable_at);
700         }
701     }
702
703     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
704             it != m_TransmitProcessors.end();
705             ++it ) {
706         if(*it != m_SyncSource) {
707             debugOutput( DEBUG_LEVEL_VERBOSE, " Prepare Transmit SP (%p)...\n",*it);
708             (*it)->prepareForEnable(time_to_enable_at);
709         }
710     }
711
712     // then we enable the streamprocessors
713     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
714             it != m_ReceiveProcessors.end();
715             ++it ) {
716         if(*it != m_SyncSource) {
717             debugOutput( DEBUG_LEVEL_VERBOSE, " Enable Receive SP (%p)...\n",*it);
718             (*it)->enable(time_to_enable_at);
719         }
720     }
721
722     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
723             it != m_TransmitProcessors.end();
724             ++it ) {
725         if(*it != m_SyncSource) {
726             debugOutput( DEBUG_LEVEL_VERBOSE, " Enable Transmit SP (%p)...\n",*it);
727             (*it)->enable(time_to_enable_at);
728         }
729     }
730
731     // now we wait for the SP's to get enabled
732 //     debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for all StreamProcessors to be enabled...\n");
733 //     // we have to wait until all streamprocessors indicate that they are running
734 //     // i.e. that there is actually some data stream flowing
735 //     int wait_cycles=ENABLE_TIMEOUT_MSEC; // two seconds
736 //     bool notEnabled=true;
737 //     while (notEnabled && wait_cycles) {
738 //         wait_cycles--;
739 //         notEnabled=false;
740 //
741 //         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
742 //                 it != m_ReceiveProcessors.end();
743 //                 ++it ) {
744 //             if(!(*it)->isEnabled()) notEnabled=true;
745 //         }
746 //
747 //         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
748 //                 it != m_TransmitProcessors.end();
749 //                 ++it ) {
750 //             if(!(*it)->isEnabled()) notEnabled=true;
751 //         }
752 //         usleep(1000); // one cycle
753 //     }
754 //
755 //     if(!wait_cycles) { // timout has occurred
756 //         debugFatal("One or more streams couldn't be enabled (timeout):\n");
757 //
758 //         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
759 //                 it != m_ReceiveProcessors.end();
760 //                 ++it ) {
761 //             if(!(*it)->isEnabled()) {
762 //                     debugFatal(" receive stream %p not enabled\n",*it);
763 //             } else {
764 //                     debugFatal(" receive stream %p enabled\n",*it);
765 //             }
766 //         }
767 //
768 //         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
769 //                 it != m_TransmitProcessors.end();
770 //                 ++it ) {
771 //             if(!(*it)->isEnabled()) {
772 //                     debugFatal(" transmit stream %p not enabled\n",*it);
773 //             } else {
774 //                     debugFatal(" transmit stream %p enabled\n",*it);
775 //             }
776 //         }
777 //         return false;
778 //     }
779
780     debugOutput( DEBUG_LEVEL_VERBOSE, " => all StreamProcessors enabled...\n");
781
782     return true;
783 }
784
785 /**
786  * Disables the registered StreamProcessors
787  * @return true if successful, false otherwise
788  */
789 bool StreamProcessorManager::disableStreamProcessors() {
790     // we prepare the streamprocessors for disable
791     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
792             it != m_ReceiveProcessors.end();
793             ++it ) {
794         (*it)->prepareForDisable();
795     }
796
797     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
798             it != m_TransmitProcessors.end();
799             ++it ) {
800         (*it)->prepareForDisable();
801     }
802
803     // then we disable the streamprocessors
804     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
805             it != m_ReceiveProcessors.end();
806             ++it ) {
807         (*it)->disable();
808         (*it)->m_data_buffer->setTransparent(true);
809     }
810
811     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
812             it != m_TransmitProcessors.end();
813             ++it ) {
814         (*it)->disable();
815         (*it)->m_data_buffer->setTransparent(true);
816     }
817
818     // now we wait for the SP's to get disabled
819     debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for all StreamProcessors to be disabled...\n");
820     // we have to wait until all streamprocessors indicate that they are running
821     // i.e. that there is actually some data stream flowing
822     int wait_cycles=ENABLE_TIMEOUT_MSEC; // two seconds
823     bool enabled=true;
824     while (enabled && wait_cycles) {
825         wait_cycles--;
826         enabled=false;
827
828         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
829                 it != m_ReceiveProcessors.end();
830                 ++it ) {
831             if((*it)->isEnabled()) enabled=true;
832         }
833
834         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
835                 it != m_TransmitProcessors.end();
836                 ++it ) {
837             if((*it)->isEnabled()) enabled=true;
838         }
839         usleep(1000); // one cycle
840     }
841
842     if(!wait_cycles) { // timout has occurred
843         debugFatal("One or more streams couldn't be disabled (timeout):\n");
844
845         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
846                 it != m_ReceiveProcessors.end();
847                 ++it ) {
848             if(!(*it)->isEnabled()) {
849                     debugFatal(" receive stream %p not enabled\n",*it);
850             } else {
851                     debugFatal(" receive stream %p enabled\n",*it);
852             }
853         }
854
855         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
856                 it != m_TransmitProcessors.end();
857                 ++it ) {
858             if(!(*it)->isEnabled()) {
859                     debugFatal(" transmit stream %p not enabled\n",*it);
860             } else {
861                     debugFatal(" transmit stream %p enabled\n",*it);
862             }
863         }
864         return false;
865     }
866
867     debugOutput( DEBUG_LEVEL_VERBOSE, " => all StreamProcessors disabled...\n");
868
869     return true;
870 }
871
872 /**
873  * Called upon Xrun events. This brings all StreamProcessors back
874  * into their starting state, and then carries on streaming. This should
875  * have the same effect as restarting the whole thing.
876  *
877  * @return true if successful, false otherwise
878  */
879 bool StreamProcessorManager::handleXrun() {
880
881     debugOutput( DEBUG_LEVEL_VERBOSE, "Handling Xrun ...\n");
882
883     dumpInfo();
884
885     /*
886      * Reset means:
887      * 1) Disabling the SP's, so that they don't process any packets
888      *    note: the isomanager does keep on delivering/requesting them
889      * 2) Bringing all buffers & streamprocessors into a know state
890      *    - Clear all capture buffers
891      *    - Put nb_periods*period_size of null frames into the playback buffers
892      * 3) Re-enable the SP's
893      */
894     debugOutput( DEBUG_LEVEL_VERBOSE, "Disabling StreamProcessors...\n");
895         if (!disableStreamProcessors()) {
896         debugFatal("Could not disable StreamProcessors...\n");
897         return false;
898     }
899
900     debugOutput( DEBUG_LEVEL_VERBOSE, "Restarting StreamProcessors...\n");
901     // start all SP's synchonized
902     if (!syncStartAll()) {
903         debugFatal("Could not syncStartAll...\n");
904         return false;
905     }
906
907     debugOutput( DEBUG_LEVEL_VERBOSE, "Xrun handled...\n");
908
909     return true;
910 }
911
912 /**
913  * @brief Waits until the next period of samples is ready
914  *
915  * This function does not return until a full period of samples is (or should be)
916  * ready to be transferred.
917  *
918  * @return true if the period is ready, false if an xrun occurred
919  */
920 bool StreamProcessorManager::waitForPeriod() {
921     int time_till_next_period;
922     bool xrun_occurred=false;
923
924     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n");
925
926     assert(m_SyncSource);
927
928     time_till_next_period=m_SyncSource->getTimeUntilNextPeriodSignalUsecs();
929
930     while(time_till_next_period > 0) {
931         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "waiting for %d usecs...\n", time_till_next_period);
932
933         // wait for the period
934         usleep(time_till_next_period);
935
936         // check for underruns on the ISO side,
937         // those should make us bail out of the wait loop
938         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
939             it != m_ReceiveProcessors.end();
940             ++it ) {
941             // a xrun has occurred on the Iso side
942             xrun_occurred |= (*it)->xrunOccurred();
943         }
944         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
945             it != m_TransmitProcessors.end();
946             ++it ) {
947             // a xrun has occurred on the Iso side
948             xrun_occurred |= (*it)->xrunOccurred();
949         }
950
951         if(xrun_occurred) break;
952
953         // check if we were waked up too soon
954         time_till_next_period=m_SyncSource->getTimeUntilNextPeriodSignalUsecs();
955     }
956
957     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "delayed for %d usecs...\n", time_till_next_period);
958
959     // this is to notify the client of the delay
960     // that we introduced
961     m_delayed_usecs=time_till_next_period;
962
963     // we save the 'ideal' time of the transfer at this point,
964     // because we can have interleaved read - process - write
965     // cycles making that we modify a receiving stream's buffer
966     // before we get to writing.
967     // NOTE: before waitForPeriod() is called again, both the transmit
968     //       and the receive processors should have done their transfer.
969     m_time_of_transfer = m_SyncSource->getTimeAtPeriod();
970     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "transfer at %llu ticks...\n",
971         m_time_of_transfer);
972
973 #ifdef DEBUG
974     int rcv_bf=0, xmt_bf=0;
975     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
976         it != m_ReceiveProcessors.end();
977         ++it ) {
978         rcv_bf = (*it)->getBufferFill();
979     }
980     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
981         it != m_TransmitProcessors.end();
982         ++it ) {
983         xmt_bf = (*it)->getBufferFill();
984     }
985     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "XF at %011llu ticks, RBF=%d, XBF=%d, SUM=%d...\n",
986         m_time_of_transfer, rcv_bf, xmt_bf, rcv_bf+xmt_bf);
987
988 #endif
989
990     xrun_occurred=false;
991
992     // check if xruns occurred on the Iso side.
993     // also check if xruns will occur should we transfer() now
994
995     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
996           it != m_ReceiveProcessors.end();
997           ++it ) {
998         // a xrun has occurred on the Iso side
999         xrun_occurred |= (*it)->xrunOccurred();
1000
1001         // if this is true, a xrun will occur
1002         xrun_occurred |= !((*it)->canClientTransferFrames(m_period)) && (*it)->isEnabled();
1003
1004 #ifdef DEBUG
1005         if ((*it)->xrunOccurred()) {
1006             debugWarning("Xrun on RECV SP %p due to ISO xrun\n",*it);
1007             (*it)->dumpInfo();
1008         }
1009         if (!((*it)->canClientTransferFrames(m_period)) && (*it)->isEnabled()) {
1010             debugWarning("Xrun on RECV SP %p due to buffer xrun\n",*it);
1011             (*it)->dumpInfo();
1012         }
1013 #endif
1014
1015     }
1016     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1017           it != m_TransmitProcessors.end();
1018           ++it ) {
1019         // a xrun has occurred on the Iso side
1020         xrun_occurred |= (*it)->xrunOccurred();
1021
1022         // if this is true, a xrun will occur
1023         xrun_occurred |= !((*it)->canClientTransferFrames(m_period)) && (*it)->isEnabled();
1024
1025 #ifdef DEBUG
1026         if ((*it)->xrunOccurred()) {
1027             debugWarning("Xrun on XMIT SP %p due to ISO xrun\n",*it);
1028         }
1029         if (!((*it)->canClientTransferFrames(m_period)) && (*it)->isEnabled()) {
1030             debugWarning("Xrun on XMIT SP %p due to buffer xrun\n",*it);
1031         }
1032 #endif
1033     }
1034
1035     m_nbperiods++;
1036
1037     // now we can signal the client that we are (should be) ready
1038     return !xrun_occurred;
1039 }
1040
1041 /**
1042  * @brief Transfer one period of frames for both receive and transmit StreamProcessors
1043  *
1044  * Transfers one period of frames from the client side to the Iso side and vice versa.
1045  *
1046  * @return true if successful, false otherwise (indicates xrun).
1047  */
1048 bool StreamProcessorManager::transfer() {
1049
1050     debugOutput( DEBUG_LEVEL_VERBOSE, "Transferring period...\n");
1051     bool retval=true;
1052     retval &= dryRun(StreamProcessor::ePT_Receive);
1053     retval &= dryRun(StreamProcessor::ePT_Transmit);
1054     return retval;
1055 }
1056
1057 /**
1058  * @brief Transfer one period of frames for either the receive or transmit StreamProcessors
1059  *
1060  * Transfers one period of frames from the client side to the Iso side or vice versa.
1061  *
1062  * @param t The processor type to tranfer for (receive or transmit)
1063  * @return true if successful, false otherwise (indicates xrun).
1064  */
1065
1066 bool StreamProcessorManager::transfer(enum StreamProcessor::eProcessorType t) {
1067     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n");
1068     bool retval = true;
1069     // a static cast could make sure that there is no performance
1070     // penalty for the virtual functions (to be checked)
1071     if (t==StreamProcessor::ePT_Receive) {
1072         // determine the time at which we want reception to start
1073         float rate=m_SyncSource->getTicksPerFrame();
1074         int64_t one_frame_in_ticks=(int64_t)(((float)m_period)*rate);
1075        
1076         int64_t receive_timestamp = substractTicks(m_time_of_transfer, one_frame_in_ticks);
1077        
1078         if(receive_timestamp<0) {
1079             debugWarning("receive ts < 0.0 : %lld, m_time_of_transfer= %llu, one_frame_in_ticks=%lld\n",
1080              receive_timestamp, m_time_of_transfer, one_frame_in_ticks);
1081         }
1082         if(receive_timestamp>(128L*TICKS_PER_SECOND)) {
1083             debugWarning("receive ts > 128L*TICKS_PER_SECOND : %lld, m_time_of_transfer= %llu, one_frame_in_ticks=%lld\n",
1084              receive_timestamp, m_time_of_transfer, one_frame_in_ticks);
1085         }
1086        
1087         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1088                 it != m_ReceiveProcessors.end();
1089                 ++it ) {
1090
1091             if(!(*it)->getFrames(m_period, receive_timestamp)) {
1092                     debugOutput(DEBUG_LEVEL_VERBOSE,"could not getFrames(%u, %11llu) from stream processor (%p)\n",
1093                             m_period, m_time_of_transfer,*it);
1094                 retval &= false; // buffer underrun
1095             }
1096         }
1097     } else {
1098         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1099                 it != m_TransmitProcessors.end();
1100                 ++it ) {
1101             // FIXME: in the SPM it would be nice to have system time instead of
1102             //        1394 time
1103             float rate=m_SyncSource->getTicksPerFrame();
1104             int64_t one_ringbuffer_in_ticks=(int64_t)(((float)(m_nb_buffers*m_period))*rate);
1105
1106             // the data we are putting into the buffer is intended to be transmitted
1107             // one ringbuffer size after it has been received
1108             int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks);
1109
1110             if(!(*it)->putFrames(m_period, transmit_timestamp)) {
1111                 debugOutput(DEBUG_LEVEL_VERBOSE, "could not putFrames(%u,%llu) to stream processor (%p)\n",
1112                         m_period, transmit_timestamp, *it);
1113                 retval &= false; // buffer underrun
1114             }
1115
1116         }
1117     }
1118     return retval;
1119 }
1120
1121 /**
1122  * @brief Dry run one period for both receive and transmit StreamProcessors
1123  *
1124  * Process one period of frames for all streamprocessors, without touching the
1125  * client buffers. This only removes an incoming period from the ISO receive buffer and
1126  * puts one period of silence into the transmit buffers.
1127  *
1128  * @return true if successful, false otherwise (indicates xrun).
1129  */
1130 bool StreamProcessorManager::dryRun() {
1131     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Dry-running period...\n");
1132     bool retval=true;
1133     retval &= dryRun(StreamProcessor::ePT_Receive);
1134     retval &= dryRun(StreamProcessor::ePT_Transmit);
1135     return retval;
1136 }
1137
1138 /**
1139  * @brief Dry run one period for either the receive or transmit StreamProcessors
1140  *
1141  * see dryRun()
1142  *
1143  * @param t The processor type to dryRun for (receive or transmit)
1144  * @return true if successful, false otherwise (indicates xrun).
1145  */
1146
1147 bool StreamProcessorManager::dryRun(enum StreamProcessor::eProcessorType t) {
1148     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Dry-running period...\n");
1149     bool retval = true;
1150     // a static cast could make sure that there is no performance
1151     // penalty for the virtual functions (to be checked)
1152     if (t==StreamProcessor::ePT_Receive) {
1153         // determine the time at which we want reception to start
1154         float rate=m_SyncSource->getTicksPerFrame();
1155         int64_t one_frame_in_ticks=(int64_t)(((float)m_period)*rate);
1156        
1157         int64_t receive_timestamp = substractTicks(m_time_of_transfer, one_frame_in_ticks);
1158        
1159         if(receive_timestamp<0) {
1160             debugWarning("receive ts < 0.0 : %lld, m_time_of_transfer= %llu, one_frame_in_ticks=%lld\n",
1161              receive_timestamp, m_time_of_transfer, one_frame_in_ticks);
1162         }
1163         if(receive_timestamp>(128L*TICKS_PER_SECOND)) {
1164             debugWarning("receive ts > 128L*TICKS_PER_SECOND : %lld, m_time_of_transfer= %llu, one_frame_in_ticks=%lld\n",
1165              receive_timestamp, m_time_of_transfer, one_frame_in_ticks);
1166         }
1167        
1168         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1169                 it != m_ReceiveProcessors.end();
1170                 ++it ) {
1171
1172             if(!(*it)->getFramesDry(m_period, receive_timestamp)) {
1173                     debugOutput(DEBUG_LEVEL_VERBOSE,"could not getFrames(%u, %11llu) from stream processor (%p)\n",
1174                             m_period, m_time_of_transfer,*it);
1175                 retval &= false; // buffer underrun
1176             }
1177
1178         }
1179     } else {
1180         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1181                 it != m_TransmitProcessors.end();
1182                 ++it ) {
1183             // FIXME: in the SPM it would be nice to have system time instead of
1184             //        1394 time
1185             float rate=m_SyncSource->getTicksPerFrame();
1186             int64_t one_ringbuffer_in_ticks=(int64_t)(((float)(m_nb_buffers*m_period))*rate);
1187
1188             // the data we are putting into the buffer is intended to be transmitted
1189             // one ringbuffer size after it has been received
1190             int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks);
1191
1192             if(!(*it)->putFramesDry(m_period, transmit_timestamp)) {
1193                 debugOutput(DEBUG_LEVEL_VERBOSE, "could not putFrames(%u,%llu) to stream processor (%p)\n",
1194                         m_period, transmit_timestamp, *it);
1195                 retval &= false; // buffer underrun
1196             }
1197
1198         }
1199     }
1200     return retval;
1201 }
1202
1203 void StreamProcessorManager::dumpInfo() {
1204     debugOutputShort( DEBUG_LEVEL_NORMAL, "----------------------------------------------------\n");
1205     debugOutputShort( DEBUG_LEVEL_NORMAL, "Dumping StreamProcessorManager information...\n");
1206     debugOutputShort( DEBUG_LEVEL_NORMAL, "Period count: %6d\n", m_nbperiods);
1207
1208     debugOutputShort( DEBUG_LEVEL_NORMAL, " Receive processors...\n");
1209     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1210         it != m_ReceiveProcessors.end();
1211         ++it ) {
1212         (*it)->dumpInfo();
1213     }
1214
1215     debugOutputShort( DEBUG_LEVEL_NORMAL, " Transmit processors...\n");
1216     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1217         it != m_TransmitProcessors.end();
1218         ++it ) {
1219         (*it)->dumpInfo();
1220     }
1221
1222     debugOutputShort( DEBUG_LEVEL_NORMAL, "Iso handler info:\n");
1223     m_isoManager->dumpInfo();
1224     debugOutputShort( DEBUG_LEVEL_NORMAL, "----------------------------------------------------\n");
1225
1226 }
1227
1228 void StreamProcessorManager::setVerboseLevel(int l) {
1229     setDebugLevel(l);
1230
1231     if (m_isoManager) m_isoManager->setVerboseLevel(l);
1232
1233     debugOutput( DEBUG_LEVEL_VERBOSE, " Receive processors...\n");
1234     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1235         it != m_ReceiveProcessors.end();
1236         ++it ) {
1237         (*it)->setVerboseLevel(l);
1238     }
1239
1240     debugOutput( DEBUG_LEVEL_VERBOSE, " Transmit processors...\n");
1241     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1242         it != m_TransmitProcessors.end();
1243         ++it ) {
1244         (*it)->setVerboseLevel(l);
1245     }
1246 }
1247
1248
1249 int StreamProcessorManager::getPortCount(enum Port::E_PortType type, enum Port::E_Direction direction) {
1250     int count=0;
1251
1252     if (direction == Port::E_Capture) {
1253         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1254             it != m_ReceiveProcessors.end();
1255             ++it ) {
1256             count += (*it)->getPortCount(type);
1257         }
1258     } else {
1259         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1260             it != m_TransmitProcessors.end();
1261             ++it ) {
1262             count += (*it)->getPortCount(type);
1263         }
1264     }
1265     return count;
1266 }
1267
1268 int StreamProcessorManager::getPortCount(enum Port::E_Direction direction) {
1269     int count=0;
1270
1271     if (direction == Port::E_Capture) {
1272         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1273             it != m_ReceiveProcessors.end();
1274             ++it ) {
1275             count += (*it)->getPortCount();
1276         }
1277     } else {
1278         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1279             it != m_TransmitProcessors.end();
1280             ++it ) {
1281             count += (*it)->getPortCount();
1282         }
1283     }
1284     return count;
1285 }
1286
1287 // TODO: implement a port map here, instead of the loop
1288
1289 Port* StreamProcessorManager::getPortByIndex(int idx, enum Port::E_Direction direction) {
1290     int count=0;
1291     int prevcount=0;
1292
1293     if (direction == Port::E_Capture) {
1294         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin();
1295             it != m_ReceiveProcessors.end();
1296             ++it ) {
1297             count += (*it)->getPortCount();
1298             if (count > idx) {
1299                 return (*it)->getPortAtIdx(idx-prevcount);
1300             }
1301             prevcount=count;
1302         }
1303     } else {
1304         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();
1305             it != m_TransmitProcessors.end();
1306             ++it ) {
1307             count += (*it)->getPortCount();
1308             if (count > idx) {
1309                 return (*it)->getPortAtIdx(idx-prevcount);
1310             }
1311             prevcount=count;
1312         }
1313     }
1314     return NULL;
1315 }
1316
1317 bool StreamProcessorManager::setThreadParameters(bool rt, int priority) {
1318     m_thread_realtime=rt;
1319     m_thread_priority=priority;
1320     return true;
1321 }
1322
1323
1324 } // end of namespace
Note: See TracBrowser for help on using the browser.