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

Revision 864, 22.9 kB (checked in by ppalmers, 16 years ago)

update license to GPLv2 or GPLv3 instead of GPLv2 or any later version. Update copyrights to reflect the new year

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     // check if we already have a valid VendorModel entry
101     // e.g. because a subclass called this function
102     if (!GenericAVC::VendorModel::isValid(m_model)) {
103         unsigned int vendorId = getConfigRom().getNodeVendorId();
104         unsigned int modelId = getConfigRom().getModelId();
105
106         GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_genericavc.txt" );
107         if ( vendorModel.parse() ) {
108             m_model = vendorModel.find( vendorId, modelId );
109         }
110
111         if (!GenericAVC::VendorModel::isValid(m_model)) {
112             return false;
113         }
114         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
115                 m_model.vendor_name.c_str(), m_model.model_name.c_str());
116     }
117
118     if ( !Unit::discover() ) {
119         debugError( "Could not discover unit\n" );
120         return false;
121     }
122
123     if((getAudioSubunit( 0 ) == NULL)) {
124         debugError( "Unit doesn't have an Audio subunit.\n");
125         return false;
126     }
127     if((getMusicSubunit( 0 ) == NULL)) {
128         debugError( "Unit doesn't have a Music subunit.\n");
129         return false;
130     }
131
132     return true;
133 }
134
135 void
136 AvDevice::setVerboseLevel(int l)
137 {
138     setDebugLevel(l);
139     m_pPlugManager->setVerboseLevel(l);
140     FFADODevice::setVerboseLevel(l);
141     AVC::Unit::setVerboseLevel(l);
142     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
143 }
144
145 int
146 AvDevice::getSamplingFrequency( ) {
147     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
148     if ( !inputPlug ) {
149         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
150         return false;
151     }
152     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
153     if ( !outputPlug ) {
154         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
155         return false;
156     }
157
158     int samplerate_playback=inputPlug->getSampleRate();
159     int samplerate_capture=outputPlug->getSampleRate();
160
161     if (samplerate_playback != samplerate_capture) {
162         debugWarning("Samplerates for capture and playback differ!\n");
163     }
164     return samplerate_capture;
165 }
166
167 bool
168 AvDevice::setSamplingFrequency( int s )
169 {
170     bool snoopMode=false;
171     if(!getOption("snoopMode", snoopMode)) {
172         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
173     }
174
175     if(snoopMode) {
176         int current_sr=getSamplingFrequency();
177         if (current_sr != s ) {
178             debugError("In snoop mode it is impossible to set the sample rate.\n");
179             debugError("Please start the client with the correct setting.\n");
180             return false;
181         }
182         return true;
183     } else {
184         AVC::Plug* plug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
185         if ( !plug ) {
186             debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
187             return false;
188         }
189
190         if ( !plug->setSampleRate( s ) )
191         {
192             debugError( "setSampleRate: Setting sample rate failed\n" );
193             return false;
194         }
195
196         plug = getPlugById( m_pcrPlugs, Plug::eAPD_Output,  0 );
197         if ( !plug ) {
198             debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
199             return false;
200         }
201
202         if ( !plug->setSampleRate( s ) )
203         {
204             debugError( "setSampleRate: Setting sample rate failed\n" );
205             return false;
206         }
207
208         debugOutput( DEBUG_LEVEL_VERBOSE,
209                      "setSampleRate: Set sample rate to %d\n",
210                      s );
211         return true;
212     }
213     // not executable
214     return false;
215
216 }
217
218 FFADODevice::ClockSourceVector
219 AvDevice::getSupportedClockSources() {
220     FFADODevice::ClockSourceVector r;
221
222     PlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType(
223         eST_Music,
224         0,
225         0xff,
226         0xff,
227         Plug::eAPA_SubunitPlug,
228         Plug::eAPD_Input,
229         Plug::eAPT_Sync );
230     if ( !syncMSUInputPlugs.size() ) {
231         debugWarning( "No sync input plug for MSU subunit found\n" );
232         return r;
233     }
234
235     for ( SyncInfoVector::const_iterator it
236               = getSyncInfos().begin();
237           it != getSyncInfos().end();
238           ++it )
239     {
240         const SyncInfo si=*it;
241
242         // check if the destination is a MSU input plug
243         bool found=false;
244         for ( PlugVector::const_iterator it2 = syncMSUInputPlugs.begin();
245               it2 != syncMSUInputPlugs.end();
246               ++it2 )
247         {
248             AVC::Plug* msuPlug = *it2;
249             found |= (msuPlug == si.m_destination);
250         }
251
252         if (found) {
253             ClockSource s=syncInfoToClockSource(*it);
254             r.push_back(s);
255         }
256     }
257
258     return r;
259 }
260
261 bool
262 AvDevice::setActiveClockSource(ClockSource s) {
263     Plug *src=m_pPlugManager->getPlug( s.id );
264     if (!src) {
265         debugError("Could not find plug with id %d\n", s.id);
266         return false;
267     }
268
269     for ( SyncInfoVector::const_iterator it
270               = getSyncInfos().begin();
271           it != getSyncInfos().end();
272           ++it )
273     {
274         const SyncInfo si=*it;
275
276         if (si.m_source==src) {
277             return setActiveSync(si);
278         }
279     }
280
281     return false;
282 }
283
284 FFADODevice::ClockSource
285 AvDevice::getActiveClockSource() {
286     const SyncInfo* si=getActiveSyncInfo();
287     if ( !si ) {
288         debugError( "Could not retrieve active sync information\n" );
289         ClockSource s;
290         s.type=eCT_Invalid;
291         return s;
292     }
293     debugOutput(DEBUG_LEVEL_VERBOSE, "Active Sync mode:  %s\n", si->m_description.c_str() );
294
295     return syncInfoToClockSource(*si);
296 }
297
298 FFADODevice::ClockSource
299 AvDevice::syncInfoToClockSource(const SyncInfo& si) {
300     ClockSource s;
301
302     // the description is easy
303     // it can be that we overwrite it later
304     s.description=si.m_description;
305
306     // FIXME: always valid at the moment
307     s.valid=true;
308
309     assert(si.m_source);
310     s.id=si.m_source->getGlobalId();
311
312     // now figure out what type this is
313     switch(si.m_source->getPlugType()) {
314         case Plug::eAPT_IsoStream:
315             s.type=eCT_SytMatch;
316             break;
317         case Plug::eAPT_Sync:
318             if(si.m_source->getPlugAddressType() == Plug::eAPA_PCR) {
319                 s.type=eCT_SytStream; // this is logical
320             } else if(si.m_source->getPlugAddressType() == Plug::eAPA_SubunitPlug) {
321                 s.type=eCT_Internal; // this assumes some stuff
322             } else if(si.m_source->getPlugAddressType() == Plug::eAPA_ExternalPlug) {
323                 std::string plugname=si.m_source->getName();
324                 s.description=plugname;
325                 // this is basically due to Focusrites interpretation
326                 if(plugname.find( "SPDIF", 0 ) != string::npos) {
327                     s.type=eCT_SPDIF; // this assumes the name will tell us
328                 } else {
329                     s.type=eCT_WordClock; // this assumes a whole lot more
330                 }
331             } else {
332                 s.type=eCT_Invalid;
333             }
334             break;
335         case Plug::eAPT_Digital:
336             if(si.m_source->getPlugAddressType() == Plug::eAPA_ExternalPlug) {
337                 std::string plugname=si.m_source->getName();
338                 s.description=plugname;
339                 // this is basically due to Focusrites interpretation
340                 if(plugname.find( "ADAT", 0 ) != string::npos) {
341                     s.type=eCT_ADAT; // this assumes the name will tell us
342                 } else if(plugname.find( "SPDIF", 0 ) != string::npos) {
343                     s.type=eCT_SPDIF; // this assumes the name will tell us
344                 } else {
345                     s.type=eCT_WordClock; // this assumes a whole lot more
346                 }
347             } else {
348                 s.type=eCT_Invalid;
349             }
350             break;
351         default:
352             s.type=eCT_Invalid; break;
353     }
354
355     // is it active?
356     const SyncInfo* active=getActiveSyncInfo();
357     if (active) {
358         if ((active->m_source == si.m_source)
359            && (active->m_destination == si.m_destination))
360            s.active=true;
361         else s.active=false;
362     } else s.active=false;
363
364     return s;
365 }
366
367 bool
368 AvDevice::lock() {
369     bool snoopMode=false;
370     if(!getOption("snoopMode", snoopMode)) {
371         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
372     }
373
374     if (snoopMode) {
375         // don't lock
376     } else {
377 //         return Unit::reserve(4);
378     }
379
380     return true;
381 }
382
383 bool
384 AvDevice::unlock() {
385     bool snoopMode=false;
386     if(!getOption("snoopMode", snoopMode)) {
387         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
388     }
389
390     if (snoopMode) {
391         // don't unlock
392     } else {
393 //         return Unit::reserve(0);
394     }
395     return true;
396 }
397
398 void
399 AvDevice::showDevice()
400 {
401     FFADODevice::showDevice();
402
403     AVC::Unit::show();
404     flushDebugOutput();
405 }
406
407 bool
408 AvDevice::prepare() {
409     bool snoopMode=false;
410     if(!getOption("snoopMode", snoopMode)) {
411         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
412     }
413
414     ///////////
415     // get plugs
416
417     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
418     if ( !inputPlug ) {
419         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
420         return false;
421     }
422     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
423     if ( !outputPlug ) {
424         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
425         return false;
426     }
427
428     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n");
429     // create & add streamprocessors
430     Streaming::StreamProcessor *p;
431
432     if ( outputPlug->getNrOfChannels() == 0 ) {
433         debugError("Receive plug has no channels\n");
434         return false;
435     }
436     p = new Streaming::AmdtpReceiveStreamProcessor(*this,
437                              outputPlug->getNrOfChannels());
438
439     if(!p->init()) {
440         debugFatal("Could not initialize receive processor!\n");
441         delete p;
442         return false;
443     }
444
445     if (!addPlugToProcessor(*outputPlug, p,
446         Streaming::Port::E_Capture)) {
447         debugFatal("Could not add plug to processor!\n");
448         delete p;
449         return false;
450     }
451
452     m_receiveProcessors.push_back(p);
453
454     // do the transmit processor
455     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing transmit processor%s...\n",
456             (snoopMode?" in snoop mode":""));
457     if (snoopMode) {
458         // we are snooping, so this is receive too.
459         p=new Streaming::AmdtpReceiveStreamProcessor(*this,
460                                   inputPlug->getNrOfChannels());
461     } else {
462         p=new Streaming::AmdtpTransmitStreamProcessor(*this,
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                         *processor,
535                         portname.str(),
536                         direction,
537                         channelInfo->m_streamPosition,
538                         channelInfo->m_location,
539                         Streaming::AmdtpPortInfo::E_MBLA
540                 );
541                 break;
542
543             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
544                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding MIDI channel %s (pos=0x%02X, loc=0x%02X)\n",
545                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, processor->getPortCount(Streaming::Port::E_Midi));
546                 p=new Streaming::AmdtpMidiPort(
547                         *processor,
548                         portname.str(),
549                         direction,
550                         channelInfo->m_streamPosition,
551                         // Workaround for out-of-spec hardware
552                         // should be:
553                         // channelInfo->m_location,
554                         // but now we renumber the midi channels' location as they
555                         // are discovered
556                         processor->getPortCount(Streaming::Port::E_Midi),
557                         Streaming::AmdtpPortInfo::E_Midi
558                 );
559
560                 break;
561             case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
562             case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
563             case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
564             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
565             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
566                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding digital audio channel %s (pos=0x%02X, loc=0x%02X)\n",
567                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
568                 p=new Streaming::AmdtpAudioPort(
569                         *processor,
570                         portname.str(),
571                         direction,
572                         channelInfo->m_streamPosition,
573                         channelInfo->m_location,
574                         Streaming::AmdtpPortInfo::E_MBLA
575                 );
576                 break;
577
578             case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
579             default:
580             // unsupported
581                 break;
582             }
583
584             if (!p) {
585                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
586             }
587          }
588     }
589     return true;
590 }
591
592 int
593 AvDevice::getStreamCount() {
594     return m_receiveProcessors.size() + m_transmitProcessors.size();
595     //return 1;
596 }
597
598 Streaming::StreamProcessor *
599 AvDevice::getStreamProcessorByIndex(int i) {
600
601     if (i<(int)m_receiveProcessors.size()) {
602         return m_receiveProcessors.at(i);
603     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
604         return m_transmitProcessors.at(i-m_receiveProcessors.size());
605     }
606
607     return NULL;
608 }
609
610 bool
611 AvDevice::startStreamByIndex(int i) {
612     int iso_channel=-1;
613     bool snoopMode=false;
614     if(!getOption("snoopMode", snoopMode)) {
615         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
616     }
617
618     if (i<(int)m_receiveProcessors.size()) {
619         int n=i;
620         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
621
622         if(snoopMode) { // a stream from the device to another host
623             // FIXME: put this into a decent framework!
624             // we should check the oPCR[n] on the device
625             struct iec61883_oPCR opcr;
626             if (iec61883_get_oPCRX(
627                     get1394Service().getHandle(),
628                     getConfigRom().getNodeId() | 0xffc0,
629                     (quadlet_t *)&opcr,
630                     n)) {
631
632                 debugWarning("Error getting the channel for SP %d\n",i);
633                 return false;
634             }
635
636             iso_channel=opcr.channel;
637         } else {
638             iso_channel=get1394Service().allocateIsoChannelCMP(
639                 getConfigRom().getNodeId() | 0xffc0, n,
640                 get1394Service().getLocalNodeId()| 0xffc0, -1);
641         }
642         if (iso_channel<0) {
643             debugError("Could not allocate ISO channel for SP %d\n",i);
644             return false;
645         }
646
647         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
648
649         p->setChannel(iso_channel);
650         return true;
651
652     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
653         int n=i-m_receiveProcessors.size();
654         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
655
656         if(snoopMode) { // a stream from another host to the device
657             // FIXME: put this into a decent framework!
658             // we should check the iPCR[n] on the device
659             struct iec61883_iPCR ipcr;
660             if (iec61883_get_iPCRX(
661                     get1394Service().getHandle(),
662                     getConfigRom().getNodeId() | 0xffc0,
663                     (quadlet_t *)&ipcr,
664                     n)) {
665
666                 debugWarning("Error getting the channel for SP %d\n",i);
667                 return false;
668             }
669
670             iso_channel=ipcr.channel;
671
672         } else {
673             iso_channel=get1394Service().allocateIsoChannelCMP(
674                 get1394Service().getLocalNodeId()| 0xffc0, -1,
675                 getConfigRom().getNodeId() | 0xffc0, n);
676         }
677
678         if (iso_channel<0) {
679             debugError("Could not allocate ISO channel for SP %d\n",i);
680             return false;
681         }
682
683         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
684
685         p->setChannel(iso_channel);
686         return true;
687     }
688
689     debugError("SP index %d out of range!\n",i);
690     return false;
691 }
692
693 bool
694 AvDevice::stopStreamByIndex(int i) {
695     bool snoopMode=false;
696     if(!getOption("snoopMode", snoopMode)) {
697         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
698     }
699
700     if (i<(int)m_receiveProcessors.size()) {
701         int n=i;
702         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
703
704         if(snoopMode) {
705
706         } else {
707             // deallocate ISO channel
708             if(!get1394Service().freeIsoChannel(p->getChannel())) {
709                 debugError("Could not deallocate iso channel for SP %d\n",i);
710                 return false;
711             }
712         }
713         p->setChannel(-1);
714
715         return true;
716
717     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
718         int n=i-m_receiveProcessors.size();
719         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
720
721         if(snoopMode) {
722
723         } else {
724             // deallocate ISO channel
725             if(!get1394Service().freeIsoChannel(p->getChannel())) {
726                 debugError("Could not deallocate iso channel for SP %d\n",i);
727                 return false;
728             }
729         }
730         p->setChannel(-1);
731
732         return true;
733     }
734
735     debugError("SP index %d out of range!\n",i);
736     return false;
737 }
738
739 bool
740 AvDevice::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const
741 {
742     bool result;
743     result  = AVC::Unit::serialize( basePath, ser );
744     result &= serializeOptions( basePath + "Options", ser );
745     return result;
746 }
747
748 bool
749 AvDevice::deserialize( Glib::ustring basePath, Util::IODeserialize& deser )
750 {
751     bool result;
752     result = AVC::Unit::deserialize( basePath, deser );
753     return result;
754 }
755
756 }
Note: See TracBrowser for help on using the browser.