1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2011-2017 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 */
27 #define LSMASH_IMPORTER_INTERNAL
30 /***************************************************************************
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) */
41 uint64_t next_frame_pos
;
43 uint8_t buffer
[AC3_MAX_SYNCFRAME_LENGTH
];
47 static void remove_ac3_importer( ac3_importer_t
*ac3_imp
)
51 lsmash_bits_cleanup( ac3_imp
->info
.bits
);
52 lsmash_free( ac3_imp
);
55 static ac3_importer_t
*create_ac3_importer( importer_t
*importer
)
57 ac3_importer_t
*ac3_imp
= (ac3_importer_t
*)lsmash_malloc_zero( sizeof(ac3_importer_t
) );
60 ac3_imp
->info
.bits
= lsmash_bits_create( importer
->bs
);
61 if( !ac3_imp
->info
.bits
)
63 lsmash_free( ac3_imp
);
69 static void ac3_importer_cleanup( importer_t
*importer
)
71 debug_if( importer
&& importer
->info
)
72 remove_ac3_importer( importer
->info
);
75 static const uint32_t ac3_frame_size_table
[19][3] =
99 static lsmash_audio_summary_t
*ac3_create_summary( ac3_info_t
*info
)
101 lsmash_audio_summary_t
*summary
= (lsmash_audio_summary_t
*)lsmash_create_summary( LSMASH_SUMMARY_TYPE_AUDIO
);
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
);
109 lsmash_cleanup_summary( (lsmash_summary_t
*)summary
);
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 )
116 lsmash_cleanup_summary( (lsmash_summary_t
*)summary
);
117 lsmash_destroy_codec_specific_data( cs
);
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 */
131 static int ac3_compare_specific_param( lsmash_ac3_specific_parameters_t
*a
, lsmash_ac3_specific_parameters_t
*b
)
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));
141 static int ac3_buffer_frame( uint8_t *buffer
, lsmash_bs_t
*bs
)
143 uint64_t remain_size
= lsmash_bs_get_remaining_buffer_size( bs
);
144 if( remain_size
< AC3_MAX_SYNCFRAME_LENGTH
)
146 if( bs
->buffer
.pos
> AC3_MAX_SYNCFRAME_LENGTH
* 1000 )
147 lsmash_bs_dispose_past_data( bs
);
148 int err
= lsmash_bs_read( bs
, bs
->buffer
.max_size
);
151 remain_size
= lsmash_bs_get_remaining_buffer_size( bs
);
153 uint64_t copy_size
= LSMASH_MIN( remain_size
, AC3_MAX_SYNCFRAME_LENGTH
);
154 memcpy( buffer
, lsmash_bs_get_buffer_data( bs
), copy_size
);
158 static int ac3_importer_get_accessunit( importer_t
*importer
, uint32_t track_number
, lsmash_sample_t
**p_sample
)
160 if( !importer
->info
)
161 return LSMASH_ERR_NAMELESS
;
162 if( track_number
!= 1 )
163 return LSMASH_ERR_FUNCTION_PARAM
;
164 lsmash_audio_summary_t
*summary
= (lsmash_audio_summary_t
*)lsmash_list_get_entry_data( importer
->summaries
, track_number
);
166 return LSMASH_ERR_NAMELESS
;
167 ac3_importer_t
*ac3_imp
= (ac3_importer_t
*)importer
->info
;
168 ac3_info_t
*info
= &ac3_imp
->info
;
169 importer_status current_status
= importer
->status
;
170 if( current_status
== IMPORTER_ERROR
)
171 return LSMASH_ERR_NAMELESS
;
172 if( current_status
== IMPORTER_EOF
)
174 lsmash_ac3_specific_parameters_t
*param
= &info
->dac3_param
;
175 uint32_t frame_size
= ac3_frame_size_table
[ param
->frmsizecod
>> 1 ][ param
->fscod
];
176 if( param
->fscod
== 0x1 && param
->frmsizecod
& 0x1 )
178 if( current_status
== IMPORTER_CHANGE
)
180 lsmash_codec_specific_t
*cs
= isom_get_codec_specific( summary
->opaque
, LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_AC_3
);
183 cs
->destruct( cs
->data
.unstructured
);
184 cs
->data
.unstructured
= ac3_imp
->next_dac3
;
186 summary
->frequency
= ac3_get_sample_rate( param
);
187 summary
->channels
= ac3_get_channel_count( param
);
188 //summary->layout_tag = ac3_channel_layout_table[ param->acmod ][ param->lfeon ];
190 lsmash_sample_t
*sample
= lsmash_create_sample( frame_size
);
192 return LSMASH_ERR_MEMORY_ALLOC
;
194 memcpy( sample
->data
, ac3_imp
->buffer
, frame_size
);
195 sample
->length
= frame_size
;
196 sample
->dts
= ac3_imp
->au_number
++ * summary
->samples_in_frame
;
197 sample
->cts
= sample
->dts
;
198 sample
->prop
.ra_flags
= ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC
;
199 sample
->prop
.pre_roll
.distance
= 1; /* MDCT */
200 lsmash_bs_t
*bs
= info
->bits
->bs
;
201 ac3_imp
->next_frame_pos
+= frame_size
;
202 lsmash_bs_read_seek( bs
, ac3_imp
->next_frame_pos
, SEEK_SET
);
203 uint8_t syncword
[2] =
205 lsmash_bs_show_byte( bs
, 0 ),
206 lsmash_bs_show_byte( bs
, 1 )
208 if( bs
->eob
|| (bs
->eof
&& 0 == lsmash_bs_get_remaining_buffer_size( bs
)) )
209 importer
->status
= IMPORTER_EOF
;
212 /* Parse the next syncframe header. */
213 if( syncword
[0] != 0x0b
214 || syncword
[1] != 0x77
215 || ac3_buffer_frame( ac3_imp
->buffer
, bs
) < 0 )
217 importer
->status
= IMPORTER_ERROR
;
218 return current_status
;
220 lsmash_ac3_specific_parameters_t current_param
= info
->dac3_param
;
221 ac3_parse_syncframe_header( info
);
222 if( ac3_compare_specific_param( ¤t_param
, &info
->dac3_param
) )
225 uint8_t *dac3
= lsmash_create_ac3_specific_info( &info
->dac3_param
, &dummy
);
228 importer
->status
= IMPORTER_ERROR
;
229 return current_status
;
231 ac3_imp
->next_dac3
= dac3
;
232 importer
->status
= IMPORTER_CHANGE
;
235 importer
->status
= IMPORTER_OK
;
237 return current_status
;
240 static int ac3_importer_probe( importer_t
*importer
)
242 ac3_importer_t
*ac3_imp
= create_ac3_importer( importer
);
244 return LSMASH_ERR_MEMORY_ALLOC
;
245 lsmash_bits_t
*bits
= ac3_imp
->info
.bits
;
246 lsmash_bs_t
*bs
= bits
->bs
;
247 bs
->buffer
.max_size
= AC3_MAX_SYNCFRAME_LENGTH
;
248 /* Check the syncword and parse the syncframe header */
250 if( lsmash_bs_show_byte( bs
, 0 ) != 0x0b
251 || lsmash_bs_show_byte( bs
, 1 ) != 0x77 )
253 err
= LSMASH_ERR_INVALID_DATA
;
256 if( (err
= ac3_buffer_frame( ac3_imp
->buffer
, bs
)) < 0
257 || (err
= ac3_parse_syncframe_header( &ac3_imp
->info
)) < 0 )
259 lsmash_audio_summary_t
*summary
= ac3_create_summary( &ac3_imp
->info
);
262 err
= LSMASH_ERR_NAMELESS
;
265 if( lsmash_list_add_entry( importer
->summaries
, summary
) < 0 )
267 lsmash_cleanup_summary( (lsmash_summary_t
*)summary
);
268 err
= LSMASH_ERR_MEMORY_ALLOC
;
271 ac3_imp
->au_number
= 0;
272 importer
->info
= ac3_imp
;
273 importer
->status
= IMPORTER_OK
;
276 remove_ac3_importer( ac3_imp
);
280 static uint32_t ac3_importer_get_last_delta( importer_t
*importer
, uint32_t track_number
)
282 debug_if( !importer
|| !importer
->info
)
284 ac3_importer_t
*ac3_imp
= (ac3_importer_t
*)importer
->info
;
285 if( !ac3_imp
|| track_number
!= 1 || importer
->status
!= IMPORTER_EOF
)
287 return AC3_SAMPLE_DURATION
;
290 const importer_functions ac3_importer
=
295 ac3_importer_get_accessunit
,
296 ac3_importer_get_last_delta
,
300 /***************************************************************************
301 Enhanced AC-3 importer
302 ETSI TS 102 366 V1.2.1 (2008-08)
303 ***************************************************************************/
304 #define EAC3_MIN_SAMPLE_DURATION 256
309 uint64_t next_frame_pos
;
310 uint32_t next_dec3_length
;
312 uint8_t current_fscod2
;
313 uint8_t buffer
[EAC3_MAX_SYNCFRAME_LENGTH
];
314 lsmash_multiple_buffers_t
*au_buffers
;
316 uint8_t *incomplete_au
;
318 uint32_t incomplete_au_length
;
320 uint32_t syncframe_count_in_au
;
323 static void remove_eac3_importer( eac3_importer_t
*eac3_imp
)
327 lsmash_destroy_multiple_buffers( eac3_imp
->au_buffers
);
328 lsmash_bits_cleanup( eac3_imp
->info
.bits
);
329 lsmash_free( eac3_imp
);
332 static eac3_importer_t
*create_eac3_importer( importer_t
*importer
)
334 eac3_importer_t
*eac3_imp
= (eac3_importer_t
*)lsmash_malloc_zero( sizeof(eac3_importer_t
) );
337 eac3_info_t
*info
= &eac3_imp
->info
;
338 info
->bits
= lsmash_bits_create( importer
->bs
);
341 lsmash_free( eac3_imp
);
344 eac3_imp
->au_buffers
= lsmash_create_multiple_buffers( 2, EAC3_MAX_SYNCFRAME_LENGTH
);
345 if( !eac3_imp
->au_buffers
)
347 lsmash_bits_cleanup( info
->bits
);
348 lsmash_free( eac3_imp
);
351 eac3_imp
->au
= lsmash_withdraw_buffer( eac3_imp
->au_buffers
, 1 );
352 eac3_imp
->incomplete_au
= lsmash_withdraw_buffer( eac3_imp
->au_buffers
, 2 );
356 static void eac3_importer_cleanup( importer_t
*importer
)
358 debug_if( importer
&& importer
->info
)
359 remove_eac3_importer( importer
->info
);
362 static int eac3_importer_get_next_accessunit_internal( importer_t
*importer
)
364 int au_completed
= 0;
365 eac3_importer_t
*eac3_imp
= (eac3_importer_t
*)importer
->info
;
366 eac3_info_t
*info
= &eac3_imp
->info
;
367 lsmash_bs_t
*bs
= info
->bits
->bs
;
368 while( !au_completed
)
370 /* Read data from the stream if needed. */
371 eac3_imp
->next_frame_pos
+= info
->frame_size
;
372 lsmash_bs_read_seek( bs
, eac3_imp
->next_frame_pos
, SEEK_SET
);
373 uint64_t remain_size
= lsmash_bs_get_remaining_buffer_size( bs
);
374 if( remain_size
< EAC3_MAX_SYNCFRAME_LENGTH
)
376 if( bs
->buffer
.pos
> EAC3_MAX_SYNCFRAME_LENGTH
* 1000 )
377 lsmash_bs_dispose_past_data( bs
);
378 int err
= lsmash_bs_read( bs
, bs
->buffer
.max_size
);
381 lsmash_log( importer
, LSMASH_LOG_ERROR
, "failed to read data from the stream.\n" );
384 remain_size
= lsmash_bs_get_remaining_buffer_size( bs
);
386 uint64_t copy_size
= LSMASH_MIN( remain_size
, EAC3_MAX_SYNCFRAME_LENGTH
);
387 memcpy( eac3_imp
->buffer
, lsmash_bs_get_buffer_data( bs
), copy_size
);
388 /* Check the remainder length of the buffer.
389 * If there is enough length, then parse the syncframe in it.
390 * The length 5 is the required byte length to get frame size. */
391 if( bs
->eob
|| (bs
->eof
&& remain_size
< 5) )
393 /* Reached the end of stream.
394 * According to ETSI TS 102 366 V1.2.1 (2008-08),
395 * one access unit consists of 6 audio blocks and begins with independent substream 0.
396 * The specification doesn't mention the case where a enhanced AC-3 stream ends at non-mod6 audio blocks.
397 * At the end of the stream, therefore, we might make an access unit which has less than 6 audio blocks anyway. */
398 importer
->status
= IMPORTER_EOF
;
399 au_completed
= !!eac3_imp
->incomplete_au_length
;
402 /* No more access units in the stream. */
403 if( lsmash_bs_get_remaining_buffer_size( bs
) )
405 lsmash_log( importer
, LSMASH_LOG_WARNING
, "the stream is truncated at the end.\n" );
406 return LSMASH_ERR_INVALID_DATA
;
410 if( !info
->dec3_param_initialized
)
411 eac3_update_specific_param( info
);
415 /* Check the syncword. */
416 if( lsmash_bs_show_byte( bs
, 0 ) != 0x0b
417 || lsmash_bs_show_byte( bs
, 1 ) != 0x77 )
419 lsmash_log( importer
, LSMASH_LOG_ERROR
, "a syncword is not found.\n" );
420 return LSMASH_ERR_INVALID_DATA
;
422 /* Parse syncframe. */
423 info
->frame_size
= 0;
424 int err
= eac3_parse_syncframe( info
);
427 lsmash_log( importer
, LSMASH_LOG_ERROR
, "failed to parse syncframe.\n" );
430 if( remain_size
< info
->frame_size
)
432 lsmash_log( importer
, LSMASH_LOG_ERROR
, "a frame is truncated.\n" );
433 return LSMASH_ERR_INVALID_DATA
;
435 int independent
= info
->strmtyp
!= 0x1;
436 if( independent
&& info
->substreamid
== 0x0 )
438 if( info
->number_of_audio_blocks
== 6 )
440 /* Encountered the first syncframe of the next access unit. */
441 info
->number_of_audio_blocks
= 0;
444 else if( info
->number_of_audio_blocks
> 6 )
446 lsmash_log( importer
, LSMASH_LOG_ERROR
, "greater than 6 consecutive independent substreams.\n" );
447 return LSMASH_ERR_INVALID_DATA
;
449 info
->number_of_audio_blocks
+= eac3_audio_block_table
[ info
->numblkscod
];
450 info
->number_of_independent_substreams
= 0;
451 eac3_imp
->current_fscod2
= info
->fscod2
;
453 else if( info
->syncframe_count
== 0 )
455 /* The first syncframe in an AU must be independent and assigned substream ID 0. */
456 lsmash_log( importer
, LSMASH_LOG_ERROR
, "the first syncframe is NOT an independent substream.\n" );
457 return LSMASH_ERR_INVALID_DATA
;
460 info
->independent_info
[info
->number_of_independent_substreams
++].num_dep_sub
= 0;
462 ++ info
->independent_info
[info
->number_of_independent_substreams
- 1].num_dep_sub
;
466 memcpy( eac3_imp
->au
, eac3_imp
->incomplete_au
, eac3_imp
->incomplete_au_length
);
467 eac3_imp
->au_length
= eac3_imp
->incomplete_au_length
;
468 eac3_imp
->incomplete_au_length
= 0;
469 eac3_imp
->syncframe_count_in_au
= info
->syncframe_count
;
470 info
->syncframe_count
= 0;
471 if( importer
->status
== IMPORTER_EOF
)
474 /* Increase buffer size to store AU if short. */
475 if( eac3_imp
->incomplete_au_length
+ info
->frame_size
> eac3_imp
->au_buffers
->buffer_size
)
477 lsmash_multiple_buffers_t
*temp
= lsmash_resize_multiple_buffers( eac3_imp
->au_buffers
,
478 eac3_imp
->au_buffers
->buffer_size
+ EAC3_MAX_SYNCFRAME_LENGTH
);
480 return LSMASH_ERR_MEMORY_ALLOC
;
481 eac3_imp
->au_buffers
= temp
;
482 eac3_imp
->au
= lsmash_withdraw_buffer( eac3_imp
->au_buffers
, 1 );
483 eac3_imp
->incomplete_au
= lsmash_withdraw_buffer( eac3_imp
->au_buffers
, 2 );
485 /* Append syncframe data. */
486 memcpy( eac3_imp
->incomplete_au
+ eac3_imp
->incomplete_au_length
, eac3_imp
->buffer
, info
->frame_size
);
487 eac3_imp
->incomplete_au_length
+= info
->frame_size
;
488 ++ info
->syncframe_count
;
490 return bs
->error
? LSMASH_ERR_NAMELESS
: 0;
493 static int eac3_importer_get_accessunit( importer_t
*importer
, uint32_t track_number
, lsmash_sample_t
**p_sample
)
495 if( !importer
->info
)
496 return LSMASH_ERR_NAMELESS
;
497 if( track_number
!= 1 )
498 return LSMASH_ERR_FUNCTION_PARAM
;
499 lsmash_audio_summary_t
*summary
= (lsmash_audio_summary_t
*)lsmash_list_get_entry_data( importer
->summaries
, track_number
);
501 return LSMASH_ERR_NAMELESS
;
502 eac3_importer_t
*eac3_imp
= (eac3_importer_t
*)importer
->info
;
503 eac3_info_t
*info
= &eac3_imp
->info
;
504 importer_status current_status
= importer
->status
;
505 if( current_status
== IMPORTER_ERROR
)
506 return LSMASH_ERR_NAMELESS
;
507 if( current_status
== IMPORTER_EOF
&& eac3_imp
->au_length
== 0 )
509 if( current_status
== IMPORTER_CHANGE
)
511 lsmash_codec_specific_t
*cs
= isom_get_codec_specific( summary
->opaque
, LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_EC_3
);
514 cs
->destruct( cs
->data
.unstructured
);
515 cs
->data
.unstructured
= eac3_imp
->next_dec3
;
516 cs
->size
= eac3_imp
->next_dec3_length
;
518 summary
->max_au_length
= eac3_imp
->syncframe_count_in_au
* EAC3_MAX_SYNCFRAME_LENGTH
;
519 eac3_update_sample_rate( &summary
->frequency
, &info
->dec3_param
, &eac3_imp
->current_fscod2
);
520 eac3_update_channel_count( &summary
->channels
, &info
->dec3_param
);
522 lsmash_sample_t
*sample
= lsmash_create_sample( eac3_imp
->au_length
);
524 return LSMASH_ERR_MEMORY_ALLOC
;
526 memcpy( sample
->data
, eac3_imp
->au
, eac3_imp
->au_length
);
527 sample
->length
= eac3_imp
->au_length
;
528 sample
->dts
= eac3_imp
->au_number
++ * summary
->samples_in_frame
;
529 sample
->cts
= sample
->dts
;
530 sample
->prop
.ra_flags
= ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC
;
531 sample
->prop
.pre_roll
.distance
= 1; /* MDCT */
532 if( importer
->status
== IMPORTER_EOF
)
534 eac3_imp
->au_length
= 0;
537 uint32_t old_syncframe_count_in_au
= eac3_imp
->syncframe_count_in_au
;
538 if( eac3_importer_get_next_accessunit_internal( importer
) < 0 )
540 importer
->status
= IMPORTER_ERROR
;
541 return current_status
;
543 if( eac3_imp
->syncframe_count_in_au
)
545 /* Check sample description change. */
547 uint8_t *dec3
= lsmash_create_eac3_specific_info( &info
->dec3_param
, &new_length
);
550 importer
->status
= IMPORTER_ERROR
;
551 return current_status
;
553 lsmash_codec_specific_t
*cs
= isom_get_codec_specific( summary
->opaque
, LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_EC_3
);
554 if( (eac3_imp
->syncframe_count_in_au
> old_syncframe_count_in_au
)
555 || (cs
&& (new_length
!= cs
->size
|| memcmp( dec3
, cs
->data
.unstructured
, cs
->size
))) )
557 importer
->status
= IMPORTER_CHANGE
;
558 eac3_imp
->next_dec3
= dec3
;
559 eac3_imp
->next_dec3_length
= new_length
;
563 if( importer
->status
!= IMPORTER_EOF
)
564 importer
->status
= IMPORTER_OK
;
568 return current_status
;
571 static lsmash_audio_summary_t
*eac3_create_summary( eac3_importer_t
*eac3_imp
)
573 lsmash_audio_summary_t
*summary
= (lsmash_audio_summary_t
*)lsmash_create_summary( LSMASH_SUMMARY_TYPE_AUDIO
);
576 eac3_info_t
*info
= &eac3_imp
->info
;
577 lsmash_codec_specific_t
*cs
= lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_EC_3
,
578 LSMASH_CODEC_SPECIFIC_FORMAT_UNSTRUCTURED
);
581 lsmash_cleanup_summary( (lsmash_summary_t
*)summary
);
584 cs
->data
.unstructured
= lsmash_create_eac3_specific_info( &info
->dec3_param
, &cs
->size
);
585 if( !cs
->data
.unstructured
586 || lsmash_list_add_entry( &summary
->opaque
->list
, cs
) < 0 )
588 lsmash_cleanup_summary( (lsmash_summary_t
*)summary
);
589 lsmash_destroy_codec_specific_data( cs
);
592 summary
->sample_type
= ISOM_CODEC_TYPE_EC_3_AUDIO
;
593 summary
->max_au_length
= eac3_imp
->syncframe_count_in_au
* EAC3_MAX_SYNCFRAME_LENGTH
;
594 summary
->aot
= MP4A_AUDIO_OBJECT_TYPE_NULL
; /* no effect */
595 summary
->sample_size
= 16; /* no effect */
596 summary
->samples_in_frame
= EAC3_MIN_SAMPLE_DURATION
* 6; /* 256 (samples per audio block) * 6 (audio blocks) */
597 summary
->sbr_mode
= MP4A_AAC_SBR_NOT_SPECIFIED
; /* no effect */
598 eac3_update_sample_rate( &summary
->frequency
, &info
->dec3_param
, &eac3_imp
->current_fscod2
);
599 eac3_update_channel_count( &summary
->channels
, &info
->dec3_param
);
603 static int eac3_importer_probe( importer_t
*importer
)
605 eac3_importer_t
*eac3_imp
= create_eac3_importer( importer
);
607 return LSMASH_ERR_MEMORY_ALLOC
;
608 lsmash_bits_t
*bits
= eac3_imp
->info
.bits
;
609 lsmash_bs_t
*bs
= bits
->bs
;
610 bs
->buffer
.max_size
= EAC3_MAX_SYNCFRAME_LENGTH
;
611 importer
->info
= eac3_imp
;
612 int err
= eac3_importer_get_next_accessunit_internal( importer
);
615 lsmash_audio_summary_t
*summary
= eac3_create_summary( eac3_imp
);
618 err
= LSMASH_ERR_NAMELESS
;
621 if( importer
->status
!= IMPORTER_EOF
)
622 importer
->status
= IMPORTER_OK
;
623 eac3_imp
->au_number
= 0;
624 if( lsmash_list_add_entry( importer
->summaries
, summary
) < 0 )
626 lsmash_cleanup_summary( (lsmash_summary_t
*)summary
);
627 err
= LSMASH_ERR_MEMORY_ALLOC
;
632 remove_eac3_importer( eac3_imp
);
633 importer
->info
= NULL
;
637 static uint32_t eac3_importer_get_last_delta( importer_t
*importer
, uint32_t track_number
)
639 debug_if( !importer
|| !importer
->info
)
641 eac3_importer_t
*eac3_imp
= (eac3_importer_t
*)importer
->info
;
642 if( !eac3_imp
|| track_number
!= 1 || importer
->status
!= IMPORTER_EOF
|| eac3_imp
->au_length
)
644 return EAC3_MIN_SAMPLE_DURATION
* eac3_imp
->info
.number_of_audio_blocks
;
647 const importer_functions eac3_importer
=
649 { "Enhanced AC-3", offsetof( importer_t
, log_level
) },
652 eac3_importer_get_accessunit
,
653 eac3_importer_get_last_delta
,
654 eac3_importer_cleanup