1 /*****************************************************************************
2 * a52_imp.c
3 *****************************************************************************
4 * Copyright (C) 2011-2017 L-SMASH project
5 *
6 * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
7 *
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.
11 *
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 *****************************************************************************/
20
21 /* This file is available under an ISC license. */
22
23 #include "common/internal.h" /* must be placed first */
24
25 #include <string.h>
26
27 #define LSMASH_IMPORTER_INTERNAL
28 #include "importer.h"
29
30 /***************************************************************************
31 AC-3 importer
32 ETSI TS 102 366 V1.2.1 (2008-08)
33 ***************************************************************************/
34 #include "codecs/a52.h"
35
36 #define AC3_SAMPLE_DURATION 1536 /* 256 (samples per audio block) * 6 (audio blocks) */
37
38 typedef struct
39 {
40 ac3_info_t info;
41 uint64_t next_frame_pos;
42 uint8_t *next_dac3;
43 uint8_t buffer[AC3_MAX_SYNCFRAME_LENGTH];
44 uint32_t au_number;
45 } ac3_importer_t;
46
remove_ac3_importer(ac3_importer_t * ac3_imp)47 static void remove_ac3_importer( ac3_importer_t *ac3_imp )
48 {
49 if( !ac3_imp )
50 return;
51 lsmash_bits_cleanup( ac3_imp->info.bits );
52 lsmash_free( ac3_imp );
53 }
54
create_ac3_importer(importer_t * importer)55 static ac3_importer_t *create_ac3_importer( importer_t *importer )
56 {
57 ac3_importer_t *ac3_imp = (ac3_importer_t *)lsmash_malloc_zero( sizeof(ac3_importer_t) );
58 if( !ac3_imp )
59 return NULL;
60 ac3_imp->info.bits = lsmash_bits_create( importer->bs );
61 if( !ac3_imp->info.bits )
62 {
63 lsmash_free( ac3_imp );
64 return NULL;
65 }
66 return ac3_imp;
67 }
68
ac3_importer_cleanup(importer_t * importer)69 static void ac3_importer_cleanup( importer_t *importer )
70 {
71 debug_if( importer && importer->info )
72 remove_ac3_importer( importer->info );
73 }
74
75 static const uint32_t ac3_frame_size_table[19][3] =
76 {
77 /* 48, 44.1, 32 */
78 { 128, 138, 192 },
79 { 160, 174, 240 },
80 { 192, 208, 288 },
81 { 224, 242, 336 },
82 { 256, 278, 384 },
83 { 320, 348, 480 },
84 { 384, 416, 576 },
85 { 448, 486, 672 },
86 { 512, 556, 768 },
87 { 640, 696, 960 },
88 { 768, 834, 1152 },
89 { 896, 974, 1344 },
90 { 1024, 1114, 1536 },
91 { 1280, 1392, 1920 },
92 { 1536, 1670, 2304 },
93 { 1792, 1950, 2688 },
94 { 2048, 2228, 3072 },
95 { 2304, 2506, 3456 },
96 { 2560, 2786, 3840 }
97 };
98
ac3_create_summary(ac3_info_t * info)99 static lsmash_audio_summary_t *ac3_create_summary( ac3_info_t *info )
100 {
101 lsmash_audio_summary_t *summary = (lsmash_audio_summary_t *)lsmash_create_summary( LSMASH_SUMMARY_TYPE_AUDIO );
102 if( !summary )
103 return NULL;
104 lsmash_ac3_specific_parameters_t *param = &info->dac3_param;
105 lsmash_codec_specific_t *cs = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_AC_3,
106 LSMASH_CODEC_SPECIFIC_FORMAT_UNSTRUCTURED );
107 if( !cs )
108 {
109 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
110 return NULL;
111 }
112 cs->data.unstructured = lsmash_create_ac3_specific_info( &info->dac3_param, &cs->size );
113 if( !cs->data.unstructured
114 || lsmash_list_add_entry( &summary->opaque->list, cs ) < 0 )
115 {
116 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
117 lsmash_destroy_codec_specific_data( cs );
118 return NULL;
119 }
120 summary->sample_type = ISOM_CODEC_TYPE_AC_3_AUDIO;
121 summary->max_au_length = AC3_MAX_SYNCFRAME_LENGTH;
122 summary->aot = MP4A_AUDIO_OBJECT_TYPE_NULL; /* no effect */
123 summary->frequency = ac3_get_sample_rate( param );
124 summary->channels = ac3_get_channel_count( param );
125 summary->sample_size = 16; /* no effect */
126 summary->samples_in_frame = AC3_SAMPLE_DURATION;
127 summary->sbr_mode = MP4A_AAC_SBR_NOT_SPECIFIED; /* no effect */
128 return summary;
129 }
130
ac3_compare_specific_param(lsmash_ac3_specific_parameters_t * a,lsmash_ac3_specific_parameters_t * b)131 static int ac3_compare_specific_param( lsmash_ac3_specific_parameters_t *a, lsmash_ac3_specific_parameters_t *b )
132 {
133 return (a->fscod != b->fscod)
134 || (a->bsid != b->bsid)
135 || (a->bsmod != b->bsmod)
136 || (a->acmod != b->acmod)
137 || (a->lfeon != b->lfeon)
138 || ((a->frmsizecod >> 1) != (b->frmsizecod >> 1));
139 }
140
ac3_buffer_frame(uint8_t * buffer,lsmash_bs_t * bs)141 static int ac3_buffer_frame( uint8_t *buffer, lsmash_bs_t *bs )
142 {
143 uint64_t remain_size = lsmash_bs_get_remaining_buffer_size( bs );
144 if( remain_size < AC3_MAX_SYNCFRAME_LENGTH )
145 {
146 int err = lsmash_bs_read( bs, bs->buffer.max_size );
147 if( err < 0 )
148 return err;
149 remain_size = lsmash_bs_get_remaining_buffer_size( bs );
150 }
151 uint64_t copy_size = LSMASH_MIN( remain_size, AC3_MAX_SYNCFRAME_LENGTH );
152 memcpy( buffer, lsmash_bs_get_buffer_data( bs ), copy_size );
153 return 0;
154 }
155
ac3_importer_get_accessunit(importer_t * importer,uint32_t track_number,lsmash_sample_t ** p_sample)156 static int ac3_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t **p_sample )
157 {
158 if( !importer->info )
159 return LSMASH_ERR_NAMELESS;
160 if( track_number != 1 )
161 return LSMASH_ERR_FUNCTION_PARAM;
162 lsmash_audio_summary_t *summary = (lsmash_audio_summary_t *)lsmash_list_get_entry_data( importer->summaries, track_number );
163 if( !summary )
164 return LSMASH_ERR_NAMELESS;
165 ac3_importer_t *ac3_imp = (ac3_importer_t *)importer->info;
166 ac3_info_t *info = &ac3_imp->info;
167 importer_status current_status = importer->status;
168 if( current_status == IMPORTER_ERROR )
169 return LSMASH_ERR_NAMELESS;
170 if( current_status == IMPORTER_EOF )
171 return IMPORTER_EOF;
172 lsmash_ac3_specific_parameters_t *param = &info->dac3_param;
173 uint32_t frame_size = ac3_frame_size_table[ param->frmsizecod >> 1 ][ param->fscod ];
174 if( param->fscod == 0x1 && param->frmsizecod & 0x1 )
175 frame_size += 2;
176 if( current_status == IMPORTER_CHANGE )
177 {
178 lsmash_codec_specific_t *cs = isom_get_codec_specific( summary->opaque, LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_AC_3 );
179 if( cs )
180 {
181 cs->destruct( cs->data.unstructured );
182 cs->data.unstructured = ac3_imp->next_dac3;
183 }
184 summary->frequency = ac3_get_sample_rate( param );
185 summary->channels = ac3_get_channel_count( param );
186 //summary->layout_tag = ac3_channel_layout_table[ param->acmod ][ param->lfeon ];
187 }
188 lsmash_sample_t *sample = lsmash_create_sample( frame_size );
189 if( !sample )
190 return LSMASH_ERR_MEMORY_ALLOC;
191 *p_sample = sample;
192 memcpy( sample->data, ac3_imp->buffer, frame_size );
193 sample->length = frame_size;
194 sample->dts = ac3_imp->au_number++ * summary->samples_in_frame;
195 sample->cts = sample->dts;
196 sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC;
197 sample->prop.pre_roll.distance = 1; /* MDCT */
198 lsmash_bs_t *bs = info->bits->bs;
199 ac3_imp->next_frame_pos += frame_size;
200 lsmash_bs_read_seek( bs, ac3_imp->next_frame_pos, SEEK_SET );
201 uint8_t syncword[2] =
202 {
203 lsmash_bs_show_byte( bs, 0 ),
204 lsmash_bs_show_byte( bs, 1 )
205 };
206 if( bs->eob || (bs->eof && 0 == lsmash_bs_get_remaining_buffer_size( bs )) )
207 importer->status = IMPORTER_EOF;
208 else
209 {
210 /* Parse the next syncframe header. */
211 if( syncword[0] != 0x0b
212 || syncword[1] != 0x77
213 || ac3_buffer_frame( ac3_imp->buffer, bs ) < 0 )
214 {
215 importer->status = IMPORTER_ERROR;
216 return current_status;
217 }
218 lsmash_ac3_specific_parameters_t current_param = info->dac3_param;
219 ac3_parse_syncframe_header( info );
220 if( ac3_compare_specific_param( ¤t_param, &info->dac3_param ) )
221 {
222 uint32_t dummy;
223 uint8_t *dac3 = lsmash_create_ac3_specific_info( &info->dac3_param, &dummy );
224 if( !dac3 )
225 {
226 importer->status = IMPORTER_ERROR;
227 return current_status;
228 }
229 ac3_imp->next_dac3 = dac3;
230 importer->status = IMPORTER_CHANGE;
231 }
232 else
233 importer->status = IMPORTER_OK;
234 }
235 return current_status;
236 }
237
ac3_importer_probe(importer_t * importer)238 static int ac3_importer_probe( importer_t *importer )
239 {
240 ac3_importer_t *ac3_imp = create_ac3_importer( importer );
241 if( !ac3_imp )
242 return LSMASH_ERR_MEMORY_ALLOC;
243 lsmash_bits_t *bits = ac3_imp->info.bits;
244 lsmash_bs_t *bs = bits->bs;
245 bs->buffer.max_size = AC3_MAX_SYNCFRAME_LENGTH;
246 /* Check the syncword and parse the syncframe header */
247 int err;
248 if( lsmash_bs_show_byte( bs, 0 ) != 0x0b
249 || lsmash_bs_show_byte( bs, 1 ) != 0x77 )
250 {
251 err = LSMASH_ERR_INVALID_DATA;
252 goto fail;
253 }
254 if( (err = ac3_buffer_frame( ac3_imp->buffer, bs )) < 0
255 || (err = ac3_parse_syncframe_header( &ac3_imp->info )) < 0 )
256 goto fail;
257 lsmash_audio_summary_t *summary = ac3_create_summary( &ac3_imp->info );
258 if( !summary )
259 {
260 err = LSMASH_ERR_NAMELESS;
261 goto fail;
262 }
263 if( lsmash_list_add_entry( importer->summaries, summary ) < 0 )
264 {
265 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
266 err = LSMASH_ERR_MEMORY_ALLOC;
267 goto fail;
268 }
269 ac3_imp->au_number = 0;
270 importer->info = ac3_imp;
271 importer->status = IMPORTER_OK;
272 return 0;
273 fail:
274 remove_ac3_importer( ac3_imp );
275 return err;
276 }
277
ac3_importer_get_last_delta(importer_t * importer,uint32_t track_number)278 static uint32_t ac3_importer_get_last_delta( importer_t *importer, uint32_t track_number )
279 {
280 debug_if( !importer || !importer->info )
281 return 0;
282 ac3_importer_t *ac3_imp = (ac3_importer_t *)importer->info;
283 if( !ac3_imp || track_number != 1 || importer->status != IMPORTER_EOF )
284 return 0;
285 return AC3_SAMPLE_DURATION;
286 }
287
288 const importer_functions ac3_importer =
289 {
290 { "AC-3" },
291 1,
292 ac3_importer_probe,
293 ac3_importer_get_accessunit,
294 ac3_importer_get_last_delta,
295 ac3_importer_cleanup
296 };
297
298 /***************************************************************************
299 Enhanced AC-3 importer
300 ETSI TS 102 366 V1.2.1 (2008-08)
301 ***************************************************************************/
302 #define EAC3_MIN_SAMPLE_DURATION 256
303
304 typedef struct
305 {
306 eac3_info_t info;
307 uint64_t next_frame_pos;
308 uint32_t next_dec3_length;
309 uint8_t *next_dec3;
310 uint8_t current_fscod2;
311 uint8_t buffer[EAC3_MAX_SYNCFRAME_LENGTH];
312 lsmash_multiple_buffers_t *au_buffers;
313 uint8_t *au;
314 uint8_t *incomplete_au;
315 uint32_t au_length;
316 uint32_t incomplete_au_length;
317 uint32_t au_number;
318 uint32_t syncframe_count_in_au;
319 } eac3_importer_t;
320
remove_eac3_importer(eac3_importer_t * eac3_imp)321 static void remove_eac3_importer( eac3_importer_t *eac3_imp )
322 {
323 if( !eac3_imp )
324 return;
325 lsmash_destroy_multiple_buffers( eac3_imp->au_buffers );
326 lsmash_bits_cleanup( eac3_imp->info.bits );
327 lsmash_free( eac3_imp );
328 }
329
create_eac3_importer(importer_t * importer)330 static eac3_importer_t *create_eac3_importer( importer_t *importer )
331 {
332 eac3_importer_t *eac3_imp = (eac3_importer_t *)lsmash_malloc_zero( sizeof(eac3_importer_t) );
333 if( !eac3_imp )
334 return NULL;
335 eac3_info_t *info = &eac3_imp->info;
336 info->bits = lsmash_bits_create( importer->bs );
337 if( !info->bits )
338 {
339 lsmash_free( eac3_imp );
340 return NULL;
341 }
342 eac3_imp->au_buffers = lsmash_create_multiple_buffers( 2, EAC3_MAX_SYNCFRAME_LENGTH );
343 if( !eac3_imp->au_buffers )
344 {
345 lsmash_bits_cleanup( info->bits );
346 lsmash_free( eac3_imp );
347 return NULL;
348 }
349 eac3_imp->au = lsmash_withdraw_buffer( eac3_imp->au_buffers, 1 );
350 eac3_imp->incomplete_au = lsmash_withdraw_buffer( eac3_imp->au_buffers, 2 );
351 return eac3_imp;
352 }
353
eac3_importer_cleanup(importer_t * importer)354 static void eac3_importer_cleanup( importer_t *importer )
355 {
356 debug_if( importer && importer->info )
357 remove_eac3_importer( importer->info );
358 }
359
eac3_importer_get_next_accessunit_internal(importer_t * importer)360 static int eac3_importer_get_next_accessunit_internal( importer_t *importer )
361 {
362 int au_completed = 0;
363 eac3_importer_t *eac3_imp = (eac3_importer_t *)importer->info;
364 eac3_info_t *info = &eac3_imp->info;
365 lsmash_bs_t *bs = info->bits->bs;
366 while( !au_completed )
367 {
368 /* Read data from the stream if needed. */
369 eac3_imp->next_frame_pos += info->frame_size;
370 lsmash_bs_read_seek( bs, eac3_imp->next_frame_pos, SEEK_SET );
371 uint64_t remain_size = lsmash_bs_get_remaining_buffer_size( bs );
372 if( remain_size < EAC3_MAX_SYNCFRAME_LENGTH )
373 {
374 int err = lsmash_bs_read( bs, bs->buffer.max_size );
375 if( err < 0 )
376 {
377 lsmash_log( importer, LSMASH_LOG_ERROR, "failed to read data from the stream.\n" );
378 return err;
379 }
380 remain_size = lsmash_bs_get_remaining_buffer_size( bs );
381 }
382 uint64_t copy_size = LSMASH_MIN( remain_size, EAC3_MAX_SYNCFRAME_LENGTH );
383 memcpy( eac3_imp->buffer, lsmash_bs_get_buffer_data( bs ), copy_size );
384 /* Check the remainder length of the buffer.
385 * If there is enough length, then parse the syncframe in it.
386 * The length 5 is the required byte length to get frame size. */
387 if( bs->eob || (bs->eof && remain_size < 5) )
388 {
389 /* Reached the end of stream.
390 * According to ETSI TS 102 366 V1.2.1 (2008-08),
391 * one access unit consists of 6 audio blocks and begins with independent substream 0.
392 * The specification doesn't mention the case where a enhanced AC-3 stream ends at non-mod6 audio blocks.
393 * At the end of the stream, therefore, we might make an access unit which has less than 6 audio blocks anyway. */
394 importer->status = IMPORTER_EOF;
395 au_completed = !!eac3_imp->incomplete_au_length;
396 if( !au_completed )
397 {
398 /* No more access units in the stream. */
399 if( lsmash_bs_get_remaining_buffer_size( bs ) )
400 {
401 lsmash_log( importer, LSMASH_LOG_WARNING, "the stream is truncated at the end.\n" );
402 return LSMASH_ERR_INVALID_DATA;
403 }
404 return 0;
405 }
406 if( !info->dec3_param_initialized )
407 eac3_update_specific_param( info );
408 }
409 else
410 {
411 /* Check the syncword. */
412 if( lsmash_bs_show_byte( bs, 0 ) != 0x0b
413 || lsmash_bs_show_byte( bs, 1 ) != 0x77 )
414 {
415 lsmash_log( importer, LSMASH_LOG_ERROR, "a syncword is not found.\n" );
416 return LSMASH_ERR_INVALID_DATA;
417 }
418 /* Parse syncframe. */
419 info->frame_size = 0;
420 int err = eac3_parse_syncframe( info );
421 if( err < 0 )
422 {
423 lsmash_log( importer, LSMASH_LOG_ERROR, "failed to parse syncframe.\n" );
424 return err;
425 }
426 if( remain_size < info->frame_size )
427 {
428 lsmash_log( importer, LSMASH_LOG_ERROR, "a frame is truncated.\n" );
429 return LSMASH_ERR_INVALID_DATA;
430 }
431 int independent = info->strmtyp != 0x1;
432 if( independent && info->substreamid == 0x0 )
433 {
434 if( info->number_of_audio_blocks == 6 )
435 {
436 /* Encountered the first syncframe of the next access unit. */
437 info->number_of_audio_blocks = 0;
438 au_completed = 1;
439 }
440 else if( info->number_of_audio_blocks > 6 )
441 {
442 lsmash_log( importer, LSMASH_LOG_ERROR, "greater than 6 consecutive independent substreams.\n" );
443 return LSMASH_ERR_INVALID_DATA;
444 }
445 info->number_of_audio_blocks += eac3_audio_block_table[ info->numblkscod ];
446 info->number_of_independent_substreams = 0;
447 eac3_imp->current_fscod2 = info->fscod2;
448 }
449 else if( info->syncframe_count == 0 )
450 {
451 /* The first syncframe in an AU must be independent and assigned substream ID 0. */
452 lsmash_log( importer, LSMASH_LOG_ERROR, "the first syncframe is NOT an independent substream.\n" );
453 return LSMASH_ERR_INVALID_DATA;
454 }
455 if( independent )
456 info->independent_info[info->number_of_independent_substreams ++].num_dep_sub = 0;
457 else
458 ++ info->independent_info[info->number_of_independent_substreams - 1].num_dep_sub;
459 }
460 if( au_completed )
461 {
462 memcpy( eac3_imp->au, eac3_imp->incomplete_au, eac3_imp->incomplete_au_length );
463 eac3_imp->au_length = eac3_imp->incomplete_au_length;
464 eac3_imp->incomplete_au_length = 0;
465 eac3_imp->syncframe_count_in_au = info->syncframe_count;
466 info->syncframe_count = 0;
467 if( importer->status == IMPORTER_EOF )
468 break;
469 }
470 /* Increase buffer size to store AU if short. */
471 if( eac3_imp->incomplete_au_length + info->frame_size > eac3_imp->au_buffers->buffer_size )
472 {
473 lsmash_multiple_buffers_t *temp = lsmash_resize_multiple_buffers( eac3_imp->au_buffers,
474 eac3_imp->au_buffers->buffer_size + EAC3_MAX_SYNCFRAME_LENGTH );
475 if( !temp )
476 return LSMASH_ERR_MEMORY_ALLOC;
477 eac3_imp->au_buffers = temp;
478 eac3_imp->au = lsmash_withdraw_buffer( eac3_imp->au_buffers, 1 );
479 eac3_imp->incomplete_au = lsmash_withdraw_buffer( eac3_imp->au_buffers, 2 );
480 }
481 /* Append syncframe data. */
482 memcpy( eac3_imp->incomplete_au + eac3_imp->incomplete_au_length, eac3_imp->buffer, info->frame_size );
483 eac3_imp->incomplete_au_length += info->frame_size;
484 ++ info->syncframe_count;
485 }
486 return bs->error ? LSMASH_ERR_NAMELESS : 0;
487 }
488
eac3_importer_get_accessunit(importer_t * importer,uint32_t track_number,lsmash_sample_t ** p_sample)489 static int eac3_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t **p_sample )
490 {
491 if( !importer->info )
492 return LSMASH_ERR_NAMELESS;
493 if( track_number != 1 )
494 return LSMASH_ERR_FUNCTION_PARAM;
495 lsmash_audio_summary_t *summary = (lsmash_audio_summary_t *)lsmash_list_get_entry_data( importer->summaries, track_number );
496 if( !summary )
497 return LSMASH_ERR_NAMELESS;
498 eac3_importer_t *eac3_imp = (eac3_importer_t *)importer->info;
499 eac3_info_t *info = &eac3_imp->info;
500 importer_status current_status = importer->status;
501 if( current_status == IMPORTER_ERROR )
502 return LSMASH_ERR_NAMELESS;
503 if( current_status == IMPORTER_EOF && eac3_imp->au_length == 0 )
504 return IMPORTER_EOF;
505 if( current_status == IMPORTER_CHANGE )
506 {
507 lsmash_codec_specific_t *cs = isom_get_codec_specific( summary->opaque, LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_EC_3 );
508 if( cs )
509 {
510 cs->destruct( cs->data.unstructured );
511 cs->data.unstructured = eac3_imp->next_dec3;
512 cs->size = eac3_imp->next_dec3_length;
513 }
514 summary->max_au_length = eac3_imp->syncframe_count_in_au * EAC3_MAX_SYNCFRAME_LENGTH;
515 eac3_update_sample_rate( &summary->frequency, &info->dec3_param, &eac3_imp->current_fscod2 );
516 eac3_update_channel_count( &summary->channels, &info->dec3_param );
517 }
518 lsmash_sample_t *sample = lsmash_create_sample( eac3_imp->au_length );
519 if( !sample )
520 return LSMASH_ERR_MEMORY_ALLOC;
521 *p_sample = sample;
522 memcpy( sample->data, eac3_imp->au, eac3_imp->au_length );
523 sample->length = eac3_imp->au_length;
524 sample->dts = eac3_imp->au_number++ * summary->samples_in_frame;
525 sample->cts = sample->dts;
526 sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC;
527 sample->prop.pre_roll.distance = 1; /* MDCT */
528 if( importer->status == IMPORTER_EOF )
529 {
530 eac3_imp->au_length = 0;
531 return 0;
532 }
533 uint32_t old_syncframe_count_in_au = eac3_imp->syncframe_count_in_au;
534 if( eac3_importer_get_next_accessunit_internal( importer ) < 0 )
535 {
536 importer->status = IMPORTER_ERROR;
537 return current_status;
538 }
539 if( eac3_imp->syncframe_count_in_au )
540 {
541 /* Check sample description change. */
542 uint32_t new_length;
543 uint8_t *dec3 = lsmash_create_eac3_specific_info( &info->dec3_param, &new_length );
544 if( !dec3 )
545 {
546 importer->status = IMPORTER_ERROR;
547 return current_status;
548 }
549 lsmash_codec_specific_t *cs = isom_get_codec_specific( summary->opaque, LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_EC_3 );
550 if( (eac3_imp->syncframe_count_in_au > old_syncframe_count_in_au)
551 || (cs && (new_length != cs->size || memcmp( dec3, cs->data.unstructured, cs->size ))) )
552 {
553 importer->status = IMPORTER_CHANGE;
554 eac3_imp->next_dec3 = dec3;
555 eac3_imp->next_dec3_length = new_length;
556 }
557 else
558 {
559 if( importer->status != IMPORTER_EOF )
560 importer->status = IMPORTER_OK;
561 lsmash_free( dec3 );
562 }
563 }
564 return current_status;
565 }
566
eac3_create_summary(eac3_importer_t * eac3_imp)567 static lsmash_audio_summary_t *eac3_create_summary( eac3_importer_t *eac3_imp )
568 {
569 lsmash_audio_summary_t *summary = (lsmash_audio_summary_t *)lsmash_create_summary( LSMASH_SUMMARY_TYPE_AUDIO );
570 if( !summary )
571 return NULL;
572 eac3_info_t *info = &eac3_imp->info;
573 lsmash_codec_specific_t *cs = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_EC_3,
574 LSMASH_CODEC_SPECIFIC_FORMAT_UNSTRUCTURED );
575 if( !cs )
576 {
577 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
578 return NULL;
579 }
580 cs->data.unstructured = lsmash_create_eac3_specific_info( &info->dec3_param, &cs->size );
581 if( !cs->data.unstructured
582 || lsmash_list_add_entry( &summary->opaque->list, cs ) < 0 )
583 {
584 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
585 lsmash_destroy_codec_specific_data( cs );
586 return NULL;
587 }
588 summary->sample_type = ISOM_CODEC_TYPE_EC_3_AUDIO;
589 summary->max_au_length = eac3_imp->syncframe_count_in_au * EAC3_MAX_SYNCFRAME_LENGTH;
590 summary->aot = MP4A_AUDIO_OBJECT_TYPE_NULL; /* no effect */
591 summary->sample_size = 16; /* no effect */
592 summary->samples_in_frame = EAC3_MIN_SAMPLE_DURATION * 6; /* 256 (samples per audio block) * 6 (audio blocks) */
593 summary->sbr_mode = MP4A_AAC_SBR_NOT_SPECIFIED; /* no effect */
594 eac3_update_sample_rate( &summary->frequency, &info->dec3_param, &eac3_imp->current_fscod2 );
595 eac3_update_channel_count( &summary->channels, &info->dec3_param );
596 return summary;
597 }
598
eac3_importer_probe(importer_t * importer)599 static int eac3_importer_probe( importer_t *importer )
600 {
601 eac3_importer_t *eac3_imp = create_eac3_importer( importer );
602 if( !eac3_imp )
603 return LSMASH_ERR_MEMORY_ALLOC;
604 lsmash_bits_t *bits = eac3_imp->info.bits;
605 lsmash_bs_t *bs = bits->bs;
606 bs->buffer.max_size = EAC3_MAX_SYNCFRAME_LENGTH;
607 importer->info = eac3_imp;
608 int err = eac3_importer_get_next_accessunit_internal( importer );
609 if( err < 0 )
610 goto fail;
611 lsmash_audio_summary_t *summary = eac3_create_summary( eac3_imp );
612 if( !summary )
613 {
614 err = LSMASH_ERR_NAMELESS;
615 goto fail;
616 }
617 if( importer->status != IMPORTER_EOF )
618 importer->status = IMPORTER_OK;
619 eac3_imp->au_number = 0;
620 if( lsmash_list_add_entry( importer->summaries, summary ) < 0 )
621 {
622 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
623 err = LSMASH_ERR_MEMORY_ALLOC;
624 goto fail;
625 }
626 return 0;
627 fail:
628 remove_eac3_importer( eac3_imp );
629 importer->info = NULL;
630 return err;
631 }
632
eac3_importer_get_last_delta(importer_t * importer,uint32_t track_number)633 static uint32_t eac3_importer_get_last_delta( importer_t *importer, uint32_t track_number )
634 {
635 debug_if( !importer || !importer->info )
636 return 0;
637 eac3_importer_t *eac3_imp = (eac3_importer_t *)importer->info;
638 if( !eac3_imp || track_number != 1 || importer->status != IMPORTER_EOF || eac3_imp->au_length )
639 return 0;
640 return EAC3_MIN_SAMPLE_DURATION * eac3_imp->info.number_of_audio_blocks;
641 }
642
643 const importer_functions eac3_importer =
644 {
645 { "Enhanced AC-3", offsetof( importer_t, log_level ) },
646 1,
647 eac3_importer_probe,
648 eac3_importer_get_accessunit,
649 eac3_importer_get_last_delta,
650 eac3_importer_cleanup
651 };
652