root/trunk/libfreebob/src/libfreebobavc/avc_extended_stream_format.cpp

Revision 125, 12.0 kB (checked in by wagi, 18 years ago)

Initial revision

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