1 |
/* bebob_light_avdevice.cpp |
---|
2 |
* Copyright (C) 2006 by Daniel Wagner |
---|
3 |
* |
---|
4 |
* This file is part of FreeBoB. |
---|
5 |
* |
---|
6 |
* FreeBoB is free software; you can redistribute it and/or modify |
---|
7 |
* it under the terms of the GNU General Public License as published by |
---|
8 |
* the Free Software Foundation; either version 2 of the License, or |
---|
9 |
* (at your option) any later version. |
---|
10 |
* FreeBoB is distributed in the hope that it will be useful, |
---|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
13 |
* GNU General Public License for more details. |
---|
14 |
* |
---|
15 |
* You should have received a copy of the GNU General Public License |
---|
16 |
* along with FreeBoB; if not, write to the Free Software |
---|
17 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
---|
18 |
* MA 02111-1307 USA. |
---|
19 |
*/ |
---|
20 |
|
---|
21 |
#include "bebob_light/bebob_light_avdevice.h" |
---|
22 |
#include "bebob_light/bebob_light_avdevicesubunit.h" |
---|
23 |
|
---|
24 |
#include "configrom.h" |
---|
25 |
|
---|
26 |
#include "libfreebobavc/avc_plug_info.h" |
---|
27 |
#include "libfreebobavc/avc_extended_plug_info.h" |
---|
28 |
#include "libfreebobavc/avc_subunit_info.h" |
---|
29 |
#include "libfreebobavc/avc_extended_stream_format.h" |
---|
30 |
#include "libfreebobavc/serialize.h" |
---|
31 |
#include "libfreebobavc/ieee1394service.h" |
---|
32 |
#include "libfreebobavc/avc_definitions.h" |
---|
33 |
|
---|
34 |
#include "debugmodule/debugmodule.h" |
---|
35 |
|
---|
36 |
#include <iostream> |
---|
37 |
#include <stdint.h> |
---|
38 |
|
---|
39 |
namespace BeBoB_Light { |
---|
40 |
|
---|
41 |
using namespace std; |
---|
42 |
|
---|
43 |
IMPL_DEBUG_MODULE( AvDevice, AvDevice, DEBUG_LEVEL_VERBOSE ); |
---|
44 |
|
---|
45 |
AvDevice::AvDevice( Ieee1394Service& ieee1394service, |
---|
46 |
int nodeId, |
---|
47 |
int verboseLevel ) |
---|
48 |
: m_1394Service( &ieee1394service ) |
---|
49 |
, m_nodeId( nodeId ) |
---|
50 |
, m_verboseLevel( verboseLevel ) |
---|
51 |
, m_id( 0 ) |
---|
52 |
{ |
---|
53 |
if ( m_verboseLevel ) { |
---|
54 |
setDebugLevel( DEBUG_LEVEL_VERBOSE ); |
---|
55 |
} |
---|
56 |
debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB_Light::AvDevice " |
---|
57 |
"(NodeID %d)\n", nodeId ); |
---|
58 |
|
---|
59 |
m_configRom = new ConfigRom( m_1394Service, m_nodeId ); |
---|
60 |
m_configRom->initialize(); |
---|
61 |
} |
---|
62 |
|
---|
63 |
AvDevice::~AvDevice() |
---|
64 |
{ |
---|
65 |
delete m_configRom; |
---|
66 |
for ( AvDeviceSubunitVector::iterator it = m_subunits.begin(); |
---|
67 |
it != m_subunits.end(); |
---|
68 |
++it ) |
---|
69 |
{ |
---|
70 |
delete *it; |
---|
71 |
} |
---|
72 |
for ( AvPlugConnectionVector::iterator it = m_plugConnections.begin(); |
---|
73 |
it != m_plugConnections.end(); |
---|
74 |
++it ) |
---|
75 |
{ |
---|
76 |
delete *it; |
---|
77 |
} |
---|
78 |
for ( AvPlugVector::iterator it = m_isoInputPlugs.begin(); |
---|
79 |
it != m_isoInputPlugs.end(); |
---|
80 |
++it ) |
---|
81 |
{ |
---|
82 |
delete *it; |
---|
83 |
} |
---|
84 |
for ( AvPlugVector::iterator it = m_isoOutputPlugs.begin(); |
---|
85 |
it != m_isoOutputPlugs.end(); |
---|
86 |
++it ) |
---|
87 |
{ |
---|
88 |
delete *it; |
---|
89 |
} |
---|
90 |
} |
---|
91 |
|
---|
92 |
bool |
---|
93 |
AvDevice::discover() |
---|
94 |
{ |
---|
95 |
if ( !enumerateSubUnits() ) { |
---|
96 |
debugError( "Could not enumarate sub units\n" ); |
---|
97 |
return false; |
---|
98 |
} |
---|
99 |
|
---|
100 |
if ( !discoverStep1() ) { |
---|
101 |
debugError( "Discover step 1 failed\n" ); |
---|
102 |
return false; |
---|
103 |
} |
---|
104 |
if ( !discoverStep2() ) { |
---|
105 |
debugError( "Discover step 2 failed\n" ); |
---|
106 |
return false; |
---|
107 |
} |
---|
108 |
if ( !discoverStep3() ) { |
---|
109 |
debugError( "Discover step 3 failed\n" ); |
---|
110 |
return false; |
---|
111 |
} |
---|
112 |
if ( !discoverStep4() ) { |
---|
113 |
debugError( "Discover step 4 failed\n" ); |
---|
114 |
return false; |
---|
115 |
} |
---|
116 |
if ( !discoverStep5() ) { |
---|
117 |
debugError( "Discover step 5 failed\n" ); |
---|
118 |
return false; |
---|
119 |
} |
---|
120 |
if ( !discoverStep6() ) { |
---|
121 |
debugError( "Discover step 6 failed\n" ); |
---|
122 |
return false; |
---|
123 |
} |
---|
124 |
if ( !discoverStep7() ) { |
---|
125 |
debugError( "Discover step 7 failed\n" ); |
---|
126 |
return false; |
---|
127 |
} |
---|
128 |
if ( !discoverStep8() ) { |
---|
129 |
debugError( "Discover step 8 failed\n" ); |
---|
130 |
return false; |
---|
131 |
} |
---|
132 |
if ( !discoverStep9() ) { |
---|
133 |
debugError( "Discover step 9 failed\n" ); |
---|
134 |
return false; |
---|
135 |
} |
---|
136 |
if ( !discoverStep10() ) { |
---|
137 |
debugError( "Discover step 10 failed\n" ); |
---|
138 |
return false; |
---|
139 |
} |
---|
140 |
|
---|
141 |
return true; |
---|
142 |
} |
---|
143 |
|
---|
144 |
bool |
---|
145 |
AvDevice::discoverStep1() |
---|
146 |
{ |
---|
147 |
////////////////////////////////////////////// |
---|
148 |
// Step 1: Get number of available isochronous input |
---|
149 |
// and output plugs of unit |
---|
150 |
|
---|
151 |
PlugInfoCmd plugInfoCmd( m_1394Service ); |
---|
152 |
plugInfoCmd.setNodeId( m_nodeId ); |
---|
153 |
plugInfoCmd.setCommandType( AVCCommand::eCT_Status ); |
---|
154 |
|
---|
155 |
if ( !plugInfoCmd.fire() ) { |
---|
156 |
debugError( "discover: plug info command failed (step 1)\n" ); |
---|
157 |
return false; |
---|
158 |
} |
---|
159 |
|
---|
160 |
for ( int plugId = 0; plugId < plugInfoCmd.m_serialBusIsochronousInputPlugs; ++plugId ) |
---|
161 |
{ |
---|
162 |
AvPlug* plug = new AvPlug; |
---|
163 |
plug->m_plugId = plugId; |
---|
164 |
plug->m_subunitType = PlugAddress::ePAM_Unit; |
---|
165 |
plug->m_direction = PlugAddress::ePD_Input; |
---|
166 |
plug->m_name = "IsoStreamInput"; |
---|
167 |
|
---|
168 |
m_isoInputPlugs.push_back( plug ); |
---|
169 |
} |
---|
170 |
|
---|
171 |
for ( int plugId = 0; plugId < plugInfoCmd.m_serialBusIsochronousOutputPlugs; ++plugId ) |
---|
172 |
{ |
---|
173 |
AvPlug* plug = new AvPlug; |
---|
174 |
plug->m_plugId = plugId; |
---|
175 |
plug->m_subunitType = PlugAddress::ePAM_Unit; |
---|
176 |
plug->m_direction = PlugAddress::ePD_Output; |
---|
177 |
plug->m_name = "IsoStreamOutput"; |
---|
178 |
|
---|
179 |
m_isoOutputPlugs.push_back( plug ); |
---|
180 |
} |
---|
181 |
|
---|
182 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
183 |
"number of iso input plugs = %d, " |
---|
184 |
"number of iso output plugs = %d\n", |
---|
185 |
plugInfoCmd.m_serialBusIsochronousInputPlugs, |
---|
186 |
plugInfoCmd.m_serialBusIsochronousOutputPlugs ); |
---|
187 |
|
---|
188 |
return true; |
---|
189 |
} |
---|
190 |
|
---|
191 |
bool |
---|
192 |
AvDevice::discoverStep2() |
---|
193 |
{ |
---|
194 |
////////////////////////////////////////////// |
---|
195 |
// Step 2: For each ISO input plug: get internal |
---|
196 |
// output connections (data sink) of the ISO input plug |
---|
197 |
|
---|
198 |
for ( AvPlugVector::iterator it = m_isoInputPlugs.begin(); |
---|
199 |
it != m_isoInputPlugs.end(); |
---|
200 |
++it ) |
---|
201 |
{ |
---|
202 |
AvPlug* isoInputPlug = *it; |
---|
203 |
|
---|
204 |
ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service ); |
---|
205 |
UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, |
---|
206 |
isoInputPlug->getPlugId() ); |
---|
207 |
extPlugInfoCmd.setPlugAddress( PlugAddress( PlugAddress::ePD_Input, |
---|
208 |
PlugAddress::ePAM_Unit, |
---|
209 |
unitPlugAddress ) ); |
---|
210 |
extPlugInfoCmd.setNodeId( m_nodeId ); |
---|
211 |
extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status ); |
---|
212 |
//extPlugInfoCmd.setVerbose( true ); |
---|
213 |
ExtendedPlugInfoInfoType extendedPlugInfoInfoType( |
---|
214 |
ExtendedPlugInfoInfoType::eIT_PlugOutput ); |
---|
215 |
extendedPlugInfoInfoType.initialize(); |
---|
216 |
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); |
---|
217 |
|
---|
218 |
if ( !extPlugInfoCmd.fire() ) { |
---|
219 |
debugError( "discoverStep2: plug outputs command failed\n" ); |
---|
220 |
return false; |
---|
221 |
} |
---|
222 |
|
---|
223 |
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType(); |
---|
224 |
if ( infoType |
---|
225 |
&& infoType->m_plugOutput ) |
---|
226 |
{ |
---|
227 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
228 |
"number of output plugs is %d for iso input " |
---|
229 |
"plug %d\n", |
---|
230 |
infoType->m_plugOutput->m_nrOfOutputPlugs, |
---|
231 |
isoInputPlug->getPlugId() ); |
---|
232 |
|
---|
233 |
if ( infoType->m_plugOutput->m_nrOfOutputPlugs |
---|
234 |
!= infoType->m_plugOutput->m_outputPlugAddresses.size() ) |
---|
235 |
{ |
---|
236 |
debugError( "number of output plugs (%d) disagree with " |
---|
237 |
"number of elements in plug address vector (%d)\n", |
---|
238 |
infoType->m_plugOutput->m_nrOfOutputPlugs, |
---|
239 |
infoType->m_plugOutput->m_outputPlugAddresses.size()); |
---|
240 |
} |
---|
241 |
for ( unsigned int i = 0; |
---|
242 |
i < infoType->m_plugOutput->m_outputPlugAddresses.size(); |
---|
243 |
++i ) |
---|
244 |
{ |
---|
245 |
PlugAddressSpecificData* plugAddress |
---|
246 |
= infoType->m_plugOutput->m_outputPlugAddresses[i]; |
---|
247 |
|
---|
248 |
|
---|
249 |
UnitPlugSpecificDataPlugAddress* pUnitPlugAddress = |
---|
250 |
dynamic_cast<UnitPlugSpecificDataPlugAddress*> |
---|
251 |
( plugAddress->m_plugAddressData ); |
---|
252 |
|
---|
253 |
if ( pUnitPlugAddress ) { |
---|
254 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
255 |
"unit plug address is not handled\n" ); |
---|
256 |
} |
---|
257 |
|
---|
258 |
SubunitPlugSpecificDataPlugAddress* pSubunitPlugAddress = |
---|
259 |
dynamic_cast<SubunitPlugSpecificDataPlugAddress*> |
---|
260 |
( plugAddress->m_plugAddressData ); |
---|
261 |
|
---|
262 |
if ( pSubunitPlugAddress ) { |
---|
263 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
264 |
"output plug %d is owned by subunit_type %d, " |
---|
265 |
"subunit_id = %d\n", |
---|
266 |
pSubunitPlugAddress->m_plugId, |
---|
267 |
pSubunitPlugAddress->m_subunitType, |
---|
268 |
pSubunitPlugAddress->m_subunitId ); |
---|
269 |
|
---|
270 |
if ( !discoverPlugConnection( *isoInputPlug, |
---|
271 |
*pSubunitPlugAddress ) ) |
---|
272 |
{ |
---|
273 |
debugError( "Discovering of plug connection failed\n" ); |
---|
274 |
return false; |
---|
275 |
} |
---|
276 |
} |
---|
277 |
|
---|
278 |
FunctionBlockPlugSpecificDataPlugAddress* |
---|
279 |
pFunctionBlockPlugAddress = |
---|
280 |
dynamic_cast<FunctionBlockPlugSpecificDataPlugAddress*> |
---|
281 |
( plugAddress->m_plugAddressData ); |
---|
282 |
|
---|
283 |
if ( pFunctionBlockPlugAddress ) { |
---|
284 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
285 |
"function block address is not handled\n" ); |
---|
286 |
} |
---|
287 |
} |
---|
288 |
} else { |
---|
289 |
debugError( "discoverStep2: no valid info type, output plug\n" ); |
---|
290 |
return false; |
---|
291 |
} |
---|
292 |
} |
---|
293 |
|
---|
294 |
return true; |
---|
295 |
} |
---|
296 |
|
---|
297 |
bool |
---|
298 |
AvDevice::discoverStep3() |
---|
299 |
{ |
---|
300 |
////////////////////////////////////////////// |
---|
301 |
// Step 3: For each ISO output plug: get internal |
---|
302 |
// intput connections (data source) of the ISO output plug |
---|
303 |
|
---|
304 |
for ( AvPlugVector::iterator it = m_isoOutputPlugs.begin(); |
---|
305 |
it != m_isoOutputPlugs.end(); |
---|
306 |
++it ) |
---|
307 |
{ |
---|
308 |
AvPlug* isoOutputPlug = *it; |
---|
309 |
|
---|
310 |
ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service ); |
---|
311 |
UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, |
---|
312 |
isoOutputPlug->getPlugId() ); |
---|
313 |
extPlugInfoCmd.setPlugAddress( PlugAddress( PlugAddress::ePD_Output, |
---|
314 |
PlugAddress::ePAM_Unit, |
---|
315 |
unitPlugAddress ) ); |
---|
316 |
extPlugInfoCmd.setNodeId( m_nodeId ); |
---|
317 |
extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status ); |
---|
318 |
//extPlugInfoCmd.setVerbose( true ); |
---|
319 |
ExtendedPlugInfoInfoType extendedPlugInfoInfoType( |
---|
320 |
ExtendedPlugInfoInfoType::eIT_PlugInput ); |
---|
321 |
extendedPlugInfoInfoType.initialize(); |
---|
322 |
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); |
---|
323 |
|
---|
324 |
if ( !extPlugInfoCmd.fire() ) { |
---|
325 |
debugError( "discoverStep3: plug inputs command failed\n" ); |
---|
326 |
return false; |
---|
327 |
} |
---|
328 |
|
---|
329 |
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType(); |
---|
330 |
if ( infoType |
---|
331 |
&& infoType->m_plugInput ) |
---|
332 |
{ |
---|
333 |
PlugAddressSpecificData* plugAddress |
---|
334 |
= infoType->m_plugInput->m_plugAddress; |
---|
335 |
|
---|
336 |
|
---|
337 |
UnitPlugSpecificDataPlugAddress* pUnitPlugAddress = |
---|
338 |
dynamic_cast<UnitPlugSpecificDataPlugAddress*> |
---|
339 |
( plugAddress->m_plugAddressData ); |
---|
340 |
|
---|
341 |
if ( pUnitPlugAddress ) { |
---|
342 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
343 |
"unit plug address is not handled\n" ); |
---|
344 |
} |
---|
345 |
|
---|
346 |
SubunitPlugSpecificDataPlugAddress* pSubunitPlugAddress = |
---|
347 |
dynamic_cast<SubunitPlugSpecificDataPlugAddress*> |
---|
348 |
( plugAddress->m_plugAddressData ); |
---|
349 |
|
---|
350 |
if ( pSubunitPlugAddress ) { |
---|
351 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
352 |
"output plug %d is owned by subunit_type %d, " |
---|
353 |
"subunit_id %d\n", |
---|
354 |
pSubunitPlugAddress->m_plugId, |
---|
355 |
pSubunitPlugAddress->m_subunitType, |
---|
356 |
pSubunitPlugAddress->m_subunitId ); |
---|
357 |
|
---|
358 |
if ( !discoverPlugConnection( *isoOutputPlug, *pSubunitPlugAddress ) ) { |
---|
359 |
debugError( "Discovering of plug connection failed\n" ); |
---|
360 |
return false; |
---|
361 |
} |
---|
362 |
} |
---|
363 |
|
---|
364 |
FunctionBlockPlugSpecificDataPlugAddress* |
---|
365 |
pFunctionBlockPlugAddress = |
---|
366 |
dynamic_cast<FunctionBlockPlugSpecificDataPlugAddress*> |
---|
367 |
( plugAddress->m_plugAddressData ); |
---|
368 |
|
---|
369 |
if ( pFunctionBlockPlugAddress ) { |
---|
370 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
371 |
"function block address is not handled\n" ); |
---|
372 |
} |
---|
373 |
} else { |
---|
374 |
debugError( "discoverStep3: no valid info type, input plug\n" ); |
---|
375 |
return false; |
---|
376 |
} |
---|
377 |
} |
---|
378 |
|
---|
379 |
return true; |
---|
380 |
} |
---|
381 |
|
---|
382 |
bool |
---|
383 |
AvDevice::discoverStep4Plug( AvPlugVector& isoPlugs ) |
---|
384 |
{ |
---|
385 |
////////////////////////////////////////////// |
---|
386 |
// Step 4: For all ISO plugs with valid internal connections: |
---|
387 |
// get type of data stream flowing through plug. |
---|
388 |
// Stream type of interest: iso stream & sync stream |
---|
389 |
|
---|
390 |
for ( AvPlugVector::iterator it = isoPlugs.begin(); |
---|
391 |
it != isoPlugs.end(); |
---|
392 |
++it ) |
---|
393 |
{ |
---|
394 |
AvPlug* isoPlug = *it; |
---|
395 |
|
---|
396 |
AvPlugConnection* plugConnection = getPlugConnection( *isoPlug ); |
---|
397 |
if ( !plugConnection ) { |
---|
398 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
399 |
"plug %d has no valid connecton -> skip\n", |
---|
400 |
isoPlug->getPlugId() ); |
---|
401 |
continue; |
---|
402 |
} |
---|
403 |
|
---|
404 |
ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service ); |
---|
405 |
UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, |
---|
406 |
isoPlug->getPlugId() ); |
---|
407 |
PlugAddress::EPlugDirection direction = |
---|
408 |
static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() ); |
---|
409 |
extPlugInfoCmd.setPlugAddress( PlugAddress( direction, |
---|
410 |
PlugAddress::ePAM_Unit, |
---|
411 |
unitPlugAddress ) ); |
---|
412 |
extPlugInfoCmd.setNodeId( m_nodeId ); |
---|
413 |
extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status ); |
---|
414 |
//extPlugInfoCmd.setVerbose( true ); |
---|
415 |
ExtendedPlugInfoInfoType extendedPlugInfoInfoType( |
---|
416 |
ExtendedPlugInfoInfoType::eIT_PlugType ); |
---|
417 |
extendedPlugInfoInfoType.initialize(); |
---|
418 |
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); |
---|
419 |
|
---|
420 |
if ( !extPlugInfoCmd.fire() ) { |
---|
421 |
debugError( "discoverStep4Plug: plug type command failed\n" ); |
---|
422 |
return false; |
---|
423 |
} |
---|
424 |
|
---|
425 |
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType(); |
---|
426 |
if ( infoType |
---|
427 |
&& infoType->m_plugType ) |
---|
428 |
{ |
---|
429 |
plug_type_t plugType = infoType->m_plugType->m_plugType; |
---|
430 |
|
---|
431 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
432 |
"plug %d is of type %d (%s)\n", |
---|
433 |
isoPlug->getPlugId(), |
---|
434 |
plugType, |
---|
435 |
extendedPlugInfoPlugTypeToString( plugType ) ); |
---|
436 |
|
---|
437 |
isoPlug->m_plugType = plugType; |
---|
438 |
} |
---|
439 |
} |
---|
440 |
|
---|
441 |
return true; |
---|
442 |
} |
---|
443 |
|
---|
444 |
bool |
---|
445 |
AvDevice::discoverStep4() |
---|
446 |
{ |
---|
447 |
bool success; |
---|
448 |
success = discoverStep4Plug( m_isoInputPlugs ); |
---|
449 |
success &= discoverStep4Plug( m_isoOutputPlugs ); |
---|
450 |
|
---|
451 |
return success; |
---|
452 |
} |
---|
453 |
|
---|
454 |
bool |
---|
455 |
AvDevice::discoverStep5Plug( AvPlugVector& isoPlugs ) |
---|
456 |
{ |
---|
457 |
////////////////////////////////////////////// |
---|
458 |
// Step 5: For all ISO plugs with valid internal connections: |
---|
459 |
// get data block size of the stream flowing through the plug |
---|
460 |
|
---|
461 |
for ( AvPlugVector::iterator it = isoPlugs.begin(); |
---|
462 |
it != isoPlugs.end(); |
---|
463 |
++it ) |
---|
464 |
{ |
---|
465 |
AvPlug* isoPlug = *it; |
---|
466 |
|
---|
467 |
AvPlugConnection* plugConnection = getPlugConnection( *isoPlug ); |
---|
468 |
if ( !plugConnection ) { |
---|
469 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
470 |
"plug %d has no valid connecton -> skip\n", |
---|
471 |
isoPlug->getPlugId() ); |
---|
472 |
continue; |
---|
473 |
} |
---|
474 |
|
---|
475 |
ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service ); |
---|
476 |
UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, |
---|
477 |
isoPlug->getPlugId() ); |
---|
478 |
PlugAddress::EPlugDirection direction = |
---|
479 |
static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() ); |
---|
480 |
extPlugInfoCmd.setPlugAddress( PlugAddress( direction, |
---|
481 |
PlugAddress::ePAM_Unit, |
---|
482 |
unitPlugAddress ) ); |
---|
483 |
extPlugInfoCmd.setNodeId( m_nodeId ); |
---|
484 |
extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status ); |
---|
485 |
//extPlugInfoCmd.setVerbose( true ); |
---|
486 |
ExtendedPlugInfoInfoType extendedPlugInfoInfoType( |
---|
487 |
ExtendedPlugInfoInfoType::eIT_NoOfChannels ); |
---|
488 |
extendedPlugInfoInfoType.initialize(); |
---|
489 |
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); |
---|
490 |
|
---|
491 |
if ( !extPlugInfoCmd.fire() ) { |
---|
492 |
debugError( "discoverStep5Plug: number of channels command failed\n" ); |
---|
493 |
return false; |
---|
494 |
} |
---|
495 |
|
---|
496 |
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType(); |
---|
497 |
if ( infoType |
---|
498 |
&& infoType->m_plugNrOfChns ) |
---|
499 |
{ |
---|
500 |
nr_of_channels_t nrOfChannels |
---|
501 |
= infoType->m_plugNrOfChns->m_nrOfChannels; |
---|
502 |
|
---|
503 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
504 |
"plug %d has %d channels\n", |
---|
505 |
isoPlug->getPlugId(), |
---|
506 |
nrOfChannels ); |
---|
507 |
|
---|
508 |
isoPlug->m_nrOfChannels = nrOfChannels; |
---|
509 |
} |
---|
510 |
} |
---|
511 |
|
---|
512 |
return true; |
---|
513 |
} |
---|
514 |
|
---|
515 |
|
---|
516 |
bool |
---|
517 |
AvDevice::discoverStep5() |
---|
518 |
{ |
---|
519 |
bool success; |
---|
520 |
success = discoverStep5Plug( m_isoInputPlugs ); |
---|
521 |
success &= discoverStep5Plug( m_isoOutputPlugs ); |
---|
522 |
|
---|
523 |
return success; |
---|
524 |
} |
---|
525 |
|
---|
526 |
bool |
---|
527 |
AvDevice::discoverStep6Plug( AvPlugVector& isoPlugs ) |
---|
528 |
{ |
---|
529 |
////////////////////////////////////////////// |
---|
530 |
// Step 6: For all ISO plugs with valid internal connections: |
---|
531 |
// get position of channels within data block |
---|
532 |
|
---|
533 |
for ( AvPlugVector::iterator it = isoPlugs.begin(); |
---|
534 |
it != isoPlugs.end(); |
---|
535 |
++it ) |
---|
536 |
{ |
---|
537 |
AvPlug* isoPlug = *it; |
---|
538 |
|
---|
539 |
AvPlugConnection* plugConnection = getPlugConnection( *isoPlug ); |
---|
540 |
if ( !plugConnection ) { |
---|
541 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
542 |
"plug %d has no valid connecton -> skip\n", |
---|
543 |
isoPlug->getPlugId() ); |
---|
544 |
continue; |
---|
545 |
} |
---|
546 |
|
---|
547 |
ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service ); |
---|
548 |
UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, |
---|
549 |
isoPlug->getPlugId() ); |
---|
550 |
PlugAddress::EPlugDirection direction = |
---|
551 |
static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() ); |
---|
552 |
extPlugInfoCmd.setPlugAddress( PlugAddress( direction, |
---|
553 |
PlugAddress::ePAM_Unit, |
---|
554 |
unitPlugAddress ) ); |
---|
555 |
extPlugInfoCmd.setNodeId( m_nodeId ); |
---|
556 |
extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status ); |
---|
557 |
//extPlugInfoCmd.setVerbose( true ); |
---|
558 |
ExtendedPlugInfoInfoType extendedPlugInfoInfoType( |
---|
559 |
ExtendedPlugInfoInfoType::eIT_ChannelPosition ); |
---|
560 |
extendedPlugInfoInfoType.initialize(); |
---|
561 |
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); |
---|
562 |
|
---|
563 |
if ( !extPlugInfoCmd.fire() ) { |
---|
564 |
debugError( "discoverStep6Plug: channels position command failed\n" ); |
---|
565 |
return false; |
---|
566 |
} |
---|
567 |
|
---|
568 |
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType(); |
---|
569 |
if ( infoType |
---|
570 |
&& infoType->m_plugChannelPosition ) |
---|
571 |
{ |
---|
572 |
if ( !isoPlug->copyClusterInfo( |
---|
573 |
*( infoType->m_plugChannelPosition ) ) ) |
---|
574 |
{ |
---|
575 |
debugError( "discoverStep6Plug: Could not copy channel position " |
---|
576 |
"information\n" ); |
---|
577 |
return false; |
---|
578 |
} |
---|
579 |
|
---|
580 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
581 |
"plug %d: channel position information " |
---|
582 |
"retrieved\n", |
---|
583 |
isoPlug->getPlugId() ); |
---|
584 |
|
---|
585 |
isoPlug->debugOutputClusterInfos( DEBUG_LEVEL_VERBOSE ); |
---|
586 |
} |
---|
587 |
} |
---|
588 |
|
---|
589 |
return true; |
---|
590 |
} |
---|
591 |
|
---|
592 |
bool |
---|
593 |
AvDevice::discoverStep6() |
---|
594 |
{ |
---|
595 |
bool success; |
---|
596 |
success = discoverStep6Plug( m_isoInputPlugs ); |
---|
597 |
success &= discoverStep6Plug( m_isoOutputPlugs ); |
---|
598 |
|
---|
599 |
return success; |
---|
600 |
} |
---|
601 |
|
---|
602 |
bool |
---|
603 |
AvDevice::discoverStep7Plug( AvPlugVector& isoPlugs ) |
---|
604 |
{ |
---|
605 |
////////////////////////////////////////////// |
---|
606 |
// Step 7: For all ISO plugs with valid internal connections: |
---|
607 |
// get hardware name of channel |
---|
608 |
|
---|
609 |
for ( AvPlugVector::iterator it = isoPlugs.begin(); |
---|
610 |
it != isoPlugs.end(); |
---|
611 |
++it ) |
---|
612 |
{ |
---|
613 |
AvPlug* isoPlug = *it; |
---|
614 |
|
---|
615 |
AvPlugConnection* plugConnection = getPlugConnection( *isoPlug ); |
---|
616 |
if ( !plugConnection ) { |
---|
617 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
618 |
"plug %d has no valid connecton -> skip\n", |
---|
619 |
isoPlug->getPlugId() ); |
---|
620 |
continue; |
---|
621 |
} |
---|
622 |
|
---|
623 |
for ( AvPlug::ClusterInfoVector::iterator clit = |
---|
624 |
isoPlug->m_clusterInfos.begin(); |
---|
625 |
clit != isoPlug->m_clusterInfos.end(); |
---|
626 |
++clit ) |
---|
627 |
{ |
---|
628 |
AvPlug::ClusterInfo* clitInfo = &*clit; |
---|
629 |
|
---|
630 |
for ( AvPlug::ChannelInfoVector::iterator pit = |
---|
631 |
clitInfo->m_channelInfos.begin(); |
---|
632 |
pit != clitInfo->m_channelInfos.end(); |
---|
633 |
++pit ) |
---|
634 |
{ |
---|
635 |
AvPlug::ChannelInfo* channelInfo = &*pit; |
---|
636 |
|
---|
637 |
ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service ); |
---|
638 |
UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, |
---|
639 |
isoPlug->getPlugId() ); |
---|
640 |
PlugAddress::EPlugDirection direction = |
---|
641 |
static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() ); |
---|
642 |
extPlugInfoCmd.setPlugAddress( PlugAddress( direction, |
---|
643 |
PlugAddress::ePAM_Unit, |
---|
644 |
unitPlugAddress ) ); |
---|
645 |
extPlugInfoCmd.setNodeId( m_nodeId ); |
---|
646 |
extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status ); |
---|
647 |
//extPlugInfoCmd.setVerbose( true ); |
---|
648 |
ExtendedPlugInfoInfoType extendedPlugInfoInfoType( |
---|
649 |
ExtendedPlugInfoInfoType::eIT_ChannelName ); |
---|
650 |
extendedPlugInfoInfoType.initialize(); |
---|
651 |
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); |
---|
652 |
|
---|
653 |
ExtendedPlugInfoInfoType* infoType = |
---|
654 |
extPlugInfoCmd.getInfoType(); |
---|
655 |
if ( infoType ) { |
---|
656 |
infoType->m_plugChannelName->m_streamPosition = |
---|
657 |
channelInfo->m_streamPosition; |
---|
658 |
} |
---|
659 |
if ( !extPlugInfoCmd.fire() ) { |
---|
660 |
debugError( "discoverStep7: channel name command failed\n" ); |
---|
661 |
return false; |
---|
662 |
} |
---|
663 |
infoType = extPlugInfoCmd.getInfoType(); |
---|
664 |
if ( infoType |
---|
665 |
&& infoType->m_plugChannelName ) |
---|
666 |
{ |
---|
667 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
668 |
"plug %d stream " |
---|
669 |
"position %d: channel name = %s\n", |
---|
670 |
isoPlug->getPlugId(), |
---|
671 |
channelInfo->m_streamPosition, |
---|
672 |
infoType->m_plugChannelName->m_plugChannelName.c_str() ); |
---|
673 |
channelInfo->m_name = |
---|
674 |
infoType->m_plugChannelName->m_plugChannelName; |
---|
675 |
} |
---|
676 |
|
---|
677 |
} |
---|
678 |
} |
---|
679 |
} |
---|
680 |
|
---|
681 |
return true; |
---|
682 |
} |
---|
683 |
bool |
---|
684 |
AvDevice::discoverStep7() |
---|
685 |
{ |
---|
686 |
bool success; |
---|
687 |
success = discoverStep7Plug( m_isoInputPlugs ); |
---|
688 |
success &= discoverStep7Plug( m_isoOutputPlugs ); |
---|
689 |
|
---|
690 |
return success; |
---|
691 |
} |
---|
692 |
|
---|
693 |
bool |
---|
694 |
AvDevice::discoverStep8Plug( AvPlugVector& isoPlugs ) |
---|
695 |
{ |
---|
696 |
////////////////////////////////////////////// |
---|
697 |
// Step 8: For all ISO plugs with valid internal connections: |
---|
698 |
// get logical input and output streams provided by the device |
---|
699 |
|
---|
700 |
for ( AvPlugVector::iterator it = isoPlugs.begin(); |
---|
701 |
it != isoPlugs.end(); |
---|
702 |
++it ) |
---|
703 |
{ |
---|
704 |
AvPlug* isoPlug = *it; |
---|
705 |
|
---|
706 |
AvPlugConnection* plugConnection = getPlugConnection( *isoPlug ); |
---|
707 |
if ( !plugConnection ) { |
---|
708 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
709 |
"%s plug %d has no valid connecton -> skip\n", |
---|
710 |
isoPlug->getName(), |
---|
711 |
isoPlug->getPlugId() ); |
---|
712 |
continue; |
---|
713 |
} |
---|
714 |
|
---|
715 |
if ( isoPlug->getPlugType() |
---|
716 |
== ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_Sync ) |
---|
717 |
{ |
---|
718 |
// If the plug is of type sync it is either a normal 2 channel |
---|
719 |
// stream (not compound stream) or it is a compound stream |
---|
720 |
// with exactly one cluster. This depends on the |
---|
721 |
// extended stream format command version which is used. |
---|
722 |
// We are not interested in this plug so we skip it. |
---|
723 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
724 |
"%s plug %d is of type sync -> skip\n", |
---|
725 |
isoPlug->getName(), |
---|
726 |
isoPlug->getPlugId() ); |
---|
727 |
continue; |
---|
728 |
} |
---|
729 |
|
---|
730 |
for ( AvPlug::ClusterInfoVector::iterator clit = |
---|
731 |
isoPlug->m_clusterInfos.begin(); |
---|
732 |
clit != isoPlug->m_clusterInfos.end(); |
---|
733 |
++clit ) |
---|
734 |
{ |
---|
735 |
AvPlug::ClusterInfo* clusterInfo = &*clit; |
---|
736 |
|
---|
737 |
ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service ); |
---|
738 |
UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, |
---|
739 |
isoPlug->getPlugId() ); |
---|
740 |
PlugAddress::EPlugDirection direction = |
---|
741 |
static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() ); |
---|
742 |
extPlugInfoCmd.setPlugAddress( PlugAddress( direction, |
---|
743 |
PlugAddress::ePAM_Unit, |
---|
744 |
unitPlugAddress ) ); |
---|
745 |
extPlugInfoCmd.setNodeId( m_nodeId ); |
---|
746 |
extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status ); |
---|
747 |
//extPlugInfoCmd.setVerbose( true ); |
---|
748 |
ExtendedPlugInfoInfoType extendedPlugInfoInfoType( |
---|
749 |
ExtendedPlugInfoInfoType::eIT_ClusterInfo ); |
---|
750 |
extendedPlugInfoInfoType.initialize(); |
---|
751 |
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); |
---|
752 |
|
---|
753 |
extPlugInfoCmd.getInfoType()->m_plugClusterInfo->m_clusterIndex = |
---|
754 |
clusterInfo->m_index; |
---|
755 |
|
---|
756 |
if ( !extPlugInfoCmd.fire() ) { |
---|
757 |
debugError( "discoverStep8Plug: cluster info command failed\n" ); |
---|
758 |
return false; |
---|
759 |
} |
---|
760 |
|
---|
761 |
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType(); |
---|
762 |
if ( infoType |
---|
763 |
&& infoType->m_plugClusterInfo ) |
---|
764 |
{ |
---|
765 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
766 |
"%s plug %d: cluster index = %d, " |
---|
767 |
"portType %s, cluster name = %s\n", |
---|
768 |
isoPlug->getName(), |
---|
769 |
isoPlug->getPlugId(), |
---|
770 |
infoType->m_plugClusterInfo->m_clusterIndex, |
---|
771 |
extendedPlugInfoClusterInfoPortTypeToString( |
---|
772 |
infoType->m_plugClusterInfo->m_portType ), |
---|
773 |
infoType->m_plugClusterInfo->m_clusterName.c_str() ); |
---|
774 |
|
---|
775 |
clusterInfo->m_portType = infoType->m_plugClusterInfo->m_portType; |
---|
776 |
clusterInfo->m_name = infoType->m_plugClusterInfo->m_clusterName; |
---|
777 |
} |
---|
778 |
} |
---|
779 |
} |
---|
780 |
|
---|
781 |
return true; |
---|
782 |
} |
---|
783 |
|
---|
784 |
bool |
---|
785 |
AvDevice::discoverStep8() |
---|
786 |
{ |
---|
787 |
bool success; |
---|
788 |
success = discoverStep8Plug( m_isoInputPlugs ); |
---|
789 |
success &= discoverStep8Plug( m_isoOutputPlugs ); |
---|
790 |
|
---|
791 |
return success; |
---|
792 |
} |
---|
793 |
|
---|
794 |
bool |
---|
795 |
AvDevice::discoverStep9Plug( AvPlugVector& isoPlugs ) |
---|
796 |
{ |
---|
797 |
////////////////////////////////////////////// |
---|
798 |
// Step 9: For all ISO plugs with valid internal connections: |
---|
799 |
// get current stream format |
---|
800 |
|
---|
801 |
for ( AvPlugVector::iterator it = isoPlugs.begin(); |
---|
802 |
it != isoPlugs.end(); |
---|
803 |
++it ) |
---|
804 |
{ |
---|
805 |
AvPlug* isoPlug = *it; |
---|
806 |
|
---|
807 |
AvPlugConnection* plugConnection = getPlugConnection( *isoPlug ); |
---|
808 |
if ( !plugConnection ) { |
---|
809 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
810 |
"%s plug %d has no valid connecton -> skip\n", |
---|
811 |
isoPlug->getName(), |
---|
812 |
isoPlug->getPlugId() ); |
---|
813 |
continue; |
---|
814 |
} |
---|
815 |
|
---|
816 |
ExtendedStreamFormatCmd extStreamFormatCmd( m_1394Service ); |
---|
817 |
UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, |
---|
818 |
isoPlug->getPlugId() ); |
---|
819 |
PlugAddress::EPlugDirection direction = |
---|
820 |
static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() ); |
---|
821 |
extStreamFormatCmd.setPlugAddress( PlugAddress( direction, |
---|
822 |
PlugAddress::ePAM_Unit, |
---|
823 |
unitPlugAddress ) ); |
---|
824 |
|
---|
825 |
extStreamFormatCmd.setNodeId( m_nodeId ); |
---|
826 |
extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); |
---|
827 |
//extStreamFormatCmd.setVerbose( true ); |
---|
828 |
|
---|
829 |
if ( !extStreamFormatCmd.fire() ) { |
---|
830 |
debugError( "discoverStep9Plug: stream format command failed\n" ); |
---|
831 |
return false; |
---|
832 |
} |
---|
833 |
|
---|
834 |
FormatInformation* formatInfo = |
---|
835 |
extStreamFormatCmd.getFormatInformation(); |
---|
836 |
FormatInformationStreamsCompound* compoundStream |
---|
837 |
= dynamic_cast< FormatInformationStreamsCompound* > ( |
---|
838 |
formatInfo->m_streams ); |
---|
839 |
if ( compoundStream ) { |
---|
840 |
isoPlug->m_samplingFrequency = |
---|
841 |
compoundStream->m_samplingFrequency; |
---|
842 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
843 |
"discoverStep9Plug: %s plug %d uses " |
---|
844 |
"sampling frequency %d\n", |
---|
845 |
isoPlug->getName(), |
---|
846 |
isoPlug->getPlugId(), |
---|
847 |
isoPlug->m_samplingFrequency ); |
---|
848 |
|
---|
849 |
for ( int i = 1; |
---|
850 |
i <= compoundStream->m_numberOfStreamFormatInfos; |
---|
851 |
++i ) |
---|
852 |
{ |
---|
853 |
AvPlug::ClusterInfo* clusterInfo = |
---|
854 |
isoPlug->getClusterInfoByIndex( i ); |
---|
855 |
|
---|
856 |
if ( !clusterInfo ) { |
---|
857 |
debugError( "discoverStep9Plug: No matching cluster info found " |
---|
858 |
"for index %d\n", i ); |
---|
859 |
return false; |
---|
860 |
} |
---|
861 |
StreamFormatInfo* streamFormatInfo = |
---|
862 |
compoundStream->m_streamFormatInfos[ i - 1 ]; |
---|
863 |
|
---|
864 |
int nrOfChannels = clusterInfo->m_nrOfChannels; |
---|
865 |
if ( streamFormatInfo->m_streamFormat == |
---|
866 |
FormatInformation::eFHL2_AM824_MIDI_CONFORMANT ) |
---|
867 |
{ |
---|
868 |
// 8 logical midi channels fit into 1 channel |
---|
869 |
nrOfChannels = ( ( nrOfChannels + 7 ) / 8 ); |
---|
870 |
} |
---|
871 |
// sanity checks |
---|
872 |
if ( nrOfChannels != |
---|
873 |
streamFormatInfo->m_numberOfChannels ) |
---|
874 |
{ |
---|
875 |
debugError( "discoverStep9Plug: Number of channels " |
---|
876 |
"mismatch: %s plug %d discovering reported " |
---|
877 |
"%d channels for cluster '%s', while stream format " |
---|
878 |
"reported %d\n", |
---|
879 |
isoPlug->getName(), |
---|
880 |
isoPlug->getPlugId(), |
---|
881 |
nrOfChannels, |
---|
882 |
clusterInfo->m_name.c_str(), |
---|
883 |
streamFormatInfo->m_numberOfChannels); |
---|
884 |
return false; |
---|
885 |
} |
---|
886 |
clusterInfo->m_streamFormat = streamFormatInfo->m_streamFormat; |
---|
887 |
|
---|
888 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
889 |
"%s plug %d cluster info %d ('%s'): stream format %d\n", |
---|
890 |
isoPlug->getName(), |
---|
891 |
isoPlug->getPlugId(), |
---|
892 |
i, |
---|
893 |
clusterInfo->m_name.c_str(), |
---|
894 |
clusterInfo->m_streamFormat ); |
---|
895 |
} |
---|
896 |
} |
---|
897 |
|
---|
898 |
FormatInformationStreamsSync* syncStream |
---|
899 |
= dynamic_cast< FormatInformationStreamsSync* > ( |
---|
900 |
formatInfo->m_streams ); |
---|
901 |
if ( syncStream ) { |
---|
902 |
isoPlug->m_samplingFrequency = |
---|
903 |
syncStream->m_samplingFrequency; |
---|
904 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
905 |
"%s plug %d is sync stream with sampling frequency %d\n", |
---|
906 |
isoPlug->getName(), |
---|
907 |
isoPlug->getPlugId(), |
---|
908 |
isoPlug->m_samplingFrequency ); |
---|
909 |
} |
---|
910 |
|
---|
911 |
if ( !compoundStream && !syncStream ) { |
---|
912 |
debugError( "discoverStep9Plug: Unsupported stream format\n" ); |
---|
913 |
return false; |
---|
914 |
} |
---|
915 |
} |
---|
916 |
|
---|
917 |
return true; |
---|
918 |
} |
---|
919 |
|
---|
920 |
bool |
---|
921 |
AvDevice::discoverStep9() |
---|
922 |
{ |
---|
923 |
bool success; |
---|
924 |
success = discoverStep9Plug( m_isoInputPlugs ); |
---|
925 |
success &= discoverStep9Plug( m_isoOutputPlugs ); |
---|
926 |
|
---|
927 |
return success; |
---|
928 |
} |
---|
929 |
|
---|
930 |
bool |
---|
931 |
AvDevice::discoverStep10Plug( AvPlugVector& isoPlugs ) |
---|
932 |
{ |
---|
933 |
for ( AvPlugVector::iterator it = isoPlugs.begin(); |
---|
934 |
it != isoPlugs.end(); |
---|
935 |
++it ) |
---|
936 |
{ |
---|
937 |
AvPlug* isoPlug = *it; |
---|
938 |
ExtendedStreamFormatCmd extStreamFormatCmd( m_1394Service, |
---|
939 |
ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList); |
---|
940 |
UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, |
---|
941 |
isoPlug->getPlugId() ); |
---|
942 |
PlugAddress::EPlugDirection direction = |
---|
943 |
static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() ); |
---|
944 |
extStreamFormatCmd.setPlugAddress( PlugAddress( direction, |
---|
945 |
PlugAddress::ePAM_Unit, |
---|
946 |
unitPlugAddress ) ); |
---|
947 |
|
---|
948 |
extStreamFormatCmd.setNodeId( m_nodeId ); |
---|
949 |
//extStreamFormatCmd.setVerbose( true ); |
---|
950 |
|
---|
951 |
int i = 0; |
---|
952 |
bool cmdSuccess = false; |
---|
953 |
|
---|
954 |
do { |
---|
955 |
extStreamFormatCmd.setIndexInStreamFormat( i ); |
---|
956 |
extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); |
---|
957 |
cmdSuccess = extStreamFormatCmd.fire(); |
---|
958 |
if ( cmdSuccess |
---|
959 |
&& ( extStreamFormatCmd.getResponse() == AVCCommand::eR_Implemented ) ) |
---|
960 |
{ |
---|
961 |
AvPlug::FormatInfo formatInfo; |
---|
962 |
formatInfo.m_index = i; |
---|
963 |
|
---|
964 |
FormatInformationStreamsSync* syncStream |
---|
965 |
= dynamic_cast< FormatInformationStreamsSync* > |
---|
966 |
( extStreamFormatCmd.getFormatInformation()->m_streams ); |
---|
967 |
if ( syncStream ) { |
---|
968 |
formatInfo.m_samplingFrequency = |
---|
969 |
syncStream->m_samplingFrequency; |
---|
970 |
formatInfo.m_isSyncStream = true ; |
---|
971 |
} |
---|
972 |
|
---|
973 |
FormatInformationStreamsCompound* compoundStream |
---|
974 |
= dynamic_cast< FormatInformationStreamsCompound* > |
---|
975 |
( extStreamFormatCmd.getFormatInformation()->m_streams ); |
---|
976 |
if ( compoundStream ) { |
---|
977 |
formatInfo.m_samplingFrequency = |
---|
978 |
compoundStream->m_samplingFrequency; |
---|
979 |
formatInfo.m_isSyncStream = false; |
---|
980 |
for ( int j = 0; |
---|
981 |
j < compoundStream->m_numberOfStreamFormatInfos; |
---|
982 |
++j ) |
---|
983 |
{ |
---|
984 |
switch ( compoundStream->m_streamFormatInfos[j]->m_streamFormat ) { |
---|
985 |
case AVC1394_STREAM_FORMAT_AM824_MULTI_BIT_LINEAR_AUDIO_RAW: |
---|
986 |
formatInfo.m_audioChannels += |
---|
987 |
compoundStream->m_streamFormatInfos[j]->m_numberOfChannels; |
---|
988 |
break; |
---|
989 |
case AVC1394_STREAM_FORMAT_AM824_MIDI_CONFORMANT: |
---|
990 |
formatInfo.m_midiChannels += |
---|
991 |
compoundStream->m_streamFormatInfos[j]->m_numberOfChannels; |
---|
992 |
break; |
---|
993 |
default: |
---|
994 |
debugWarning( "discoverStep10Plug: unknown stream " |
---|
995 |
"format for channel (%d)\n", j ); |
---|
996 |
} |
---|
997 |
} |
---|
998 |
} |
---|
999 |
|
---|
1000 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
1001 |
"[%s:%d] formatInfo[%d].m_samplingFrequency = %d\n", |
---|
1002 |
isoPlug->getName(), isoPlug->getPlugId(), |
---|
1003 |
i, formatInfo.m_samplingFrequency ); |
---|
1004 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
1005 |
"[%s:%d] formatInfo[%d].m_isSyncStream = %d\n", |
---|
1006 |
isoPlug->getName(), isoPlug->getPlugId(), |
---|
1007 |
i, formatInfo.m_isSyncStream ); |
---|
1008 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
1009 |
"[%s:%d] formatInfo[%d].m_audioChannels = %d\n", |
---|
1010 |
isoPlug->getName(), isoPlug->getPlugId(), |
---|
1011 |
i, formatInfo.m_audioChannels ); |
---|
1012 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
1013 |
"[%s:%d] formatInfo[%d].m_midiChannels = %d\n", |
---|
1014 |
isoPlug->getName(), isoPlug->getPlugId(), |
---|
1015 |
i, formatInfo.m_midiChannels ); |
---|
1016 |
|
---|
1017 |
isoPlug->m_formatInfos.push_back( formatInfo ); |
---|
1018 |
} |
---|
1019 |
|
---|
1020 |
++i; |
---|
1021 |
} while ( cmdSuccess && ( extStreamFormatCmd.getResponse() |
---|
1022 |
== ExtendedStreamFormatCmd::eR_Implemented ) ); |
---|
1023 |
} |
---|
1024 |
|
---|
1025 |
return true; |
---|
1026 |
} |
---|
1027 |
|
---|
1028 |
|
---|
1029 |
bool |
---|
1030 |
AvDevice::discoverStep10() |
---|
1031 |
{ |
---|
1032 |
////////////////////////////////////////////// |
---|
1033 |
// Step 10: For all ISO plugs: get all stream |
---|
1034 |
// supported formats |
---|
1035 |
|
---|
1036 |
bool success; |
---|
1037 |
|
---|
1038 |
success = discoverStep10Plug( m_isoInputPlugs ); |
---|
1039 |
success &= discoverStep10Plug( m_isoOutputPlugs ); |
---|
1040 |
|
---|
1041 |
return success; |
---|
1042 |
} |
---|
1043 |
|
---|
1044 |
bool |
---|
1045 |
AvDevice::discoverPlugConnection( AvPlug& srcPlug, |
---|
1046 |
SubunitPlugSpecificDataPlugAddress& subunitPlugAddress ) |
---|
1047 |
{ |
---|
1048 |
AvDeviceSubunit* subunit = getSubunit( subunitPlugAddress.m_subunitType, |
---|
1049 |
subunitPlugAddress.m_subunitId ); |
---|
1050 |
|
---|
1051 |
if ( subunit ) { |
---|
1052 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
1053 |
"%s plug %d has a valid connection to plug %d of " |
---|
1054 |
"%s subunit %d \n", |
---|
1055 |
srcPlug.getName(), |
---|
1056 |
srcPlug.getPlugId(), |
---|
1057 |
subunitPlugAddress.m_plugId, |
---|
1058 |
subunit->getName(), |
---|
1059 |
subunit->getSubunitId() ); |
---|
1060 |
|
---|
1061 |
AvPlug* destPlug = new AvPlug; |
---|
1062 |
destPlug->m_plugId = subunitPlugAddress.m_plugId; |
---|
1063 |
destPlug->m_subunitType = subunitPlugAddress.m_subunitType; |
---|
1064 |
destPlug->m_subunitId = subunitPlugAddress.m_subunitId; |
---|
1065 |
|
---|
1066 |
if ( !subunit->addPlug( *destPlug ) ) { |
---|
1067 |
debugError( "Could not add plug %d to subunit %d\n", |
---|
1068 |
destPlug->getPlugId(), subunit->getSubunitId() ); |
---|
1069 |
return false; |
---|
1070 |
} |
---|
1071 |
|
---|
1072 |
AvPlugConnection* plugConnection = new AvPlugConnection; |
---|
1073 |
plugConnection->m_srcPlug = &srcPlug; |
---|
1074 |
plugConnection->m_destPlug = destPlug; |
---|
1075 |
m_plugConnections.push_back( plugConnection ); |
---|
1076 |
|
---|
1077 |
return true; |
---|
1078 |
} else { |
---|
1079 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
1080 |
"found plug address points to unhandled " |
---|
1081 |
"subunit -> ignored\n" ); |
---|
1082 |
} |
---|
1083 |
|
---|
1084 |
return true; |
---|
1085 |
} |
---|
1086 |
|
---|
1087 |
bool |
---|
1088 |
AvDevice::enumerateSubUnits() |
---|
1089 |
{ |
---|
1090 |
bool musicSubunitFound=false; |
---|
1091 |
bool audioSubunitFound=false; |
---|
1092 |
|
---|
1093 |
SubUnitInfoCmd subUnitInfoCmd( m_1394Service ); |
---|
1094 |
//subUnitInfoCmd.setVerbose( 1 ); |
---|
1095 |
subUnitInfoCmd.setCommandType( AVCCommand::eCT_Status ); |
---|
1096 |
|
---|
1097 |
// BeBob has always exactly one audio and one music subunit. This |
---|
1098 |
// means is fits into the first page of the SubUnitInfo command. |
---|
1099 |
// So there is no need to do more than needed |
---|
1100 |
|
---|
1101 |
subUnitInfoCmd.m_page = 0; |
---|
1102 |
subUnitInfoCmd.setNodeId( m_nodeId ); |
---|
1103 |
if ( !subUnitInfoCmd.fire() ) { |
---|
1104 |
debugError( "Subunit info command failed\n" ); |
---|
1105 |
// shouldn't this be an error situation? |
---|
1106 |
return false; |
---|
1107 |
} |
---|
1108 |
|
---|
1109 |
for ( int i = 0; i < subUnitInfoCmd.getNrOfValidEntries(); ++i ) { |
---|
1110 |
subunit_type_t subunit_type |
---|
1111 |
= subUnitInfoCmd.m_table[i].m_subunit_type; |
---|
1112 |
|
---|
1113 |
unsigned int subunitId = getNrOfSubunits( subunit_type ); |
---|
1114 |
|
---|
1115 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
1116 |
"subunit_id = %2d, subunit_type = %2d (%s)\n", |
---|
1117 |
subunitId, |
---|
1118 |
subunit_type, |
---|
1119 |
subunitTypeToString( subunit_type ) ); |
---|
1120 |
|
---|
1121 |
AvDeviceSubunit* subunit = 0; |
---|
1122 |
switch( subunit_type ) { |
---|
1123 |
case AVCCommand::eST_Audio: |
---|
1124 |
subunit = new AvDeviceSubunitAudio( this, subunitId ); |
---|
1125 |
if ( !subunit ) { |
---|
1126 |
debugFatal( "Could not allocate AvDeviceSubunitAudio\n" ); |
---|
1127 |
return false; |
---|
1128 |
} |
---|
1129 |
m_subunits.push_back( subunit ); |
---|
1130 |
audioSubunitFound=true; |
---|
1131 |
break; |
---|
1132 |
case AVCCommand::eST_Music: |
---|
1133 |
subunit = new AvDeviceSubunitMusic( this, subunitId ); |
---|
1134 |
if ( !subunit ) { |
---|
1135 |
debugFatal( "Could not allocate AvDeviceSubunitMusic\n" ); |
---|
1136 |
return false; |
---|
1137 |
} |
---|
1138 |
m_subunits.push_back( subunit ); |
---|
1139 |
musicSubunitFound=true; |
---|
1140 |
break; |
---|
1141 |
default: |
---|
1142 |
debugOutput( DEBUG_LEVEL_NORMAL, |
---|
1143 |
"Unsupported subunit found, subunit_type = %d (%s)\n", |
---|
1144 |
subunit_type, |
---|
1145 |
subunitTypeToString( subunit_type ) ); |
---|
1146 |
|
---|
1147 |
} |
---|
1148 |
|
---|
1149 |
} |
---|
1150 |
|
---|
1151 |
// a BeBoB always has an audio and a music subunit |
---|
1152 |
return (musicSubunitFound && audioSubunitFound); |
---|
1153 |
} |
---|
1154 |
|
---|
1155 |
|
---|
1156 |
AvDeviceSubunit* |
---|
1157 |
AvDevice::getSubunit( subunit_type_t subunitType, |
---|
1158 |
subunit_id_t subunitId ) const |
---|
1159 |
{ |
---|
1160 |
for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin(); |
---|
1161 |
it != m_subunits.end(); |
---|
1162 |
++it ) |
---|
1163 |
{ |
---|
1164 |
AvDeviceSubunit* subunit = *it; |
---|
1165 |
if ( ( subunitType == subunit->getSubunitType() ) |
---|
1166 |
&& ( subunitId == subunit->getSubunitId() ) ) |
---|
1167 |
{ |
---|
1168 |
return subunit; |
---|
1169 |
} |
---|
1170 |
} |
---|
1171 |
|
---|
1172 |
return 0; |
---|
1173 |
} |
---|
1174 |
|
---|
1175 |
|
---|
1176 |
unsigned int |
---|
1177 |
AvDevice::getNrOfSubunits( subunit_type_t subunitType ) const |
---|
1178 |
{ |
---|
1179 |
unsigned int nrOfSubunits = 0; |
---|
1180 |
|
---|
1181 |
for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin(); |
---|
1182 |
it != m_subunits.end(); |
---|
1183 |
++it ) |
---|
1184 |
{ |
---|
1185 |
AvDeviceSubunit* subunit = *it; |
---|
1186 |
if ( subunitType == subunit->getSubunitType() ) { |
---|
1187 |
nrOfSubunits++; |
---|
1188 |
} |
---|
1189 |
} |
---|
1190 |
|
---|
1191 |
return nrOfSubunits; |
---|
1192 |
} |
---|
1193 |
|
---|
1194 |
AvPlugConnection* |
---|
1195 |
AvDevice::getPlugConnection( AvPlug& srcPlug ) const |
---|
1196 |
{ |
---|
1197 |
for ( AvPlugConnectionVector::const_iterator it |
---|
1198 |
= m_plugConnections.begin(); |
---|
1199 |
it != m_plugConnections.end(); |
---|
1200 |
++it ) |
---|
1201 |
{ |
---|
1202 |
AvPlugConnection* plugConnection = *it; |
---|
1203 |
if ( plugConnection->m_srcPlug == &srcPlug ) { |
---|
1204 |
return plugConnection; |
---|
1205 |
} |
---|
1206 |
} |
---|
1207 |
|
---|
1208 |
return 0; |
---|
1209 |
} |
---|
1210 |
|
---|
1211 |
AvPlug* |
---|
1212 |
AvDevice::getPlugById( AvPlugVector& plugs, int id ) |
---|
1213 |
{ |
---|
1214 |
for ( AvPlugVector::iterator it = plugs.begin(); |
---|
1215 |
it != plugs.end(); |
---|
1216 |
++it ) |
---|
1217 |
{ |
---|
1218 |
AvPlug* plug = *it; |
---|
1219 |
if ( id == plug->getPlugId() ) { |
---|
1220 |
return plug; |
---|
1221 |
} |
---|
1222 |
} |
---|
1223 |
|
---|
1224 |
return 0; |
---|
1225 |
} |
---|
1226 |
|
---|
1227 |
bool |
---|
1228 |
AvDevice::addXmlDescriptionPlug( AvPlug& plug, |
---|
1229 |
xmlNodePtr connectionSet ) |
---|
1230 |
{ |
---|
1231 |
char* result; |
---|
1232 |
|
---|
1233 |
int direction; |
---|
1234 |
switch ( plug.getPlugDirection() ) { |
---|
1235 |
case 0: |
---|
1236 |
direction = FREEBOB_PLAYBACK; |
---|
1237 |
break; |
---|
1238 |
case 1: |
---|
1239 |
direction = FREEBOB_CAPTURE; |
---|
1240 |
break; |
---|
1241 |
default: |
---|
1242 |
debugError( "plug direction invalid (%d)\n", |
---|
1243 |
plug.getPlugDirection() ); |
---|
1244 |
return false; |
---|
1245 |
} |
---|
1246 |
|
---|
1247 |
asprintf( &result, "%d", direction ); |
---|
1248 |
if ( !xmlNewChild( connectionSet, |
---|
1249 |
0, |
---|
1250 |
BAD_CAST "Direction", |
---|
1251 |
BAD_CAST result ) ) |
---|
1252 |
{ |
---|
1253 |
debugError( "Couldn't create 'Direction' node\n" ); |
---|
1254 |
free( result ); |
---|
1255 |
return false; |
---|
1256 |
} |
---|
1257 |
free( result ); |
---|
1258 |
|
---|
1259 |
xmlNodePtr connection = xmlNewChild( connectionSet, 0, |
---|
1260 |
BAD_CAST "Connection", 0 ); |
---|
1261 |
if ( !connection ) { |
---|
1262 |
debugError( "Couldn't create 'Connection' node for " |
---|
1263 |
"direction %d\n", plug.getPlugDirection() ); |
---|
1264 |
return false; |
---|
1265 |
} |
---|
1266 |
|
---|
1267 |
asprintf( &result, "%08x%08x", |
---|
1268 |
( quadlet_t )( m_configRom->getGuid() >> 32 ), |
---|
1269 |
( quadlet_t )( m_configRom->getGuid() & 0xfffffff ) ); |
---|
1270 |
if ( !xmlNewChild( connection, 0, |
---|
1271 |
BAD_CAST "GUID", BAD_CAST result ) ) { |
---|
1272 |
debugError( "Couldn't create 'GUID' node\n" ); |
---|
1273 |
free( result ); |
---|
1274 |
return false; |
---|
1275 |
} |
---|
1276 |
free( result ); |
---|
1277 |
|
---|
1278 |
|
---|
1279 |
asprintf( &result, "%d", m_id & 0xff ); |
---|
1280 |
if ( !xmlNewChild( connection, 0, |
---|
1281 |
BAD_CAST "Id", BAD_CAST result ) ) { |
---|
1282 |
debugError( "Couldn't create 'Id' node\n" ); |
---|
1283 |
free( result ); |
---|
1284 |
return false; |
---|
1285 |
} |
---|
1286 |
free( result ); |
---|
1287 |
|
---|
1288 |
asprintf( &result, "%d", m_1394Service->getPort() ); |
---|
1289 |
if ( !xmlNewChild( connection, 0, |
---|
1290 |
BAD_CAST "Port", BAD_CAST result ) ) { |
---|
1291 |
debugError( "Couldn't create 'Port' node\n" ); |
---|
1292 |
free( result ); |
---|
1293 |
return false; |
---|
1294 |
} |
---|
1295 |
free( result ); |
---|
1296 |
|
---|
1297 |
asprintf( &result, "%d", m_nodeId); |
---|
1298 |
if ( !xmlNewChild( connection, 0, |
---|
1299 |
BAD_CAST "Node", BAD_CAST result ) ) { |
---|
1300 |
debugError( "Couldn't create 'Node' node\n" ); |
---|
1301 |
free( result ); |
---|
1302 |
return false; |
---|
1303 |
} |
---|
1304 |
free( result ); |
---|
1305 |
|
---|
1306 |
|
---|
1307 |
asprintf( &result, "%d", plug.getNrOfChannels() ); |
---|
1308 |
if ( !xmlNewChild( connection, 0, |
---|
1309 |
BAD_CAST "Dimension", BAD_CAST result ) ) { |
---|
1310 |
debugError( "Couldn't create 'Dimension' node\n" ); |
---|
1311 |
free( result ); |
---|
1312 |
return false; |
---|
1313 |
} |
---|
1314 |
free( result ); |
---|
1315 |
|
---|
1316 |
|
---|
1317 |
asprintf( &result, "%d", plug.getSampleRate() ); |
---|
1318 |
if ( !xmlNewChild( connection, 0, |
---|
1319 |
BAD_CAST "Samplerate", BAD_CAST result ) ) { |
---|
1320 |
debugError( "Couldn't create 'Samplerate' node\n" ); |
---|
1321 |
free( result ); |
---|
1322 |
return false; |
---|
1323 |
} |
---|
1324 |
free( result ); |
---|
1325 |
|
---|
1326 |
|
---|
1327 |
if ( !xmlNewChild( connection, 0, |
---|
1328 |
BAD_CAST "IsoChannel", BAD_CAST "-1" ) ) |
---|
1329 |
{ |
---|
1330 |
debugError( "Couldn't create 'IsoChannel' node\n" ); |
---|
1331 |
return false; |
---|
1332 |
} |
---|
1333 |
|
---|
1334 |
xmlNodePtr streams = xmlNewChild( connection, 0, |
---|
1335 |
BAD_CAST "Streams", 0 ); |
---|
1336 |
if ( !streams ) { |
---|
1337 |
debugError( "Couldn't create 'Streams' node for " |
---|
1338 |
"direction %d\n", plug.getPlugDirection() ); |
---|
1339 |
return false; |
---|
1340 |
} |
---|
1341 |
|
---|
1342 |
AvPlug::ClusterInfoVector& clusterInfos = plug.getClusterInfos(); |
---|
1343 |
for ( AvPlug::ClusterInfoVector::const_iterator it = clusterInfos.begin(); |
---|
1344 |
it != clusterInfos.end(); |
---|
1345 |
++it ) |
---|
1346 |
{ |
---|
1347 |
const AvPlug::ClusterInfo* clusterInfo = &( *it ); |
---|
1348 |
|
---|
1349 |
AvPlug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos; |
---|
1350 |
for ( AvPlug::ChannelInfoVector::const_iterator it = channelInfos.begin(); |
---|
1351 |
it != channelInfos.end(); |
---|
1352 |
++it ) |
---|
1353 |
{ |
---|
1354 |
const AvPlug::ChannelInfo* channelInfo = &( *it ); |
---|
1355 |
|
---|
1356 |
xmlNodePtr stream = xmlNewChild( streams, 0, |
---|
1357 |
BAD_CAST "Stream", 0 ); |
---|
1358 |
if ( !stream ) { |
---|
1359 |
debugError( "Coulnd't create 'Stream' node" ); |
---|
1360 |
free(result); |
---|
1361 |
return false; |
---|
1362 |
} |
---|
1363 |
|
---|
1364 |
// \todo: iec61883 backend expects indexing starting from 0 |
---|
1365 |
// but bebob reports it starting from 1. Decide where |
---|
1366 |
// and how to handle this |
---|
1367 |
asprintf( &result, "%d", channelInfo->m_streamPosition - 1 ); |
---|
1368 |
if ( !xmlNewChild( stream, 0, |
---|
1369 |
BAD_CAST "Position", BAD_CAST result ) ) |
---|
1370 |
{ |
---|
1371 |
debugError( "Couldn't create 'Position' node" ); |
---|
1372 |
free( result ); |
---|
1373 |
return false; |
---|
1374 |
} |
---|
1375 |
free( result ); |
---|
1376 |
|
---|
1377 |
asprintf( &result, "%d", channelInfo->m_location ); |
---|
1378 |
if ( !xmlNewChild( stream, 0, |
---|
1379 |
BAD_CAST "Location", BAD_CAST result ) ) |
---|
1380 |
{ |
---|
1381 |
debugError( "Couldn't create 'Location' node" ); |
---|
1382 |
free( result ); |
---|
1383 |
return false; |
---|
1384 |
} |
---|
1385 |
free( result ); |
---|
1386 |
|
---|
1387 |
asprintf( &result, "%d", clusterInfo->m_streamFormat ); |
---|
1388 |
if ( !xmlNewChild( stream, 0, |
---|
1389 |
BAD_CAST "Format", BAD_CAST result ) ) |
---|
1390 |
{ |
---|
1391 |
debugError( "Couldn't create 'Format' node" ); |
---|
1392 |
free( result ); |
---|
1393 |
return false; |
---|
1394 |
} |
---|
1395 |
free( result ); |
---|
1396 |
|
---|
1397 |
|
---|
1398 |
asprintf( &result, "%d", clusterInfo->m_portType ); |
---|
1399 |
if ( !xmlNewChild( stream, 0, |
---|
1400 |
BAD_CAST "Type", BAD_CAST result ) ) |
---|
1401 |
{ |
---|
1402 |
debugError( "Couldn't create 'Type' node" ); |
---|
1403 |
free( result ); |
---|
1404 |
return false; |
---|
1405 |
} |
---|
1406 |
free( result ); |
---|
1407 |
|
---|
1408 |
|
---|
1409 |
// \todo XXX: What do to do with DestinationPort value?? |
---|
1410 |
asprintf( &result, "%d", 0 ); |
---|
1411 |
if ( !xmlNewChild( stream, 0, |
---|
1412 |
BAD_CAST "DestinationPort", BAD_CAST result ) ) |
---|
1413 |
{ |
---|
1414 |
debugError( "Couldn't create 'DestinationPort' node" ); |
---|
1415 |
free( result ); |
---|
1416 |
return false; |
---|
1417 |
} |
---|
1418 |
free( result ); |
---|
1419 |
|
---|
1420 |
if ( !xmlNewChild( stream, 0, |
---|
1421 |
BAD_CAST "Name", |
---|
1422 |
BAD_CAST channelInfo->m_name.c_str() ) ) |
---|
1423 |
{ |
---|
1424 |
debugError( "Couldn't create 'Name' node" ); |
---|
1425 |
return false; |
---|
1426 |
} |
---|
1427 |
} |
---|
1428 |
} |
---|
1429 |
|
---|
1430 |
return true; |
---|
1431 |
} |
---|
1432 |
|
---|
1433 |
bool |
---|
1434 |
AvDevice::addXmlDescriptionStreamFormats( AvPlug& plug, |
---|
1435 |
xmlNodePtr streamFormatNode ) |
---|
1436 |
{ |
---|
1437 |
int direction; |
---|
1438 |
switch ( plug.getPlugDirection() ) { |
---|
1439 |
case 0: |
---|
1440 |
direction = FREEBOB_PLAYBACK; |
---|
1441 |
break; |
---|
1442 |
case 1: |
---|
1443 |
direction = FREEBOB_CAPTURE; |
---|
1444 |
break; |
---|
1445 |
default: |
---|
1446 |
debugError( "addXmlDescriptionStreamFormats: plug direction invalid (%d)\n", |
---|
1447 |
plug.getPlugDirection() ); |
---|
1448 |
return false; |
---|
1449 |
} |
---|
1450 |
|
---|
1451 |
char* result; |
---|
1452 |
asprintf( &result, "%d", direction ); |
---|
1453 |
if ( !xmlNewChild( streamFormatNode, |
---|
1454 |
0, |
---|
1455 |
BAD_CAST "Direction", |
---|
1456 |
BAD_CAST result ) ) |
---|
1457 |
{ |
---|
1458 |
debugError( "addXmlDescriptionStreamFormats: Could not create 'Direction' node\n" ); |
---|
1459 |
return false; |
---|
1460 |
} |
---|
1461 |
|
---|
1462 |
for ( AvPlug::FormatInfoVector::iterator it = |
---|
1463 |
plug.m_formatInfos.begin(); |
---|
1464 |
it != plug.m_formatInfos.end(); |
---|
1465 |
++it ) |
---|
1466 |
{ |
---|
1467 |
AvPlug::FormatInfo formatInfo = *it; |
---|
1468 |
xmlNodePtr formatNode = xmlNewChild( streamFormatNode, 0, |
---|
1469 |
BAD_CAST "Format", 0 ); |
---|
1470 |
if ( !formatNode ) { |
---|
1471 |
debugError( "addXmlDescriptionStreamFormats: Could not create 'Format' node\n" ); |
---|
1472 |
return false; |
---|
1473 |
} |
---|
1474 |
|
---|
1475 |
asprintf( &result, "%d", |
---|
1476 |
convertESamplingFrequency( static_cast<ESamplingFrequency>( formatInfo.m_samplingFrequency ) ) ); |
---|
1477 |
if ( !xmlNewChild( formatNode, 0, |
---|
1478 |
BAD_CAST "Samplerate", BAD_CAST result ) ) |
---|
1479 |
{ |
---|
1480 |
debugError( "Couldn't create 'Samplerate' node\n" ); |
---|
1481 |
free(result); |
---|
1482 |
return false; |
---|
1483 |
} |
---|
1484 |
|
---|
1485 |
asprintf( &result, "%d", formatInfo.m_audioChannels ); |
---|
1486 |
if ( !xmlNewChild( formatNode, 0, |
---|
1487 |
BAD_CAST "AudioChannels", BAD_CAST result ) ) |
---|
1488 |
{ |
---|
1489 |
debugError( "Couldn't create 'AudioChannels' node\n" ); |
---|
1490 |
free(result); |
---|
1491 |
return false; |
---|
1492 |
} |
---|
1493 |
|
---|
1494 |
asprintf( &result, "%d", formatInfo.m_midiChannels ); |
---|
1495 |
if ( !xmlNewChild( formatNode, 0, |
---|
1496 |
BAD_CAST "MidiChannels", BAD_CAST result ) ) |
---|
1497 |
{ |
---|
1498 |
debugError( "Couldn't create 'MidiChannels' node\n" ); |
---|
1499 |
free(result); |
---|
1500 |
return false; |
---|
1501 |
} |
---|
1502 |
} |
---|
1503 |
|
---|
1504 |
free(result); |
---|
1505 |
return true; |
---|
1506 |
} |
---|
1507 |
|
---|
1508 |
bool |
---|
1509 |
AvDevice::addXmlDescription( xmlNodePtr deviceNode ) |
---|
1510 |
{ |
---|
1511 |
// connection set |
---|
1512 |
// direction |
---|
1513 |
// connection |
---|
1514 |
// id |
---|
1515 |
// port |
---|
1516 |
// node |
---|
1517 |
// plug |
---|
1518 |
// dimension |
---|
1519 |
// samplerate |
---|
1520 |
// streams |
---|
1521 |
// stream |
---|
1522 |
|
---|
1523 |
|
---|
1524 |
/////////// |
---|
1525 |
// get plugs |
---|
1526 |
|
---|
1527 |
AvPlug* inputPlug = getPlugById( m_isoInputPlugs, 0 ); |
---|
1528 |
if ( !inputPlug ) { |
---|
1529 |
debugError( "addXmlDescription: No iso input plug found with id %d\n" ); |
---|
1530 |
return false; |
---|
1531 |
} |
---|
1532 |
AvPlug* outputPlug = getPlugById( m_isoOutputPlugs, 0 ); |
---|
1533 |
if ( !outputPlug ) { |
---|
1534 |
debugError( "addXmlDescription: No iso output plug found with id %d\n" ); |
---|
1535 |
return false; |
---|
1536 |
} |
---|
1537 |
|
---|
1538 |
/////////// |
---|
1539 |
// add connection set output |
---|
1540 |
|
---|
1541 |
xmlNodePtr connectionSet = xmlNewChild( deviceNode, 0, |
---|
1542 |
BAD_CAST "ConnectionSet", 0 ); |
---|
1543 |
if ( !connectionSet ) { |
---|
1544 |
debugError( "addXmlDescription:: Could not create 'ConnnectionSet' node for " |
---|
1545 |
"direction 1 (playback)\n" ); |
---|
1546 |
return false; |
---|
1547 |
} |
---|
1548 |
|
---|
1549 |
if ( !addXmlDescriptionPlug( *inputPlug, connectionSet ) ) { |
---|
1550 |
debugError( "addXmlDescription: Could not add iso input plug 0 to XML description\n" ); |
---|
1551 |
return false; |
---|
1552 |
} |
---|
1553 |
|
---|
1554 |
// add connection set input |
---|
1555 |
|
---|
1556 |
connectionSet = xmlNewChild( deviceNode, 0, |
---|
1557 |
BAD_CAST "ConnectionSet", 0 ); |
---|
1558 |
if ( !connectionSet ) { |
---|
1559 |
debugError( "addXmlDescription: Couldn't create 'ConnectionSet' node for " |
---|
1560 |
"direction 0 (recorder)\n" ); |
---|
1561 |
return false; |
---|
1562 |
} |
---|
1563 |
|
---|
1564 |
if ( !addXmlDescriptionPlug( *outputPlug, connectionSet ) ) { |
---|
1565 |
debugError( "addXmlDescription: Could not add iso output plug 0 to XML description\n" ); |
---|
1566 |
return false; |
---|
1567 |
} |
---|
1568 |
|
---|
1569 |
//////////// |
---|
1570 |
// add stream format |
---|
1571 |
|
---|
1572 |
xmlNodePtr streamFormatNode = xmlNewChild( deviceNode, 0, |
---|
1573 |
BAD_CAST "StreamFormats", 0 ); |
---|
1574 |
if ( !streamFormatNode ) { |
---|
1575 |
debugError( "addXmlDescription: Could not create 'StreamFormats' node\n" ); |
---|
1576 |
return false; |
---|
1577 |
} |
---|
1578 |
|
---|
1579 |
if ( !addXmlDescriptionStreamFormats( *inputPlug, streamFormatNode ) ) { |
---|
1580 |
debugError( "addXmlDescription:: Could not add stream format info\n" ); |
---|
1581 |
return false; |
---|
1582 |
} |
---|
1583 |
|
---|
1584 |
streamFormatNode= xmlNewChild( deviceNode, 0, |
---|
1585 |
BAD_CAST "StreamFormats", 0 ); |
---|
1586 |
if ( !streamFormatNode ) { |
---|
1587 |
debugError( "addXmlDescription: Could not create 'StreamFormat' node\n" ); |
---|
1588 |
return false; |
---|
1589 |
} |
---|
1590 |
|
---|
1591 |
if ( !addXmlDescriptionStreamFormats( *outputPlug, streamFormatNode ) ) { |
---|
1592 |
debugError( "addXmlDescription:: Could not add stream format info\n" ); |
---|
1593 |
return false; |
---|
1594 |
} |
---|
1595 |
|
---|
1596 |
return true; |
---|
1597 |
} |
---|
1598 |
|
---|
1599 |
bool |
---|
1600 |
AvDevice::setSamplingFrequencyPlug( AvPlug& plug, |
---|
1601 |
PlugAddress::EPlugDirection direction, |
---|
1602 |
ESamplingFrequency samplingFrequency ) |
---|
1603 |
{ |
---|
1604 |
ExtendedStreamFormatCmd extStreamFormatCmd( m_1394Service, |
---|
1605 |
ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList ); |
---|
1606 |
UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, |
---|
1607 |
plug.getPlugId() ); |
---|
1608 |
extStreamFormatCmd.setPlugAddress( PlugAddress( direction, |
---|
1609 |
PlugAddress::ePAM_Unit, |
---|
1610 |
unitPlugAddress ) ); |
---|
1611 |
|
---|
1612 |
extStreamFormatCmd.setNodeId( m_nodeId ); |
---|
1613 |
extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); |
---|
1614 |
//extStreamFormatCmd.setVerbose( true ); |
---|
1615 |
|
---|
1616 |
int i = 0; |
---|
1617 |
bool cmdSuccess = false; |
---|
1618 |
bool correctFormatFound = false; |
---|
1619 |
|
---|
1620 |
do { |
---|
1621 |
extStreamFormatCmd.setIndexInStreamFormat( i ); |
---|
1622 |
extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); |
---|
1623 |
|
---|
1624 |
cmdSuccess = extStreamFormatCmd.fire(); |
---|
1625 |
if ( cmdSuccess |
---|
1626 |
&& ( extStreamFormatCmd.getResponse() == AVCCommand::eR_Implemented ) ) |
---|
1627 |
{ |
---|
1628 |
ESamplingFrequency foundFreq = eSF_DontCare; |
---|
1629 |
|
---|
1630 |
FormatInformation* formatInfo = |
---|
1631 |
extStreamFormatCmd.getFormatInformation(); |
---|
1632 |
FormatInformationStreamsCompound* compoundStream |
---|
1633 |
= dynamic_cast< FormatInformationStreamsCompound* > ( |
---|
1634 |
formatInfo->m_streams ); |
---|
1635 |
if ( compoundStream ) { |
---|
1636 |
foundFreq = static_cast<ESamplingFrequency>( compoundStream->m_samplingFrequency ); |
---|
1637 |
} |
---|
1638 |
|
---|
1639 |
FormatInformationStreamsSync* syncStream |
---|
1640 |
= dynamic_cast< FormatInformationStreamsSync* > ( |
---|
1641 |
formatInfo->m_streams ); |
---|
1642 |
if ( syncStream ) { |
---|
1643 |
foundFreq = static_cast<ESamplingFrequency>( compoundStream->m_samplingFrequency ); |
---|
1644 |
} |
---|
1645 |
|
---|
1646 |
if ( foundFreq == samplingFrequency ) |
---|
1647 |
{ |
---|
1648 |
correctFormatFound = true; |
---|
1649 |
break; |
---|
1650 |
} |
---|
1651 |
} |
---|
1652 |
|
---|
1653 |
++i; |
---|
1654 |
} while ( cmdSuccess && ( extStreamFormatCmd.getResponse() |
---|
1655 |
== ExtendedStreamFormatCmd::eR_Implemented ) ); |
---|
1656 |
|
---|
1657 |
if ( !cmdSuccess ) { |
---|
1658 |
debugError( "setSampleRatePlug: Failed to retrieve format info\n" ); |
---|
1659 |
return false; |
---|
1660 |
} |
---|
1661 |
|
---|
1662 |
if ( !correctFormatFound ) { |
---|
1663 |
debugError( "setSampleRatePlug: %s plug %d does not support sample rate %d\n", |
---|
1664 |
plug.getName(), |
---|
1665 |
plug.getPlugId(), |
---|
1666 |
convertESamplingFrequency( samplingFrequency ) ); |
---|
1667 |
return false; |
---|
1668 |
} |
---|
1669 |
|
---|
1670 |
extStreamFormatCmd.setSubFunction( |
---|
1671 |
ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommand ); |
---|
1672 |
extStreamFormatCmd.setCommandType( AVCCommand::eCT_Control ); |
---|
1673 |
|
---|
1674 |
if ( !extStreamFormatCmd.fire() ) { |
---|
1675 |
debugError( "setSampleRate: Could not set sample rate %d " |
---|
1676 |
"to %s plug %d\n", |
---|
1677 |
convertESamplingFrequency( samplingFrequency ), |
---|
1678 |
plug.getName(), |
---|
1679 |
plug.getPlugId() ); |
---|
1680 |
return false; |
---|
1681 |
} |
---|
1682 |
|
---|
1683 |
return true; |
---|
1684 |
} |
---|
1685 |
|
---|
1686 |
bool |
---|
1687 |
AvDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency ) |
---|
1688 |
{ |
---|
1689 |
AvPlug* plug = getPlugById( m_isoInputPlugs, 0 ); |
---|
1690 |
if ( !plug ) { |
---|
1691 |
debugError( "setSampleRate: Could not retrieve iso input plug 0\n" ); |
---|
1692 |
return false; |
---|
1693 |
} |
---|
1694 |
|
---|
1695 |
if ( !setSamplingFrequencyPlug( *plug, PlugAddress::ePD_Input, samplingFrequency ) ) { |
---|
1696 |
debugError( "setSampleRate: Setting sample rate failed\n" ); |
---|
1697 |
return false; |
---|
1698 |
} |
---|
1699 |
|
---|
1700 |
plug = getPlugById( m_isoOutputPlugs, 0 ); |
---|
1701 |
if ( !plug ) { |
---|
1702 |
debugError( "setSampleRate: Could not retrieve iso output plug 0\n" ); |
---|
1703 |
return false; |
---|
1704 |
} |
---|
1705 |
|
---|
1706 |
if ( !setSamplingFrequencyPlug( *plug, PlugAddress::ePD_Output, samplingFrequency ) ) { |
---|
1707 |
debugError( "setSampleRate: Setting sample rate failed\n" ); |
---|
1708 |
return false; |
---|
1709 |
} |
---|
1710 |
|
---|
1711 |
debugOutput( DEBUG_LEVEL_VERBOSE, |
---|
1712 |
"setSampleRate: Set sample rate to %d\n", convertESamplingFrequency( samplingFrequency ) ); |
---|
1713 |
return true; |
---|
1714 |
} |
---|
1715 |
|
---|
1716 |
ConfigRom& |
---|
1717 |
AvDevice::getConfigRom() const |
---|
1718 |
{ |
---|
1719 |
return *m_configRom; |
---|
1720 |
} |
---|
1721 |
|
---|
1722 |
void |
---|
1723 |
AvDevice::showDevice() const |
---|
1724 |
{ |
---|
1725 |
printf( "showDevice: not implemented\n" ); |
---|
1726 |
} |
---|
1727 |
|
---|
1728 |
bool AvDevice::setId( unsigned int id) { |
---|
1729 |
m_id=id; |
---|
1730 |
return true; |
---|
1731 |
} |
---|
1732 |
|
---|
1733 |
} |
---|