isom: Evaluate return value properly.
[L-SMASH.git] / cli / a52_imp.c
blobdbf599786152fdb57c85a409ed71794c93ae1fb0
1 /*****************************************************************************
2 * a52_imp.c
3 *****************************************************************************
4 * Copyright (C) 2011-2014 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 <string.h>
27 #define LSMASH_IMPORTER_INTERNAL
28 #include "importer.h"
30 /***************************************************************************
31 AC-3 importer
32 ETSI TS 102 366 V1.2.1 (2008-08)
33 ***************************************************************************/
34 #include "codecs/a52.h"
36 #define AC3_SAMPLE_DURATION 1536 /* 256 (samples per audio block) * 6 (audio blocks) */
38 typedef struct
40 importer_status status;
41 ac3_info_t info;
42 uint64_t next_frame_pos;
43 uint8_t *next_dac3;
44 uint8_t buffer[AC3_MAX_SYNCFRAME_LENGTH];
45 uint32_t au_number;
46 } ac3_importer_t;
48 static void remove_ac3_importer( ac3_importer_t *ac3_imp )
50 if( !ac3_imp )
51 return;
52 lsmash_bits_adhoc_cleanup( ac3_imp->info.bits );
53 lsmash_free( ac3_imp );
56 static ac3_importer_t *create_ac3_importer( void )
58 ac3_importer_t *ac3_imp = (ac3_importer_t *)lsmash_malloc_zero( sizeof(ac3_importer_t) );
59 if( !ac3_imp )
60 return NULL;
61 ac3_imp->info.bits = lsmash_bits_adhoc_create();
62 if( !ac3_imp->info.bits )
64 lsmash_free( ac3_imp );
65 return NULL;
67 return ac3_imp;
70 static void ac3_importer_cleanup( importer_t *importer )
72 debug_if( importer && importer->info )
73 remove_ac3_importer( importer->info );
76 static const uint32_t ac3_frame_size_table[19][3] =
78 /* 48, 44.1, 32 */
79 { 128, 138, 192 },
80 { 160, 174, 240 },
81 { 192, 208, 288 },
82 { 224, 242, 336 },
83 { 256, 278, 384 },
84 { 320, 348, 480 },
85 { 384, 416, 576 },
86 { 448, 486, 672 },
87 { 512, 556, 768 },
88 { 640, 696, 960 },
89 { 768, 834, 1152 },
90 { 896, 974, 1344 },
91 { 1024, 1114, 1536 },
92 { 1280, 1392, 1920 },
93 { 1536, 1670, 2304 },
94 { 1792, 1950, 2688 },
95 { 2048, 2228, 3072 },
96 { 2304, 2506, 3456 },
97 { 2560, 2786, 3840 }
100 static lsmash_audio_summary_t *ac3_create_summary( ac3_info_t *info )
102 lsmash_audio_summary_t *summary = (lsmash_audio_summary_t *)lsmash_create_summary( LSMASH_SUMMARY_TYPE_AUDIO );
103 if( !summary )
104 return NULL;
105 lsmash_ac3_specific_parameters_t *param = &info->dac3_param;
106 lsmash_codec_specific_t *cs = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_AC_3,
107 LSMASH_CODEC_SPECIFIC_FORMAT_UNSTRUCTURED );
108 cs->data.unstructured = lsmash_create_ac3_specific_info( &info->dac3_param, &cs->size );
109 if( !cs->data.unstructured
110 || lsmash_add_entry( &summary->opaque->list, cs ) )
112 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
113 lsmash_destroy_codec_specific_data( cs );
114 return NULL;
116 summary->sample_type = ISOM_CODEC_TYPE_AC_3_AUDIO;
117 summary->max_au_length = AC3_MAX_SYNCFRAME_LENGTH;
118 summary->aot = MP4A_AUDIO_OBJECT_TYPE_NULL; /* no effect */
119 summary->frequency = ac3_get_sample_rate( param );
120 summary->channels = ac3_get_channel_count( param );
121 summary->sample_size = 16; /* no effect */
122 summary->samples_in_frame = AC3_SAMPLE_DURATION;
123 summary->sbr_mode = MP4A_AAC_SBR_NOT_SPECIFIED; /* no effect */
124 return summary;
127 static int ac3_compare_specific_param( lsmash_ac3_specific_parameters_t *a, lsmash_ac3_specific_parameters_t *b )
129 return (a->fscod != b->fscod)
130 || (a->bsid != b->bsid)
131 || (a->bsmod != b->bsmod)
132 || (a->acmod != b->acmod)
133 || (a->lfeon != b->lfeon)
134 || ((a->frmsizecod >> 1) != (b->frmsizecod >> 1));
137 static int ac3_buffer_frame( uint8_t *buffer, lsmash_bs_t *bs )
139 uint64_t remain_size = lsmash_bs_get_remaining_buffer_size( bs );
140 if( remain_size < AC3_MAX_SYNCFRAME_LENGTH )
142 if( lsmash_bs_read( bs, bs->buffer.max_size ) < 0 )
143 return -1;
144 remain_size = lsmash_bs_get_remaining_buffer_size( bs );
146 uint64_t copy_size = LSMASH_MIN( remain_size, AC3_MAX_SYNCFRAME_LENGTH );
147 memcpy( buffer, lsmash_bs_get_buffer_data( bs ), copy_size );
148 return 0;
151 static int ac3_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample )
153 debug_if( !importer || !importer->info || !buffered_sample->data || !buffered_sample->length )
154 return -1;
155 if( !importer->info || track_number != 1 )
156 return -1;
157 lsmash_audio_summary_t *summary = (lsmash_audio_summary_t *)lsmash_get_entry_data( importer->summaries, track_number );
158 if( !summary )
159 return -1;
160 ac3_importer_t *ac3_imp = (ac3_importer_t *)importer->info;
161 ac3_info_t *info = &ac3_imp->info;
162 importer_status current_status = ac3_imp->status;
163 if( current_status == IMPORTER_ERROR )
164 return -1;
165 if( current_status == IMPORTER_EOF )
167 buffered_sample->length = 0;
168 return 0;
170 lsmash_ac3_specific_parameters_t *param = &info->dac3_param;
171 uint32_t frame_size = ac3_frame_size_table[ param->frmsizecod >> 1 ][ param->fscod ];
172 if( param->fscod == 0x1 && param->frmsizecod & 0x1 )
173 frame_size += 2;
174 if( buffered_sample->length < frame_size )
175 return -1;
176 if( current_status == IMPORTER_CHANGE )
178 lsmash_codec_specific_t *cs = isom_get_codec_specific( summary->opaque, LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_AC_3 );
179 if( cs )
181 cs->destruct( cs->data.unstructured );
182 cs->data.unstructured = ac3_imp->next_dac3;
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 ];
188 memcpy( buffered_sample->data, ac3_imp->buffer, frame_size );
189 buffered_sample->length = frame_size;
190 buffered_sample->dts = ac3_imp->au_number++ * summary->samples_in_frame;
191 buffered_sample->cts = buffered_sample->dts;
192 buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC;
193 buffered_sample->prop.pre_roll.distance = 1; /* MDCT */
194 lsmash_bs_t *bs = info->bits->bs;
195 ac3_imp->next_frame_pos += frame_size;
196 lsmash_bs_read_seek( bs, ac3_imp->next_frame_pos, SEEK_SET );
197 uint8_t syncword[2] =
199 lsmash_bs_show_byte( bs, 0 ),
200 lsmash_bs_show_byte( bs, 1 )
202 if( bs->eob || (bs->eof && 0 == lsmash_bs_get_remaining_buffer_size( bs )) )
203 ac3_imp->status = IMPORTER_EOF;
204 else
206 /* Parse the next syncframe header. */
207 if( syncword[0] != 0x0b
208 || syncword[1] != 0x77
209 || ac3_buffer_frame( ac3_imp->buffer, bs ) < 0 )
211 ac3_imp->status = IMPORTER_ERROR;
212 return current_status;
214 lsmash_ac3_specific_parameters_t current_param = info->dac3_param;
215 ac3_parse_syncframe_header( info );
216 if( ac3_compare_specific_param( &current_param, &info->dac3_param ) )
218 uint32_t dummy;
219 uint8_t *dac3 = lsmash_create_ac3_specific_info( &info->dac3_param, &dummy );
220 if( !dac3 )
222 ac3_imp->status = IMPORTER_ERROR;
223 return current_status;
225 ac3_imp->status = IMPORTER_CHANGE;
226 ac3_imp->next_dac3 = dac3;
228 else
229 ac3_imp->status = IMPORTER_OK;
231 return current_status;
234 static int ac3_importer_probe( importer_t *importer )
236 ac3_importer_t *ac3_imp = create_ac3_importer();
237 if( !ac3_imp )
238 return -1;
239 lsmash_bits_t *bits = ac3_imp->info.bits;
240 lsmash_bs_t *bs = bits->bs;
241 bs->stream = importer->stream;
242 bs->read = lsmash_fread_wrapper;
243 bs->seek = lsmash_fseek_wrapper;
244 bs->unseekable = importer->is_stdin;
245 bs->buffer.max_size = AC3_MAX_SYNCFRAME_LENGTH;
246 /* Check the syncword and parse the syncframe header */
247 if( lsmash_bs_show_byte( bs, 0 ) != 0x0b
248 || lsmash_bs_show_byte( bs, 1 ) != 0x77
249 || ac3_buffer_frame( ac3_imp->buffer, bs ) < 0
250 || ac3_parse_syncframe_header( &ac3_imp->info ) < 0 )
251 goto fail;
252 lsmash_audio_summary_t *summary = ac3_create_summary( &ac3_imp->info );
253 if( !summary )
254 goto fail;
255 if( lsmash_add_entry( importer->summaries, summary ) < 0 )
257 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
258 goto fail;
260 ac3_imp->status = IMPORTER_OK;
261 ac3_imp->au_number = 0;
262 importer->info = ac3_imp;
263 return 0;
264 fail:
265 remove_ac3_importer( ac3_imp );
266 return -1;
269 static uint32_t ac3_importer_get_last_delta( importer_t *importer, uint32_t track_number )
271 debug_if( !importer || !importer->info )
272 return 0;
273 ac3_importer_t *ac3_imp = (ac3_importer_t *)importer->info;
274 if( !ac3_imp || track_number != 1 || ac3_imp->status != IMPORTER_EOF )
275 return 0;
276 return AC3_SAMPLE_DURATION;
279 const importer_functions ac3_importer =
281 { "AC-3" },
283 ac3_importer_probe,
284 ac3_importer_get_accessunit,
285 ac3_importer_get_last_delta,
286 ac3_importer_cleanup
289 /***************************************************************************
290 Enhanced AC-3 importer
291 ETSI TS 102 366 V1.2.1 (2008-08)
292 ***************************************************************************/
293 #define EAC3_MIN_SAMPLE_DURATION 256
295 typedef struct
297 importer_status status;
298 eac3_info_t info;
299 uint64_t next_frame_pos;
300 uint32_t next_dec3_length;
301 uint8_t *next_dec3;
302 uint8_t current_fscod2;
303 uint8_t buffer[EAC3_MAX_SYNCFRAME_LENGTH];
304 lsmash_multiple_buffers_t *au_buffers;
305 uint8_t *au;
306 uint8_t *incomplete_au;
307 uint32_t au_length;
308 uint32_t incomplete_au_length;
309 uint32_t au_number;
310 uint32_t syncframe_count_in_au;
311 } eac3_importer_t;
313 static void remove_eac3_importer( eac3_importer_t *eac3_imp )
315 if( !eac3_imp )
316 return;
317 lsmash_destroy_multiple_buffers( eac3_imp->au_buffers );
318 lsmash_bits_adhoc_cleanup( eac3_imp->info.bits );
319 lsmash_free( eac3_imp );
322 static eac3_importer_t *create_eac3_importer( void )
324 eac3_importer_t *eac3_imp = (eac3_importer_t *)lsmash_malloc_zero( sizeof(eac3_importer_t) );
325 if( !eac3_imp )
326 return NULL;
327 eac3_info_t *info = &eac3_imp->info;
328 info->bits = lsmash_bits_adhoc_create();
329 if( !info->bits )
331 lsmash_free( eac3_imp );
332 return NULL;
334 eac3_imp->au_buffers = lsmash_create_multiple_buffers( 2, EAC3_MAX_SYNCFRAME_LENGTH );
335 if( !eac3_imp->au_buffers )
337 lsmash_bits_adhoc_cleanup( info->bits );
338 lsmash_free( eac3_imp );
339 return NULL;
341 eac3_imp->au = lsmash_withdraw_buffer( eac3_imp->au_buffers, 1 );
342 eac3_imp->incomplete_au = lsmash_withdraw_buffer( eac3_imp->au_buffers, 2 );
343 return eac3_imp;
346 static void eac3_importer_cleanup( importer_t *importer )
348 debug_if( importer && importer->info )
349 remove_eac3_importer( importer->info );
352 static int eac3_importer_get_next_accessunit_internal( importer_t *importer )
354 int au_completed = 0;
355 eac3_importer_t *eac3_imp = (eac3_importer_t *)importer->info;
356 eac3_info_t *info = &eac3_imp->info;
357 lsmash_bs_t *bs = info->bits->bs;
358 while( !au_completed )
360 /* Read data from the stream if needed. */
361 eac3_imp->next_frame_pos += info->frame_size;
362 lsmash_bs_read_seek( bs, eac3_imp->next_frame_pos, SEEK_SET );
363 uint64_t remain_size = lsmash_bs_get_remaining_buffer_size( bs );
364 if( remain_size < EAC3_MAX_SYNCFRAME_LENGTH )
366 if( lsmash_bs_read( bs, bs->buffer.max_size ) < 0 )
368 lsmash_log( importer, LSMASH_LOG_ERROR, "failed to read data from the stream.\n" );
369 return -1;
371 remain_size = lsmash_bs_get_remaining_buffer_size( bs );
373 uint64_t copy_size = LSMASH_MIN( remain_size, EAC3_MAX_SYNCFRAME_LENGTH );
374 memcpy( eac3_imp->buffer, lsmash_bs_get_buffer_data( bs ), copy_size );
375 /* Check the remainder length of the buffer.
376 * If there is enough length, then parse the syncframe in it.
377 * The length 5 is the required byte length to get frame size. */
378 if( bs->eob || (bs->eof && remain_size < 5) )
380 /* Reached the end of stream.
381 * According to ETSI TS 102 366 V1.2.1 (2008-08),
382 * one access unit consists of 6 audio blocks and begins with independent substream 0.
383 * The specification doesn't mention the case where a enhanced AC-3 stream ends at non-mod6 audio blocks.
384 * At the end of the stream, therefore, we might make an access unit which has less than 6 audio blocks anyway. */
385 eac3_imp->status = IMPORTER_EOF;
386 au_completed = !!eac3_imp->incomplete_au_length;
387 if( !au_completed )
389 /* No more access units in the stream. */
390 if( lsmash_bs_get_remaining_buffer_size( bs ) )
392 lsmash_log( importer, LSMASH_LOG_WARNING, "the stream is truncated at the end.\n" );
393 return -1;
395 return 0;
397 if( !info->dec3_param_initialized )
398 eac3_update_specific_param( info );
400 else
402 /* Check the syncword. */
403 if( lsmash_bs_show_byte( bs, 0 ) != 0x0b
404 || lsmash_bs_show_byte( bs, 1 ) != 0x77 )
406 lsmash_log( importer, LSMASH_LOG_ERROR, "a syncword is not found.\n" );
407 return -1;
409 /* Parse syncframe. */
410 info->frame_size = 0;
411 if( eac3_parse_syncframe( info ) < 0 )
413 lsmash_log( importer, LSMASH_LOG_ERROR, "failed to parse syncframe.\n" );
414 return -1;
416 if( remain_size < info->frame_size )
418 lsmash_log( importer, LSMASH_LOG_ERROR, "a frame is truncated.\n" );
419 return -1;
421 int independent = info->strmtyp != 0x1;
422 if( independent && info->substreamid == 0x0 )
424 if( info->number_of_audio_blocks == 6 )
426 /* Encountered the first syncframe of the next access unit. */
427 info->number_of_audio_blocks = 0;
428 au_completed = 1;
430 else if( info->number_of_audio_blocks > 6 )
432 lsmash_log( importer, LSMASH_LOG_ERROR, "greater than 6 consecutive independent substreams.\n" );
433 return -1;
435 info->number_of_audio_blocks += eac3_audio_block_table[ info->numblkscod ];
436 info->number_of_independent_substreams = 0;
437 eac3_imp->current_fscod2 = info->fscod2;
439 else if( info->syncframe_count == 0 )
441 /* The first syncframe in an AU must be independent and assigned substream ID 0. */
442 lsmash_log( importer, LSMASH_LOG_ERROR, "the first syncframe is NOT an independent substream.\n" );
443 return -1;
445 if( independent )
446 info->independent_info[info->number_of_independent_substreams ++].num_dep_sub = 0;
447 else
448 ++ info->independent_info[info->number_of_independent_substreams - 1].num_dep_sub;
450 if( au_completed )
452 memcpy( eac3_imp->au, eac3_imp->incomplete_au, eac3_imp->incomplete_au_length );
453 eac3_imp->au_length = eac3_imp->incomplete_au_length;
454 eac3_imp->incomplete_au_length = 0;
455 eac3_imp->syncframe_count_in_au = info->syncframe_count;
456 info->syncframe_count = 0;
457 if( eac3_imp->status == IMPORTER_EOF )
458 break;
460 /* Increase buffer size to store AU if short. */
461 if( eac3_imp->incomplete_au_length + info->frame_size > eac3_imp->au_buffers->buffer_size )
463 lsmash_multiple_buffers_t *temp = lsmash_resize_multiple_buffers( eac3_imp->au_buffers,
464 eac3_imp->au_buffers->buffer_size + EAC3_MAX_SYNCFRAME_LENGTH );
465 if( !temp )
466 return -1;
467 eac3_imp->au_buffers = temp;
468 eac3_imp->au = lsmash_withdraw_buffer( eac3_imp->au_buffers, 1 );
469 eac3_imp->incomplete_au = lsmash_withdraw_buffer( eac3_imp->au_buffers, 2 );
471 /* Append syncframe data. */
472 memcpy( eac3_imp->incomplete_au + eac3_imp->incomplete_au_length, eac3_imp->buffer, info->frame_size );
473 eac3_imp->incomplete_au_length += info->frame_size;
474 ++ info->syncframe_count;
476 return info->bits->bs->error ? -1 : 0;
479 static int eac3_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample )
481 debug_if( !importer || !importer->info || !buffered_sample->data || !buffered_sample->length )
482 return -1;
483 if( !importer->info || track_number != 1 )
484 return -1;
485 lsmash_audio_summary_t *summary = (lsmash_audio_summary_t *)lsmash_get_entry_data( importer->summaries, track_number );
486 if( !summary )
487 return -1;
488 eac3_importer_t *eac3_imp = (eac3_importer_t *)importer->info;
489 eac3_info_t *info = &eac3_imp->info;
490 importer_status current_status = eac3_imp->status;
491 if( current_status == IMPORTER_ERROR || buffered_sample->length < eac3_imp->au_length )
492 return -1;
493 if( current_status == IMPORTER_EOF && eac3_imp->au_length == 0 )
495 buffered_sample->length = 0;
496 return 0;
498 if( current_status == IMPORTER_CHANGE )
500 lsmash_codec_specific_t *cs = isom_get_codec_specific( summary->opaque, LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_EC_3 );
501 if( cs )
503 cs->destruct( cs->data.unstructured );
504 cs->data.unstructured = eac3_imp->next_dec3;
505 cs->size = eac3_imp->next_dec3_length;
507 summary->max_au_length = eac3_imp->syncframe_count_in_au * EAC3_MAX_SYNCFRAME_LENGTH;
508 eac3_update_sample_rate( &summary->frequency, &info->dec3_param, &eac3_imp->current_fscod2 );
509 eac3_update_channel_count( &summary->channels, &info->dec3_param );
511 memcpy( buffered_sample->data, eac3_imp->au, eac3_imp->au_length );
512 buffered_sample->length = eac3_imp->au_length;
513 buffered_sample->dts = eac3_imp->au_number++ * summary->samples_in_frame;
514 buffered_sample->cts = buffered_sample->dts;
515 buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC;
516 buffered_sample->prop.pre_roll.distance = 1; /* MDCT */
517 if( eac3_imp->status == IMPORTER_EOF )
519 eac3_imp->au_length = 0;
520 return 0;
522 uint32_t old_syncframe_count_in_au = eac3_imp->syncframe_count_in_au;
523 if( eac3_importer_get_next_accessunit_internal( importer ) < 0 )
525 eac3_imp->status = IMPORTER_ERROR;
526 return current_status;
528 if( eac3_imp->syncframe_count_in_au )
530 /* Check sample description change. */
531 uint32_t new_length;
532 uint8_t *dec3 = lsmash_create_eac3_specific_info( &info->dec3_param, &new_length );
533 if( !dec3 )
535 eac3_imp->status = IMPORTER_ERROR;
536 return current_status;
538 lsmash_codec_specific_t *cs = isom_get_codec_specific( summary->opaque, LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_EC_3 );
539 if( (eac3_imp->syncframe_count_in_au > old_syncframe_count_in_au)
540 || (cs && (new_length != cs->size || memcmp( dec3, cs->data.unstructured, cs->size ))) )
542 eac3_imp->status = IMPORTER_CHANGE;
543 eac3_imp->next_dec3 = dec3;
544 eac3_imp->next_dec3_length = new_length;
546 else
548 if( eac3_imp->status != IMPORTER_EOF )
549 eac3_imp->status = IMPORTER_OK;
550 lsmash_free( dec3 );
553 return current_status;
556 static lsmash_audio_summary_t *eac3_create_summary( eac3_importer_t *eac3_imp )
558 lsmash_audio_summary_t *summary = (lsmash_audio_summary_t *)lsmash_create_summary( LSMASH_SUMMARY_TYPE_AUDIO );
559 if( !summary )
560 return NULL;
561 eac3_info_t *info = &eac3_imp->info;
562 lsmash_codec_specific_t *cs = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_EC_3,
563 LSMASH_CODEC_SPECIFIC_FORMAT_UNSTRUCTURED );
564 cs->data.unstructured = lsmash_create_eac3_specific_info( &info->dec3_param, &cs->size );
565 if( !cs->data.unstructured
566 || lsmash_add_entry( &summary->opaque->list, cs ) < 0 )
568 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
569 lsmash_destroy_codec_specific_data( cs );
570 return NULL;
572 summary->sample_type = ISOM_CODEC_TYPE_EC_3_AUDIO;
573 summary->max_au_length = eac3_imp->syncframe_count_in_au * EAC3_MAX_SYNCFRAME_LENGTH;
574 summary->aot = MP4A_AUDIO_OBJECT_TYPE_NULL; /* no effect */
575 summary->sample_size = 16; /* no effect */
576 summary->samples_in_frame = EAC3_MIN_SAMPLE_DURATION * 6; /* 256 (samples per audio block) * 6 (audio blocks) */
577 summary->sbr_mode = MP4A_AAC_SBR_NOT_SPECIFIED; /* no effect */
578 eac3_update_sample_rate( &summary->frequency, &info->dec3_param, &eac3_imp->current_fscod2 );
579 eac3_update_channel_count( &summary->channels, &info->dec3_param );
580 return summary;
583 static int eac3_importer_probe( importer_t *importer )
585 eac3_importer_t *eac3_imp = create_eac3_importer();
586 if( !eac3_imp )
587 return -1;
588 lsmash_bits_t *bits = eac3_imp->info.bits;
589 lsmash_bs_t *bs = bits->bs;
590 bs->stream = importer->stream;
591 bs->read = lsmash_fread_wrapper;
592 bs->seek = lsmash_fseek_wrapper;
593 bs->unseekable = importer->is_stdin;
594 bs->buffer.max_size = EAC3_MAX_SYNCFRAME_LENGTH;
595 importer->info = eac3_imp;
596 if( eac3_importer_get_next_accessunit_internal( importer ) < 0 )
597 goto fail;
598 lsmash_audio_summary_t *summary = eac3_create_summary( eac3_imp );
599 if( !summary )
600 goto fail;
601 if( eac3_imp->status != IMPORTER_EOF )
602 eac3_imp->status = IMPORTER_OK;
603 eac3_imp->au_number = 0;
604 if( lsmash_add_entry( importer->summaries, summary ) < 0 )
606 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
607 goto fail;
609 return 0;
610 fail:
611 remove_eac3_importer( eac3_imp );
612 importer->info = NULL;
613 return -1;
616 static uint32_t eac3_importer_get_last_delta( importer_t *importer, uint32_t track_number )
618 debug_if( !importer || !importer->info )
619 return 0;
620 eac3_importer_t *eac3_imp = (eac3_importer_t *)importer->info;
621 if( !eac3_imp || track_number != 1 || eac3_imp->status != IMPORTER_EOF || eac3_imp->au_length )
622 return 0;
623 return EAC3_MIN_SAMPLE_DURATION * eac3_imp->info.number_of_audio_blocks;
626 const importer_functions eac3_importer =
628 { "Enhanced AC-3", offsetof( importer_t, log_level ) },
630 eac3_importer_probe,
631 eac3_importer_get_accessunit,
632 eac3_importer_get_last_delta,
633 eac3_importer_cleanup