root/trunk/libffado/src/genericavc/avc_avdevice.cpp

Revision 1134, 23.6 kB (checked in by ppalmers, 13 years ago)

revert r1131 since it's does unconditional byteswapping

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 <netinet/in.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         // check if the destination is a MSU input plug
249         bool found=false;
250         for ( PlugVector::const_iterator it2 = syncMSUInputPlugs.begin();
251               it2 != syncMSUInputPlugs.end();
252               ++it2 )
253         {
254             AVC::Plug* msuPlug = *it2;
255             found |= (msuPlug == si.m_destination);
256         }
257
258         if (found) {
259             ClockSource s=syncInfoToClockSource(*it);
260             r.push_back(s);
261         }
262     }
263     return r;
264 }
265
266 bool
267 AvDevice::setActiveClockSource(ClockSource s) {
268     Plug *src=m_pPlugManager->getPlug( s.id );
269     if (!src) {
270         debugError("Could not find plug with id %d\n", s.id);
271         return false;
272     }
273
274     Util::MutexLockHelper lock(m_DeviceMutex);
275     for ( SyncInfoVector::const_iterator it
276               = getSyncInfos().begin();
277           it != getSyncInfos().end();
278           ++it )
279     {
280         const SyncInfo si=*it;
281
282         if (si.m_source==src) {
283             return setActiveSync(si);
284         }
285     }
286     return false;
287 }
288
289 FFADODevice::ClockSource
290 AvDevice::getActiveClockSource() {
291     const SyncInfo* si=getActiveSyncInfo();
292     if ( !si ) {
293         debugError( "Could not retrieve active sync information\n" );
294         ClockSource s;
295         s.type=eCT_Invalid;
296         return s;
297     }
298     debugOutput(DEBUG_LEVEL_VERBOSE, "Active Sync mode:  %s\n", si->m_description.c_str() );
299
300     return syncInfoToClockSource(*si);
301 }
302
303 FFADODevice::ClockSource
304 AvDevice::syncInfoToClockSource(const SyncInfo& si) {
305     ClockSource s;
306
307     // the description is easy
308     // it can be that we overwrite it later
309     s.description=si.m_description;
310
311     // FIXME: always valid at the moment
312     s.valid=true;
313
314     assert(si.m_source);
315     s.id=si.m_source->getGlobalId();
316
317     // now figure out what type this is
318     switch(si.m_source->getPlugType()) {
319         case Plug::eAPT_IsoStream:
320             s.type=eCT_SytMatch;
321             break;
322         case Plug::eAPT_Sync:
323             if(si.m_source->getPlugAddressType() == Plug::eAPA_PCR) {
324                 s.type=eCT_SytStream; // this is logical
325             } else if(si.m_source->getPlugAddressType() == Plug::eAPA_SubunitPlug) {
326                 s.type=eCT_Internal; // this assumes some stuff
327             } else if(si.m_source->getPlugAddressType() == Plug::eAPA_ExternalPlug) {
328                 std::string plugname=si.m_source->getName();
329                 s.description=plugname;
330                 // this is basically due to Focusrites interpretation
331                 if(plugname.find( "SPDIF", 0 ) != string::npos) {
332                     s.type=eCT_SPDIF; // this assumes the name will tell us
333                 } else {
334                     s.type=eCT_WordClock; // this assumes a whole lot more
335                 }
336             } else {
337                 s.type=eCT_Invalid;
338             }
339             break;
340         case Plug::eAPT_Digital:
341             if(si.m_source->getPlugAddressType() == Plug::eAPA_ExternalPlug) {
342                 std::string plugname=si.m_source->getName();
343                 s.description=plugname;
344                 // this is basically due to Focusrites interpretation
345                 if(plugname.find( "ADAT", 0 ) != string::npos) {
346                     s.type=eCT_ADAT; // this assumes the name will tell us
347                 } else if(plugname.find( "SPDIF", 0 ) != string::npos) {
348                     s.type=eCT_SPDIF; // this assumes the name will tell us
349                 } else {
350                     s.type=eCT_WordClock; // this assumes a whole lot more
351                 }
352             } else {
353                 s.type=eCT_Invalid;
354             }
355             break;
356         default:
357             s.type=eCT_Invalid; break;
358     }
359
360     // is it active?
361     const SyncInfo* active=getActiveSyncInfo();
362     if (active) {
363         if ((active->m_source == si.m_source)
364            && (active->m_destination == si.m_destination))
365            s.active=true;
366         else s.active=false;
367     } else s.active=false;
368
369     return s;
370 }
371
372 bool
373 AvDevice::lock() {
374     bool snoopMode=false;
375     Util::MutexLockHelper lock(m_DeviceMutex);
376     if(!getOption("snoopMode", snoopMode)) {
377         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
378     }
379
380     if (snoopMode) {
381         // don't lock
382     } else {
383 //         return Unit::reserve(4);
384     }
385
386     return true;
387 }
388
389 bool
390 AvDevice::unlock() {
391     bool snoopMode=false;
392     Util::MutexLockHelper lock(m_DeviceMutex);
393     if(!getOption("snoopMode", snoopMode)) {
394         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
395     }
396
397     if (snoopMode) {
398         // don't unlock
399     } else {
400 //         return Unit::reserve(0);
401     }
402     return true;
403 }
404
405 void
406 AvDevice::showDevice()
407 {
408     FFADODevice::showDevice();
409
410     AVC::Unit::show();
411     flushDebugOutput();
412 }
413
414 bool
415 AvDevice::prepare() {
416     bool snoopMode=false;
417     Util::MutexLockHelper lock(m_DeviceMutex);
418     if(!getOption("snoopMode", snoopMode)) {
419         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
420     }
421
422     ///////////
423     // get plugs
424
425     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
426     if ( !inputPlug ) {
427         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
428         return false;
429     }
430     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
431     if ( !outputPlug ) {
432         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
433         return false;
434     }
435
436     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n");
437     // create & add streamprocessors
438     Streaming::StreamProcessor *p;
439
440     if ( outputPlug->getNrOfChannels() == 0 ) {
441         debugError("Receive plug has no channels\n");
442         return false;
443     }
444     p = new Streaming::AmdtpReceiveStreamProcessor(*this,
445                              outputPlug->getNrOfChannels());
446
447     if(!p->init()) {
448         debugFatal("Could not initialize receive processor!\n");
449         delete p;
450         return false;
451     }
452
453     if (!addPlugToProcessor(*outputPlug, p,
454         Streaming::Port::E_Capture)) {
455         debugFatal("Could not add plug to processor!\n");
456         delete p;
457         return false;
458     }
459
460     m_receiveProcessors.push_back(p);
461
462     // do the transmit processor
463     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing transmit processor%s...\n",
464             (snoopMode?" in snoop mode":""));
465     if (snoopMode) {
466         // we are snooping, so this is receive too.
467         p=new Streaming::AmdtpReceiveStreamProcessor(*this,
468                                   inputPlug->getNrOfChannels());
469     } else {
470         Streaming::AmdtpTransmitStreamProcessor * t;
471         t=new Streaming::AmdtpTransmitStreamProcessor(*this,
472                                 inputPlug->getNrOfChannels());
473         #if AMDTP_ALLOW_PAYLOAD_IN_NODATA_XMIT
474             // FIXME: it seems that some BeBoB devices can't handle NO-DATA without payload
475             t->sendPayloadForNoDataPackets(true);
476         #endif
477         p=t;
478     }
479
480     if(!p->init()) {
481         debugFatal("Could not initialize transmit processor %s!\n",
482             (snoopMode?" in snoop mode":""));
483         delete p;
484         return false;
485     }
486
487     if (snoopMode) {
488         if (!addPlugToProcessor(*inputPlug, p,
489             Streaming::Port::E_Capture)) {
490             debugFatal("Could not add plug to processor!\n");
491             return false;
492         }
493     } else {
494         if (!addPlugToProcessor(*inputPlug, p,
495             Streaming::Port::E_Playback)) {
496             debugFatal("Could not add plug to processor!\n");
497             return false;
498         }
499     }
500
501     // we put this SP into the transmit SP vector,
502     // no matter if we are in snoop mode or not
503     // this allows us to find out what direction
504     // a certain stream should have.
505     m_transmitProcessors.push_back(p);
506
507     return true;
508 }
509
510 bool
511 AvDevice::addPlugToProcessor(
512     AVC::Plug& plug,
513     Streaming::StreamProcessor *processor,
514     Streaming::AmdtpAudioPort::E_Direction direction) {
515
516     std::string id=std::string("dev?");
517     if(!getOption("id", id)) {
518         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
519     }
520
521     Plug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
522     for ( Plug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
523           it != clusterInfos.end();
524           ++it )
525     {
526         const Plug::ClusterInfo* clusterInfo = &( *it );
527
528         Plug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
529         for ( Plug::ChannelInfoVector::const_iterator it = channelInfos.begin();
530               it != channelInfos.end();
531               ++it )
532         {
533             const Plug::ChannelInfo* channelInfo = &( *it );
534             std::ostringstream portname;
535
536             portname << id << "_" << channelInfo->m_name;
537
538             Streaming::Port *p=NULL;
539             switch(clusterInfo->m_portType) {
540             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker:
541             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone:
542             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone:
543             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line:
544             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog:
545                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding audio channel %s (pos=0x%02X, loc=0x%02X)\n",
546                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
547                 p=new Streaming::AmdtpAudioPort(
548                         *processor,
549                         portname.str(),
550                         direction,
551                         channelInfo->m_streamPosition,
552                         channelInfo->m_location,
553                         Streaming::AmdtpPortInfo::E_MBLA
554                 );
555                 break;
556
557             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
558                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding MIDI channel %s (pos=0x%02X, loc=0x%02X)\n",
559                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, processor->getPortCount(Streaming::Port::E_Midi));
560                 p=new Streaming::AmdtpMidiPort(
561                         *processor,
562                         portname.str(),
563                         direction,
564                         channelInfo->m_streamPosition,
565                         // Workaround for out-of-spec hardware
566                         // should be:
567                         // channelInfo->m_location,
568                         // but now we renumber the midi channels' location as they
569                         // are discovered
570                         processor->getPortCount(Streaming::Port::E_Midi),
571                         Streaming::AmdtpPortInfo::E_Midi
572                 );
573
574                 break;
575             case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
576             case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
577             case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
578             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
579             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
580                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding digital audio channel %s (pos=0x%02X, loc=0x%02X)\n",
581                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
582                 p=new Streaming::AmdtpAudioPort(
583                         *processor,
584                         portname.str(),
585                         direction,
586                         channelInfo->m_streamPosition,
587                         channelInfo->m_location,
588                         Streaming::AmdtpPortInfo::E_MBLA
589                 );
590                 break;
591
592             case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
593             default:
594             // unsupported
595                 break;
596             }
597
598             if (!p) {
599                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
600             }
601          }
602     }
603     return true;
604 }
605
606 int
607 AvDevice::getStreamCount() {
608     int retval;
609     Util::MutexLockHelper lock(m_DeviceMutex);
610     retval = m_receiveProcessors.size() + m_transmitProcessors.size();
611     return retval;
612 }
613
614 Streaming::StreamProcessor *
615 AvDevice::getStreamProcessorByIndex(int i) {
616
617     if (i<(int)m_receiveProcessors.size()) {
618         return m_receiveProcessors.at(i);
619     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
620         return m_transmitProcessors.at(i-m_receiveProcessors.size());
621     }
622
623     return NULL;
624 }
625
626 bool
627 AvDevice::startStreamByIndex(int i) {
628     int iso_channel=-1;
629     bool snoopMode=false;
630     if(!getOption("snoopMode", snoopMode)) {
631         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
632     }
633
634     if (i<(int)m_receiveProcessors.size()) {
635         int n=i;
636         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
637
638         if(snoopMode) { // a stream from the device to another host
639             // FIXME: put this into a decent framework!
640             // we should check the oPCR[n] on the device
641             struct iec61883_oPCR opcr;
642             if (iec61883_get_oPCRX(
643                     get1394Service().getHandle(),
644                     getConfigRom().getNodeId() | 0xffc0,
645                     (quadlet_t *)&opcr,
646                     n)) {
647
648                 debugWarning("Error getting the channel for SP %d\n",i);
649                 return false;
650             }
651
652             iso_channel=opcr.channel;
653         } else {
654             iso_channel=get1394Service().allocateIsoChannelCMP(
655                 getConfigRom().getNodeId() | 0xffc0, n,
656                 get1394Service().getLocalNodeId()| 0xffc0, -1);
657         }
658         if (iso_channel<0) {
659             debugError("Could not allocate ISO channel for SP %d\n",i);
660             return false;
661         }
662
663         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
664
665         p->setChannel(iso_channel);
666         return true;
667
668     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
669         int n=i-m_receiveProcessors.size();
670         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
671
672         if(snoopMode) { // a stream from another host to the device
673             // FIXME: put this into a decent framework!
674             // we should check the iPCR[n] on the device
675             struct iec61883_iPCR ipcr;
676             if (iec61883_get_iPCRX(
677                     get1394Service().getHandle(),
678                     getConfigRom().getNodeId() | 0xffc0,
679                     (quadlet_t *)&ipcr,
680                     n)) {
681
682                 debugWarning("Error getting the channel for SP %d\n",i);
683                 return false;
684             }
685
686             iso_channel=ipcr.channel;
687
688         } else {
689             iso_channel=get1394Service().allocateIsoChannelCMP(
690                 get1394Service().getLocalNodeId()| 0xffc0, -1,
691                 getConfigRom().getNodeId() | 0xffc0, n);
692         }
693
694         if (iso_channel<0) {
695             debugError("Could not allocate ISO channel for SP %d\n",i);
696             return false;
697         }
698
699         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
700
701         p->setChannel(iso_channel);
702         return true;
703     }
704
705     debugError("SP index %d out of range!\n",i);
706     return false;
707 }
708
709 bool
710 AvDevice::stopStreamByIndex(int i) {
711     bool snoopMode=false;
712     if(!getOption("snoopMode", snoopMode)) {
713         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
714     }
715
716     if (i<(int)m_receiveProcessors.size()) {
717         int n=i;
718         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
719
720         if(snoopMode) {
721
722         } else {
723             // deallocate ISO channel
724             if(!get1394Service().freeIsoChannel(p->getChannel())) {
725                 debugError("Could not deallocate iso channel for SP %d\n",i);
726                 return false;
727             }
728         }
729         p->setChannel(-1);
730
731         return true;
732
733     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
734         int n=i-m_receiveProcessors.size();
735         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
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( Glib::ustring 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( Glib::ustring 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.