importer: Don't treat single frame VC-1 and H.264 stream as still image.
[L-SMASH.git] / a52.c
blob0f5718f414bab827f2a7d522bc96be6da4afbdbb
1 /*****************************************************************************
2 * a52.c:
3 *****************************************************************************
4 * Copyright (C) 2012 L-SMASH project
6 * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *****************************************************************************/
21 /* This file is available under an ISC license. */
23 #include "internal.h" /* must be placed first */
25 #include <stdlib.h>
26 #include <string.h>
27 #include <inttypes.h>
29 #include "box.h"
31 static const char *bit_stream_mode[] =
33 "Main audio service: complete main (CM)",
34 "Main audio service: music and effects (ME)",
35 "Associated service: visually impaired (VI)",
36 "Associated service: hearing impaired (HI)",
37 "Associated service: dialogue (D)",
38 "Associated service: commentary (C)",
39 "Associated service: emergency (E)",
40 "Undefined service",
41 "Associated service: voice over (VO)", /* only if acmod == 0b001 */
42 "Main audio service: karaoke"
45 /* For karaoke mode, C->M, S->V1, SL->V1 and SR->V2. */
46 static const char *audio_coding_mode[] =
48 "1 + 1: Dual mono",
49 "1/0: C",
50 "2/0: L, R",
51 "3/0: L, C, R",
52 "2/1: L, R, S",
53 "3/1: L, C, R, S",
54 "2/2: L, R, SL, SR",
55 "3/2: L, C, R, SL, SR",
56 "Undefined audio coding mode",
57 "Undefined audio coding mode",
58 "2/0: L, R",
59 "3/0: L, M, R",
60 "2/1: L, R, V1",
61 "3/1: L, M, R, V1",
62 "2/2: L, R, V1, V2",
63 "3/2: L, M, R, V1, V2"
66 /***************************************************************************
67 AC-3 tools
68 ETSI TS 102 366 V1.2.1 (2008-08)
69 ***************************************************************************/
70 #include "a52.h"
72 #define AC3_SPECIFIC_BOX_LENGTH 11
74 uint8_t *lsmash_create_ac3_specific_info( lsmash_ac3_specific_parameters_t *param, uint32_t *data_length )
76 lsmash_bits_t bits = { 0 };
77 lsmash_bs_t bs = { 0 };
78 lsmash_bits_init( &bits, &bs );
79 uint8_t buffer[AC3_SPECIFIC_BOX_LENGTH] = { 0 };
80 bs.data = buffer;
81 bs.alloc = AC3_SPECIFIC_BOX_LENGTH;
82 lsmash_bits_put( &bits, 32, AC3_SPECIFIC_BOX_LENGTH ); /* box size */
83 lsmash_bits_put( &bits, 32, ISOM_BOX_TYPE_DAC3.fourcc ); /* box type: 'dac3' */
84 lsmash_bits_put( &bits, 2, param->fscod );
85 lsmash_bits_put( &bits, 5, param->bsid );
86 lsmash_bits_put( &bits, 3, param->bsmod );
87 lsmash_bits_put( &bits, 3, param->acmod );
88 lsmash_bits_put( &bits, 1, param->lfeon );
89 lsmash_bits_put( &bits, 5, param->frmsizecod >> 1 );
90 lsmash_bits_put( &bits, 5, 0 );
91 uint8_t *data = lsmash_bits_export_data( &bits, data_length );
92 lsmash_bits_empty( &bits );
93 return data;
96 int lsmash_setup_ac3_specific_parameters_from_syncframe( lsmash_ac3_specific_parameters_t *param, uint8_t *data, uint32_t data_length )
98 if( !data || data_length < AC3_MIN_SYNCFRAME_LENGTH )
99 return -1;
100 IF_A52_SYNCWORD( data )
101 return -1;
102 lsmash_bits_t bits = { 0 };
103 lsmash_bs_t bs = { 0 };
104 uint8_t buffer[AC3_MAX_SYNCFRAME_LENGTH] = { 0 };
105 bs.data = buffer;
106 bs.alloc = AC3_MAX_SYNCFRAME_LENGTH;
107 ac3_info_t handler = { { 0 } };
108 ac3_info_t *info = &handler;
109 memcpy( info->buffer, data, LSMASH_MIN( data_length, AC3_MAX_SYNCFRAME_LENGTH ) );
110 info->bits = &bits;
111 lsmash_bits_init( &bits, &bs );
112 if( ac3_parse_syncframe_header( info, info->buffer ) )
113 return -1;
114 *param = info->dac3_param;
115 return 0;
118 static int ac3_check_syncframe_header( lsmash_ac3_specific_parameters_t *param )
120 if( param->fscod == 0x3 )
121 return -1; /* unknown Sample Rate Code */
122 if( param->frmsizecod > 0x25 )
123 return -1; /* unknown Frame Size Code */
124 if( param->bsid >= 10 )
125 return -1; /* might be EAC-3 */
126 return 0;
129 int ac3_parse_syncframe_header( ac3_info_t *info, uint8_t *data )
131 lsmash_bits_t *bits = info->bits;
132 if( lsmash_bits_import_data( bits, data, AC3_MIN_SYNCFRAME_LENGTH ) )
133 return -1;
134 lsmash_ac3_specific_parameters_t *param = &info->dac3_param;
135 lsmash_bits_get( bits, 32 ); /* syncword + crc1 */
136 param->fscod = lsmash_bits_get( bits, 2 );
137 param->frmsizecod = lsmash_bits_get( bits, 6 );
138 param->bsid = lsmash_bits_get( bits, 5 );
139 param->bsmod = lsmash_bits_get( bits, 3 );
140 param->acmod = lsmash_bits_get( bits, 3 );
141 if( (param->acmod & 0x01) && (param->acmod != 0x01) )
142 lsmash_bits_get( bits, 2 ); /* cmixlev */
143 if( param->acmod & 0x04 )
144 lsmash_bits_get( bits, 2 ); /* surmixlev */
145 if( param->acmod == 0x02 )
146 lsmash_bits_get( bits, 2 ); /* dsurmod */
147 param->lfeon = lsmash_bits_get( bits, 1 );
148 lsmash_bits_empty( bits );
149 return ac3_check_syncframe_header( param );
152 int ac3_construct_specific_parameters( lsmash_codec_specific_t *dst, lsmash_codec_specific_t *src )
154 assert( dst && dst->data.structured && src && src->data.unstructured );
155 if( src->size < AC3_SPECIFIC_BOX_LENGTH )
156 return -1;
157 lsmash_ac3_specific_parameters_t *param = (lsmash_ac3_specific_parameters_t *)dst->data.structured;
158 uint8_t *data = src->data.unstructured;
159 uint64_t size = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
160 data += ISOM_BASEBOX_COMMON_SIZE;
161 if( size == 1 )
163 size = ((uint64_t)data[0] << 56) | ((uint64_t)data[1] << 48) | ((uint64_t)data[2] << 40) | ((uint64_t)data[3] << 32)
164 | ((uint64_t)data[4] << 24) | ((uint64_t)data[5] << 16) | ((uint64_t)data[6] << 8) | (uint64_t)data[7];
165 data += 8;
167 if( size != src->size )
168 return -1;
169 param->fscod = (data[0] >> 6) & 0x03; /* XXxx xxxx xxxx xxxx xxxx xxxx */
170 param->bsid = (data[0] >> 1) & 0x1F; /* xxXX XXXx xxxx xxxx xxxx xxxx */
171 param->bsmod = ((data[0] & 0x01) << 2) | ((data[2] >> 6) & 0x03); /* xxxx xxxX XXxx xxxx xxxx xxxx */
172 param->acmod = (data[1] >> 3) & 0x07; /* xxxx xxxx xxXX Xxxx xxxx xxxx */
173 param->lfeon = (data[1] >> 2) & 0x01; /* xxxx xxxx xxxx xXxx xxxx xxxx */
174 param->frmsizecod = ((data[1] & 0x03) << 3) | ((data[3] >> 5) & 0x07); /* xxxx xxxx xxxx xxXX XXXx xxxx */
175 param->frmsizecod <<= 1;
176 return 0;
179 int ac3_print_codec_specific( FILE *fp, lsmash_root_t *root, isom_box_t *box, int level )
181 assert( fp && root && box );
182 int indent = level;
183 lsmash_ifprintf( fp, indent++, "[%s: AC3 Specific Box]\n", isom_4cc2str( box->type.fourcc ) );
184 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", box->pos );
185 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", box->size );
186 if( box->size < AC3_SPECIFIC_BOX_LENGTH )
187 return -1;
188 isom_extension_box_t *ext = (isom_extension_box_t *)box;
189 assert( ext->format == EXTENSION_FORMAT_BINARY );
190 uint8_t *data = ext->form.binary;
191 isom_skip_box_common( &data );
192 uint8_t fscod = (data[0] >> 6) & 0x03;
193 uint8_t bsid = (data[0] >> 1) & 0x1F;
194 uint8_t bsmod = ((data[0] & 0x01) << 2) | ((data[1] >> 6) & 0x03);
195 uint8_t acmod = (data[1] >> 3) & 0x07;
196 uint8_t lfeon = (data[1] >> 2) & 0x01;
197 uint8_t bit_rate_code = ((data[1] & 0x03) << 3) | ((data[2] >> 5) & 0x07);
198 if( fscod != 0x03 )
199 lsmash_ifprintf( fp, indent, "fscod = %"PRIu8" (%"PRIu32" Hz)\n", fscod, ac3_sample_rate_table[fscod] );
200 else
201 lsmash_ifprintf( fp, indent, "fscod = 0x03 (reserved)\n" );
202 lsmash_ifprintf( fp, indent, "bsid = %"PRIu8"\n", bsid );
203 lsmash_ifprintf( fp, indent, "bsmod = %"PRIu8" (%s)\n", bsmod, bit_stream_mode[bsmod + (acmod == 0x01 ? 1 : acmod > 0x01 ? 2 : 0)] );
204 lsmash_ifprintf( fp, indent, "acmod = %"PRIu8" (%s)\n", acmod, audio_coding_mode[acmod + (bsmod == 0x07 ? 8 : 0)] );
205 lsmash_ifprintf( fp, indent, "lfeon = %s\n", lfeon ? "1 (LFE)" : "0" );
206 static const uint32_t bit_rate[] =
208 32, 40, 48, 56, 64, 80, 96, 112, 128,
209 160, 192, 224, 256, 320, 384, 448, 512, 576, 640,
210 0 /* undefined */
212 lsmash_ifprintf( fp, indent, "bit_rate_code = 0x%02"PRIx8" (%"PRIu32" kbit/s)\n", bit_rate_code, bit_rate[bit_rate_code] );
213 lsmash_ifprintf( fp, indent, "reserved = 0x%02"PRIx8"\n", data[2] & 0x1F );
214 return 0;
217 #undef AC3_SPECIFIC_BOX_LENGTH
219 /***************************************************************************
220 Enhanced AC-3 tools
221 ETSI TS 102 366 V1.2.1 (2008-08)
222 ***************************************************************************/
224 uint8_t *lsmash_create_eac3_specific_info( lsmash_eac3_specific_parameters_t *param, uint32_t *data_length )
226 #define EAC3_SPECIFIC_BOX_MAX_LENGTH 42
227 if( param->num_ind_sub > 7 )
228 return NULL;
229 lsmash_bits_t bits = { 0 };
230 lsmash_bs_t bs = { 0 };
231 lsmash_bits_init( &bits, &bs );
232 uint8_t buffer[EAC3_SPECIFIC_BOX_MAX_LENGTH] = { 0 };
233 bs.data = buffer;
234 bs.alloc = EAC3_SPECIFIC_BOX_MAX_LENGTH;
235 lsmash_bits_put( &bits, 32, 0 ); /* box size */
236 lsmash_bits_put( &bits, 32, ISOM_BOX_TYPE_DEC3.fourcc ); /* box type: 'dec3' */
237 lsmash_bits_put( &bits, 13, param->data_rate ); /* data_rate; setup by isom_update_bitrate_description */
238 lsmash_bits_put( &bits, 3, param->num_ind_sub );
239 /* Apparently, the condition of this loop defined in ETSI TS 102 366 V1.2.1 (2008-08) is wrong. */
240 for( int i = 0; i <= param->num_ind_sub; i++ )
242 lsmash_eac3_substream_info_t *independent_info = &param->independent_info[i];
243 lsmash_bits_put( &bits, 2, independent_info->fscod );
244 lsmash_bits_put( &bits, 5, independent_info->bsid );
245 lsmash_bits_put( &bits, 5, independent_info->bsmod );
246 lsmash_bits_put( &bits, 3, independent_info->acmod );
247 lsmash_bits_put( &bits, 1, independent_info->lfeon );
248 lsmash_bits_put( &bits, 3, 0 ); /* reserved */
249 lsmash_bits_put( &bits, 4, independent_info->num_dep_sub );
250 if( independent_info->num_dep_sub > 0 )
251 lsmash_bits_put( &bits, 9, independent_info->chan_loc );
252 else
253 lsmash_bits_put( &bits, 1, 0 ); /* reserved */
255 uint8_t *data = lsmash_bits_export_data( &bits, data_length );
256 lsmash_bits_empty( &bits );
257 /* Update box size. */
258 data[0] = ((*data_length) >> 24) & 0xff;
259 data[1] = ((*data_length) >> 16) & 0xff;
260 data[2] = ((*data_length) >> 8) & 0xff;
261 data[3] = (*data_length) & 0xff;
262 return data;
263 #undef EAC3_SPECIFIC_BOX_MAX_LENGTH
266 /* Return -1 if incomplete Enhanced AC-3 sample is given. */
267 int lsmash_setup_eac3_specific_parameters_from_frame( lsmash_eac3_specific_parameters_t *param, uint8_t *data, uint32_t data_length )
269 if( !data || data_length < 5 )
270 return -1;
271 lsmash_bits_t bits = { 0 };
272 lsmash_bs_t bs = { 0 };
273 uint8_t buffer[EAC3_MAX_SYNCFRAME_LENGTH] = { 0 };
274 bs.data = buffer;
275 bs.alloc = EAC3_MAX_SYNCFRAME_LENGTH;
276 eac3_info_t handler = { { 0 } };
277 eac3_info_t *info = &handler;
278 uint32_t overall_wasted_data_length = 0;
279 info->buffer_pos = info->buffer;
280 info->buffer_end = info->buffer;
281 info->bits = &bits;
282 lsmash_bits_init( &bits, &bs );
283 while( 1 )
285 /* Check the remainder length of the input data.
286 * If there is enough length, then parse the syncframe in it.
287 * The length 5 is the required byte length to get frame size. */
288 uint32_t remainder_length = info->buffer_end - info->buffer_pos;
289 if( !info->no_more_read && remainder_length < EAC3_MAX_SYNCFRAME_LENGTH )
291 if( remainder_length )
292 memmove( info->buffer, info->buffer_pos, remainder_length );
293 uint32_t wasted_data_length = LSMASH_MIN( data_length, EAC3_MAX_SYNCFRAME_LENGTH );
294 data_length -= wasted_data_length;
295 memcpy( info->buffer + remainder_length, data + overall_wasted_data_length, wasted_data_length );
296 overall_wasted_data_length += wasted_data_length;
297 remainder_length += wasted_data_length;
298 info->buffer_pos = info->buffer;
299 info->buffer_end = info->buffer + remainder_length;
300 info->no_more_read = (data_length < 5);
302 if( remainder_length < 5 && info->no_more_read )
303 goto setup_param; /* No more valid data. */
304 /* Parse syncframe. */
305 IF_A52_SYNCWORD( info->buffer_pos )
306 goto setup_param;
307 info->frame_size = 0;
308 if( eac3_parse_syncframe( info, info->buffer_pos, LSMASH_MIN( remainder_length, EAC3_MAX_SYNCFRAME_LENGTH ) ) )
309 goto setup_param;
310 if( remainder_length < info->frame_size )
311 goto setup_param;
312 int independent = info->strmtyp != 0x1;
313 if( independent && info->substreamid == 0x0 )
315 if( info->number_of_audio_blocks == 6 )
317 /* Encountered the first syncframe of the next access unit. */
318 info->number_of_audio_blocks = 0;
319 goto setup_param;
321 else if( info->number_of_audio_blocks > 6 )
322 goto setup_param;
323 info->number_of_audio_blocks += eac3_audio_block_table[ info->numblkscod ];
324 info->number_of_independent_substreams = 0;
326 else if( info->syncframe_count == 0 )
327 /* The first syncframe in an AU must be independent and assigned substream ID 0. */
328 return -2;
329 if( independent )
330 info->independent_info[info->number_of_independent_substreams ++].num_dep_sub = 0;
331 else
332 ++ info->independent_info[info->number_of_independent_substreams - 1].num_dep_sub;
333 info->buffer_pos += info->frame_size;
334 ++ info->syncframe_count;
336 setup_param:
337 if( info->number_of_independent_substreams == 0 || info->number_of_independent_substreams > 8 )
338 return -1;
339 if( !info->dec3_param_initialized )
340 eac3_update_specific_param( info );
341 *param = info->dec3_param;
342 return info->number_of_audio_blocks == 6 ? 0 : -1;
345 uint16_t lsmash_eac3_get_chan_loc_from_chanmap( uint16_t chanmap )
347 return ((chanmap & 0x7f8) >> 2) | ((chanmap & 0x2) >> 1);
350 static int eac3_check_syncframe_header( eac3_info_t *info )
352 if( info->strmtyp == 0x3 )
353 return -1; /* unknown Stream type */
354 lsmash_eac3_substream_info_t *substream_info;
355 if( info->strmtyp != 0x1 )
356 substream_info = &info->independent_info[ info->current_independent_substream_id ];
357 else
358 substream_info = &info->dependent_info;
359 if( substream_info->fscod == 0x3 && substream_info->fscod2 == 0x3 )
360 return -1; /* unknown Sample Rate Code */
361 if( substream_info->bsid < 10 || substream_info->bsid > 16 )
362 return -1; /* not EAC-3 */
363 return 0;
366 int eac3_parse_syncframe( eac3_info_t *info, uint8_t *data, uint32_t data_length )
368 lsmash_bits_t *bits = info->bits;
369 if( lsmash_bits_import_data( bits, data, data_length ) )
370 return -1;
371 lsmash_bits_get( bits, 16 ); /* syncword (16) */
372 info->strmtyp = lsmash_bits_get( bits, 2 ); /* strmtyp (2) */
373 info->substreamid = lsmash_bits_get( bits, 3 ); /* substreamid (3) */
374 lsmash_eac3_substream_info_t *substream_info;
375 if( info->strmtyp != 0x1 )
377 if( info->substreamid == 0x0 && info->number_of_independent_substreams )
378 eac3_update_specific_param( info );
379 info->current_independent_substream_id = info->substreamid;
380 substream_info = &info->independent_info[ info->current_independent_substream_id ];
381 substream_info->chan_loc = 0;
383 else
384 substream_info = &info->dependent_info;
385 info->frame_size = 2 * (lsmash_bits_get( bits, 11 ) + 1); /* frmsiz (11) */
386 substream_info->fscod = lsmash_bits_get( bits, 2 ); /* fscod (2) */
387 if( substream_info->fscod == 0x3 )
389 substream_info->fscod2 = lsmash_bits_get( bits, 2 ); /* fscod2 (2) */
390 info->numblkscod = 0x3;
392 else
393 info->numblkscod = lsmash_bits_get( bits, 2 ); /* numblkscod (2) */
394 substream_info->acmod = lsmash_bits_get( bits, 3 ); /* acmod (3) */
395 substream_info->lfeon = lsmash_bits_get( bits, 1 ); /* lfeon (1) */
396 substream_info->bsid = lsmash_bits_get( bits, 5 ); /* bsid (5) */
397 lsmash_bits_get( bits, 5 ); /* dialnorm (5) */
398 if( lsmash_bits_get( bits, 1 ) ) /* compre (1) */
399 lsmash_bits_get( bits, 8 ); /* compr (8) */
400 if( substream_info->acmod == 0x0 )
402 lsmash_bits_get( bits, 5 ); /* dialnorm2 (5) */
403 if( lsmash_bits_get( bits, 1 ) ) /* compre2 (1) */
404 lsmash_bits_get( bits, 8 ); /* compr2 (8) */
406 if( info->strmtyp == 0x1 && lsmash_bits_get( bits, 1 ) ) /* chanmape (1) */
408 uint16_t chanmap = lsmash_bits_get( bits, 16 ); /* chanmap (16) */
409 info->independent_info[ info->current_independent_substream_id ].chan_loc |= lsmash_eac3_get_chan_loc_from_chanmap( chanmap );
411 if( lsmash_bits_get( bits, 1 ) ) /* mixmdate (1) */
413 if( substream_info->acmod > 0x2 )
414 lsmash_bits_get( bits, 2 ); /* dmixmod (2) */
415 if( ((substream_info->acmod & 0x1) && (substream_info->acmod > 0x2)) || (substream_info->acmod & 0x4) )
416 lsmash_bits_get( bits, 6 ); /* ltrt[c/sur]mixlev (3)
417 * loro[c/sur]mixlev (3) */
418 if( substream_info->lfeon && lsmash_bits_get( bits, 1 ) ) /* lfemixlevcode (1) */
419 lsmash_bits_get( bits, 5 ); /* lfemixlevcod (5) */
420 if( info->strmtyp == 0x0 )
422 if( lsmash_bits_get( bits, 1 ) ) /* pgmscle (1) */
423 lsmash_bits_get( bits, 6 ); /* pgmscl (6) */
424 if( substream_info->acmod == 0x0 && lsmash_bits_get( bits, 1 ) ) /* pgmscle2 (1) */
425 lsmash_bits_get( bits, 6 ); /* pgmscl2 (6) */
426 if( lsmash_bits_get( bits, 1 ) ) /* extpgmscle (1) */
427 lsmash_bits_get( bits, 6 ); /* extpgmscl (6) */
428 uint8_t mixdef = lsmash_bits_get( bits, 2 ); /* mixdef (2) */
429 if( mixdef == 0x1 )
430 lsmash_bits_get( bits, 5 ); /* premixcmpsel (1)
431 * drcsrc (1)
432 * premixcmpscl (3) */
433 else if( mixdef == 0x2 )
434 lsmash_bits_get( bits, 12 ); /* mixdata (12) */
435 else if( mixdef == 0x3 )
437 uint8_t mixdeflen = lsmash_bits_get( bits, 5 ); /* mixdeflen (5) */
438 lsmash_bits_get( bits, 8 * (mixdeflen + 2) ); /* mixdata (8 * (mixdeflen + 2))
439 * mixdatafill (0-7) */
441 if( substream_info->acmod < 0x2 )
443 if( lsmash_bits_get( bits, 1 ) ) /* paninfoe (1) */
444 lsmash_bits_get( bits, 14 ); /* panmean (8)
445 * paninfo (6) */
446 if( substream_info->acmod == 0x0 && lsmash_bits_get( bits, 1 ) ) /* paninfo2e (1) */
447 lsmash_bits_get( bits, 14 ); /* panmean2 (8)
448 * paninfo2 (6) */
450 if( lsmash_bits_get( bits, 1 ) ) /* frmmixcfginfoe (1) */
452 if( info->numblkscod == 0x0 )
453 lsmash_bits_get( bits, 5 ); /* blkmixcfginfo[0] (5) */
454 else
456 int number_of_blocks_per_syncframe = ((int []){ 1, 2, 3, 6 })[ info->numblkscod ];
457 for( int blk = 0; blk < number_of_blocks_per_syncframe; blk++ )
458 if( lsmash_bits_get( bits, 1 ) ) /* blkmixcfginfoe (1)*/
459 lsmash_bits_get( bits, 5 ); /* blkmixcfginfo[blk] (5) */
464 if( lsmash_bits_get( bits, 1 ) ) /* infomdate (1) */
466 substream_info->bsmod = lsmash_bits_get( bits, 3 ); /* bsmod (3) */
467 lsmash_bits_get( bits, 1 ); /* copyrightb (1) */
468 lsmash_bits_get( bits, 1 ); /* origbs (1) */
469 if( substream_info->acmod == 0x2 )
470 lsmash_bits_get( bits, 4 ); /* dsurmod (2)
471 * dheadphonmod (2) */
472 else if( substream_info->acmod >= 0x6 )
473 lsmash_bits_get( bits, 2 ); /* dsurexmod (2) */
474 if( lsmash_bits_get( bits, 1 ) ) /* audprodie (1) */
475 lsmash_bits_get( bits, 8 ); /* mixlevel (5)
476 * roomtyp (2)
477 * adconvtyp (1) */
478 if( substream_info->acmod == 0x0 && lsmash_bits_get( bits, 1 ) ) /* audprodie2 (1) */
479 lsmash_bits_get( bits, 8 ); /* mixlevel2 (5)
480 * roomtyp2 (2)
481 * adconvtyp2 (1) */
482 if( substream_info->fscod < 0x3 )
483 lsmash_bits_get( bits, 1 ); /* sourcefscod (1) */
485 else
486 substream_info->bsmod = 0;
487 if( info->strmtyp == 0x0 && info->numblkscod != 0x3 )
488 lsmash_bits_get( bits, 1 ); /* convsync (1) */
489 if( info->strmtyp == 0x2 )
491 int blkid;
492 if( info->numblkscod == 0x3 )
493 blkid = 1;
494 else
495 blkid = lsmash_bits_get( bits, 1 ); /* blkid (1) */
496 if( blkid )
497 lsmash_bits_get( bits, 6 ); /* frmsizecod (6) */
499 if( lsmash_bits_get( bits, 1 ) ) /* addbsie (1) */
501 uint8_t addbsil = lsmash_bits_get( bits, 6 ); /* addbsil (6) */
502 lsmash_bits_get( bits, (addbsil + 1) * 8 ); /* addbsi ((addbsil + 1) * 8) */
504 lsmash_bits_empty( bits );
505 return eac3_check_syncframe_header( info );
508 void eac3_update_specific_param( eac3_info_t *info )
510 lsmash_eac3_specific_parameters_t *param = &info->dec3_param;
511 param->data_rate = 0;
512 param->num_ind_sub = info->number_of_independent_substreams - 1;
513 for( uint8_t i = 0; i <= param->num_ind_sub; i++ )
514 param->independent_info[i] = info->independent_info[i];
515 info->dec3_param_initialized = 1;
518 #define EAC3_SPECIFIC_BOX_MIN_LENGTH 13
520 int eac3_construct_specific_parameters( lsmash_codec_specific_t *dst, lsmash_codec_specific_t *src )
522 assert( dst && dst->data.structured && src && src->data.unstructured );
523 if( src->size < EAC3_SPECIFIC_BOX_MIN_LENGTH )
524 return -1;
525 lsmash_eac3_specific_parameters_t *param = (lsmash_eac3_specific_parameters_t *)dst->data.structured;
526 uint8_t *data = src->data.unstructured;
527 uint64_t size = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
528 data += ISOM_BASEBOX_COMMON_SIZE;
529 if( size == 1 )
531 size = ((uint64_t)data[0] << 56) | ((uint64_t)data[1] << 48) | ((uint64_t)data[2] << 40) | ((uint64_t)data[3] << 32)
532 | ((uint64_t)data[4] << 24) | ((uint64_t)data[5] << 16) | ((uint64_t)data[6] << 8) | (uint64_t)data[7];
533 data += 8;
535 if( size != src->size )
536 return -1;
537 param->data_rate = (data[0] << 5) | ((data[1] >> 3) & 0x1F); /* XXXX XXXX XXXX Xxxx */
538 param->num_ind_sub = data[1] & 0x07; /* xxxx xxxx xxxx xXXX */
539 data += 2;
540 size -= 2;
541 for( int i = 0; i <= param->num_ind_sub; i++ )
543 if( size < 3 )
544 return -1;
545 lsmash_eac3_substream_info_t *independent_info = &param->independent_info[i];
546 independent_info->fscod = (data[0] >> 6) & 0x03; /* XXxx xxxx xxxx xxxx xxxx xxxx */
547 independent_info->bsid = (data[0] >> 1) & 0x1F; /* xxXX XXXx xxxx xxxx xxxx xxxx */
548 independent_info->bsmod = ((data[0] & 0x01) << 4) | ((data[1] >> 4) & 0x0F); /* xxxx xxxX XXXX xxxx xxxx xxxx */
549 independent_info->acmod = (data[1] >> 1) & 0x07; /* xxxx xxxx xxxx XXXx xxxx xxxx */
550 independent_info->lfeon = data[1] & 0x01; /* xxxx xxxx xxxx xxxX xxxx xxxx */
551 independent_info->num_dep_sub = (data[2] >> 1) & 0x0F; /* xxxx xxxx xxxx xxxx xxxX XXXx */
552 data += 3;
553 size -= 3;
554 if( independent_info->num_dep_sub > 0 )
556 if( size < 1 )
557 return -1;
558 independent_info->chan_loc = ((data[-1] & 0x01) << 8) | data[0]; /* xxxx xxxX XXXX XXXX */
559 data += 1;
560 size -= 1;
563 return 0;
566 int eac3_print_codec_specific( FILE *fp, lsmash_root_t *root, isom_box_t *box, int level )
568 assert( fp && root && box );
569 int indent = level;
570 lsmash_ifprintf( fp, indent++, "[%s: EC3 Specific Box]\n", isom_4cc2str( box->type.fourcc ) );
571 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", box->pos );
572 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", box->size );
573 if( box->size < EAC3_SPECIFIC_BOX_MIN_LENGTH )
574 return -1;
575 isom_extension_box_t *ext = (isom_extension_box_t *)box;
576 assert( ext->format == EXTENSION_FORMAT_BINARY );
577 uint8_t *data = ext->form.binary;
578 isom_skip_box_common( &data );
579 lsmash_ifprintf( fp, indent, "data_rate = %"PRIu16" kbit/s\n", (data[0] << 5) | ((data[1] >> 3) & 0x1F) );
580 uint8_t num_ind_sub = data[1] & 0x07;
581 lsmash_ifprintf( fp, indent, "num_ind_sub = %"PRIu8"\n", num_ind_sub );
582 data += 2;
583 for( int i = 0; i <= num_ind_sub; i++ )
585 lsmash_ifprintf( fp, indent, "independent_substream[%d]\n", i );
586 int sub_indent = indent + 1;
587 uint8_t fscod = (data[0] >> 6) & 0x03;
588 uint8_t bsid = (data[0] >> 1) & 0x1F;
589 uint8_t bsmod = ((data[0] & 0x01) << 4) | ((data[1] >> 4) & 0x0F);
590 uint8_t acmod = (data[1] >> 1) & 0x07;
591 uint8_t lfeon = data[1] & 0x01;
592 uint8_t num_dep_sub = (data[2] >> 1) & 0x0F;
593 if( fscod != 0x03 )
594 lsmash_ifprintf( fp, sub_indent, "fscod = %"PRIu8" (%"PRIu32" Hz)\n", fscod, ac3_sample_rate_table[fscod] );
595 else
596 lsmash_ifprintf( fp, sub_indent, "fscod = 0x03 (reduced sample rate)\n" );
597 lsmash_ifprintf( fp, sub_indent, "bsid = %"PRIu8"\n", bsid );
598 if( bsmod < 0x08 )
599 lsmash_ifprintf( fp, sub_indent, "bsmod = %"PRIu8" (%s)\n", bsmod, bit_stream_mode[bsmod + (acmod == 0x01 ? 1 : acmod > 0x01 ? 2 : 0)] );
600 else
601 lsmash_ifprintf( fp, sub_indent, "bsmod = %"PRIu8" (Undefined service)\n" );
602 lsmash_ifprintf( fp, sub_indent, "acmod = %"PRIu8" (%s)\n", acmod, audio_coding_mode[acmod + (bsmod == 0x07 ? 8 : 0)] );
603 lsmash_ifprintf( fp, sub_indent, "lfeon = %s\n", lfeon ? "1 (LFE)" : "0" );
604 lsmash_ifprintf( fp, sub_indent, "num_dep_sub = %"PRIu8"\n", num_dep_sub );
605 data += 3;
606 if( num_dep_sub > 0 )
608 static const char *channel_location[] =
610 "LFE2",
611 "Cvh",
612 "Lvh/Rvh pair",
613 "Lw/Rw pair",
614 "Lsd/Rsd pair",
615 "Ts",
616 "Cs",
617 "Lrs/Rrs pair",
618 "Lc/Rc pair"
620 uint16_t chan_loc = ((data[-1] & 0x01) << 8) | data[0];
621 lsmash_ifprintf( fp, sub_indent, "chan_loc = 0x%04"PRIu16"\n", chan_loc );
622 for( int j = 0; j < 9; j++ )
623 if( (chan_loc >> j & 0x01) )
624 lsmash_ifprintf( fp, sub_indent + 1, "%s\n", channel_location[j] );
625 data += 1;
627 else
628 lsmash_ifprintf( fp, sub_indent, "reserved = %"PRIu8"\n", data[2] & 0x01 );
630 return 0;
633 #undef EAC3_SPECIFIC_BOX_MIN_LENGTH