root/branches/stable_0_2_0/libfreebob/src/libfreebobavc/avc_extended_stream_format.cpp

Revision 161, 12.9 kB (checked in by anonymous, 18 years ago)

This commit was manufactured by cvs2svn to create branch 'stable_0_2_0'.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /* avc_extended_stream_format.cpp
2  * Copyright (C) 2005 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 "avc_extended_stream_format.h"
22 #include "serialize.h"
23 #include "ieee1394service.h"
24
25 #include <netinet/in.h>
26
27 ///////////////////////////////////////////////////////////
28 std::ostream& operator<<( std::ostream& stream, StreamFormatInfo info )
29 {
30 /*    stream << info.m_freq << " Hz (";
31     if ( info.m_format ) {
32             stream << "sync ";
33     } else {
34         stream << "compound ";
35     }
36     stream << "stream, ";
37     stream << "audio channels: " << info.m_audioChannels
38            << ", midi channels: " << info.m_midiChannels << ")";
39 */
40         stream << "  NbChannels " << (int)info.m_numberOfChannels << ", Format " << (int)info.m_streamFormat;
41     return stream;
42 }
43
44 StreamFormatInfo::StreamFormatInfo()
45     : IBusData()
46 {
47 }
48
49 bool
50 StreamFormatInfo::serialize( IOSSerialize& se )
51 {
52     se.write( m_numberOfChannels, "StreamFormatInfo numberOfChannels" );
53     se.write( m_streamFormat, "StreamFormatInfo streamFormat" );
54     return true;
55 }
56
57 bool
58 StreamFormatInfo::deserialize( IISDeserialize& de )
59 {
60     de.read( &m_numberOfChannels );
61     de.read( &m_streamFormat );
62     return true;
63 }
64
65 StreamFormatInfo*
66 StreamFormatInfo::clone() const
67 {
68     return new StreamFormatInfo( *this );
69 }
70
71 ////////////////////////////////////////////////////////////
72
73 FormatInformationStreamsSync::FormatInformationStreamsSync()
74     : FormatInformationStreams()
75     , m_reserved0( 0xff )
76     , m_samplingFrequency( eSF_DontCare )
77     , m_rateControl( eRC_DontCare )
78     , m_reserved1( 0xff )
79 {
80 }
81
82 bool
83 FormatInformationStreamsSync::serialize( IOSSerialize& se )
84 {
85     se.write( m_reserved0, "FormatInformationStreamsSync reserved" );
86
87     // we have to clobber some bits
88     byte_t operand = ( m_samplingFrequency << 4 ) | 0x0e;
89     if ( m_rateControl == eRC_DontCare) {
90         operand |= 0x1;
91     }
92     se.write( operand, "FormatInformationStreamsSync sampling frequency and rate control" );
93
94     se.write( m_reserved1, "FormatInformationStreamsSync reserved" );
95     return true;
96 }
97
98 bool
99 FormatInformationStreamsSync::deserialize( IISDeserialize& de )
100 {
101     de.read( &m_reserved0 );
102
103     byte_t operand;
104     de.read( &operand );
105     m_samplingFrequency = operand >> 4;
106     m_rateControl = operand & 0x01;
107
108     de.read( &m_reserved1 );
109     return true;
110 }
111
112 FormatInformationStreamsSync*
113 FormatInformationStreamsSync::clone() const
114 {
115     return new FormatInformationStreamsSync( *this );
116 }
117
118 ////////////////////////////////////////////////////////////
119 std::ostream& operator<<( std::ostream& stream, FormatInformationStreamsCompound info )
120 {
121     stream << (int)info.m_samplingFrequency << " Hz (rate control: ";
122         stream << (int)info.m_rateControl << ")" << std::endl;
123        
124         for ( FormatInformationStreamsCompound::StreamFormatInfoVector::iterator it = info.m_streamFormatInfos.begin();
125                 it != info.m_streamFormatInfos.end();
126                 ++it )
127         {
128                 StreamFormatInfo* sfi=*it;
129                 stream << "     > " << *sfi << std::endl;
130         }
131
132     return stream;
133 }
134
135 FormatInformationStreamsCompound::FormatInformationStreamsCompound()
136     : FormatInformationStreams()
137     , m_samplingFrequency( eSF_DontCare )
138     , m_rateControl( eRC_DontCare )
139     , m_numberOfStreamFormatInfos( 0 )
140 {
141 }
142
143 FormatInformationStreamsCompound::~FormatInformationStreamsCompound()
144 {
145     for ( StreamFormatInfoVector::iterator it = m_streamFormatInfos.begin();
146           it != m_streamFormatInfos.end();
147           ++it )
148     {
149         delete *it;
150     }
151 }
152
153 bool
154 FormatInformationStreamsCompound::serialize( IOSSerialize& se )
155 {
156     se.write( m_samplingFrequency, "FormatInformationStreamsCompound samplingFrequency" );
157     se.write( m_rateControl, "FormatInformationStreamsCompound rateControl" );
158     se.write( m_numberOfStreamFormatInfos, "FormatInformationStreamsCompound numberOfStreamFormatInfos" );
159     for ( StreamFormatInfoVector::iterator it = m_streamFormatInfos.begin();
160           it != m_streamFormatInfos.end();
161           ++it )
162     {
163         ( *it )->serialize( se );
164     }
165     return true;
166 }
167
168 bool
169 FormatInformationStreamsCompound::deserialize( IISDeserialize& de )
170 {
171     de.read( &m_samplingFrequency );
172     de.read( &m_rateControl );
173     de.read( &m_numberOfStreamFormatInfos );
174     for ( int i = 0; i < m_numberOfStreamFormatInfos; ++i ) {
175         StreamFormatInfo* streamFormatInfo = new StreamFormatInfo;
176         if ( !streamFormatInfo->deserialize( de ) ) {
177             return false;
178         }
179         m_streamFormatInfos.push_back( streamFormatInfo );
180     }
181     return true;
182 }
183
184 FormatInformationStreamsCompound*
185 FormatInformationStreamsCompound::clone() const
186 {
187     return new FormatInformationStreamsCompound( *this );
188 }
189
190 ////////////////////////////////////////////////////////////
191
192 FormatInformation::FormatInformation()
193     : IBusData()
194     , m_root( eFHR_Invalid )
195     , m_level1( eFHL1_AUDIOMUSIC_DONT_CARE )
196     , m_level2( eFHL2_AM824_DONT_CARE )
197     , m_streams( 0 )
198 {
199 }
200
201 FormatInformation::~FormatInformation()
202 {
203     delete m_streams;
204     m_streams = 0;
205 }
206
207 bool
208 FormatInformation::serialize( IOSSerialize& se )
209 {
210     if ( m_root != eFHR_Invalid ) {
211         se.write( m_root, "FormatInformation hierarchy root" );
212         if ( m_level1 != eFHL1_AUDIOMUSIC_DONT_CARE ) {
213             se.write( m_level1, "FormatInformation hierarchy level 1" );
214             if ( m_level2 != eFHL2_AM824_DONT_CARE ) {
215                 se.write( m_level2, "FormatInformation hierarchy level 2" );
216             }
217         }
218     }
219     if ( m_streams ) {
220         return m_streams->serialize( se );
221     }
222     return true;
223 }
224
225 bool
226 FormatInformation::deserialize( IISDeserialize& de )
227 {
228     bool result = false;
229
230     delete m_streams;
231     m_streams = 0;
232
233     // this code just parses BeBoB replies.
234     de.read( &m_root );
235
236     // just parse an audio and music hierarchy
237     if ( m_root == eFHR_AudioMusic ) {
238         de.read( &m_level1 );
239
240         switch ( m_level1 ) {
241         case eFHL1_AUDIOMUSIC_AM824:
242         {
243             // note: compound streams don't have a second level
244             de.read( &m_level2 );
245
246             if (m_level2 == eFHL2_AM824_SYNC_STREAM ) {
247                 m_streams = new FormatInformationStreamsSync();
248                 result = m_streams->deserialize( de );
249             } else {
250                 // anything but the sync stream workds currently.
251                 printf( "could not parse format information. (format hierarchy level 2 not recognized)\n" );
252             }
253         }
254         break;
255         case  eFHL1_AUDIOMUSIC_AM824_COMPOUND:
256         {
257             m_streams = new FormatInformationStreamsCompound();
258             result = m_streams->deserialize( de );
259         }
260         break;
261         default:
262             printf( "could not parse format information. (format hierarchy level 1 not recognized)\n" );
263         }
264     }
265
266     return result;
267 }
268
269 FormatInformation*
270 FormatInformation::clone() const
271 {
272     return new FormatInformation( *this );
273 }
274
275 ////////////////////////////////////////////////////////////
276
277 ExtendedStreamFormatCmd::ExtendedStreamFormatCmd( Ieee1394Service* service,
278                                                   ESubFunction eSubFunction )
279     : AVCCommand( service, AVC1394_STREAM_FORMAT_SUPPORT )
280     , m_subFunction( eSubFunction )
281     , m_status( eS_NotUsed )
282     , m_indexInStreamFormat( 0 )
283     , m_formatInformation( new FormatInformation )
284 {
285     UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, 0x00 );
286     m_plugAddress = new PlugAddress( PlugAddress::ePD_Output, PlugAddress::ePAM_Unit, unitPlugAddress );
287 }
288
289 ExtendedStreamFormatCmd::~ExtendedStreamFormatCmd()
290 {
291     delete m_plugAddress;
292     m_plugAddress = 0;
293     delete m_formatInformation;
294     m_formatInformation = 0;
295 }
296
297 bool
298 ExtendedStreamFormatCmd::setPlugAddress( const PlugAddress& plugAddress )
299 {
300     delete m_plugAddress;
301     m_plugAddress = plugAddress.clone();
302     return true;
303 }
304
305 bool
306 ExtendedStreamFormatCmd::setIndexInStreamFormat( const int index )
307 {
308     m_indexInStreamFormat = index;
309     return true;
310 }
311
312 bool
313 ExtendedStreamFormatCmd::serialize( IOSSerialize& se )
314 {
315     AVCCommand::serialize( se );
316     se.write( m_subFunction, "ExtendedStreamFormatCmd subFunction" );
317     m_plugAddress->serialize( se );
318     se.write( m_status, "ExtendedStreamFormatCmd status" );
319     if ( m_subFunction == eSF_ExtendedStreamFormatInformationCommandList ) {
320         se.write( m_indexInStreamFormat, "indexInStreamFormat" );
321     }
322     m_formatInformation->serialize( se );
323     return true;
324 }
325
326 bool
327 ExtendedStreamFormatCmd::deserialize( IISDeserialize& de )
328 {
329     AVCCommand::deserialize( de );
330     de.read( &m_subFunction );
331     m_plugAddress->deserialize( de );
332     de.read( &m_status );
333     if ( m_subFunction == eSF_ExtendedStreamFormatInformationCommandList ) {
334         de.read( &m_indexInStreamFormat );
335     }
336     m_formatInformation->deserialize( de );
337     return true;
338 }
339
340 bool
341 ExtendedStreamFormatCmd::fire()
342 {
343     bool result = false;
344
345     #define STREAM_FORMAT_REQUEST_SIZE 20 // XXX random length
346     union UPacket {
347         quadlet_t     quadlet[STREAM_FORMAT_REQUEST_SIZE];
348         unsigned char byte[STREAM_FORMAT_REQUEST_SIZE*4];
349     };
350     typedef union UPacket packet_t;
351
352     packet_t  req;
353     packet_t* resp;
354
355     // initialize complete packet
356     memset( &req,  0xff,  sizeof( req ) );
357
358     BufferSerialize se( req.byte, sizeof( req ) );
359     if ( !serialize( se ) ) {
360         printf(  "ExtendedStreamFormatCmd::fire: Could not serialize\n" );
361         return false;
362     }
363
364     // reorder the bytes to the correct layout
365     for (int i = 0; i < STREAM_FORMAT_REQUEST_SIZE; ++i) {
366         req.quadlet[i] = ntohl( req.quadlet[i] );
367     }
368
369     if ( isVerbose() ) {
370         // debug output
371         puts("request:");
372         for (int i = 0; i < STREAM_FORMAT_REQUEST_SIZE; ++i) {
373             printf("  %2d: 0x%08x\n", i, req.quadlet[i]);
374         }
375     }
376     resp = reinterpret_cast<packet_t*>(
377         m_1394Service->transactionBlock( m_nodeId,
378                                          req.quadlet,
379                                          STREAM_FORMAT_REQUEST_SIZE ) );
380     if ( resp ) {
381         if ( isVerbose() ) {
382             // debug output
383             puts("response:");
384             for ( int i = 0; i < STREAM_FORMAT_REQUEST_SIZE; ++i ) {
385                 printf( "  %2d: 0x%08x\n", i, resp->quadlet[i] );
386             }
387         }
388
389         // reorder the bytes to the correct layout
390         for ( int i = 0; i < STREAM_FORMAT_REQUEST_SIZE; ++i ) {
391             resp->quadlet[i] = htonl( resp->quadlet[i] );
392         }
393
394         if ( isVerbose() ) {
395             // a more detailed debug output
396             printf( "\n" );
397             printf( " idx type                       value\n" );
398             printf( "-------------------------------------\n" );
399             printf( "  %02d                     ctype: 0x%02x\n", 0, resp->byte[0] );
400             printf( "  %02d subunit_type + subunit_id: 0x%02x\n", 1, resp->byte[1] );
401             printf( "  %02d                    opcode: 0x%02x\n", 2, resp->byte[2] );
402
403             for ( int i = 3; i < STREAM_FORMAT_REQUEST_SIZE * 4; ++i ) {
404                 printf( "  %02d                operand %2d: 0x%02x\n", i, i-3, resp->byte[i] );
405             }
406         }
407
408         // parse output
409         parseResponse( resp->byte[0] );
410         switch ( getResponse() )
411         {
412             case eR_Implemented:
413             {
414                 BufferDeserialize de( resp->byte, sizeof( req ) );
415                 deserialize( de );
416                 result = true;
417             }
418             break;
419             case eR_Rejected:
420                 if ( m_subFunction == eSF_ExtendedStreamFormatInformationCommandList ) {
421                     if ( isVerbose() ) {
422                         printf( "no futher stream formats defined\n" );
423                     }
424                     result = true;
425                 } else {
426                     printf( "request rejected\n" );
427                 }
428                 break;
429             default:
430                 printf( "unexpected response received (0x%x)\n", getResponse() );
431         }
432     } else {
433         printf( "no response\n" );
434     }
435
436     return result;
437 }
438
439 status_t
440 ExtendedStreamFormatCmd::getStatus()
441 {
442     return m_status;
443 }
444
445 FormatInformation*
446 ExtendedStreamFormatCmd::getFormatInformation()
447 {
448     return m_formatInformation;
449 }
450
451 ExtendedStreamFormatCmd::index_in_stream_format_t
452 ExtendedStreamFormatCmd::getIndex()
453 {
454     return m_indexInStreamFormat;
455 }
456
457 bool
458 ExtendedStreamFormatCmd::setSubFunction( ESubFunction subFunction )
459 {
460     m_subFunction = subFunction;
461     return true;
462 }
Note: See TracBrowser for help on using the browser.