1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2010 L-SMASH project
6 * Authors: Takashi Hirata <silverfilain@gmail.com>
7 * Contributors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
9 * Permission to use, copy, modify, and/or distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 *****************************************************************************/
22 /* This file is available under an ISC license. */
24 #include "internal.h" /* must be placed first */
29 #define LSMASH_IMPORTER_INTERNAL
35 /***************************************************************************
37 ***************************************************************************/
38 struct mp4sys_importer_tag
;
40 typedef void ( *mp4sys_importer_cleanup
)( struct mp4sys_importer_tag
* importer
);
41 typedef int ( *mp4sys_importer_get_accessunit
)( struct mp4sys_importer_tag
*, uint32_t track_number
, void* buf
, uint32_t* size
);
42 typedef int ( *mp4sys_importer_probe
)( struct mp4sys_importer_tag
* importer
);
48 mp4sys_importer_probe probe
;
49 mp4sys_importer_get_accessunit get_accessunit
;
50 mp4sys_importer_cleanup cleanup
;
51 } mp4sys_importer_functions
;
53 typedef struct mp4sys_importer_tag
57 void* info
; /* importer internal status information. */
58 mp4sys_importer_functions funcs
;
59 lsmash_entry_list_t
* summaries
;
64 MP4SYS_IMPORTER_ERROR
= -1,
65 MP4SYS_IMPORTER_OK
= 0,
66 MP4SYS_IMPORTER_CHANGE
= 1,
67 MP4SYS_IMPORTER_EOF
= 2,
68 } mp4sys_importer_status
;
70 /***************************************************************************
72 ***************************************************************************/
73 #define MP4SYS_ADTS_FIXED_HEADER_LENGTH 4 /* this is partly a lie. actually 28 bits. */
74 #define MP4SYS_ADTS_BASIC_HEADER_LENGTH 7
75 #define MP4SYS_ADTS_MAX_FRAME_LENGTH ( ( 1 << 13 ) - 1 )
76 #define MP4SYS_ADTS_MAX_RAW_DATA_BLOCKS 4
80 uint16_t syncword
; /* 12; */
82 uint8_t layer
; /* 2; */
83 uint8_t protection_absent
; /* 1; */
84 uint8_t profile_ObjectType
; /* 2; */
85 uint8_t sampling_frequency_index
; /* 4; */
86 // uint8_t private_bit; /* 1; we don't care. */
87 uint8_t channel_configuration
; /* 3; */
88 // uint8_t original_copy; /* 1; we don't care. */
89 // uint8_t home; /* 1; we don't care. */
91 } mp4sys_adts_fixed_header_t
;
95 // uint8_t copyright_identification_bit; /* 1; we don't care. */
96 // uint8_t copyright_identification_start; /* 1; we don't care. */
97 uint16_t frame_length
; /* 13; */
98 // uint16_t adts_buffer_fullness; /* 11; we don't care. */
99 uint8_t number_of_raw_data_blocks_in_frame
; /* 2; */
100 // uint16_t adts_error_check; /* we don't support */
101 // uint16_t raw_data_block_position[MP4SYS_ADTS_MAX_RAW_DATA_BLOCKS-1]; /* we don't use this directly, and... */
102 uint16_t raw_data_block_size
[MP4SYS_ADTS_MAX_RAW_DATA_BLOCKS
]; /* use this instead of above. */
103 // uint16_t adts_header_error_check; /* we don't support, actually crc_check within this */
104 // uint16_t adts_raw_data_block_error_check[MP4SYS_ADTS_MAX_RAW_DATA_BLOCKS]; /* we don't support */
105 } mp4sys_adts_variable_header_t
;
107 static void mp4sys_adts_parse_fixed_header( uint8_t* buf
, mp4sys_adts_fixed_header_t
* header
)
109 /* FIXME: should we rewrite these code using bitstream reader? */
110 header
->syncword
= (buf
[0] << 4) | (buf
[1] >> 4);
111 header
->ID
= (buf
[1] >> 3) & 0x1;
112 header
->layer
= (buf
[1] >> 1) & 0x3;
113 header
->protection_absent
= buf
[1] & 0x1;
114 header
->profile_ObjectType
= buf
[2] >> 6;
115 header
->sampling_frequency_index
= (buf
[2] >> 2) & 0xF;
116 // header->private_bit = (buf[2] >> 1) & 0x1; /* we don't care currently. */
117 header
->channel_configuration
= ((buf
[2] << 2) | (buf
[3] >> 6)) & 0x07;
118 // header->original_copy = (buf[3] >> 5) & 0x1; /* we don't care currently. */
119 // header->home = (buf[3] >> 4) & 0x1; /* we don't care currently. */
122 static int mp4sys_adts_check_fixed_header( mp4sys_adts_fixed_header_t
* header
)
124 if( header
->syncword
!= 0xFFF ) return -1;
125 // if( header->ID != 0x0 ) return -1; /* we don't care. */
126 if( header
->layer
!= 0x0 ) return -1; /* must be 0b00 for any type of AAC */
127 // if( header->protection_absent != 0x1 ) return -1; /* we don't care. */
128 if( header
->profile_ObjectType
!= 0x1 ) return -1; /* FIXME: 0b00=Main, 0b01=LC, 0b10=SSR, 0b11=LTP. */
129 if( header
->sampling_frequency_index
> 0xB ) return -1; /* must not be > 0xB. */
130 if( header
->channel_configuration
== 0x0 ) return -1; /* FIXME: we do not support 0b000 currently. */
131 if( header
->profile_ObjectType
== 0x3 && header
->ID
!= 0x0 ) return -1; /* LTP is valid only if ID==0. */
135 static int mp4sys_adts_parse_variable_header( FILE* stream
, uint8_t* buf
, unsigned int protection_absent
, mp4sys_adts_variable_header_t
* header
)
137 /* FIXME: should we rewrite these code using bitstream reader? */
138 // header->copyright_identification_bit = (buf[3] >> 3) & 0x1; /* we don't care. */
139 // header->copyright_identification_start = (buf[3] >> 2) & 0x1; /* we don't care. */
140 header
->frame_length
= ((buf
[3] << 11) | (buf
[4] << 3) | (buf
[5] >> 5)) & 0x1FFF ;
141 // header->adts_buffer_fullness = ((buf[5] << 6) | (buf[6] >> 2)) 0x7FF ; /* we don't care. */
142 header
->number_of_raw_data_blocks_in_frame
= buf
[6] & 0x3;
144 if( header
->frame_length
<= MP4SYS_ADTS_BASIC_HEADER_LENGTH
+ 2 * (protection_absent
== 0) )
145 return -1; /* easy error check */
147 /* protection_absent and number_of_raw_data_blocks_in_frame relatives */
150 unsigned int number_of_blocks
= header
->number_of_raw_data_blocks_in_frame
;
151 if( number_of_blocks
== 0 )
153 header
->raw_data_block_size
[0] = header
->frame_length
- MP4SYS_ADTS_BASIC_HEADER_LENGTH
;
154 /* skip adts_error_check() and subtract that from block_size */
155 if( protection_absent
== 0 )
157 header
->raw_data_block_size
[0] -= 2;
158 if( fread( buf2
, 1, 2, stream
) != 2 )
164 /* now we have multiple raw_data_block()s, so evaluate adts_header_error_check() */
166 uint16_t raw_data_block_position
[MP4SYS_ADTS_MAX_RAW_DATA_BLOCKS
];
167 uint16_t first_offset
= MP4SYS_ADTS_BASIC_HEADER_LENGTH
;
168 if( protection_absent
== 0 )
170 /* process adts_header_error_check() */
171 for( int i
= 0 ; i
< number_of_blocks
; i
++ ) /* 1-based in the spec, but we use 0-based */
173 if( fread( buf2
, 1, 2, stream
) != 2 )
175 raw_data_block_position
[i
] = (buf2
[0] << 8) | buf2
[1];
177 /* skip crc_check in adts_header_error_check().
178 Or might be sizeof( adts_error_check() ) if we share with the case number_of_raw_data_blocks_in_frame == 0 */
179 if( fread( buf2
, 1, 2, stream
) != 2 )
181 first_offset
+= ( 2 * number_of_blocks
) + 2; /* according to above */
186 * NOTE: We never support the case where number_of_raw_data_blocks_in_frame != 0 && protection_absent != 0,
187 * because we have to parse the raw AAC bitstream itself to find boundaries of raw_data_block()s in this case.
188 * Which is to say, that braindamaged spec requires us (mp4 muxer) to decode AAC once to split frames.
189 * L-SMASH is NOT AAC DECODER, so that we've just given up for this case.
190 * This is ISO/IEC 13818-7's sin which defines ADTS format originally.
195 /* convert raw_data_block_position --> raw_data_block_size */
197 /* do conversion for first */
198 header
->raw_data_block_size
[0] = raw_data_block_position
[0] - first_offset
;
199 /* set dummy offset to tail for loop, do coversion for rest. */
200 raw_data_block_position
[number_of_blocks
] = header
->frame_length
;
201 for( int i
= 1 ; i
<= number_of_blocks
; i
++ )
202 header
->raw_data_block_size
[i
] = raw_data_block_position
[i
] - raw_data_block_position
[i
-1];
204 /* adjustment for adts_raw_data_block_error_check() */
205 if( protection_absent
== 0 && number_of_blocks
!= 0 )
206 for( int i
= 0 ; i
<= number_of_blocks
; i
++ )
207 header
->raw_data_block_size
[i
] -= 2;
212 static int mp4sys_adts_parse_headers( FILE* stream
, uint8_t* buf
, mp4sys_adts_fixed_header_t
* header
, mp4sys_adts_variable_header_t
* variable_header
)
214 mp4sys_adts_parse_fixed_header( buf
, header
);
215 if( mp4sys_adts_check_fixed_header( header
) )
217 /* get payload length & skip extra(crc) header */
218 return mp4sys_adts_parse_variable_header( stream
, buf
, header
->protection_absent
, variable_header
);
221 static lsmash_audio_summary_t
* mp4sys_adts_create_summary( mp4sys_adts_fixed_header_t
* header
)
223 lsmash_audio_summary_t
* summary
= lsmash_create_audio_summary();
226 summary
->sample_type
= ISOM_CODEC_TYPE_MP4A_AUDIO
;
227 summary
->object_type_indication
= MP4SYS_OBJECT_TYPE_Audio_ISO_14496_3
;
228 summary
->stream_type
= MP4SYS_STREAM_TYPE_AudioStream
;
229 summary
->max_au_length
= MP4SYS_ADTS_MAX_FRAME_LENGTH
;
230 summary
->frequency
= mp4a_AAC_frequency_table
[header
->sampling_frequency_index
][1];
231 summary
->channels
= header
->channel_configuration
+ ( header
->channel_configuration
== 0x07 ); /* 0x07 means 7.1ch */
232 summary
->bit_depth
= 16;
233 summary
->samples_in_frame
= 1024;
234 summary
->aot
= header
->profile_ObjectType
+ MP4A_AUDIO_OBJECT_TYPE_AAC_MAIN
;
235 summary
->sbr_mode
= MP4A_AAC_SBR_NOT_SPECIFIED
;
236 #if 0 /* FIXME: This is very unstable. Many players crash with this. */
237 if( header
->ID
!= 0 )
240 * NOTE: This ADTS seems of ISO/IEC 13818-7 (MPEG-2 AAC).
241 * It has special object_type_indications, depending on it's profile (Legacy Interface).
242 * If ADIF header is not available, it should not have decoder specific information, so AudioObjectType neither.
243 * see ISO/IEC 14496-1, DecoderSpecificInfo and 14496-3 Subpart 9: MPEG-1/2 Audio in MPEG-4.
245 summary
->object_type_indication
= header
->profile_ObjectType
+ MP4SYS_OBJECT_TYPE_Audio_ISO_13818_7_Main_Profile
;
246 summary
->aot
= MP4A_AUDIO_OBJECT_TYPE_NULL
;
248 summary
->asc_length
= 0;
249 // summary->sbr_mode = MP4A_AAC_SBR_NONE; /* MPEG-2 AAC should not be HE-AAC, but we forgive them. */
253 if( lsmash_setup_AudioSpecificConfig( summary
) )
255 lsmash_cleanup_audio_summary( summary
);
263 mp4sys_importer_status status
;
264 unsigned int raw_data_block_idx
;
265 mp4sys_adts_fixed_header_t header
;
266 mp4sys_adts_variable_header_t variable_header
;
267 } mp4sys_adts_info_t
;
269 static int mp4sys_adts_get_accessunit( mp4sys_importer_t
* importer
, uint32_t track_number
, void* userbuf
, uint32_t *size
)
271 debug_if( !importer
|| !importer
->info
|| !userbuf
|| !size
)
273 if( !importer
->info
|| track_number
!= 1 )
275 mp4sys_adts_info_t
* info
= (mp4sys_adts_info_t
*)importer
->info
;
276 mp4sys_importer_status current_status
= info
->status
;
277 uint16_t raw_data_block_size
= info
->variable_header
.raw_data_block_size
[info
->raw_data_block_idx
];
278 if( current_status
== MP4SYS_IMPORTER_ERROR
|| *size
< raw_data_block_size
)
280 if( current_status
== MP4SYS_IMPORTER_EOF
)
285 if( current_status
== MP4SYS_IMPORTER_CHANGE
)
287 lsmash_audio_summary_t
* summary
= mp4sys_adts_create_summary( &info
->header
);
290 lsmash_entry_t
* entry
= lsmash_get_entry( importer
->summaries
, track_number
);
291 if( !entry
|| !entry
->data
)
293 lsmash_cleanup_audio_summary( entry
->data
);
294 entry
->data
= summary
;
297 /* read a raw_data_block(), typically == payload of a ADTS frame */
298 if( fread( userbuf
, 1, raw_data_block_size
, importer
->stream
) != raw_data_block_size
)
300 info
->status
= MP4SYS_IMPORTER_ERROR
;
303 *size
= raw_data_block_size
;
305 /* now we succeeded to read current frame, so "return" takes 0 always below. */
307 /* skip adts_raw_data_block_error_check() */
308 if( info
->header
.protection_absent
== 0
309 && info
->variable_header
.number_of_raw_data_blocks_in_frame
!= 0
310 && fread( userbuf
, 1, 2, importer
->stream
) != 2 )
312 info
->status
= MP4SYS_IMPORTER_ERROR
;
315 /* current adts_frame() has any more raw_data_block()? */
316 if( info
->raw_data_block_idx
< info
->variable_header
.number_of_raw_data_blocks_in_frame
)
318 info
->raw_data_block_idx
++;
319 info
->status
= MP4SYS_IMPORTER_OK
;
322 info
->raw_data_block_idx
= 0;
324 /* preparation for next frame */
326 uint8_t buf
[MP4SYS_ADTS_MAX_FRAME_LENGTH
];
327 size_t ret
= fread( buf
, 1, MP4SYS_ADTS_BASIC_HEADER_LENGTH
, importer
->stream
);
330 info
->status
= MP4SYS_IMPORTER_EOF
;
333 if( ret
!= MP4SYS_ADTS_BASIC_HEADER_LENGTH
)
335 info
->status
= MP4SYS_IMPORTER_ERROR
;
339 * NOTE: About the spec of ADTS headers.
340 * By the spec definition, ADTS's fixed header cannot change in the middle of stream.
341 * But spec of MP4 allows that a stream(track) changes its properties in the middle of it.
344 * NOTE: About detailed check for ADTS headers.
345 * We do not ommit detailed check for fixed header by simply testing bits' identification,
346 * because there're some flags which does not matter to audio_summary (so AudioSpecificConfig neither)
347 * so that we can take them as no change and never make new ObjectDescriptor.
348 * I know that can be done with/by bitmask also and that should be fast, but L-SMASH project prefers
349 * even foolishly straightforward way.
352 * NOTE: About our reading algorithm for ADTS.
353 * It's rather simple if we retrieve payload of ADTS (i.e. raw AAC frame) at the same time to
355 * But then we have to cache and memcpy every frame so that it requires more clocks and memory.
356 * To avoid them, I adopted this separate retrieving method.
358 mp4sys_adts_fixed_header_t header
= {0};
359 mp4sys_adts_variable_header_t variable_header
= {0};
360 if( mp4sys_adts_parse_headers( importer
->stream
, buf
, &header
, &variable_header
) )
362 info
->status
= MP4SYS_IMPORTER_ERROR
;
365 info
->variable_header
= variable_header
;
368 * NOTE: About our support for change(s) of properties within an ADTS stream.
369 * We have to modify these conditions depending on the features we support.
370 * For example, if we support copyright_identification_* in any way within any feature
371 * defined by/in any specs, such as ISO/IEC 14496-1 (MPEG-4 Systems), like...
372 * "8.3 Intellectual Property Management and Protection (IPMP)", or something similar,
373 * we have to check copyright_identification_* and treat them in audio_summary.
374 * "Change(s)" may result in MP4SYS_IMPORTER_ERROR or MP4SYS_IMPORTER_CHANGE
375 * depending on the features we support, and what the spec allows.
376 * Sometimes the "change(s)" can be allowed, while sometimes they're forbidden.
378 /* currently UNsupported "change(s)". */
379 if( info
->header
.profile_ObjectType
!= header
.profile_ObjectType
/* currently unsupported. */
380 || info
->header
.ID
!= header
.ID
/* In strict, this means change of object_type_indication. */
381 || info
->header
.sampling_frequency_index
!= header
.sampling_frequency_index
) /* This may change timebase. */
383 info
->status
= MP4SYS_IMPORTER_ERROR
;
386 /* currently supported "change(s)". */
387 if( info
->header
.channel_configuration
!= header
.channel_configuration
)
390 * FIXME: About conditions of VALID "change(s)".
391 * we have to check whether any "change(s)" affect to audioProfileLevelIndication
392 * in InitialObjectDescriptor (MP4_IOD) or not.
393 * If another type or upper level is required by the change(s), that is forbidden.
394 * Because ObjectDescriptor does not have audioProfileLevelIndication,
395 * so that it seems impossible to change audioProfileLevelIndication in the middle of the stream.
396 * Note also any other properties, such as AudioObjectType, object_type_indication.
399 * NOTE: updating summary must be done on next call,
400 * because user may retrieve summary right after this function call of this time,
401 * and that should be of current, before change, one.
403 info
->header
= header
;
404 info
->status
= MP4SYS_IMPORTER_CHANGE
;
407 /* no change which matters to mp4 muxing was found */
408 info
->status
= MP4SYS_IMPORTER_OK
;
412 static void mp4sys_adts_cleanup( mp4sys_importer_t
* importer
)
414 debug_if( importer
&& importer
->info
)
415 free( importer
->info
);
418 /* returns 0 if it seems adts. */
419 static int mp4sys_adts_probe( mp4sys_importer_t
* importer
)
421 uint8_t buf
[MP4SYS_ADTS_MAX_FRAME_LENGTH
];
422 if( fread( buf
, 1, MP4SYS_ADTS_BASIC_HEADER_LENGTH
, importer
->stream
) != MP4SYS_ADTS_BASIC_HEADER_LENGTH
)
425 mp4sys_adts_fixed_header_t header
= {0};
426 mp4sys_adts_variable_header_t variable_header
= {0};
427 if( mp4sys_adts_parse_headers( importer
->stream
, buf
, &header
, &variable_header
) )
430 /* now the stream seems valid ADTS */
432 lsmash_audio_summary_t
* summary
= mp4sys_adts_create_summary( &header
);
436 /* importer status */
437 mp4sys_adts_info_t
* info
= malloc( sizeof(mp4sys_adts_info_t
) );
440 lsmash_cleanup_audio_summary( summary
);
443 memset( info
, 0, sizeof(mp4sys_adts_info_t
) );
444 info
->status
= MP4SYS_IMPORTER_OK
;
445 info
->raw_data_block_idx
= 0;
446 info
->header
= header
;
447 info
->variable_header
= variable_header
;
449 if( lsmash_add_entry( importer
->summaries
, summary
) )
452 lsmash_cleanup_audio_summary( summary
);
455 importer
->info
= info
;
460 const static mp4sys_importer_functions mp4sys_adts_importer
= {
464 mp4sys_adts_get_accessunit
,
468 /***************************************************************************
469 mp3 (Legacy Interface) importer
470 ***************************************************************************/
472 static void mp4sys_mp3_cleanup( mp4sys_importer_t
* importer
)
474 debug_if( importer
&& importer
->info
)
475 free( importer
->info
);
480 uint16_t syncword
; /* <12> */
481 uint8_t ID
; /* <1> */
482 uint8_t layer
; /* <2> */
483 // uint8_t protection_bit; /* <1> don't care. */
484 uint8_t bitrate_index
; /* <4> */
485 uint8_t sampling_frequency
; /* <2> */
486 uint8_t padding_bit
; /* <1> */
487 // uint8_t private_bit; /* <1> don't care. */
488 uint8_t mode
; /* <2> */
489 // uint8_t mode_extension; /* <2> don't care. */
490 // uint8_t copyright; /* <1> don't care. */
491 // uint8_t original_copy; /* <1> don't care. */
492 uint8_t emphasis
; /* <2> for error check only. */
494 } mp4sys_mp3_header_t
;
496 static int mp4sys_mp3_parse_header( uint8_t* buf
, mp4sys_mp3_header_t
* header
)
498 /* FIXME: should we rewrite these code using bitstream reader? */
499 uint32_t data
= (buf
[0] << 24) | (buf
[1] << 16) | (buf
[2] << 8) | buf
[3];
500 header
->syncword
= (data
>> 20) & 0xFFF; /* NOTE: don't consider what is called MPEG2.5, which last bit is 0. */
501 header
->ID
= (data
>> 19) & 0x1;
502 header
->layer
= (data
>> 17) & 0x3;
503 // header->protection_bit = (data >> 16) & 0x1; /* don't care. */
504 header
->bitrate_index
= (data
>> 12) & 0xF;
505 header
->sampling_frequency
= (data
>> 10) & 0x3;
506 header
->padding_bit
= (data
>> 9) & 0x1;
507 // header->private_bit = (data >> 8) & 0x1; /* don't care. */
508 header
->mode
= (data
>> 6) & 0x3;
509 // header->mode_extension = (data >> 4) & 0x3;
510 // header->copyright = (data >> 3) & 0x1; /* don't care. */
511 // header->original_copy = (data >> 2) & 0x1; /* don't care. */
512 header
->emphasis
= data
& 0x3; /* for error check only. */
514 if( header
->syncword
!= 0xFFF ) return -1;
515 if( header
->layer
== 0x0 ) return -1;
516 if( header
->bitrate_index
== 0x0 || header
->bitrate_index
== 0xF ) return -1; /* FIXME: "free" bitrate is unsupported currently. */
517 if( header
->sampling_frequency
== 0x3) return -1;
518 if( header
->emphasis
== 0x2) return -1;
522 #define MP4SYS_MP3_MAX_FRAME_LENGTH (1152*(16/8)*2)
523 #define MP4SYS_MP3_HEADER_LENGTH 4
524 #define MP4SYS_MODE_IS_2CH( mode ) (!!~(mode))
525 #define MP4SYS_LAYER_I 0x3
527 static const uint32_t mp4sys_mp3_frequency_tbl
[2][3] = {
528 { 22050, 24000, 16000 }, /* MPEG-2 BC audio */
529 { 44100, 48000, 32000 } /* MPEG-1 audio */
532 static lsmash_audio_summary_t
* mp4sys_mp3_create_summary( mp4sys_mp3_header_t
* header
, int legacy_mode
)
534 lsmash_audio_summary_t
* summary
= lsmash_create_audio_summary();
537 summary
->sample_type
= ISOM_CODEC_TYPE_MP4A_AUDIO
;
538 summary
->object_type_indication
= header
->ID
? MP4SYS_OBJECT_TYPE_Audio_ISO_11172_3
: MP4SYS_OBJECT_TYPE_Audio_ISO_13818_3
;
539 summary
->stream_type
= MP4SYS_STREAM_TYPE_AudioStream
;
540 summary
->max_au_length
= MP4SYS_MP3_MAX_FRAME_LENGTH
;
541 summary
->frequency
= mp4sys_mp3_frequency_tbl
[header
->ID
][header
->sampling_frequency
];
542 summary
->channels
= MP4SYS_MODE_IS_2CH( header
->mode
) + 1;
543 summary
->bit_depth
= 16;
544 summary
->samples_in_frame
= header
->layer
== MP4SYS_LAYER_I
? 384 : 1152;
545 summary
->aot
= MP4A_AUDIO_OBJECT_TYPE_Layer_1
+ (MP4SYS_LAYER_I
- header
->layer
); /* no effect with Legacy Interface. */
546 summary
->sbr_mode
= MP4A_AAC_SBR_NOT_SPECIFIED
; /* no effect */
547 summary
->exdata
= NULL
;
548 summary
->exdata_length
= 0;
549 #if 0 /* FIXME: This is very unstable. Many players crash with this. */
552 summary
->object_type_indication
= MP4SYS_OBJECT_TYPE_Audio_ISO_14496_3
;
553 if( lsmash_setup_AudioSpecificConfig( summary
) )
555 lsmash_cleanup_audio_summary( summary
);
565 mp4sys_importer_status status
;
566 mp4sys_mp3_header_t header
;
567 uint8_t raw_header
[MP4SYS_MP3_HEADER_LENGTH
];
570 static int mp4sys_mp3_get_accessunit( mp4sys_importer_t
* importer
, uint32_t track_number
, void* userbuf
, uint32_t *size
)
572 debug_if( !importer
|| !importer
->info
|| !userbuf
|| !size
)
574 if( !importer
->info
|| track_number
!= 1 )
576 mp4sys_mp3_info_t
* info
= (mp4sys_mp3_info_t
*)importer
->info
;
577 mp4sys_mp3_header_t
* header
= (mp4sys_mp3_header_t
*)&info
->header
;
578 mp4sys_importer_status current_status
= info
->status
;
580 const uint32_t bitrate_tbl
[2][3][16] = {
581 { /* MPEG-2 BC audio */
582 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, /* Layer III */
583 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, /* Layer II */
584 { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 } /* Layer I */
587 { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 }, /* Layer III */
588 { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0 }, /* Layer II */
589 { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0 } /* Layer I */
592 uint32_t bitrate
= bitrate_tbl
[header
->ID
][header
->layer
-1][header
->bitrate_index
];
593 uint32_t frequency
= mp4sys_mp3_frequency_tbl
[header
->ID
][header
->sampling_frequency
];
594 debug_if( bitrate
== 0 || frequency
== 0 )
597 if( header
->layer
== MP4SYS_LAYER_I
)
599 /* mp1's 'slot' is 4 bytes unit. see 11172-3, Audio Sequence General. */
600 frame_size
= ( 12 * 1000 * bitrate
/ frequency
+ header
->padding_bit
) * 4;
604 /* mp2/3's 'slot' is 1 bytes unit. */
605 frame_size
= 144 * 1000 * bitrate
/ frequency
+ header
->padding_bit
;
608 if( current_status
== MP4SYS_IMPORTER_ERROR
|| frame_size
<= 4 || *size
< frame_size
)
610 if( current_status
== MP4SYS_IMPORTER_EOF
)
615 if( current_status
== MP4SYS_IMPORTER_CHANGE
)
617 lsmash_audio_summary_t
* summary
= mp4sys_mp3_create_summary( header
, 1 ); /* FIXME: use legacy mode. */
620 lsmash_entry_t
* entry
= lsmash_get_entry( importer
->summaries
, track_number
);
621 if( !entry
|| !entry
->data
)
623 lsmash_cleanup_audio_summary( entry
->data
);
624 entry
->data
= summary
;
626 /* read a frame's data. */
627 memcpy( userbuf
, info
->raw_header
, MP4SYS_MP3_HEADER_LENGTH
);
628 frame_size
-= MP4SYS_MP3_HEADER_LENGTH
;
629 if( fread( ((uint8_t*)userbuf
)+MP4SYS_MP3_HEADER_LENGTH
, 1, frame_size
, importer
->stream
) != frame_size
)
631 info
->status
= MP4SYS_IMPORTER_ERROR
;
634 *size
= MP4SYS_MP3_HEADER_LENGTH
+ frame_size
;
636 /* now we succeeded to read current frame, so "return" takes 0 always below. */
637 /* preparation for next frame */
639 uint8_t buf
[MP4SYS_MP3_HEADER_LENGTH
];
640 size_t ret
= fread( buf
, 1, MP4SYS_MP3_HEADER_LENGTH
, importer
->stream
);
643 info
->status
= MP4SYS_IMPORTER_EOF
;
646 if( ret
== 1 && *buf
== 0x00 )
648 /* NOTE: ugly hack for mp1 stream created with SCMPX. */
649 info
->status
= MP4SYS_IMPORTER_EOF
;
652 if( ret
!= MP4SYS_MP3_HEADER_LENGTH
)
654 info
->status
= MP4SYS_IMPORTER_ERROR
;
658 mp4sys_mp3_header_t new_header
= {0};
659 if( mp4sys_mp3_parse_header( buf
, &new_header
) )
661 info
->status
= MP4SYS_IMPORTER_ERROR
;
664 memcpy( info
->raw_header
, buf
, MP4SYS_MP3_HEADER_LENGTH
);
666 /* currently UNsupported "change(s)". */
667 if( header
->layer
!= new_header
.layer
/* This means change of object_type_indication with Legacy Interface. */
668 || header
->sampling_frequency
!= new_header
.sampling_frequency
) /* This may change timescale. */
670 info
->status
= MP4SYS_IMPORTER_ERROR
;
674 /* currently supported "change(s)". */
675 if( MP4SYS_MODE_IS_2CH( header
->mode
) != MP4SYS_MODE_IS_2CH( new_header
.mode
) )
676 info
->status
= MP4SYS_IMPORTER_CHANGE
;
678 info
->status
= MP4SYS_IMPORTER_OK
; /* no change which matters to mp4 muxing was found */
679 info
->header
= new_header
;
683 static int mp4sys_mp3_probe( mp4sys_importer_t
* importer
)
685 uint8_t buf
[MP4SYS_MP3_HEADER_LENGTH
];
686 if( fread( buf
, 1, MP4SYS_MP3_HEADER_LENGTH
, importer
->stream
) != MP4SYS_MP3_HEADER_LENGTH
)
689 mp4sys_mp3_header_t header
= {0};
690 if( mp4sys_mp3_parse_header( buf
, &header
) )
693 /* now the stream seems valid mp3 */
695 lsmash_audio_summary_t
* summary
= mp4sys_mp3_create_summary( &header
, 1 ); /* FIXME: use legacy mode. */
699 /* importer status */
700 mp4sys_mp3_info_t
* info
= malloc( sizeof(mp4sys_mp3_info_t
) );
703 lsmash_cleanup_audio_summary( summary
);
706 memset( info
, 0, sizeof(mp4sys_mp3_info_t
) );
707 info
->status
= MP4SYS_IMPORTER_OK
;
708 info
->header
= header
;
709 memcpy( info
->raw_header
, buf
, MP4SYS_MP3_HEADER_LENGTH
);
711 if( lsmash_add_entry( importer
->summaries
, summary
) )
714 lsmash_cleanup_audio_summary( summary
);
717 importer
->info
= info
;
722 const static mp4sys_importer_functions mp4sys_mp3_importer
= {
723 "MPEG-1/2BC_Audio_Legacy",
726 mp4sys_mp3_get_accessunit
,
730 /***************************************************************************
731 AMR-NB/WB storage format importer
732 http://www.ietf.org/rfc/rfc3267.txt (Obsoleted)
733 http://www.ietf.org/rfc/rfc4867.txt
734 ***************************************************************************/
735 static void mp4sys_amr_cleanup( mp4sys_importer_t
* importer
)
737 debug_if( importer
&& importer
->info
)
738 free( importer
->info
);
741 static int mp4sys_amr_get_accessunit( mp4sys_importer_t
* importer
, uint32_t track_number
, void* userbuf
, uint32_t *size
)
743 debug_if( !importer
|| !importer
->info
|| !userbuf
|| !size
)
745 if( track_number
!= 1 )
747 uint8_t wb
= *(uint8_t*)importer
->info
;
749 uint8_t* buf
= userbuf
;
750 if( fread( buf
, 1, 1, importer
->stream
) == 0 )
756 uint8_t FT
= (*buf
>> 3) & 0x0F;
758 /* AMR-NB has varieties of frame-size table like this. so I'm not sure yet. */
759 const int frame_size
[2][16] = {
760 { 13, 14, 16, 18, 20, 21, 27, 32, 5, 5, 5, 5, 0, 0, 0, 1 },
761 { 18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1 }
763 int read_size
= frame_size
[wb
][FT
];
764 if( read_size
== 0 || *size
< read_size
-- )
771 if( fread( buf
+1, 1, read_size
, importer
->stream
) != read_size
)
773 *size
= read_size
+ 1;
777 #define MP4SYS_DAMR_LENGTH 17
779 int mp4sys_amr_create_damr( lsmash_audio_summary_t
*summary
)
781 lsmash_bs_t
* bs
= lsmash_bs_create( NULL
); /* no file writing */
784 lsmash_bs_put_be32( bs
, MP4SYS_DAMR_LENGTH
);
785 lsmash_bs_put_be32( bs
, ISOM_BOX_TYPE_DAMR
);
786 /* NOTE: These are specific to each codec vendor, but we're surely not a vendor.
788 lsmash_bs_put_be32( bs
, 0x20202020 ); /* vendor */
789 lsmash_bs_put_byte( bs
, 0 ); /* decoder_version */
791 /* NOTE: Using safe value for these settings, maybe sub-optimal. */
792 lsmash_bs_put_be16( bs
, 0x83FF ); /* mode_set, represents for possibly existing frame-type (0x83FF == all). */
793 lsmash_bs_put_byte( bs
, 1 ); /* mode_change_period */
794 lsmash_bs_put_byte( bs
, 1 ); /* frames_per_sample */
796 if( summary
->exdata
)
797 free( summary
->exdata
);
798 summary
->exdata
= lsmash_bs_export_data( bs
, &summary
->exdata_length
);
799 lsmash_bs_cleanup( bs
);
800 if( !summary
->exdata
)
802 summary
->exdata_length
= MP4SYS_DAMR_LENGTH
;
806 #define MP4SYS_AMR_STORAGE_MAGIC_LENGTH 6
807 #define MP4SYS_AMRWB_EX_MAGIC_LENGTH 3
809 static int mp4sys_amr_probe( mp4sys_importer_t
* importer
)
811 uint8_t buf
[MP4SYS_AMR_STORAGE_MAGIC_LENGTH
];
813 if( fread( buf
, 1, MP4SYS_AMR_STORAGE_MAGIC_LENGTH
, importer
->stream
) != MP4SYS_AMR_STORAGE_MAGIC_LENGTH
)
815 if( memcmp( buf
, "#!AMR", MP4SYS_AMR_STORAGE_MAGIC_LENGTH
-1 ) )
817 if( buf
[MP4SYS_AMR_STORAGE_MAGIC_LENGTH
-1] != '\n' )
819 if( buf
[MP4SYS_AMR_STORAGE_MAGIC_LENGTH
-1] != '-' )
821 if( fread( buf
, 1, MP4SYS_AMRWB_EX_MAGIC_LENGTH
, importer
->stream
) != MP4SYS_AMRWB_EX_MAGIC_LENGTH
)
823 if( memcmp( buf
, "WB\n", MP4SYS_AMRWB_EX_MAGIC_LENGTH
) )
827 lsmash_audio_summary_t
* summary
= lsmash_create_audio_summary();
830 summary
->sample_type
= wb
? ISOM_CODEC_TYPE_SAWB_AUDIO
: ISOM_CODEC_TYPE_SAMR_AUDIO
;
831 summary
->object_type_indication
= MP4SYS_OBJECT_TYPE_NONE
; /* AMR is not defined in ISO/IEC 14496-3 */
832 summary
->stream_type
= MP4SYS_STREAM_TYPE_AudioStream
;
833 summary
->exdata
= NULL
; /* to be set in mp4sys_amrnb_create_damr() */
834 summary
->exdata_length
= 0; /* to be set in mp4sys_amrnb_create_damr() */
835 summary
->max_au_length
= wb
? 61 : 32;
836 summary
->aot
= MP4A_AUDIO_OBJECT_TYPE_NULL
; /* no effect */
837 summary
->frequency
= (8000 << wb
);
838 summary
->channels
= 1;
839 summary
->bit_depth
= 16;
840 summary
->samples_in_frame
= (160 << wb
);
841 summary
->sbr_mode
= MP4A_AAC_SBR_NOT_SPECIFIED
; /* no effect */
842 importer
->info
= malloc( sizeof(uint8_t) );
843 if( !importer
->info
)
845 lsmash_cleanup_audio_summary( summary
);
848 *(uint8_t*)importer
->info
= wb
;
849 if( mp4sys_amr_create_damr( summary
) || lsmash_add_entry( importer
->summaries
, summary
) )
851 free( importer
->info
);
852 importer
->info
= NULL
;
853 lsmash_cleanup_audio_summary( summary
);
859 const static mp4sys_importer_functions mp4sys_amr_importer
= {
863 mp4sys_amr_get_accessunit
,
867 /* data_length must be size of data that is available. */
868 int mp4sys_create_dac3_from_syncframe( lsmash_audio_summary_t
*summary
, uint8_t *data
, uint32_t data_length
)
870 /* Requires the following 7 bytes.
878 * if((acmod & 0x01) && (acmod != 0x01)) cmixlev : 2
879 * if(acmod & 0x04) surmixlev : 2
880 * if(acmod == 0x02) dsurmod : 2
883 if( data_length
< 7 )
886 if( data
[0] != 0x0b || data
[1] != 0x77 )
888 /* get necessary data for AC3SpecificBox */
889 uint32_t fscod
, bsid
, bsmod
, acmod
, lfeon
, frmsizecod
;
890 fscod
= data
[4] >> 6;
891 frmsizecod
= data
[4] & 0x3f;
893 bsmod
= data
[5] & 0x07;
894 acmod
= data
[6] >> 5;
896 lfeon
= data
[6] >> 2; /* skip dsurmod */
899 if( (acmod
& 0x01) && acmod
!= 0x01 && (acmod
& 0x04) )
900 lfeon
= data
[6]; /* skip cmixlev and surmixlev */
901 else if( ((acmod
& 0x01) && acmod
!= 0x01) || (acmod
& 0x04) )
902 lfeon
= data
[6] >> 2; /* skip cmixlev or surmixlev */
904 lfeon
= data
[6] >> 4;
907 /* create AC3SpecificBox */
908 lsmash_bits_t
*bits
= lsmash_bits_adhoc_create();
909 lsmash_bits_put( bits
, 11, 32 );
910 lsmash_bits_put( bits
, ISOM_BOX_TYPE_DAC3
, 32 );
911 lsmash_bits_put( bits
, fscod
, 2 );
912 lsmash_bits_put( bits
, bsid
, 5 );
913 lsmash_bits_put( bits
, bsmod
, 3 );
914 lsmash_bits_put( bits
, acmod
, 3 );
915 lsmash_bits_put( bits
, lfeon
, 1 );
916 lsmash_bits_put( bits
, frmsizecod
>> 1, 5 );
917 lsmash_bits_put( bits
, 0, 5 );
918 if( summary
->exdata
)
919 free( summary
->exdata
);
920 summary
->exdata
= lsmash_bits_export_data( bits
, &summary
->exdata_length
);
921 lsmash_bits_adhoc_cleanup( bits
);
925 /***************************************************************************
926 importer public interfaces
927 ***************************************************************************/
930 /******** importer listing table ********/
931 const static mp4sys_importer_functions
* mp4sys_importer_tbl
[] = {
932 &mp4sys_adts_importer
,
933 &mp4sys_mp3_importer
,
934 &mp4sys_amr_importer
,
938 /******** importer public functions ********/
940 void mp4sys_importer_close( mp4sys_importer_t
* importer
)
944 if( !importer
->is_stdin
&& importer
->stream
)
945 fclose( importer
->stream
);
946 if( importer
->funcs
.cleanup
)
947 importer
->funcs
.cleanup( importer
);
948 /* FIXME: To be extended to support visual summary. */
949 lsmash_remove_list( importer
->summaries
, lsmash_cleanup_audio_summary
);
953 mp4sys_importer_t
* mp4sys_importer_open( const char* identifier
, const char* format
)
955 if( identifier
== NULL
)
958 int auto_detect
= ( format
== NULL
|| !strcmp( format
, "auto" ) );
959 mp4sys_importer_t
* importer
= (mp4sys_importer_t
*)malloc( sizeof(mp4sys_importer_t
) );
962 memset( importer
, 0, sizeof(mp4sys_importer_t
) );
964 if( !strcmp( identifier
, "-" ) )
966 /* special treatment for stdin */
972 importer
->stream
= stdin
;
973 importer
->is_stdin
= 1;
975 else if( (importer
->stream
= fopen( identifier
, "rb" )) == NULL
)
977 mp4sys_importer_close( importer
);
980 importer
->summaries
= lsmash_create_entry_list();
981 if( !importer
->summaries
)
983 mp4sys_importer_close( importer
);
987 const mp4sys_importer_functions
* funcs
;
990 /* just rely on detector. */
991 for( int i
= 0; (funcs
= mp4sys_importer_tbl
[i
]) != NULL
; i
++ )
993 if( !funcs
->detectable
)
995 if( !funcs
->probe( importer
) || lsmash_fseek( importer
->stream
, 0, SEEK_SET
) )
1001 /* needs name matching. */
1002 for( int i
= 0; (funcs
= mp4sys_importer_tbl
[i
]) != NULL
; i
++ )
1004 if( strcmp( funcs
->name
, format
) )
1006 if( funcs
->probe( importer
) )
1013 mp4sys_importer_close( importer
);
1016 importer
->funcs
= *funcs
;
1020 /* 0 if success, positive if changed, negative if failed */
1021 int mp4sys_importer_get_access_unit( mp4sys_importer_t
* importer
, uint32_t track_number
, void* buf
, uint32_t* size
)
1023 if( !importer
|| !importer
->funcs
.get_accessunit
|| !buf
|| !size
|| *size
== 0 )
1025 return importer
->funcs
.get_accessunit( importer
, track_number
, buf
, size
);
1028 lsmash_audio_summary_t
* mp4sys_duplicate_audio_summary( mp4sys_importer_t
* importer
, uint32_t track_number
)
1032 lsmash_audio_summary_t
* summary
= lsmash_create_audio_summary();
1035 lsmash_audio_summary_t
* src_summary
= lsmash_get_entry_data( importer
->summaries
, track_number
);
1038 memcpy( summary
, src_summary
, sizeof(lsmash_audio_summary_t
) );
1039 summary
->exdata
= NULL
;
1040 summary
->exdata_length
= 0;
1041 if( lsmash_summary_add_exdata( summary
, src_summary
->exdata
, src_summary
->exdata_length
) )