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

Revision 742, 22.8 kB (checked in by ppalmers, 16 years ago)

- Remove some obsolete support files and dirs

- Clean up the license statements in the source files. Everything is

GPL version 3 now.

- Add license and copyright notices to scons scripts

- Clean up some other text files

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