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

Revision 1029, 24.3 kB (checked in by ppalmers, 16 years ago)

compile fix

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