root/branches/streaming-rework/src/libstreaming/IsoHandlerManager.cpp

Revision 390, 20.3 kB (checked in by pieterpalmers, 17 years ago)

* working version of SYT based AMDTP receive and transmit.

Still has to be tuned to work with low buffer sizes.

Line 
1 /* $Id$ */
2
3 /*
4  *   FreeBob Streaming API
5  *   FreeBob = Firewire (pro-)audio for linux
6  *
7  *   http://freebob.sf.net
8  *
9  *   Copyright (C) 2006 Pieter Palmers <pieterpalmers@users.sourceforge.net>
10  *
11  *   This program is free software {} you can redistribute it and/or modify
12  *   it under the terms of the GNU General Public License as published by
13  *   the Free Software Foundation {} either version 2 of the License, or
14  *   (at your option) any later version.
15  *
16  *   This program is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY {} without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *   GNU General Public License for more details.
20  *
21  *   You should have received a copy of the GNU General Public License
22  *   along with this program {} if not, write to the Free Software
23  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  *
26  *
27  */
28
29 #include "IsoHandlerManager.h"
30 #include "IsoHandler.h"
31 #include "IsoStream.h"
32 #include <assert.h>
33
34 #include "../libutil/PosixThread.h"
35
36
37 #define MINIMUM_INTERRUPTS_PER_PERIOD  4U
38 #define PACKETS_PER_INTERRUPT          4U
39
40 namespace FreebobStreaming
41 {
42
43 IMPL_DEBUG_MODULE( IsoHandlerManager, IsoHandlerManager, DEBUG_LEVEL_NORMAL );
44
45 IsoHandlerManager::IsoHandlerManager() :
46    m_State(E_Created),
47    m_poll_timeout(1), m_poll_fds(0), m_poll_nfds(0),
48    m_realtime(false), m_priority(0)
49 {
50
51 }
52
53 IsoHandlerManager::IsoHandlerManager(bool run_rt, unsigned int rt_prio) :
54    m_State(E_Created),
55    m_poll_timeout(1), m_poll_fds(0), m_poll_nfds(0),
56    m_realtime(run_rt), m_priority(rt_prio)
57 {
58
59 }
60
61 IsoHandlerManager::~IsoHandlerManager()
62 {
63
64 }
65
66 bool IsoHandlerManager::init()
67 {
68     // the tread that performs the actual packet transfer
69     // needs high priority
70     unsigned int prio=m_priority+6;
71
72     if (prio>98) prio=98;
73
74     m_isoManagerThread=new FreebobUtil::PosixThread(
75         this,
76         m_realtime, prio,
77         PTHREAD_CANCEL_DEFERRED);
78
79     if(!m_isoManagerThread) {
80         debugFatal("Could not create iso manager thread\n");
81         return false;
82     }
83
84     // propagate the debug level
85 //     m_isoManagerThread->setVerboseLevel(getDebugLevel());
86
87     return true;
88 }
89
90 bool IsoHandlerManager::Init()
91 {
92     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
93
94     return true;
95 }
96
97 /**
98  * the IsoHandlerManager thread execute function iterates the handlers.
99  *
100  * This means that once the thread is running, streams are
101  * transmitted and received (if present on the bus). Make sure
102  * that the clients are registered & ready before starting the
103  * thread!
104  *
105  * The register and unregister functions are thread unsafe, so
106  * should not be used when the thread is running.
107  *
108  * @return false if the handlers could not be iterated.
109  */
110 bool IsoHandlerManager::Execute()
111 {
112 //     updateCycleTimers();
113    
114     if(!iterate()) {
115         debugFatal("Could not iterate the isoManager\n");
116         return false;
117     }   
118    
119     return true;
120 }
121
122 /**
123  * Poll the handlers managed by this manager, and iterate them
124  * when ready
125  *
126  * @return true when successful
127  */
128 bool IsoHandlerManager::iterate()
129 {
130         int err;
131         int i=0;
132         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n");
133        
134         err = poll (m_poll_fds, m_poll_nfds, m_poll_timeout);
135        
136         if (err == -1) {
137                 if (errno == EINTR) {
138                         return true;
139                 }
140                 debugFatal("poll error: %s\n", strerror (errno));
141                 return false;
142         }
143
144         for (i = 0; i < m_poll_nfds; i++) {
145                 if (m_poll_fds[i].revents & POLLERR) {
146                         debugWarning("error on fd for %d\n",i);
147                 }
148
149                 if (m_poll_fds[i].revents & POLLHUP) {
150                         debugWarning("hangup on fd for %d\n",i);
151                 }
152                
153                 if(m_poll_fds[i].revents & (POLLIN)) {
154                         IsoHandler *s=m_IsoHandlers.at(i);
155                         assert(s);
156                        
157                         s->iterate();
158                 }
159         }
160
161         return true;
162
163 }
164
165 // updates the internal cycle timer caches of the handlers
166 void IsoHandlerManager::updateCycleTimers() {
167     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n");
168    
169     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
170           it != m_IsoHandlers.end();
171           ++it )
172     {
173         int cnt=0;
174         while (!(*it)->updateCycleTimer() && (cnt++ < MAX_UPDATE_TRIES)) {
175             usleep(USLEEP_AFTER_UPDATE_FAILURE);
176         }
177     }
178    
179 }
180
181 bool IsoHandlerManager::registerHandler(IsoHandler *handler)
182 {
183     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
184     assert(handler);
185    
186     m_IsoHandlers.push_back(handler);
187    
188     handler->setVerboseLevel(getDebugLevel());
189
190     // rebuild the fd map for poll()'ing.
191     return rebuildFdMap();     
192
193 }
194
195 bool IsoHandlerManager::unregisterHandler(IsoHandler *handler)
196 {
197         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
198         assert(handler);
199
200         for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
201           it != m_IsoHandlers.end();
202           ++it )
203         {
204                 if ( *it == handler ) {
205                         // erase the iso handler from the list
206                         m_IsoHandlers.erase(it);
207                         // rebuild the fd map for poll()'ing.
208                         return rebuildFdMap();
209                 }
210         }
211         debugFatal("Could not find handler (%p)\n", handler);
212        
213         return false; //not found
214
215 }
216
217 bool IsoHandlerManager::rebuildFdMap() {
218         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
219         int i=0;
220
221         m_poll_nfds=0;
222         if(m_poll_fds) free(m_poll_fds);
223
224         // count the number of handlers
225         m_poll_nfds=m_IsoHandlers.size();
226
227         // allocate the fd array
228         m_poll_fds   = (struct pollfd *) calloc (m_poll_nfds, sizeof (struct pollfd));
229         if(!m_poll_fds) {
230                 debugFatal("Could not allocate memory for poll FD array\n");
231                 return false;
232         }
233
234         // fill the fd map
235         for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
236           it != m_IsoHandlers.end();
237           ++it )
238         {
239                 m_poll_fds[i].fd=(*it)->getFileDescriptor();
240                 m_poll_fds[i].events = POLLIN;
241                 i++;
242         }
243
244         return true;
245 }
246
247 void IsoHandlerManager::disablePolling(IsoStream *stream) {
248     int i=0;
249    
250     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Disable polling on stream %p\n",stream);
251
252     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
253         it != m_IsoHandlers.end();
254         ++it )
255     {
256         if ((*it)->isStreamRegistered(stream)) {
257             m_poll_fds[i].events = 0;
258             m_poll_fds[i].revents = 0;
259             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "polling disabled\n");
260         }
261        
262         i++;
263     }
264 }
265
266 void IsoHandlerManager::enablePolling(IsoStream *stream) {
267     int i=0;
268    
269     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Enable polling on stream %p\n",stream);
270    
271     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
272         it != m_IsoHandlers.end();
273         ++it )
274     {
275         if ((*it)->isStreamRegistered(stream)) {
276             m_poll_fds[i].events = POLLIN;
277             m_poll_fds[i].revents = 0;
278             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "polling enabled\n");
279         }
280        
281         i++;
282     }
283 }
284
285
286 /**
287  * Registers an IsoStream with the IsoHandlerManager.
288  *
289  * If nescessary, an IsoHandler is created to handle this stream.
290  * Once an IsoStream is registered to the handler, it will be included
291  * in the ISO streaming cycle (i.e. receive/transmit of it will occur).
292  *
293  * @param stream the stream to register
294  * @return true if registration succeeds
295  *
296  * \todo : currently there is a one-to-one mapping
297  *        between streams and handlers, this is not ok for
298  *        multichannel receive
299  */
300 bool IsoHandlerManager::registerStream(IsoStream *stream)
301 {
302         debugOutput( DEBUG_LEVEL_VERBOSE, "Registering stream %p\n",stream);
303         assert(stream);
304
305         // make sure the stream isn't already attached to a handler
306         for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
307           it != m_IsoHandlers.end();
308           ++it )
309         {
310                 if((*it)->isStreamRegistered(stream)) {
311                         debugWarning( "stream already registered!\n");
312                         (*it)->unregisterStream(stream);
313                        
314                 }
315         }
316        
317         // clean up all handlers that aren't used
318         pruneHandlers();
319
320         // allocate a handler for this stream
321         if (stream->getType()==IsoStream::EST_Receive) {
322                 // setup the optimal parameters for the raw1394 ISO buffering
323                 unsigned int packets_per_period=stream->getPacketsPerPeriod();
324                
325 #if 1
326                 // hardware interrupts occur when one DMA block is full, and the size of one DMA
327                 // block = PAGE_SIZE. Setting the max_packet_size makes sure that the HW irq is
328                 // occurs at a period boundary (optimal CPU use)
329                
330                 // NOTE: try and use MINIMUM_INTERRUPTS_PER_PERIOD hardware interrupts
331                 //       per period for better latency.
332                 unsigned int max_packet_size=MINIMUM_INTERRUPTS_PER_PERIOD * getpagesize() / packets_per_period;
333                 if (max_packet_size < stream->getMaxPacketSize()) {
334                         max_packet_size=stream->getMaxPacketSize();
335                 }
336
337                 // Ensure we don't request a packet size bigger than the
338                 // kernel-enforced maximum which is currently 1 page.
339                 if (max_packet_size > (unsigned int)getpagesize())
340                         max_packet_size = getpagesize();
341
342                 unsigned int irq_interval=packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD;
343                 if(irq_interval <= 0) irq_interval=1;
344 #else
345                 // hardware interrupts occur when one DMA block is full, and the size of one DMA
346                 // block = PAGE_SIZE. Setting the max_packet_size enables control over the IRQ
347                 // frequency, as the controller uses max_packet_size, and not the effective size
348                 // when writing to the DMA buffer.
349                
350                 // configure it such that we have an irq for every PACKETS_PER_INTERRUPT packets
351                 unsigned int irq_interval=PACKETS_PER_INTERRUPT;
352                
353                 // unless the period size doesn't allow this
354                 if ((packets_per_period/MINIMUM_INTERRUPTS_PER_PERIOD) < irq_interval) {
355                         irq_interval=1;
356                 }
357                
358                 // FIXME: test
359                 irq_interval=1;
360                
361                 unsigned int max_packet_size=getpagesize() / irq_interval;
362
363                 if (max_packet_size < stream->getMaxPacketSize()) {
364                         max_packet_size=stream->getMaxPacketSize();
365                 }
366
367                 // Ensure we don't request a packet size bigger than the
368                 // kernel-enforced maximum which is currently 1 page.
369                 if (max_packet_size > (unsigned int)getpagesize())
370                         max_packet_size = getpagesize();
371
372 #endif
373                 /* the receive buffer size doesn't matter for the latency,
374                    but it has a minimal value in order for libraw to operate correctly (300) */
375                 int buffers=400;
376                
377                 // create the actual handler
378                 IsoRecvHandler *h = new IsoRecvHandler(stream->getPort(), buffers,
379                                                        max_packet_size, irq_interval);
380
381                 debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoRecvHandler\n");
382
383                 if(!h) {
384                         debugFatal("Could not create IsoRecvHandler\n");
385                         return false;
386                 }
387
388                 h->setVerboseLevel(getDebugLevel());
389
390                 // init the handler
391                 if(!h->init()) {
392                         debugFatal("Could not initialize receive handler\n");
393                         return false;
394                 }
395
396                 // register the stream with the handler
397                 if(!h->registerStream(stream)) {
398                         debugFatal("Could not register receive stream with handler\n");
399                         return false;
400                 }
401
402                 // register the handler with the manager
403                 if(!registerHandler(h)) {
404                         debugFatal("Could not register receive handler with manager\n");
405                         return false;
406                 }
407                 debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h);
408         }
409        
410         if (stream->getType()==IsoStream::EST_Transmit) {
411                 // setup the optimal parameters for the raw1394 ISO buffering
412                 unsigned int packets_per_period=stream->getPacketsPerPeriod();
413
414 #if 1
415                 // hardware interrupts occur when one DMA block is full, and the size of one DMA
416                 // block = PAGE_SIZE. Setting the max_packet_size makes sure that the HW irq 
417                 // occurs at a period boundary (optimal CPU use)
418                 // NOTE: try and use MINIMUM_INTERRUPTS_PER_PERIOD interrupts per period
419                 //       for better latency.
420                 unsigned int max_packet_size=MINIMUM_INTERRUPTS_PER_PERIOD * getpagesize() / packets_per_period;
421                 if (max_packet_size < stream->getMaxPacketSize()) {
422                         max_packet_size=stream->getMaxPacketSize();
423                 }
424
425                 // Ensure we don't request a packet size bigger than the
426                 // kernel-enforced maximum which is currently 1 page.
427                 if (max_packet_size > (unsigned int)getpagesize())
428                         max_packet_size = getpagesize();
429
430                 unsigned int irq_interval=packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD;
431                 if(irq_interval <= 0) irq_interval=1;
432 #else
433                 // hardware interrupts occur when one DMA block is full, and the size of one DMA
434                 // block = PAGE_SIZE. Setting the max_packet_size enables control over the IRQ
435                 // frequency, as the controller uses max_packet_size, and not the effective size
436                 // when writing to the DMA buffer.
437                
438                 // configure it such that we have an irq for every PACKETS_PER_INTERRUPT packets
439                 unsigned int irq_interval=PACKETS_PER_INTERRUPT;
440                
441                 // unless the period size doesn't allow this
442                 if ((packets_per_period/MINIMUM_INTERRUPTS_PER_PERIOD) < irq_interval) {
443                         irq_interval=1;
444                 }
445                
446                 // FIXME: test
447                 irq_interval=1;
448
449                 unsigned int max_packet_size=getpagesize() / irq_interval;
450
451                 if (max_packet_size < stream->getMaxPacketSize()) {
452                         max_packet_size=stream->getMaxPacketSize();
453                 }
454
455                 // Ensure we don't request a packet size bigger than the
456                 // kernel-enforced maximum which is currently 1 page.
457                 if (max_packet_size > (unsigned int)getpagesize())
458                         max_packet_size = getpagesize();
459 #endif
460                 // the transmit buffer size should be as low as possible for latency.
461                 // note however that the raw1394 subsystem tries to keep this buffer
462                 // full, so we have to make sure that we have enough events in our
463                 // event buffers
464                
465                 // every irq_interval packets an interrupt will occur. that is when
466                 // buffers get transfered, meaning that we should have at least some
467                 // margin here
468                 int buffers=irq_interval * 2;
469
470                 // half a period. the xmit handler will take care of this
471 //              int buffers=packets_per_period/4;
472                
473                 // NOTE: this is dangerous: what if there is not enough prefill?
474 //              if (buffers<10) buffers=10;     
475                
476                 // create the actual handler
477                 IsoXmitHandler *h = new IsoXmitHandler(stream->getPort(), buffers,
478                                                        max_packet_size, irq_interval);
479
480                 debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoXmitHandler\n");
481
482                 if(!h) {
483                         debugFatal("Could not create IsoXmitHandler\n");
484                         return false;
485                 }
486
487                 h->setVerboseLevel(getDebugLevel());
488
489                 // init the handler
490                 if(!h->init()) {
491                         debugFatal("Could not initialize transmit handler\n");
492                         return false;
493                 }
494
495                 // register the stream with the handler
496                 if(!h->registerStream(stream)) {
497                         debugFatal("Could not register transmit stream with handler\n");
498                         return false;
499                 }
500
501                 // register the handler with the manager
502                 if(!registerHandler(h)) {
503                         debugFatal("Could not register transmit handler with manager\n");
504                         return false;
505                 }
506                 debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h);
507         }
508
509         m_IsoStreams.push_back(stream);
510         debugOutput( DEBUG_LEVEL_VERBOSE, " %d streams, %d handlers registered\n",
511                                           m_IsoStreams.size(), m_IsoHandlers.size());
512
513         return true;
514 }
515
516 bool IsoHandlerManager::unregisterStream(IsoStream *stream)
517 {
518         debugOutput( DEBUG_LEVEL_VERBOSE, "Unregistering stream %p\n",stream);
519         assert(stream);
520
521         // make sure the stream isn't attached to a handler anymore
522         for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
523           it != m_IsoHandlers.end();
524           ++it )
525         {
526                 if((*it)->isStreamRegistered(stream)) {
527                         if(!(*it)->unregisterStream(stream)) {
528                                 debugOutput( DEBUG_LEVEL_VERBOSE, " could not unregister stream (%p) from handler (%p)...\n",stream,*it);
529                                 return false;
530                         }
531                        
532                         debugOutput( DEBUG_LEVEL_VERBOSE, " unregistered stream (%p) from handler (%p)...\n",stream,*it);
533                 }
534         }
535
536         // clean up all handlers that aren't used
537         pruneHandlers();
538
539         // remove the stream from the registered streams list
540         for ( IsoStreamVectorIterator it = m_IsoStreams.begin();
541           it != m_IsoStreams.end();
542           ++it )
543         {
544                 if ( *it == stream ) {
545                         m_IsoStreams.erase(it);
546                        
547                         debugOutput( DEBUG_LEVEL_VERBOSE, " deleted stream (%p) from list...\n", *it);
548                         return true;
549                 }
550         }
551
552         return false; //not found
553
554 }
555
556 void IsoHandlerManager::pruneHandlers() {
557     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
558     IsoHandlerVector toUnregister;
559
560     // find all handlers that are not in use
561     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
562           it != m_IsoHandlers.end();
563           ++it )
564     {
565         if(!((*it)->inUse())) {
566             debugOutput( DEBUG_LEVEL_VERBOSE, " handler (%p) not in use\n",*it);
567             toUnregister.push_back(*it);
568         }
569     }
570     // delete them
571     for ( IsoHandlerVectorIterator it = toUnregister.begin();
572           it != toUnregister.end();
573           ++it )
574     {
575         unregisterHandler(*it);
576         debugOutput( DEBUG_LEVEL_VERBOSE, " deleting handler (%p)\n",*it);
577
578         // Now the handler's been unregistered it won't be reused
579         // again.  Therefore it really needs to be formally deleted
580         // to free up the raw1394 handle.  Otherwise things fall
581         // apart after several xrun recoveries as the system runs
582         // out of resources to support all the disused but still
583         // allocated raw1394 handles.  At least this is the current
584         // theory as to why we end up with "memory allocation"
585         // failures after several Xrun recoveries.
586         delete *it;
587     }
588
589 }
590
591
592 bool IsoHandlerManager::prepare()
593 {
594     bool retval=true;
595    
596     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
597    
598     // check state
599     if(m_State != E_Created) {
600         debugError("Incorrect state, expected E_Created, got %d\n",(int)m_State);
601         return false;
602     }
603    
604     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
605           it != m_IsoHandlers.end();
606           ++it )
607     {
608         if(!(*it)->prepare()) {
609             debugFatal("Could not prepare handlers\n");
610             retval=false;
611         }
612     }
613
614     if (retval) {
615         m_State=E_Prepared;
616     } else {
617         m_State=E_Error;
618     }
619
620     return retval;
621 }
622
623 bool IsoHandlerManager::startHandlers() {
624     return startHandlers(-1);
625 }
626
627 bool IsoHandlerManager::startHandlers(int cycle) {
628     bool retval=true;
629    
630     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
631    
632     // check state
633     if(m_State != E_Prepared) {
634         debugError("Incorrect state, expected E_Prepared, got %d\n",(int)m_State);
635         return false;
636     }
637    
638     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
639         it != m_IsoHandlers.end();
640         ++it )
641     {
642         debugOutput( DEBUG_LEVEL_VERBOSE, " starting handler (%p)\n",*it);
643         if(!(*it)->start(cycle)) {
644             debugOutput( DEBUG_LEVEL_VERBOSE, " could not start handler (%p)\n",*it);
645             retval=false;
646         }
647     }
648    
649     debugOutput( DEBUG_LEVEL_VERBOSE, "Starting ISO iterator thread...\n");
650
651     // note: libraw1394 doesn't like it if you poll() and/or iterate() before
652     //       starting the streams.
653     // start the iso runner thread
654     m_isoManagerThread->Start();
655    
656     if (retval) {
657         m_State=E_Running;
658     } else {
659         m_State=E_Error;
660     }
661
662     return retval;
663 }
664
665 bool IsoHandlerManager::stopHandlers() {
666     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
667    
668     // check state
669     if(m_State != E_Running) {
670         debugError("Incorrect state, expected E_Running, got %d\n",(int)m_State);
671         return false;
672     }
673    
674     bool retval=true;
675    
676     debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping ISO iterator thread...\n");
677     m_isoManagerThread->Stop();
678    
679     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
680         it != m_IsoHandlers.end();
681         ++it )
682     {
683         debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping handler (%p)\n",*it);
684         if(!(*it)->stop()){
685             debugOutput( DEBUG_LEVEL_VERBOSE, " could not stop handler (%p)\n",*it);
686             retval=false;
687         }
688     }
689    
690     if (retval) {
691         m_State=E_Prepared;
692     } else {
693         m_State=E_Error;
694     }
695    
696     return retval;
697 }
698
699 bool IsoHandlerManager::reset() {
700     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
701    
702     // check state
703     if(m_State == E_Error) {
704         debugFatal("Resetting from error condition not yet supported...\n");
705         return false;
706     }
707    
708     // if not in an error condition, reset means stop the handlers
709     return stopHandlers();
710 }
711
712
713 void IsoHandlerManager::setVerboseLevel(int i) {
714     setDebugLevel(i);
715
716     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
717           it != m_IsoHandlers.end();
718           ++it )
719     {
720         (*it)->setVerboseLevel(i);
721     }
722 }
723
724 void IsoHandlerManager::dumpInfo() {
725     int i=0;
726    
727     debugOutputShort( DEBUG_LEVEL_NORMAL, "Dumping IsoHandlerManager Stream handler information...\n");
728     debugOutputShort( DEBUG_LEVEL_NORMAL, " State: %d\n",(int)m_State);
729
730     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
731           it != m_IsoHandlers.end();
732           ++it )
733     {
734         debugOutputShort( DEBUG_LEVEL_NORMAL, " IsoHandler %d (%p)\n",i++,*it);
735
736         (*it)->dumpInfo();
737     }
738
739 }
740
741 } // end of namespace FreebobStreaming
742
Note: See TracBrowser for help on using the browser.