root/branches/libffado-2.0/src/genericavc/avc_avdevice.cpp

Revision 1203, 23.6 kB (checked in by wagi, 16 years ago)

Currently there is no usable setup for sync streams.
There is no point in wasting time here. Let's skip
'sync stream input' and 'sync stream output'.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  * Copyright (C) 2005-2008 by Daniel Wagner
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB.
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include "genericavc/avc_avdevice.h"
26
27 #include "libieee1394/configrom.h"
28 #include "libieee1394/ieee1394service.h"
29
30 #include "libavc/avc_definitions.h"
31 #include "libavc/general/avc_plug_info.h"
32 #include "libavc/general/avc_extended_plug_info.h"
33
34 #include "debugmodule/debugmodule.h"
35
36 #include "config.h"
37
38 #include <string>
39 #include <stdint.h>
40 #include <assert.h>
41 #include "libutil/ByteSwap.h"
42 #include <iostream>
43 #include <sstream>
44
45 #include <libraw1394/csr.h>
46
47 using namespace AVC;
48
49 namespace GenericAVC {
50
51 IMPL_DEBUG_MODULE( AvDevice, AvDevice, DEBUG_LEVEL_NORMAL );
52
53 AvDevice::AvDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
54     : FFADODevice( d, configRom )
55 {
56     debugOutput( DEBUG_LEVEL_VERBOSE, "Created GenericAVC::AvDevice (NodeID %d)\n",
57                  getConfigRom().getNodeId() );
58     addOption(Util::OptionContainer::Option("snoopMode",false));
59 }
60
61 AvDevice::~AvDevice()
62 {
63     for ( StreamProcessorVectorIterator it = m_receiveProcessors.begin();
64           it != m_receiveProcessors.end();
65           ++it )
66     {
67         delete *it;
68     }
69     for ( StreamProcessorVectorIterator it = m_transmitProcessors.begin();
70           it != m_transmitProcessors.end();
71           ++it )
72     {
73         delete *it;
74     }
75 }
76
77 bool
78 AvDevice::probe( ConfigRom& configRom )
79 {
80     unsigned int vendorId = configRom.getNodeVendorId();
81     unsigned int modelId = configRom.getModelId();
82
83     GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_genericavc.txt" );
84     if ( vendorModel.parse() ) {
85         return vendorModel.isPresent( vendorId, modelId );
86     }
87
88     return false;
89 }
90
91 FFADODevice *
92 AvDevice::createDevice(DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
93 {
94     return new AvDevice(d, configRom );
95 }
96
97 bool
98 AvDevice::discover()
99 {
100     Util::MutexLockHelper lock(m_DeviceMutex);
101     // check if we already have a valid VendorModel entry
102     // e.g. because a subclass called this function
103     if (!GenericAVC::VendorModel::isValid(m_model)) {
104         unsigned int vendorId = getConfigRom().getNodeVendorId();
105         unsigned int modelId = getConfigRom().getModelId();
106
107         GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_genericavc.txt" );
108         if ( vendorModel.parse() ) {
109             m_model = vendorModel.find( vendorId, modelId );
110         }
111
112         if (!GenericAVC::VendorModel::isValid(m_model)) {
113             return false;
114         }
115         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
116                 m_model.vendor_name.c_str(), m_model.model_name.c_str());
117     }
118
119     if ( !Unit::discover() ) {
120         debugError( "Could not discover unit\n" );
121         return false;
122     }
123
124     if((getAudioSubunit( 0 ) == NULL)) {
125         debugError( "Unit doesn't have an Audio subunit.\n");
126         return false;
127     }
128     if((getMusicSubunit( 0 ) == NULL)) {
129         debugError( "Unit doesn't have a Music subunit.\n");
130         return false;
131     }
132
133     return true;
134 }
135
136 void
137 AvDevice::setVerboseLevel(int l)
138 {
139     Util::MutexLockHelper lock(m_DeviceMutex);
140     setDebugLevel(l);
141     m_pPlugManager->setVerboseLevel(l);
142     FFADODevice::setVerboseLevel(l);
143     AVC::Unit::setVerboseLevel(l);
144     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
145 }
146
147 int
148 AvDevice::getSamplingFrequency( ) {
149     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
150     if ( !inputPlug ) {
151         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
152         return false;
153     }
154     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
155     if ( !outputPlug ) {
156         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
157         return false;
158     }
159
160     int samplerate_playback=inputPlug->getSampleRate();
161     int samplerate_capture=outputPlug->getSampleRate();
162
163     if (samplerate_playback != samplerate_capture) {
164         debugWarning("Samplerates for capture and playback differ!\n");
165     }
166     return samplerate_capture;
167 }
168
169 bool
170 AvDevice::setSamplingFrequency( int s )
171 {
172     Util::MutexLockHelper lock(m_DeviceMutex);
173     bool snoopMode=false;
174     if(!getOption("snoopMode", snoopMode)) {
175         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
176     }
177
178     if(snoopMode) {
179         int current_sr=getSamplingFrequency();
180         if (current_sr != s ) {
181             debugError("In snoop mode it is impossible to set the sample rate.\n");
182             debugError("Please start the client with the correct setting.\n");
183             return false;
184         }
185         return true;
186     } else {
187         AVC::Plug* plug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
188         if ( !plug ) {
189             debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
190             return false;
191         }
192
193         if ( !plug->setSampleRate( s ) )
194         {
195             debugError( "setSampleRate: Setting sample rate failed\n" );
196             return false;
197         }
198
199         plug = getPlugById( m_pcrPlugs, Plug::eAPD_Output,  0 );
200         if ( !plug ) {
201             debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
202             return false;
203         }
204
205         if ( !plug->setSampleRate( s ) )
206         {
207             debugError( "setSampleRate: Setting sample rate failed\n" );
208             return false;
209         }
210
211         debugOutput( DEBUG_LEVEL_VERBOSE,
212                      "setSampleRate: Set sample rate to %d\n",
213                      s );
214         return true;
215     }
216     // not executable
217     return false;
218
219 }
220
221 FFADODevice::ClockSourceVector
222 AvDevice::getSupportedClockSources() {
223     FFADODevice::ClockSourceVector r;
224
225     Util::MutexLockHelper lock(m_DeviceMutex);
226
227     PlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType(
228         eST_Music,
229         0,
230         0xff,
231         0xff,
232         Plug::eAPA_SubunitPlug,
233         Plug::eAPD_Input,
234         Plug::eAPT_Sync );
235     if ( !syncMSUInputPlugs.size() ) {
236         // there exist devices which do not have a sync plug
237         // or their av/c model is broken.
238         return r;
239     }
240
241     for ( SyncInfoVector::const_iterator it
242               = getSyncInfos().begin();
243           it != getSyncInfos().end();
244           ++it )
245     {
246         const SyncInfo si=*it;
247
248         ClockSource s=syncInfoToClockSource(*it);
249         r.push_back(s);
250     }
251     return r;
252 }
253
254 bool
255 AvDevice::setActiveClockSource(ClockSource s) {
256     Plug *src=m_pPlugManager->getPlug( s.id );
257     if (!src) {
258         debugError("Could not find plug with id %d\n", s.id);
259         return false;
260     }
261
262     Util::MutexLockHelper lock(m_DeviceMutex);
263     for ( SyncInfoVector::const_iterator it
264               = getSyncInfos().begin();
265           it != getSyncInfos().end();
266           ++it )
267     {
268         const SyncInfo si=*it;
269
270         if (si.m_source==src) {
271             return setActiveSync(si);
272         }
273     }
274     return false;
275 }
276
277 FFADODevice::ClockSource
278 AvDevice::getActiveClockSource() {
279     const SyncInfo* si=getActiveSyncInfo();
280     if ( !si ) {
281         debugError( "Could not retrieve active sync information\n" );
282         ClockSource s;
283         s.type=eCT_Invalid;
284         return s;
285     }
286     debugOutput(DEBUG_LEVEL_VERBOSE, "Active Sync mode:  %s\n", si->m_description.c_str() );
287
288     return syncInfoToClockSource(*si);
289 }
290
291 FFADODevice::ClockSource
292 AvDevice::syncInfoToClockSource(const SyncInfo& si) {
293     ClockSource s;
294
295     // the description is easy
296     // it can be that we overwrite it later
297     s.description=si.m_description;
298
299     // FIXME: always valid at the moment
300     s.valid=true;
301
302     assert(si.m_source);
303     s.id=si.m_source->getGlobalId();
304
305     // now figure out what type this is
306     switch(si.m_source->getPlugType()) {
307         case Plug::eAPT_IsoStream:
308             s.type=eCT_SytMatch;
309             break;
310         case Plug::eAPT_Sync:
311             if(si.m_source->getPlugAddressType() == Plug::eAPA_PCR) {
312                 s.type=eCT_SytStream; // this is logical
313             } else if(si.m_source->getPlugAddressType() == Plug::eAPA_SubunitPlug) {
314                 s.type=eCT_Internal; // this assumes some stuff
315             } else if(si.m_source->getPlugAddressType() == Plug::eAPA_ExternalPlug) {
316                 std::string plugname=si.m_source->getName();
317                 s.description=plugname;
318                 // this is basically due to Focusrites interpretation
319                 if(plugname.find( "SPDIF", 0 ) != string::npos) {
320                     s.type=eCT_SPDIF; // this assumes the name will tell us
321                 } else {
322                     s.type=eCT_WordClock; // this assumes a whole lot more
323                 }
324             } else {
325                 s.type=eCT_Invalid;
326             }
327             break;
328         case Plug::eAPT_Digital:
329             if(si.m_source->getPlugAddressType() == Plug::eAPA_ExternalPlug) {
330                 std::string plugname=si.m_source->getName();
331                 s.description=plugname;
332                 // this is basically due to Focusrites interpretation
333                 if(plugname.find( "ADAT", 0 ) != string::npos) {
334                     s.type=eCT_ADAT; // this assumes the name will tell us
335                 } else if(plugname.find( "SPDIF", 0 ) != string::npos) {
336                     s.type=eCT_SPDIF; // this assumes the name will tell us
337                 } else {
338                     s.type=eCT_WordClock; // this assumes a whole lot more
339                 }
340             } else {
341                 s.type=eCT_Invalid;
342             }
343             break;
344         default:
345             s.type=eCT_Invalid; break;
346     }
347
348     // is it active?
349     const SyncInfo* active=getActiveSyncInfo();
350     if (active) {
351         if ((active->m_source == si.m_source)
352            && (active->m_destination == si.m_destination))
353            s.active=true;
354         else s.active=false;
355     } else s.active=false;
356
357     return s;
358 }
359
360 bool
361 AvDevice::lock() {
362     bool snoopMode=false;
363     Util::MutexLockHelper lock(m_DeviceMutex);
364     if(!getOption("snoopMode", snoopMode)) {
365         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
366     }
367
368     if (snoopMode) {
369         // don't lock
370     } else {
371 //         return Unit::reserve(4);
372     }
373
374     return true;
375 }
376
377 bool
378 AvDevice::unlock() {
379     bool snoopMode=false;
380     Util::MutexLockHelper lock(m_DeviceMutex);
381     if(!getOption("snoopMode", snoopMode)) {
382         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
383     }
384
385     if (snoopMode) {
386         // don't unlock
387     } else {
388 //         return Unit::reserve(0);
389     }
390     return true;
391 }
392
393 void
394 AvDevice::showDevice()
395 {
396     FFADODevice::showDevice();
397
398     AVC::Unit::show();
399     flushDebugOutput();
400 }
401
402 bool
403 AvDevice::prepare() {
404     bool snoopMode=false;
405     Util::MutexLockHelper lock(m_DeviceMutex);
406     if(!getOption("snoopMode", snoopMode)) {
407         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
408     }
409
410     ///////////
411     // get plugs
412
413     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
414     if ( !inputPlug ) {
415         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
416         return false;
417     }
418     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
419     if ( !outputPlug ) {
420         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
421         return false;
422     }
423
424     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n");
425     // create & add streamprocessors
426     Streaming::StreamProcessor *p;
427
428     if ( outputPlug->getNrOfChannels() == 0 ) {
429         debugError("Receive plug has no channels\n");
430         return false;
431     }
432     p = new Streaming::AmdtpReceiveStreamProcessor(*this,
433                              outputPlug->getNrOfChannels());
434
435     if(!p->init()) {
436         debugFatal("Could not initialize receive processor!\n");
437         delete p;
438         return false;
439     }
440
441     if (!addPlugToProcessor(*outputPlug, p,
442         Streaming::Port::E_Capture)) {
443         debugFatal("Could not add plug to processor!\n");
444         delete p;
445         return false;
446     }
447
448     m_receiveProcessors.push_back(p);
449
450     // do the transmit processor
451     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing transmit processor%s...\n",
452             (snoopMode?" in snoop mode":""));
453     if (snoopMode) {
454         // we are snooping, so this is receive too.
455         p=new Streaming::AmdtpReceiveStreamProcessor(*this,
456                                   inputPlug->getNrOfChannels());
457     } else {
458         Streaming::AmdtpTransmitStreamProcessor * t;
459         t=new Streaming::AmdtpTransmitStreamProcessor(*this,
460                                 inputPlug->getNrOfChannels());
461         #if AMDTP_ALLOW_PAYLOAD_IN_NODATA_XMIT
462             // FIXME: it seems that some BeBoB devices can't handle NO-DATA without payload
463             t->sendPayloadForNoDataPackets(true);
464         #endif
465         p=t;
466     }
467
468     if(!p->init()) {
469         debugFatal("Could not initialize transmit processor %s!\n",
470             (snoopMode?" in snoop mode":""));
471         delete p;
472         return false;
473     }
474
475     if (snoopMode) {
476         if (!addPlugToProcessor(*inputPlug, p,
477             Streaming::Port::E_Capture)) {
478             debugFatal("Could not add plug to processor!\n");
479             return false;
480         }
481     } else {
482         if (!addPlugToProcessor(*inputPlug, p,
483             Streaming::Port::E_Playback)) {
484             debugFatal("Could not add plug to processor!\n");
485             return false;
486         }
487     }
488
489     // we put this SP into the transmit SP vector,
490     // no matter if we are in snoop mode or not
491     // this allows us to find out what direction
492     // a certain stream should have.
493     m_transmitProcessors.push_back(p);
494
495     return true;
496 }
497
498 bool
499 AvDevice::addPlugToProcessor(
500     AVC::Plug& plug,
501     Streaming::StreamProcessor *processor,
502     Streaming::AmdtpAudioPort::E_Direction direction) {
503
504     std::string id=std::string("dev?");
505     if(!getOption("id", id)) {
506         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
507     }
508
509     Plug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
510     for ( Plug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
511           it != clusterInfos.end();
512           ++it )
513     {
514         const Plug::ClusterInfo* clusterInfo = &( *it );
515
516         Plug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
517         for ( Plug::ChannelInfoVector::const_iterator it = channelInfos.begin();
518               it != channelInfos.end();
519               ++it )
520         {
521             const Plug::ChannelInfo* channelInfo = &( *it );
522             std::ostringstream portname;
523
524             portname << id << "_" << channelInfo->m_name;
525
526             Streaming::Port *p=NULL;
527             switch(clusterInfo->m_portType) {
528             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker:
529             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone:
530             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone:
531             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line:
532             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog:
533                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding audio channel %s (pos=0x%02X, loc=0x%02X)\n",
534                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
535                 p=new Streaming::AmdtpAudioPort(
536                         *processor,
537                         portname.str(),
538                         direction,
539                         channelInfo->m_streamPosition,
540                         channelInfo->m_location,
541                         Streaming::AmdtpPortInfo::E_MBLA
542                 );
543                 break;
544
545             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
546                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding MIDI channel %s (pos=0x%02X, loc=0x%02X)\n",
547                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, processor->getPortCount(Streaming::Port::E_Midi));
548                 p=new Streaming::AmdtpMidiPort(
549                         *processor,
550                         portname.str(),
551                         direction,
552                         channelInfo->m_streamPosition,
553                         // Workaround for out-of-spec hardware
554                         // should be:
555                         // channelInfo->m_location,
556                         // but now we renumber the midi channels' location as they
557                         // are discovered
558                         processor->getPortCount(Streaming::Port::E_Midi),
559                         Streaming::AmdtpPortInfo::E_Midi
560                 );
561
562                 break;
563             case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
564             case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
565             case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
566             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
567             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
568                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding digital audio channel %s (pos=0x%02X, loc=0x%02X)\n",
569                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
570                 p=new Streaming::AmdtpAudioPort(
571                         *processor,
572                         portname.str(),
573                         direction,
574                         channelInfo->m_streamPosition,
575                         channelInfo->m_location,
576                         Streaming::AmdtpPortInfo::E_MBLA
577                 );
578                 break;
579
580             case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
581             default:
582             // unsupported
583                 break;
584             }
585
586             if (!p) {
587                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
588             }
589          }
590     }
591     return true;
592 }
593
594 int
595 AvDevice::getStreamCount() {
596     int retval;
597     Util::MutexLockHelper lock(m_DeviceMutex);
598     retval = m_receiveProcessors.size() + m_transmitProcessors.size();
599     return retval;
600 }
601
602 Streaming::StreamProcessor *
603 AvDevice::getStreamProcessorByIndex(int i) {
604
605     if (i<(int)m_receiveProcessors.size()) {
606         return m_receiveProcessors.at(i);
607     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
608         return m_transmitProcessors.at(i-m_receiveProcessors.size());
609     }
610
611     return NULL;
612 }
613
614 bool
615 AvDevice::startStreamByIndex(int i) {
616     int iso_channel=-1;
617     bool snoopMode=false;
618     if(!getOption("snoopMode", snoopMode)) {
619         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
620     }
621
622     if (i<(int)m_receiveProcessors.size()) {
623         int n=i;
624         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
625
626         if(snoopMode) { // a stream from the device to another host
627             // FIXME: put this into a decent framework!
628             // we should check the oPCR[n] on the device
629             struct iec61883_oPCR opcr;
630             if (iec61883_get_oPCRX(
631                     get1394Service().getHandle(),
632                     getConfigRom().getNodeId() | 0xffc0,
633                     (quadlet_t *)&opcr,
634                     n)) {
635
636                 debugWarning("Error getting the channel for SP %d\n",i);
637                 return false;
638             }
639
640             iso_channel=opcr.channel;
641         } else {
642             iso_channel=get1394Service().allocateIsoChannelCMP(
643                 getConfigRom().getNodeId() | 0xffc0, n,
644                 get1394Service().getLocalNodeId()| 0xffc0, -1);
645         }
646         if (iso_channel<0) {
647             debugError("Could not allocate ISO channel for SP %d\n",i);
648             return false;
649         }
650
651         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
652
653         p->setChannel(iso_channel);
654         return true;
655
656     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
657         int n=i-m_receiveProcessors.size();
658         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
659
660         if(snoopMode) { // a stream from another host to the device
661             // FIXME: put this into a decent framework!
662             // we should check the iPCR[n] on the device
663             struct iec61883_iPCR ipcr;
664             if (iec61883_get_iPCRX(
665                     get1394Service().getHandle(),
666                     getConfigRom().getNodeId() | 0xffc0,
667                     (quadlet_t *)&ipcr,
668                     n)) {
669
670                 debugWarning("Error getting the channel for SP %d\n",i);
671                 return false;
672             }
673
674             iso_channel=ipcr.channel;
675
676         } else {
677             iso_channel=get1394Service().allocateIsoChannelCMP(
678                 get1394Service().getLocalNodeId()| 0xffc0, -1,
679                 getConfigRom().getNodeId() | 0xffc0, n);
680         }
681
682         if (iso_channel<0) {
683             debugError("Could not allocate ISO channel for SP %d\n",i);
684             return false;
685         }
686
687         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
688
689         p->setChannel(iso_channel);
690         return true;
691     }
692
693     debugError("SP index %d out of range!\n",i);
694     return false;
695 }
696
697 bool
698 AvDevice::stopStreamByIndex(int i) {
699     bool snoopMode=false;
700     if(!getOption("snoopMode", snoopMode)) {
701         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
702     }
703
704     if (i<(int)m_receiveProcessors.size()) {
705         int n=i;
706         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
707
708         // can't stop it if it's not running
709         if(p->getChannel() == -1) {
710             debugOutput(DEBUG_LEVEL_VERBOSE, "SP %d not running\n",i);
711             return true;
712         }
713
714         if(snoopMode) {
715
716         } else {
717             // deallocate ISO channel
718             if(!get1394Service().freeIsoChannel(p->getChannel())) {
719                 debugError("Could not deallocate iso channel for SP %d\n",i);
720                 return false;
721             }
722         }
723         p->setChannel(-1);
724
725         return true;
726
727     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
728         int n=i-m_receiveProcessors.size();
729         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
730
731         // can't stop it if it's not running
732         if(p->getChannel() == -1) {
733             debugOutput(DEBUG_LEVEL_VERBOSE, "SP %d not running\n",i);
734             return true;
735         }
736
737         if(snoopMode) {
738
739         } else {
740             // deallocate ISO channel
741             if(!get1394Service().freeIsoChannel(p->getChannel())) {
742                 debugError("Could not deallocate iso channel for SP %d\n",i);
743                 return false;
744             }
745         }
746         p->setChannel(-1);
747
748         return true;
749     }
750
751     debugError("SP index %d out of range!\n",i);
752     return false;
753 }
754
755 bool
756 AvDevice::serialize( std::string basePath, Util::IOSerialize& ser ) const
757 {
758     bool result;
759     result  = AVC::Unit::serialize( basePath, ser );
760     result &= serializeOptions( basePath + "Options", ser );
761     return result;
762 }
763
764 bool
765 AvDevice::deserialize( std::string basePath, Util::IODeserialize& deser )
766 {
767     bool result;
768     result = AVC::Unit::deserialize( basePath, deser );
769     return result;
770 }
771
772 }
Note: See TracBrowser for help on using the browser.