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( &current_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