.gitignore: Add version script.
[L-SMASH.git] / codecs / a52.c
blob52fbc9d5688a7fc79d4df754041177a124c450e9
1 /*****************************************************************************
2 * a52.c:
3 *****************************************************************************
4 * Copyright (C) 2012-2015 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 "common/internal.h" /* must be placed first */
25 #include <stdlib.h>
26 #include <string.h>
27 #include <inttypes.h>
29 #include "core/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 const uint32_t ac3_sample_rate_table [4] = { 48000, 44100, 32000, 0 };
75 const uint32_t ac3_channel_count_table[8] = { 2, 1, 2, 3, 3, 4, 4, 5 };
77 uint32_t ac3_get_sample_rate( lsmash_ac3_specific_parameters_t *dac3_param )
79 /* The value 3 (or 0b11) of fscod is reserved. */
80 uint32_t samplerate = ac3_sample_rate_table[ dac3_param->fscod ];
81 if( samplerate == 0 )
82 lsmash_log( NULL, LSMASH_LOG_WARNING, "Unknown sampling rate is detected.\n" );
83 return samplerate;
86 #if 0
87 /* FIXME: though this table is for AC-3 in QTFF, we don't support it yet since the structure of CODEC specific info is unknown.
88 * ChannelLayout is given by ac3_channel_layout_table[ acmod ][ lfeon ]. */
89 static const lsmash_channel_layout_tag ac3_channel_layout_table[8][2] =
91 /* LFE: off LFE: on */
92 { QT_CHANNEL_LAYOUT_UNKNOWN, QT_CHANNEL_LAYOUT_UNKNOWN }, /* FIXME: dual mono */
93 { QT_CHANNEL_LAYOUT_MONO, QT_CHANNEL_LAYOUT_AC3_1_0_1 },
94 { QT_CHANNEL_LAYOUT_STEREO, QT_CHANNEL_LAYOUT_DVD_4 },
95 { QT_CHANNEL_LAYOUT_AC3_3_0, QT_CHANNEL_LAYOUT_AC3_3_0_1 },
96 { QT_CHANNEL_LAYOUT_DVD_2, QT_CHANNEL_LAYOUT_AC3_2_1_1 },
97 { QT_CHANNEL_LAYOUT_AC3_3_1, QT_CHANNEL_LAYOUT_AC3_3_1_1 },
98 { QT_CHANNEL_LAYOUT_DVD_3, QT_CHANNEL_LAYOUT_DVD_18 },
99 { QT_CHANNEL_LAYOUT_MPEG_5_0_C, QT_CHANNEL_LAYOUT_MPEG_5_1_C }
101 #endif
103 uint8_t *lsmash_create_ac3_specific_info( lsmash_ac3_specific_parameters_t *param, uint32_t *data_length )
105 lsmash_bits_t bits = { 0 };
106 lsmash_bs_t bs = { 0 };
107 lsmash_bits_init( &bits, &bs );
108 uint8_t buffer[AC3_SPECIFIC_BOX_LENGTH] = { 0 };
109 bs.buffer.data = buffer;
110 bs.buffer.alloc = AC3_SPECIFIC_BOX_LENGTH;
111 lsmash_bits_put( &bits, 32, AC3_SPECIFIC_BOX_LENGTH ); /* box size */
112 lsmash_bits_put( &bits, 32, ISOM_BOX_TYPE_DAC3.fourcc ); /* box type: 'dac3' */
113 lsmash_bits_put( &bits, 2, param->fscod );
114 lsmash_bits_put( &bits, 5, param->bsid );
115 lsmash_bits_put( &bits, 3, param->bsmod );
116 lsmash_bits_put( &bits, 3, param->acmod );
117 lsmash_bits_put( &bits, 1, param->lfeon );
118 lsmash_bits_put( &bits, 5, param->frmsizecod >> 1 );
119 lsmash_bits_put( &bits, 5, 0 );
120 uint8_t *data = lsmash_bits_export_data( &bits, data_length );
121 lsmash_bits_empty( &bits );
122 return data;
125 int lsmash_setup_ac3_specific_parameters_from_syncframe( lsmash_ac3_specific_parameters_t *param, uint8_t *data, uint32_t data_length )
127 if( !data || data_length < AC3_MIN_SYNCFRAME_LENGTH )
128 return LSMASH_ERR_FUNCTION_PARAM;
129 /* Check a syncword. */
130 if( data[0] != 0x0b
131 || data[1] != 0x77 )
132 return LSMASH_ERR_INVALID_DATA;
133 lsmash_bits_t bits = { 0 };
134 lsmash_bs_t bs = { 0 };
135 uint8_t buffer[AC3_MAX_SYNCFRAME_LENGTH] = { 0 };
136 bs.buffer.data = buffer;
137 bs.buffer.store = data_length;
138 bs.buffer.alloc = AC3_MAX_SYNCFRAME_LENGTH;
139 ac3_info_t info = { .bits = &bits };
140 lsmash_bits_init( &bits, &bs );
141 memcpy( buffer, data, LSMASH_MIN( data_length, AC3_MAX_SYNCFRAME_LENGTH ) );
142 int err = ac3_parse_syncframe_header( &info );
143 if( err < 0 )
144 return err;
145 *param = info.dac3_param;
146 return 0;
149 static int ac3_check_syncframe_header( lsmash_ac3_specific_parameters_t *param )
151 if( param->fscod == 0x3 )
152 return LSMASH_ERR_INVALID_DATA; /* unknown Sample Rate Code */
153 if( param->frmsizecod > 0x25 )
154 return LSMASH_ERR_INVALID_DATA; /* unknown Frame Size Code */
155 if( param->bsid >= 10 )
156 return LSMASH_ERR_INVALID_DATA; /* might be EAC-3 */
157 return 0;
160 int ac3_parse_syncframe_header( ac3_info_t *info )
162 lsmash_bits_t *bits = info->bits;
163 lsmash_ac3_specific_parameters_t *param = &info->dac3_param;
164 lsmash_bits_get( bits, 32 ); /* syncword + crc1 */
165 param->fscod = lsmash_bits_get( bits, 2 );
166 param->frmsizecod = lsmash_bits_get( bits, 6 );
167 param->bsid = lsmash_bits_get( bits, 5 );
168 param->bsmod = lsmash_bits_get( bits, 3 );
169 param->acmod = lsmash_bits_get( bits, 3 );
170 if( (param->acmod & 0x01) && (param->acmod != 0x01) )
171 lsmash_bits_get( bits, 2 ); /* cmixlev */
172 if( param->acmod & 0x04 )
173 lsmash_bits_get( bits, 2 ); /* surmixlev */
174 if( param->acmod == 0x02 )
175 lsmash_bits_get( bits, 2 ); /* dsurmod */
176 param->lfeon = lsmash_bits_get( bits, 1 );
177 lsmash_bits_get_align( bits );
178 return ac3_check_syncframe_header( param );
181 int ac3_construct_specific_parameters( lsmash_codec_specific_t *dst, lsmash_codec_specific_t *src )
183 assert( dst && dst->data.structured && src && src->data.unstructured );
184 if( src->size < AC3_SPECIFIC_BOX_LENGTH )
185 return LSMASH_ERR_INVALID_DATA;
186 lsmash_ac3_specific_parameters_t *param = (lsmash_ac3_specific_parameters_t *)dst->data.structured;
187 uint8_t *data = src->data.unstructured;
188 uint64_t size = LSMASH_GET_BE32( data );
189 data += ISOM_BASEBOX_COMMON_SIZE;
190 if( size == 1 )
192 size = LSMASH_GET_BE64( data );
193 data += 8;
195 if( size != src->size )
196 return LSMASH_ERR_INVALID_DATA;
197 param->fscod = (data[0] >> 6) & 0x03; /* XXxx xxxx xxxx xxxx xxxx xxxx */
198 param->bsid = (data[0] >> 1) & 0x1F; /* xxXX XXXx xxxx xxxx xxxx xxxx */
199 param->bsmod = ((data[0] & 0x01) << 2) | ((data[2] >> 6) & 0x03); /* xxxx xxxX XXxx xxxx xxxx xxxx */
200 param->acmod = (data[1] >> 3) & 0x07; /* xxxx xxxx xxXX Xxxx xxxx xxxx */
201 param->lfeon = (data[1] >> 2) & 0x01; /* xxxx xxxx xxxx xXxx xxxx xxxx */
202 param->frmsizecod = ((data[1] & 0x03) << 3) | ((data[3] >> 5) & 0x07); /* xxxx xxxx xxxx xxXX XXXx xxxx */
203 param->frmsizecod <<= 1;
204 return 0;
207 int ac3_print_codec_specific( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
209 assert( fp && file && box && (box->manager & LSMASH_BINARY_CODED_BOX) );
210 int indent = level;
211 lsmash_ifprintf( fp, indent++, "[%s: AC3 Specific Box]\n", isom_4cc2str( box->type.fourcc ) );
212 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", box->pos );
213 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", box->size );
214 if( box->size < AC3_SPECIFIC_BOX_LENGTH )
215 return LSMASH_ERR_INVALID_DATA;
216 uint8_t *data = box->binary;
217 isom_skip_box_common( &data );
218 uint8_t fscod = (data[0] >> 6) & 0x03;
219 uint8_t bsid = (data[0] >> 1) & 0x1F;
220 uint8_t bsmod = ((data[0] & 0x01) << 2) | ((data[1] >> 6) & 0x03);
221 uint8_t acmod = (data[1] >> 3) & 0x07;
222 uint8_t lfeon = (data[1] >> 2) & 0x01;
223 uint8_t bit_rate_code = ((data[1] & 0x03) << 3) | ((data[2] >> 5) & 0x07);
224 if( fscod != 0x03 )
225 lsmash_ifprintf( fp, indent, "fscod = %"PRIu8" (%"PRIu32" Hz)\n", fscod, ac3_sample_rate_table[fscod] );
226 else
227 lsmash_ifprintf( fp, indent, "fscod = 0x03 (reserved)\n" );
228 lsmash_ifprintf( fp, indent, "bsid = %"PRIu8"\n", bsid );
229 lsmash_ifprintf( fp, indent, "bsmod = %"PRIu8" (%s)\n", bsmod, bit_stream_mode[bsmod + (acmod == 0x01 ? 1 : acmod > 0x01 ? 2 : 0)] );
230 lsmash_ifprintf( fp, indent, "acmod = %"PRIu8" (%s)\n", acmod, audio_coding_mode[acmod + (bsmod == 0x07 ? 8 : 0)] );
231 lsmash_ifprintf( fp, indent, "lfeon = %s\n", lfeon ? "1 (LFE)" : "0" );
232 static const uint32_t bit_rate[] =
234 32, 40, 48, 56, 64, 80, 96, 112, 128,
235 160, 192, 224, 256, 320, 384, 448, 512, 576, 640,
236 0 /* undefined */
238 lsmash_ifprintf( fp, indent, "bit_rate_code = 0x%02"PRIx8" (%"PRIu32" kbit/s)\n", bit_rate_code, bit_rate[bit_rate_code] );
239 lsmash_ifprintf( fp, indent, "reserved = 0x%02"PRIx8"\n", data[2] & 0x1F );
240 return 0;
243 #undef AC3_SPECIFIC_BOX_LENGTH
245 /***************************************************************************
246 Enhanced AC-3 tools
247 ETSI TS 102 366 V1.2.1 (2008-08)
248 ***************************************************************************/
250 const uint8_t eac3_audio_block_table[4] = { 1, 2, 3, 6 };
252 uint8_t *lsmash_create_eac3_specific_info( lsmash_eac3_specific_parameters_t *param, uint32_t *data_length )
254 #define EAC3_SPECIFIC_BOX_MAX_LENGTH 42
255 if( param->num_ind_sub > 7 )
256 return NULL;
257 lsmash_bits_t bits = { 0 };
258 lsmash_bs_t bs = { 0 };
259 lsmash_bits_init( &bits, &bs );
260 uint8_t buffer[EAC3_SPECIFIC_BOX_MAX_LENGTH] = { 0 };
261 bs.buffer.data = buffer;
262 bs.buffer.alloc = EAC3_SPECIFIC_BOX_MAX_LENGTH;
263 lsmash_bits_put( &bits, 32, 0 ); /* box size */
264 lsmash_bits_put( &bits, 32, ISOM_BOX_TYPE_DEC3.fourcc ); /* box type: 'dec3' */
265 lsmash_bits_put( &bits, 13, param->data_rate ); /* data_rate; setup by isom_update_bitrate_description */
266 lsmash_bits_put( &bits, 3, param->num_ind_sub );
267 /* Apparently, the condition of this loop defined in ETSI TS 102 366 V1.2.1 (2008-08) is wrong. */
268 for( int i = 0; i <= param->num_ind_sub; i++ )
270 lsmash_eac3_substream_info_t *independent_info = &param->independent_info[i];
271 lsmash_bits_put( &bits, 2, independent_info->fscod );
272 lsmash_bits_put( &bits, 5, independent_info->bsid );
273 lsmash_bits_put( &bits, 5, independent_info->bsmod );
274 lsmash_bits_put( &bits, 3, independent_info->acmod );
275 lsmash_bits_put( &bits, 1, independent_info->lfeon );
276 lsmash_bits_put( &bits, 3, 0 ); /* reserved */
277 lsmash_bits_put( &bits, 4, independent_info->num_dep_sub );
278 if( independent_info->num_dep_sub > 0 )
279 lsmash_bits_put( &bits, 9, independent_info->chan_loc );
280 else
281 lsmash_bits_put( &bits, 1, 0 ); /* reserved */
283 uint8_t *data = lsmash_bits_export_data( &bits, data_length );
284 lsmash_bits_empty( &bits );
285 /* Update box size. */
286 LSMASH_SET_BE32( data, *data_length );
287 return data;
288 #undef EAC3_SPECIFIC_BOX_MAX_LENGTH
291 /* Return -1 if incomplete Enhanced AC-3 sample is given. */
292 int lsmash_setup_eac3_specific_parameters_from_frame( lsmash_eac3_specific_parameters_t *param, uint8_t *data, uint32_t data_length )
294 if( !data || data_length < 5 )
295 return LSMASH_ERR_FUNCTION_PARAM;
296 lsmash_bits_t bits = { 0 };
297 lsmash_bs_t bs = { 0 };
298 uint8_t buffer[EAC3_MAX_SYNCFRAME_LENGTH] = { 0 };
299 bs.buffer.data = buffer;
300 bs.buffer.store = data_length;
301 bs.buffer.alloc = EAC3_MAX_SYNCFRAME_LENGTH;
302 eac3_info_t *info = &(eac3_info_t){ .bits = &bits };
303 lsmash_bits_init( &bits, &bs );
304 memcpy( buffer, data, LSMASH_MIN( data_length, EAC3_MAX_SYNCFRAME_LENGTH ) );
305 uint64_t next_frame_pos = 0;
306 while( 1 )
308 /* Seek to the head of the next syncframe. */
309 bs.buffer.pos = LSMASH_MIN( data_length, next_frame_pos );
310 /* Check the remainder length of the input data.
311 * If there is enough length, then parse the syncframe in it.
312 * The length 5 is the required byte length to get frame size. */
313 uint64_t remain_size = lsmash_bs_get_remaining_buffer_size( &bs );
314 if( bs.eob || (bs.eof && remain_size < 5) )
315 goto setup_param; /* No more valid data. */
316 /* Check the syncword. */
317 if( lsmash_bs_show_byte( &bs, 0 ) != 0x0b
318 || lsmash_bs_show_byte( &bs, 1 ) != 0x77 )
319 goto setup_param;
320 /* Parse syncframe. */
321 info->frame_size = 0;
322 if( eac3_parse_syncframe( info ) < 0 )
323 goto setup_param;
324 if( remain_size < info->frame_size )
325 goto setup_param;
326 int independent = info->strmtyp != 0x1;
327 if( independent && info->substreamid == 0x0 )
329 if( info->number_of_audio_blocks == 6 )
331 /* Encountered the first syncframe of the next access unit. */
332 info->number_of_audio_blocks = 0;
333 goto setup_param;
335 else if( info->number_of_audio_blocks > 6 )
336 goto setup_param;
337 info->number_of_audio_blocks += eac3_audio_block_table[ info->numblkscod ];
338 info->number_of_independent_substreams = 0;
340 else if( info->syncframe_count == 0 )
341 /* The first syncframe in an AU must be independent and assigned substream ID 0. */
342 return LSMASH_ERR_INVALID_DATA;
343 if( independent )
344 info->independent_info[info->number_of_independent_substreams ++].num_dep_sub = 0;
345 else
346 ++ info->independent_info[info->number_of_independent_substreams - 1].num_dep_sub;
347 next_frame_pos += info->frame_size;
348 ++ info->syncframe_count;
350 setup_param:
351 if( info->number_of_independent_substreams == 0 || info->number_of_independent_substreams > 8 )
352 return LSMASH_ERR_INVALID_DATA;
353 if( !info->dec3_param_initialized )
354 eac3_update_specific_param( info );
355 *param = info->dec3_param;
356 return info->number_of_audio_blocks == 6 ? 0 : LSMASH_ERR_INVALID_DATA;
359 uint16_t lsmash_eac3_get_chan_loc_from_chanmap( uint16_t chanmap )
361 return ((chanmap & 0x7f8) >> 2) | ((chanmap & 0x2) >> 1);
364 static int eac3_check_syncframe_header( eac3_info_t *info )
366 if( info->strmtyp == 0x3 )
367 return LSMASH_ERR_INVALID_DATA; /* unknown Stream type */
368 lsmash_eac3_substream_info_t *substream_info;
369 if( info->strmtyp != 0x1 )
370 substream_info = &info->independent_info[ info->current_independent_substream_id ];
371 else
372 substream_info = &info->dependent_info;
373 if( substream_info->fscod == 0x3 && info->fscod2 == 0x3 )
374 return LSMASH_ERR_INVALID_DATA; /* unknown Sample Rate Code */
375 if( substream_info->bsid < 10 || substream_info->bsid > 16 )
376 return LSMASH_ERR_INVALID_DATA; /* not EAC-3 */
377 return 0;
380 int eac3_parse_syncframe( eac3_info_t *info )
382 lsmash_bits_t *bits = info->bits;
383 lsmash_bits_get( bits, 16 ); /* syncword (16) */
384 info->strmtyp = lsmash_bits_get( bits, 2 ); /* strmtyp (2) */
385 info->substreamid = lsmash_bits_get( bits, 3 ); /* substreamid (3) */
386 lsmash_eac3_substream_info_t *substream_info;
387 if( info->strmtyp != 0x1 )
389 if( info->substreamid == 0x0 && info->number_of_independent_substreams )
390 eac3_update_specific_param( info );
391 info->current_independent_substream_id = info->substreamid;
392 substream_info = &info->independent_info[ info->current_independent_substream_id ];
393 substream_info->chan_loc = 0;
395 else
396 substream_info = &info->dependent_info;
397 info->frame_size = 2 * (lsmash_bits_get( bits, 11 ) + 1); /* frmsiz (11) */
398 substream_info->fscod = lsmash_bits_get( bits, 2 ); /* fscod (2) */
399 if( substream_info->fscod == 0x3 )
401 info->fscod2 = lsmash_bits_get( bits, 2 ); /* fscod2 (2) */
402 info->numblkscod = 0x3;
404 else
405 info->numblkscod = lsmash_bits_get( bits, 2 ); /* numblkscod (2) */
406 substream_info->acmod = lsmash_bits_get( bits, 3 ); /* acmod (3) */
407 substream_info->lfeon = lsmash_bits_get( bits, 1 ); /* lfeon (1) */
408 substream_info->bsid = lsmash_bits_get( bits, 5 ); /* bsid (5) */
409 lsmash_bits_get( bits, 5 ); /* dialnorm (5) */
410 if( lsmash_bits_get( bits, 1 ) ) /* compre (1) */
411 lsmash_bits_get( bits, 8 ); /* compr (8) */
412 if( substream_info->acmod == 0x0 )
414 lsmash_bits_get( bits, 5 ); /* dialnorm2 (5) */
415 if( lsmash_bits_get( bits, 1 ) ) /* compre2 (1) */
416 lsmash_bits_get( bits, 8 ); /* compr2 (8) */
418 if( info->strmtyp == 0x1 && lsmash_bits_get( bits, 1 ) ) /* chanmape (1) */
420 uint16_t chanmap = lsmash_bits_get( bits, 16 ); /* chanmap (16) */
421 info->independent_info[ info->current_independent_substream_id ].chan_loc |= lsmash_eac3_get_chan_loc_from_chanmap( chanmap );
423 if( lsmash_bits_get( bits, 1 ) ) /* mixmdate (1) */
425 if( substream_info->acmod > 0x2 )
426 lsmash_bits_get( bits, 2 ); /* dmixmod (2) */
427 if( ((substream_info->acmod & 0x1) && (substream_info->acmod > 0x2)) || (substream_info->acmod & 0x4) )
428 lsmash_bits_get( bits, 6 ); /* ltrt[c/sur]mixlev (3)
429 * loro[c/sur]mixlev (3) */
430 if( substream_info->lfeon && lsmash_bits_get( bits, 1 ) ) /* lfemixlevcode (1) */
431 lsmash_bits_get( bits, 5 ); /* lfemixlevcod (5) */
432 if( info->strmtyp == 0x0 )
434 if( lsmash_bits_get( bits, 1 ) ) /* pgmscle (1) */
435 lsmash_bits_get( bits, 6 ); /* pgmscl (6) */
436 if( substream_info->acmod == 0x0 && lsmash_bits_get( bits, 1 ) ) /* pgmscle2 (1) */
437 lsmash_bits_get( bits, 6 ); /* pgmscl2 (6) */
438 if( lsmash_bits_get( bits, 1 ) ) /* extpgmscle (1) */
439 lsmash_bits_get( bits, 6 ); /* extpgmscl (6) */
440 uint8_t mixdef = lsmash_bits_get( bits, 2 ); /* mixdef (2) */
441 if( mixdef == 0x1 )
442 lsmash_bits_get( bits, 5 ); /* premixcmpsel (1)
443 * drcsrc (1)
444 * premixcmpscl (3) */
445 else if( mixdef == 0x2 )
446 lsmash_bits_get( bits, 12 ); /* mixdata (12) */
447 else if( mixdef == 0x3 )
449 uint8_t mixdeflen = lsmash_bits_get( bits, 5 ); /* mixdeflen (5) */
450 lsmash_bits_get( bits, 8 * (mixdeflen + 2) ); /* mixdata (8 * (mixdeflen + 2))
451 * mixdatafill (0-7) */
453 if( substream_info->acmod < 0x2 )
455 if( lsmash_bits_get( bits, 1 ) ) /* paninfoe (1) */
456 lsmash_bits_get( bits, 14 ); /* panmean (8)
457 * paninfo (6) */
458 if( substream_info->acmod == 0x0 && lsmash_bits_get( bits, 1 ) ) /* paninfo2e (1) */
459 lsmash_bits_get( bits, 14 ); /* panmean2 (8)
460 * paninfo2 (6) */
462 if( lsmash_bits_get( bits, 1 ) ) /* frmmixcfginfoe (1) */
464 if( info->numblkscod == 0x0 )
465 lsmash_bits_get( bits, 5 ); /* blkmixcfginfo[0] (5) */
466 else
468 int number_of_blocks_per_syncframe = ((int []){ 1, 2, 3, 6 })[ info->numblkscod ];
469 for( int blk = 0; blk < number_of_blocks_per_syncframe; blk++ )
470 if( lsmash_bits_get( bits, 1 ) ) /* blkmixcfginfoe (1)*/
471 lsmash_bits_get( bits, 5 ); /* blkmixcfginfo[blk] (5) */
476 if( lsmash_bits_get( bits, 1 ) ) /* infomdate (1) */
478 substream_info->bsmod = lsmash_bits_get( bits, 3 ); /* bsmod (3) */
479 lsmash_bits_get( bits, 1 ); /* copyrightb (1) */
480 lsmash_bits_get( bits, 1 ); /* origbs (1) */
481 if( substream_info->acmod == 0x2 )
482 lsmash_bits_get( bits, 4 ); /* dsurmod (2)
483 * dheadphonmod (2) */
484 else if( substream_info->acmod >= 0x6 )
485 lsmash_bits_get( bits, 2 ); /* dsurexmod (2) */
486 if( lsmash_bits_get( bits, 1 ) ) /* audprodie (1) */
487 lsmash_bits_get( bits, 8 ); /* mixlevel (5)
488 * roomtyp (2)
489 * adconvtyp (1) */
490 if( substream_info->acmod == 0x0 && lsmash_bits_get( bits, 1 ) ) /* audprodie2 (1) */
491 lsmash_bits_get( bits, 8 ); /* mixlevel2 (5)
492 * roomtyp2 (2)
493 * adconvtyp2 (1) */
494 if( substream_info->fscod < 0x3 )
495 lsmash_bits_get( bits, 1 ); /* sourcefscod (1) */
497 else
498 substream_info->bsmod = 0;
499 if( info->strmtyp == 0x0 && info->numblkscod != 0x3 )
500 lsmash_bits_get( bits, 1 ); /* convsync (1) */
501 if( info->strmtyp == 0x2 )
503 int blkid;
504 if( info->numblkscod == 0x3 )
505 blkid = 1;
506 else
507 blkid = lsmash_bits_get( bits, 1 ); /* blkid (1) */
508 if( blkid )
509 lsmash_bits_get( bits, 6 ); /* frmsizecod (6) */
511 if( lsmash_bits_get( bits, 1 ) ) /* addbsie (1) */
513 uint8_t addbsil = lsmash_bits_get( bits, 6 ); /* addbsil (6) */
514 lsmash_bits_get( bits, (addbsil + 1) * 8 ); /* addbsi ((addbsil + 1) * 8) */
516 lsmash_bits_get_align( bits );
517 return eac3_check_syncframe_header( info );
520 void eac3_update_specific_param( eac3_info_t *info )
522 lsmash_eac3_specific_parameters_t *param = &info->dec3_param;
523 param->data_rate = 0;
524 param->num_ind_sub = info->number_of_independent_substreams - 1;
525 for( uint8_t i = 0; i <= param->num_ind_sub; i++ )
526 param->independent_info[i] = info->independent_info[i];
527 info->dec3_param_initialized = 1;
530 #define EAC3_SPECIFIC_BOX_MIN_LENGTH 13
532 int eac3_construct_specific_parameters( lsmash_codec_specific_t *dst, lsmash_codec_specific_t *src )
534 assert( dst && dst->data.structured && src && src->data.unstructured );
535 if( src->size < EAC3_SPECIFIC_BOX_MIN_LENGTH )
536 return LSMASH_ERR_INVALID_DATA;
537 lsmash_eac3_specific_parameters_t *param = (lsmash_eac3_specific_parameters_t *)dst->data.structured;
538 uint8_t *data = src->data.unstructured;
539 uint64_t size = LSMASH_GET_BE32( data );
540 data += ISOM_BASEBOX_COMMON_SIZE;
541 if( size == 1 )
543 size = LSMASH_GET_BE64( data );
544 data += 8;
546 if( size != src->size )
547 return LSMASH_ERR_INVALID_DATA;
548 param->data_rate = (data[0] << 5) | ((data[1] >> 3) & 0x1F); /* XXXX XXXX XXXX Xxxx */
549 param->num_ind_sub = data[1] & 0x07; /* xxxx xxxx xxxx xXXX */
550 data += 2;
551 size -= 2;
552 for( int i = 0; i <= param->num_ind_sub; i++ )
554 if( size < 3 )
555 return LSMASH_ERR_INVALID_DATA;
556 lsmash_eac3_substream_info_t *independent_info = &param->independent_info[i];
557 independent_info->fscod = (data[0] >> 6) & 0x03; /* XXxx xxxx xxxx xxxx xxxx xxxx */
558 independent_info->bsid = (data[0] >> 1) & 0x1F; /* xxXX XXXx xxxx xxxx xxxx xxxx */
559 independent_info->bsmod = ((data[0] & 0x01) << 4) | ((data[1] >> 4) & 0x0F); /* xxxx xxxX XXXX xxxx xxxx xxxx */
560 independent_info->acmod = (data[1] >> 1) & 0x07; /* xxxx xxxx xxxx XXXx xxxx xxxx */
561 independent_info->lfeon = data[1] & 0x01; /* xxxx xxxx xxxx xxxX xxxx xxxx */
562 independent_info->num_dep_sub = (data[2] >> 1) & 0x0F; /* xxxx xxxx xxxx xxxx xxxX XXXx */
563 data += 3;
564 size -= 3;
565 if( independent_info->num_dep_sub > 0 )
567 if( size < 1 )
568 return LSMASH_ERR_INVALID_DATA;
569 independent_info->chan_loc = ((data[-1] & 0x01) << 8) | data[0]; /* xxxx xxxX XXXX XXXX */
570 data += 1;
571 size -= 1;
574 return 0;
577 void eac3_update_sample_rate
579 uint32_t *frequency,
580 lsmash_eac3_specific_parameters_t *dec3_param,
581 uint8_t *fscod2
584 /* Additional independent substreams 1 to 7 must be encoded at the same sample rate as independent substream 0. */
585 uint32_t samplerate = ac3_sample_rate_table[ dec3_param->independent_info[0].fscod ];
586 if( samplerate == 0 && fscod2 )
587 /* The value 3 (or 0b11) of fscod2 is reserved. */
588 samplerate = ac3_sample_rate_table[ *fscod2 ] / 2;
589 if( samplerate != 0 )
590 *frequency = samplerate;
591 else
592 lsmash_log( NULL, LSMASH_LOG_WARNING, "Unknown sampling rate is detected.\n" );
595 #if 0
596 /* FIXME: though this table is for EAC-3 in QTFF, we don't support it yet since the structure of CODEC specific info is unknown. */
597 static void eac3_update_channel_layout
599 lsmash_channel_layout_tag *layout_tag,
600 lsmash_eac3_substream_info_t *independent_info
603 if( independent_info->chan_loc == 0 )
605 *layout_tag = ac3_channel_layout_table[ independent_info->acmod ][ independent_info->lfeon ];
606 return;
608 else if( independent_info->acmod != 0x7 )
610 *layout_tag = QT_CHANNEL_LAYOUT_UNKNOWN;
611 return;
613 /* OK. All L, C, R, Ls and Rs exsist. */
614 if( !independent_info->lfeon )
616 if( independent_info->chan_loc == 0x80 )
617 *layout_tag = QT_CHANNEL_LAYOUT_EAC_7_0_A;
618 else if( independent_info->chan_loc == 0x40 )
619 *layout_tag = QT_CHANNEL_LAYOUT_EAC_6_0_A;
620 else
621 *layout_tag = QT_CHANNEL_LAYOUT_UNKNOWN;
622 return;
624 /* Also LFE exsists. */
625 static const struct
627 uint16_t chan_loc;
628 lsmash_channel_layout_tag tag;
629 } eac3_channel_layout_table[]
631 { 0x100, QT_CHANNEL_LAYOUT_EAC3_7_1_B },
632 { 0x80, QT_CHANNEL_LAYOUT_EAC3_7_1_A },
633 { 0x40, QT_CHANNEL_LAYOUT_EAC3_6_1_A },
634 { 0x20, QT_CHANNEL_LAYOUT_EAC3_6_1_B },
635 { 0x10, QT_CHANNEL_LAYOUT_EAC3_7_1_C },
636 { 0x10, QT_CHANNEL_LAYOUT_EAC3_7_1_D },
637 { 0x4, QT_CHANNEL_LAYOUT_EAC3_7_1_E },
638 { 0x2, QT_CHANNEL_LAYOUT_EAC3_6_1_C },
639 { 0x60, QT_CHANNEL_LAYOUT_EAC3_7_1_F },
640 { 0x42, QT_CHANNEL_LAYOUT_EAC3_7_1_G },
641 { 0x22, QT_CHANNEL_LAYOUT_EAC3_7_1_H },
642 { 0 }
644 for( int i = 0; eac3_channel_layout_table[i].chan_loc; i++ )
645 if( independent_info->chan_loc == eac3_channel_layout_table[i].chan_loc )
647 *layout_tag = eac3_channel_layout_table[i].tag;
648 return;
650 *layout_tag = QT_CHANNEL_LAYOUT_UNKNOWN;
652 #endif
654 void eac3_update_channel_count
656 uint32_t *channels,
657 lsmash_eac3_specific_parameters_t *dec3_param
660 /* The default programme selection should always be Programme 1.
661 * Thus, pick the number of channels of Programme 1. */
662 lsmash_eac3_substream_info_t *independent_info = &dec3_param->independent_info[0];
663 *channels = ac3_channel_count_table[ independent_info->acmod ] /* L/C/R/Ls/Rs combination */
664 + 2 * !!(independent_info->chan_loc & 0x100) /* Lc/Rc pair */
665 + 2 * !!(independent_info->chan_loc & 0x80) /* Lrs/Rrs pair */
666 + !!(independent_info->chan_loc & 0x40) /* Cs */
667 + !!(independent_info->chan_loc & 0x20) /* Ts */
668 + 2 * !!(independent_info->chan_loc & 0x10) /* Lsd/Rsd pair */
669 + 2 * !!(independent_info->chan_loc & 0x8) /* Lw/Rw pair */
670 + 2 * !!(independent_info->chan_loc & 0x4) /* Lvh/Rvh pair */
671 + !!(independent_info->chan_loc & 0x2) /* Cvh */
672 + !!(independent_info->chan_loc & 0x1) /* LFE2 */
673 + independent_info->lfeon; /* LFE */
676 int eac3_print_codec_specific( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
678 assert( fp && file && box && (box->manager & LSMASH_BINARY_CODED_BOX) );
679 int indent = level;
680 lsmash_ifprintf( fp, indent++, "[%s: EC3 Specific Box]\n", isom_4cc2str( box->type.fourcc ) );
681 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", box->pos );
682 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", box->size );
683 if( box->size < EAC3_SPECIFIC_BOX_MIN_LENGTH )
684 return LSMASH_ERR_INVALID_DATA;
685 uint8_t *data = box->binary;
686 isom_skip_box_common( &data );
687 lsmash_ifprintf( fp, indent, "data_rate = %"PRIu16" kbit/s\n", (data[0] << 5) | ((data[1] >> 3) & 0x1F) );
688 uint8_t num_ind_sub = data[1] & 0x07;
689 lsmash_ifprintf( fp, indent, "num_ind_sub = %"PRIu8"\n", num_ind_sub );
690 data += 2;
691 for( int i = 0; i <= num_ind_sub; i++ )
693 lsmash_ifprintf( fp, indent, "independent_substream[%d]\n", i );
694 int sub_indent = indent + 1;
695 uint8_t fscod = (data[0] >> 6) & 0x03;
696 uint8_t bsid = (data[0] >> 1) & 0x1F;
697 uint8_t bsmod = ((data[0] & 0x01) << 4) | ((data[1] >> 4) & 0x0F);
698 uint8_t acmod = (data[1] >> 1) & 0x07;
699 uint8_t lfeon = data[1] & 0x01;
700 uint8_t num_dep_sub = (data[2] >> 1) & 0x0F;
701 if( fscod != 0x03 )
702 lsmash_ifprintf( fp, sub_indent, "fscod = %"PRIu8" (%"PRIu32" Hz)\n", fscod, ac3_sample_rate_table[fscod] );
703 else
704 lsmash_ifprintf( fp, sub_indent, "fscod = 0x03 (reduced sample rate)\n" );
705 lsmash_ifprintf( fp, sub_indent, "bsid = %"PRIu8"\n", bsid );
706 if( bsmod < 0x08 )
707 lsmash_ifprintf( fp, sub_indent, "bsmod = %"PRIu8" (%s)\n", bsmod, bit_stream_mode[bsmod + (acmod == 0x01 ? 1 : acmod > 0x01 ? 2 : 0)] );
708 else
709 lsmash_ifprintf( fp, sub_indent, "bsmod = %"PRIu8" (Undefined service)\n" );
710 lsmash_ifprintf( fp, sub_indent, "acmod = %"PRIu8" (%s)\n", acmod, audio_coding_mode[acmod + (bsmod == 0x07 ? 8 : 0)] );
711 lsmash_ifprintf( fp, sub_indent, "lfeon = %s\n", lfeon ? "1 (LFE)" : "0" );
712 lsmash_ifprintf( fp, sub_indent, "num_dep_sub = %"PRIu8"\n", num_dep_sub );
713 data += 3;
714 if( num_dep_sub > 0 )
716 static const char *channel_location[] =
718 "LFE2",
719 "Cvh",
720 "Lvh/Rvh pair",
721 "Lw/Rw pair",
722 "Lsd/Rsd pair",
723 "Ts",
724 "Cs",
725 "Lrs/Rrs pair",
726 "Lc/Rc pair"
728 uint16_t chan_loc = ((data[-1] & 0x01) << 8) | data[0];
729 lsmash_ifprintf( fp, sub_indent, "chan_loc = 0x%04"PRIx16"\n", chan_loc );
730 for( int j = 0; j < 9; j++ )
731 if( (chan_loc >> j & 0x01) )
732 lsmash_ifprintf( fp, sub_indent + 1, "%s\n", channel_location[j] );
733 data += 1;
735 else
736 lsmash_ifprintf( fp, sub_indent, "reserved = %"PRIu8"\n", data[2] & 0x01 );
738 return 0;
741 int eac3_update_bitrate( isom_stbl_t *stbl, isom_mdhd_t *mdhd, uint32_t sample_description_index )
743 isom_audio_entry_t *eac3 = (isom_audio_entry_t *)lsmash_get_entry_data( &stbl->stsd->list, sample_description_index );
744 if( !eac3 )
745 return LSMASH_ERR_INVALID_DATA;
746 isom_box_t *ext = isom_get_extension_box( &eac3->extensions, ISOM_BOX_TYPE_DEC3 );
747 if( !(ext && (ext->manager & LSMASH_BINARY_CODED_BOX) && ext->binary && ext->size >= 10) )
748 return LSMASH_ERR_INVALID_DATA;
749 uint16_t bitrate;
750 if( isom_is_variable_size( stbl ) )
752 uint32_t bufferSizeDB;
753 uint32_t maxBitrate;
754 uint32_t avgBitrate;
755 int err = isom_calculate_bitrate_description( stbl, mdhd, &bufferSizeDB, &maxBitrate, &avgBitrate, sample_description_index );
756 if( err < 0 )
757 return err;
758 bitrate = maxBitrate / 1000; /* Use maximum bitrate if VBR. */
760 else
761 bitrate = isom_get_first_sample_size( stbl ) * (eac3->samplerate >> 16) / 192000; /* 192000 == 1536 * 1000 / 8 */
762 uint8_t *exdata = ext->binary + 8;
763 exdata[0] = (bitrate >> 5) & 0xff;
764 exdata[1] = (bitrate & 0x1f) << 3;
765 return 0;
768 #undef EAC3_SPECIFIC_BOX_MIN_LENGTH