root/branches/api-cleanup/src/genericavc/avc_avdevice.cpp

Revision 809, 22.9 kB (checked in by ppalmers, 14 years ago)

First round of cleanup:
- make Ports auto-register to a PortManager?
- remove the different 'signal' types, everything is now period-signaled.
- removed obsolete streaming test programs

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( 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.