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

Revision 715, 46.4 kB (checked in by ppalmers, 16 years ago)

some more cleaning

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