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

Revision 716, 23.0 kB (checked in by wagi, 16 years ago)

cache bebob avc model. lot's of small bug fixed. it should work now.

Line 
1 /*
2  * Copyright (C) 2005-2007 by Pieter Palmers
3  * Copyright (C) 2005-2007 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 library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License version 2.1, as published by the Free Software Foundation;
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22  * MA 02110-1301 USA
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_VERBOSE );
52
53
54 AvDevice::AvDevice( Ieee1394Service& ieee1394Service,
55                     std::auto_ptr<ConfigRom>( configRom ))
56     : FFADODevice( ieee1394Service, configRom )
57 {
58     debugOutput( DEBUG_LEVEL_VERBOSE, "Created GenericAVC::AvDevice (NodeID %d)\n",
59                  getConfigRom().getNodeId() );
60     addOption(Util::OptionContainer::Option("snoopMode",false));
61 }
62
63 AvDevice::~AvDevice()
64 {
65
66 }
67
68 bool
69 AvDevice::probe( ConfigRom& configRom )
70 {
71     unsigned int vendorId = configRom.getNodeVendorId();
72     unsigned int modelId = configRom.getModelId();
73
74     GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_genericavc.txt" );
75     if ( vendorModel.parse() ) {
76         return vendorModel.isPresent( vendorId, modelId );
77     }
78
79     return false;
80 }
81
82 FFADODevice *
83 AvDevice::createDevice( Ieee1394Service& ieee1394Service,
84                         std::auto_ptr<ConfigRom>( configRom ))
85 {
86     return new AvDevice(ieee1394Service, configRom );
87 }
88
89 bool
90 AvDevice::discover()
91 {
92     // check if we already have a valid VendorModel entry
93     // e.g. because a subclass called this function
94     if (!GenericAVC::VendorModel::isValid(m_model)) {
95         unsigned int vendorId = m_pConfigRom->getNodeVendorId();
96         unsigned int modelId = m_pConfigRom->getModelId();
97
98         GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_genericavc.txt" );
99         if ( vendorModel.parse() ) {
100             m_model = vendorModel.find( vendorId, modelId );
101         }
102
103         if (!GenericAVC::VendorModel::isValid(m_model)) {
104             return false;
105         }
106         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
107                 m_model.vendor_name.c_str(), m_model.model_name.c_str());
108     }
109
110     if ( !Unit::discover() ) {
111         debugError( "Could not discover unit\n" );
112         return false;
113     }
114
115     if((getAudioSubunit( 0 ) == NULL)) {
116         debugError( "Unit doesn't have an Audio subunit.\n");
117         return false;
118     }
119     if((getMusicSubunit( 0 ) == NULL)) {
120         debugError( "Unit doesn't have a Music subunit.\n");
121         return false;
122     }
123
124     return true;
125 }
126
127 void
128 AvDevice::setVerboseLevel(int l)
129 {
130     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
131
132     m_pPlugManager->setVerboseLevel(l);
133
134     FFADODevice::setVerboseLevel(l);
135     AVC::Unit::setVerboseLevel(l);
136 }
137
138 int
139 AvDevice::getSamplingFrequency( ) {
140     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
141     if ( !inputPlug ) {
142         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
143         return false;
144     }
145     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
146     if ( !outputPlug ) {
147         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
148         return false;
149     }
150
151     int samplerate_playback=inputPlug->getSampleRate();
152     int samplerate_capture=outputPlug->getSampleRate();
153
154     if (samplerate_playback != samplerate_capture) {
155         debugWarning("Samplerates for capture and playback differ!\n");
156     }
157     return samplerate_capture;
158 }
159
160 bool
161 AvDevice::setSamplingFrequency( int s )
162 {
163     bool snoopMode=false;
164     if(!getOption("snoopMode", snoopMode)) {
165         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
166     }
167
168     if(snoopMode) {
169         int current_sr=getSamplingFrequency();
170         if (current_sr != s ) {
171             debugError("In snoop mode it is impossible to set the sample rate.\n");
172             debugError("Please start the client with the correct setting.\n");
173             return false;
174         }
175         return true;
176     } else {
177         AVC::Plug* plug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
178         if ( !plug ) {
179             debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
180             return false;
181         }
182
183         if ( !plug->setSampleRate( s ) )
184         {
185             debugError( "setSampleRate: Setting sample rate failed\n" );
186             return false;
187         }
188
189         plug = getPlugById( m_pcrPlugs, Plug::eAPD_Output,  0 );
190         if ( !plug ) {
191             debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
192             return false;
193         }
194
195         if ( !plug->setSampleRate( s ) )
196         {
197             debugError( "setSampleRate: Setting sample rate failed\n" );
198             return false;
199         }
200
201         debugOutput( DEBUG_LEVEL_VERBOSE,
202                      "setSampleRate: Set sample rate to %d\n",
203                      s );
204         return true;
205     }
206     // not executable
207     return false;
208
209 }
210
211 FFADODevice::ClockSourceVector
212 AvDevice::getSupportedClockSources() {
213     FFADODevice::ClockSourceVector r;
214
215     PlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType(
216         eST_Music,
217         0,
218         0xff,
219         0xff,
220         Plug::eAPA_SubunitPlug,
221         Plug::eAPD_Input,
222         Plug::eAPT_Sync );
223     if ( !syncMSUInputPlugs.size() ) {
224         debugWarning( "No sync input plug for MSU subunit found\n" );
225         return r;
226     }
227
228     for ( SyncInfoVector::const_iterator it
229               = getSyncInfos().begin();
230           it != getSyncInfos().end();
231           ++it )
232     {
233         const SyncInfo si=*it;
234
235         // check if the destination is a MSU input plug
236         bool found=false;
237         for ( PlugVector::const_iterator it2 = syncMSUInputPlugs.begin();
238               it2 != syncMSUInputPlugs.end();
239               ++it2 )
240         {
241             AVC::Plug* msuPlug = *it2;
242             found |= (msuPlug == si.m_destination);
243         }
244
245         if (found) {
246             ClockSource s=syncInfoToClockSource(*it);
247             r.push_back(s);
248         }
249     }
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     for ( SyncInfoVector::const_iterator it
263               = getSyncInfos().begin();
264           it != getSyncInfos().end();
265           ++it )
266     {
267         const SyncInfo si=*it;
268
269         if (si.m_source==src) {
270             return setActiveSync(si);
271         }
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     if(!getOption("snoopMode", snoopMode)) {
364         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
365     }
366
367     if (snoopMode) {
368         // don't lock
369     } else {
370 //         return Unit::reserve(4);
371     }
372
373     return true;
374 }
375
376 bool
377 AvDevice::unlock() {
378     bool snoopMode=false;
379     if(!getOption("snoopMode", snoopMode)) {
380         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
381     }
382
383     if (snoopMode) {
384         // don't unlock
385     } else {
386 //         return Unit::reserve(0);
387     }
388     return true;
389 }
390
391 void
392 AvDevice::showDevice()
393 {
394     FFADODevice::showDevice();
395
396     debugOutput(DEBUG_LEVEL_NORMAL,
397         "%s %s\n", m_model.vendor_name.c_str(), m_model.model_name.c_str());
398
399     AVC::Unit::show();
400     flushDebugOutput();
401 }
402
403 bool
404 AvDevice::prepare() {
405     bool snoopMode=false;
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     int samplerate=outputPlug->getSampleRate();
425
426     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n");
427     // create & add streamprocessors
428     Streaming::StreamProcessor *p;
429
430     p=new Streaming::AmdtpReceiveStreamProcessor(
431                              get1394Service().getPort(),
432                              samplerate,
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(
456                                   get1394Service().getPort(),
457                                   samplerate,
458                                   inputPlug->getNrOfChannels());
459     } else {
460         p=new Streaming::AmdtpTransmitStreamProcessor(
461                                 get1394Service().getPort(),
462                                 samplerate,
463                                 inputPlug->getNrOfChannels());
464     }
465
466     if(!p->init()) {
467         debugFatal("Could not initialize transmit processor %s!\n",
468             (snoopMode?" in snoop mode":""));
469         delete p;
470         return false;
471     }
472
473     if (snoopMode) {
474         if (!addPlugToProcessor(*inputPlug,p,
475             Streaming::Port::E_Capture)) {
476             debugFatal("Could not add plug to processor!\n");
477             return false;
478         }
479     } else {
480         if (!addPlugToProcessor(*inputPlug,p,
481             Streaming::Port::E_Playback)) {
482             debugFatal("Could not add plug to processor!\n");
483             return false;
484         }
485     }
486
487     // we put this SP into the transmit SP vector,
488     // no matter if we are in snoop mode or not
489     // this allows us to find out what direction
490     // a certain stream should have.
491     m_transmitProcessors.push_back(p);
492
493     return true;
494 }
495
496 bool
497 AvDevice::addPlugToProcessor(
498     AVC::Plug& plug,
499     Streaming::StreamProcessor *processor,
500     Streaming::AmdtpAudioPort::E_Direction direction) {
501
502     std::string id=std::string("dev?");
503     if(!getOption("id", id)) {
504         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
505     }
506
507     Plug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
508     for ( Plug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
509           it != clusterInfos.end();
510           ++it )
511     {
512         const Plug::ClusterInfo* clusterInfo = &( *it );
513
514         Plug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
515         for ( Plug::ChannelInfoVector::const_iterator it = channelInfos.begin();
516               it != channelInfos.end();
517               ++it )
518         {
519             const Plug::ChannelInfo* channelInfo = &( *it );
520             std::ostringstream portname;
521
522             portname << id << "_" << channelInfo->m_name;
523
524             Streaming::Port *p=NULL;
525             switch(clusterInfo->m_portType) {
526             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker:
527             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone:
528             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone:
529             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line:
530             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog:
531                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding audio channel %s (pos=0x%02X, loc=0x%02X)\n",
532                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
533                 p=new Streaming::AmdtpAudioPort(
534                         portname.str(),
535                         direction,
536                         channelInfo->m_streamPosition,
537                         channelInfo->m_location,
538                         Streaming::AmdtpPortInfo::E_MBLA
539                 );
540                 break;
541
542             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
543                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding MIDI channel %s (pos=0x%02X, loc=0x%02X)\n",
544                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, processor->getPortCount(Streaming::Port::E_Midi));
545                 p=new Streaming::AmdtpMidiPort(
546                         portname.str(),
547                         direction,
548                         channelInfo->m_streamPosition,
549                         // Workaround for out-of-spec hardware
550                         // should be:
551                         // channelInfo->m_location,
552                         // but now we renumber the midi channels' location as they
553                         // are discovered
554                         processor->getPortCount(Streaming::Port::E_Midi),
555                         Streaming::AmdtpPortInfo::E_Midi
556                 );
557
558                 break;
559             case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
560             case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
561             case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
562             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
563             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
564                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding digital audio channel %s (pos=0x%02X, loc=0x%02X)\n",
565                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
566                 p=new Streaming::AmdtpAudioPort(
567                         portname.str(),
568                         direction,
569                         channelInfo->m_streamPosition,
570                         channelInfo->m_location,
571                         Streaming::AmdtpPortInfo::E_MBLA
572                 );
573                 break;
574
575             case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
576             default:
577             // unsupported
578                 break;
579             }
580
581             if (!p) {
582                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
583             } else {
584
585                 if (!processor->addPort(p)) {
586                     debugWarning("Could not register port with stream processor\n");
587                     return false;
588                 }
589             }
590          }
591     }
592     return true;
593 }
594
595 int
596 AvDevice::getStreamCount() {
597     return m_receiveProcessors.size() + m_transmitProcessors.size();
598 }
599
600 Streaming::StreamProcessor *
601 AvDevice::getStreamProcessorByIndex(int i) {
602
603     if (i<(int)m_receiveProcessors.size()) {
604         return m_receiveProcessors.at(i);
605     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
606         return m_transmitProcessors.at(i-m_receiveProcessors.size());
607     }
608
609     return NULL;
610 }
611
612 bool
613 AvDevice::startStreamByIndex(int i) {
614     int iso_channel=-1;
615     bool snoopMode=false;
616     if(!getOption("snoopMode", snoopMode)) {
617         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
618     }
619
620     if (i<(int)m_receiveProcessors.size()) {
621         int n=i;
622         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
623
624         if(snoopMode) { // a stream from the device to another host
625             // FIXME: put this into a decent framework!
626             // we should check the oPCR[n] on the device
627             struct iec61883_oPCR opcr;
628             if (iec61883_get_oPCRX(
629                     get1394Service().getHandle(),
630                     m_pConfigRom->getNodeId() | 0xffc0,
631                     (quadlet_t *)&opcr,
632                     n)) {
633
634                 debugWarning("Error getting the channel for SP %d\n",i);
635                 return false;
636             }
637
638             iso_channel=opcr.channel;
639         } else {
640             iso_channel=get1394Service().allocateIsoChannelCMP(
641                 m_pConfigRom->getNodeId() | 0xffc0, n,
642                 get1394Service().getLocalNodeId()| 0xffc0, -1);
643         }
644         if (iso_channel<0) {
645             debugError("Could not allocate ISO channel for SP %d\n",i);
646             return false;
647         }
648
649         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
650
651         p->setChannel(iso_channel);
652         return true;
653
654     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
655         int n=i-m_receiveProcessors.size();
656         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
657
658         if(snoopMode) { // a stream from another host to the device
659             // FIXME: put this into a decent framework!
660             // we should check the iPCR[n] on the device
661             struct iec61883_iPCR ipcr;
662             if (iec61883_get_iPCRX(
663                     get1394Service().getHandle(),
664                     m_pConfigRom->getNodeId() | 0xffc0,
665                     (quadlet_t *)&ipcr,
666                     n)) {
667
668                 debugWarning("Error getting the channel for SP %d\n",i);
669                 return false;
670             }
671
672             iso_channel=ipcr.channel;
673
674         } else {
675             iso_channel=get1394Service().allocateIsoChannelCMP(
676                 get1394Service().getLocalNodeId()| 0xffc0, -1,
677                 m_pConfigRom->getNodeId() | 0xffc0, n);
678         }
679
680         if (iso_channel<0) {
681             debugError("Could not allocate ISO channel for SP %d\n",i);
682             return false;
683         }
684
685         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
686
687         p->setChannel(iso_channel);
688         return true;
689     }
690
691     debugError("SP index %d out of range!\n",i);
692     return false;
693 }
694
695 bool
696 AvDevice::stopStreamByIndex(int i) {
697     bool snoopMode=false;
698     if(!getOption("snoopMode", snoopMode)) {
699         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
700     }
701
702     if (i<(int)m_receiveProcessors.size()) {
703         int n=i;
704         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
705
706         if(snoopMode) {
707
708         } else {
709             // deallocate ISO channel
710             if(!get1394Service().freeIsoChannel(p->getChannel())) {
711                 debugError("Could not deallocate iso channel for SP %d\n",i);
712                 return false;
713             }
714         }
715         p->setChannel(-1);
716
717         return true;
718
719     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
720         int n=i-m_receiveProcessors.size();
721         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
722
723         if(snoopMode) {
724
725         } else {
726             // deallocate ISO channel
727             if(!get1394Service().freeIsoChannel(p->getChannel())) {
728                 debugError("Could not deallocate iso channel for SP %d\n",i);
729                 return false;
730             }
731         }
732         p->setChannel(-1);
733
734         return true;
735     }
736
737     debugError("SP index %d out of range!\n",i);
738     return false;
739 }
740
741 bool
742 AvDevice::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const
743 {
744     bool result;
745     result  = AVC::Unit::serialize( basePath, ser );
746     result &= serializeOptions( basePath + "Options", ser );
747     return result;
748 }
749
750 bool
751 AvDevice::deserialize( Glib::ustring basePath, Util::IODeserialize& deser )
752 {
753     bool result;
754     result = AVC::Unit::deserialize( basePath, deser );
755     return result;
756 }
757
758 }
Note: See TracBrowser for help on using the browser.