timelineeditor: Support importing timecode format v1 and automatic timescale generation.
[L-SMASH.git] / importer.c
blob15ac9230b4855e20808afd8804793c6671247fe4
1 /*****************************************************************************
2 * importer.c:
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 */
26 #include <stdlib.h>
27 #include <string.h>
29 #define LSMASH_IMPORTER_INTERNAL
30 #include "importer.h"
32 #include "mp4a.h"
33 #include "box.h"
35 /***************************************************************************
36 importer framework
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 );
44 typedef struct
46 const char* name;
47 int detectable;
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
55 FILE* stream;
56 int is_stdin;
57 void* info; /* importer internal status information. */
58 mp4sys_importer_functions funcs;
59 lsmash_entry_list_t* summaries;
60 } mp4sys_importer_t;
62 typedef enum
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 /***************************************************************************
71 ADTS importer
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
78 typedef struct
80 uint16_t syncword; /* 12; */
81 uint8_t ID; /* 1; */
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;
93 typedef struct
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. */
132 return 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 */
149 uint8_t buf2[2];
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 )
159 return -1;
161 return 0;
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 )
174 return -1;
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 )
180 return -1;
181 first_offset += ( 2 * number_of_blocks ) + 2; /* according to above */
183 else
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.
192 return -1;
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;
209 return 0;
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 ) )
216 return -1;
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();
224 if( !summary )
225 return NULL;
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;
247 summary->asc = 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. */
250 return summary;
252 #endif
253 if( lsmash_setup_AudioSpecificConfig( summary ) )
255 lsmash_cleanup_audio_summary( summary );
256 return NULL;
258 return summary;
261 typedef struct
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 )
272 return -1;
273 if( !importer->info || track_number != 1 )
274 return -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 )
279 return -1;
280 if( current_status == MP4SYS_IMPORTER_EOF )
282 *size = 0;
283 return 0;
285 if( current_status == MP4SYS_IMPORTER_CHANGE )
287 lsmash_audio_summary_t* summary = mp4sys_adts_create_summary( &info->header );
288 if( !summary )
289 return -1;
290 lsmash_entry_t* entry = lsmash_get_entry( importer->summaries, track_number );
291 if( !entry || !entry->data )
292 return -1;
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;
301 return -1;
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;
313 return 0;
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;
320 return 0;
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 );
328 if( ret == 0 )
330 info->status = MP4SYS_IMPORTER_EOF;
331 return 0;
333 if( ret != MP4SYS_ADTS_BASIC_HEADER_LENGTH )
335 info->status = MP4SYS_IMPORTER_ERROR;
336 return 0;
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
354 * retrieve headers.
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;
363 return 0;
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;
384 return 0;
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;
405 return 0;
407 /* no change which matters to mp4 muxing was found */
408 info->status = MP4SYS_IMPORTER_OK;
409 return 0;
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 )
423 return -1;
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 ) )
428 return -1;
430 /* now the stream seems valid ADTS */
432 lsmash_audio_summary_t* summary = mp4sys_adts_create_summary( &header );
433 if( !summary )
434 return -1;
436 /* importer status */
437 mp4sys_adts_info_t* info = malloc( sizeof(mp4sys_adts_info_t) );
438 if( !info )
440 lsmash_cleanup_audio_summary( summary );
441 return -1;
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 ) )
451 free( info );
452 lsmash_cleanup_audio_summary( summary );
453 return -1;
455 importer->info = info;
457 return 0;
460 const static mp4sys_importer_functions mp4sys_adts_importer = {
461 "adts",
463 mp4sys_adts_probe,
464 mp4sys_adts_get_accessunit,
465 mp4sys_adts_cleanup
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 );
478 typedef struct
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;
519 return 0;
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();
535 if( !summary )
536 return NULL;
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. */
550 if( !legacy_mode )
552 summary->object_type_indication = MP4SYS_OBJECT_TYPE_Audio_ISO_14496_3;
553 if( lsmash_setup_AudioSpecificConfig( summary ) )
555 lsmash_cleanup_audio_summary( summary );
556 return NULL;
559 #endif
560 return summary;
563 typedef struct
565 mp4sys_importer_status status;
566 mp4sys_mp3_header_t header;
567 uint8_t raw_header[MP4SYS_MP3_HEADER_LENGTH];
568 } mp4sys_mp3_info_t;
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 )
573 return -1;
574 if( !importer->info || track_number != 1 )
575 return -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 */
586 { /* MPEG-1 audio */
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 )
595 return -1;
596 uint32_t frame_size;
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;
602 else
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 )
609 return -1;
610 if( current_status == MP4SYS_IMPORTER_EOF )
612 *size = 0;
613 return 0;
615 if( current_status == MP4SYS_IMPORTER_CHANGE )
617 lsmash_audio_summary_t* summary = mp4sys_mp3_create_summary( header, 1 ); /* FIXME: use legacy mode. */
618 if( !summary )
619 return -1;
620 lsmash_entry_t* entry = lsmash_get_entry( importer->summaries, track_number );
621 if( !entry || !entry->data )
622 return -1;
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;
632 return -1;
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 );
641 if( ret == 0 )
643 info->status = MP4SYS_IMPORTER_EOF;
644 return 0;
646 if( ret == 1 && *buf == 0x00 )
648 /* NOTE: ugly hack for mp1 stream created with SCMPX. */
649 info->status = MP4SYS_IMPORTER_EOF;
650 return 0;
652 if( ret != MP4SYS_MP3_HEADER_LENGTH )
654 info->status = MP4SYS_IMPORTER_ERROR;
655 return 0;
658 mp4sys_mp3_header_t new_header = {0};
659 if( mp4sys_mp3_parse_header( buf, &new_header ) )
661 info->status = MP4SYS_IMPORTER_ERROR;
662 return 0;
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;
671 return 0;
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;
677 else
678 info->status = MP4SYS_IMPORTER_OK; /* no change which matters to mp4 muxing was found */
679 info->header = new_header;
680 return 0;
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 )
687 return -1;
689 mp4sys_mp3_header_t header = {0};
690 if( mp4sys_mp3_parse_header( buf, &header ) )
691 return -1;
693 /* now the stream seems valid mp3 */
695 lsmash_audio_summary_t* summary = mp4sys_mp3_create_summary( &header, 1 ); /* FIXME: use legacy mode. */
696 if( !summary )
697 return -1;
699 /* importer status */
700 mp4sys_mp3_info_t* info = malloc( sizeof(mp4sys_mp3_info_t) );
701 if( !info )
703 lsmash_cleanup_audio_summary( summary );
704 return -1;
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 ) )
713 free( info );
714 lsmash_cleanup_audio_summary( summary );
715 return -1;
717 importer->info = info;
719 return 0;
722 const static mp4sys_importer_functions mp4sys_mp3_importer = {
723 "MPEG-1/2BC_Audio_Legacy",
725 mp4sys_mp3_probe,
726 mp4sys_mp3_get_accessunit,
727 mp4sys_mp3_cleanup
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 )
744 return -1;
745 if( track_number != 1 )
746 return -1;
747 uint8_t wb = *(uint8_t*)importer->info;
749 uint8_t* buf = userbuf;
750 if( fread( buf, 1, 1, importer->stream ) == 0 )
752 /* EOF */
753 *size = 0;
754 return 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-- )
765 return -1;
766 if( read_size == 0 )
768 *size = 1;
769 return 0;
771 if( fread( buf+1, 1, read_size, importer->stream ) != read_size )
772 return -1;
773 *size = read_size + 1;
774 return 0;
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 */
782 if( !bs )
783 return -1;
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.
787 Using dummy data. */
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 )
801 return -1;
802 summary->exdata_length = MP4SYS_DAMR_LENGTH;
803 return 0;
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];
812 uint8_t wb = 0;
813 if( fread( buf, 1, MP4SYS_AMR_STORAGE_MAGIC_LENGTH, importer->stream ) != MP4SYS_AMR_STORAGE_MAGIC_LENGTH )
814 return -1;
815 if( memcmp( buf, "#!AMR", MP4SYS_AMR_STORAGE_MAGIC_LENGTH-1 ) )
816 return -1;
817 if( buf[MP4SYS_AMR_STORAGE_MAGIC_LENGTH-1] != '\n' )
819 if( buf[MP4SYS_AMR_STORAGE_MAGIC_LENGTH-1] != '-' )
820 return -1;
821 if( fread( buf, 1, MP4SYS_AMRWB_EX_MAGIC_LENGTH, importer->stream ) != MP4SYS_AMRWB_EX_MAGIC_LENGTH )
822 return -1;
823 if( memcmp( buf, "WB\n", MP4SYS_AMRWB_EX_MAGIC_LENGTH ) )
824 return -1;
825 wb = 1;
827 lsmash_audio_summary_t* summary = lsmash_create_audio_summary();
828 if( !summary )
829 return -1;
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 );
846 return -1;
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 );
854 return -1;
856 return 0;
859 const static mp4sys_importer_functions mp4sys_amr_importer = {
860 "amr",
862 mp4sys_amr_probe,
863 mp4sys_amr_get_accessunit,
864 mp4sys_amr_cleanup
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.
871 * syncword : 16
872 * crc1 : 16
873 * fscod : 2
874 * frmsizecod : 6
875 * bsid : 5
876 * bsmod : 3
877 * acmod : 3
878 * if((acmod & 0x01) && (acmod != 0x01)) cmixlev : 2
879 * if(acmod & 0x04) surmixlev : 2
880 * if(acmod == 0x02) dsurmod : 2
881 * lfeon : 1
883 if( data_length < 7 )
884 return -1;
885 /* check syncword */
886 if( data[0] != 0x0b || data[1] != 0x77 )
887 return -1;
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;
892 bsid = data[5] >> 3;
893 bsmod = data[5] & 0x07;
894 acmod = data[6] >> 5;
895 if( acmod == 0x02 )
896 lfeon = data[6] >> 2; /* skip dsurmod */
897 else
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 */
903 else
904 lfeon = data[6] >> 4;
906 lfeon &= 0x01;
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 );
922 return 0;
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,
935 NULL,
938 /******** importer public functions ********/
940 void mp4sys_importer_close( mp4sys_importer_t* importer )
942 if( !importer )
943 return;
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 );
950 free( importer );
953 mp4sys_importer_t* mp4sys_importer_open( const char* identifier, const char* format )
955 if( identifier == NULL )
956 return NULL;
958 int auto_detect = ( format == NULL || !strcmp( format, "auto" ) );
959 mp4sys_importer_t* importer = (mp4sys_importer_t*)malloc( sizeof(mp4sys_importer_t) );
960 if( !importer )
961 return NULL;
962 memset( importer, 0, sizeof(mp4sys_importer_t) );
964 if( !strcmp( identifier, "-" ) )
966 /* special treatment for stdin */
967 if( auto_detect )
969 free( importer );
970 return NULL;
972 importer->stream = stdin;
973 importer->is_stdin = 1;
975 else if( (importer->stream = fopen( identifier, "rb" )) == NULL )
977 mp4sys_importer_close( importer );
978 return NULL;
980 importer->summaries = lsmash_create_entry_list();
981 if( !importer->summaries )
983 mp4sys_importer_close( importer );
984 return NULL;
986 /* find importer */
987 const mp4sys_importer_functions* funcs;
988 if( auto_detect )
990 /* just rely on detector. */
991 for( int i = 0; (funcs = mp4sys_importer_tbl[i]) != NULL; i++ )
993 if( !funcs->detectable )
994 continue;
995 if( !funcs->probe( importer ) || lsmash_fseek( importer->stream, 0, SEEK_SET ) )
996 break;
999 else
1001 /* needs name matching. */
1002 for( int i = 0; (funcs = mp4sys_importer_tbl[i]) != NULL; i++ )
1004 if( strcmp( funcs->name, format ) )
1005 continue;
1006 if( funcs->probe( importer ) )
1007 funcs = NULL;
1008 break;
1011 if( !funcs )
1013 mp4sys_importer_close( importer );
1014 return NULL;
1016 importer->funcs = *funcs;
1017 return importer;
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 )
1024 return -1;
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 )
1030 if( !importer )
1031 return NULL;
1032 lsmash_audio_summary_t* summary = lsmash_create_audio_summary();
1033 if( !summary )
1034 return NULL;
1035 lsmash_audio_summary_t* src_summary = lsmash_get_entry_data( importer->summaries, track_number );
1036 if( !src_summary )
1037 return NULL;
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 ) )
1043 free( summary );
1044 return NULL;
1046 return summary;