meta: Evaluate return value properly.
[L-SMASH.git] / cli / mp3_imp.c
blob37b7b39bf96084e9110d8592863507c0d0a94f85
1 /*****************************************************************************
2 * mp3_imp.c
3 *****************************************************************************
4 * Copyright (C) 2010-2014 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 "common/internal.h" /* must be placed first */
26 #include <string.h>
28 #define LSMASH_IMPORTER_INTERNAL
29 #include "importer.h"
31 /***************************************************************************
32 mp3 (Legacy Interface) importer
33 ***************************************************************************/
34 #include "codecs/mp4a.h"
36 #define USE_MP4SYS_LEGACY_INTERFACE 1
38 static void mp4sys_mp3_cleanup( importer_t *importer )
40 debug_if( importer && importer->info )
41 lsmash_free( importer->info );
44 typedef struct
46 uint16_t syncword; /* <12> */
47 uint8_t ID; /* <1> */
48 uint8_t layer; /* <2> */
49 uint8_t protection_bit; /* <1> */
50 uint8_t bitrate_index; /* <4> */
51 uint8_t sampling_frequency; /* <2> */
52 uint8_t padding_bit; /* <1> */
53 // uint8_t private_bit; /* <1> don't care. */
54 uint8_t mode; /* <2> */
55 // uint8_t mode_extension; /* <2> don't care. */
56 // uint8_t copyright; /* <1> don't care. */
57 // uint8_t original_copy; /* <1> don't care. */
58 uint8_t emphasis; /* <2> for error check only. */
60 } mp4sys_mp3_header_t;
62 static int mp4sys_mp3_parse_header( uint8_t* buf, mp4sys_mp3_header_t* header )
64 /* FIXME: should we rewrite these code using bitstream reader? */
65 uint32_t data = LSMASH_GET_BE32( buf );
66 header->syncword = (data >> 20) & 0xFFF; /* NOTE: don't consider what is called MPEG2.5, which last bit is 0. */
67 header->ID = (data >> 19) & 0x1;
68 header->layer = (data >> 17) & 0x3;
69 header->protection_bit = (data >> 16) & 0x1;
70 header->bitrate_index = (data >> 12) & 0xF;
71 header->sampling_frequency = (data >> 10) & 0x3;
72 header->padding_bit = (data >> 9) & 0x1;
73 // header->private_bit = (data >> 8) & 0x1; /* don't care. */
74 header->mode = (data >> 6) & 0x3;
75 // header->mode_extension = (data >> 4) & 0x3;
76 // header->copyright = (data >> 3) & 0x1; /* don't care. */
77 // header->original_copy = (data >> 2) & 0x1; /* don't care. */
78 header->emphasis = data & 0x3; /* for error check only. */
80 if( header->syncword != 0xFFF ) return -1;
81 if( header->layer == 0x0 ) return -1;
82 if( header->bitrate_index == 0x0 || header->bitrate_index == 0xF ) return -1; /* FIXME: "free" bitrate is unsupported currently. */
83 if( header->sampling_frequency == 0x3) return -1;
84 if( header->emphasis == 0x2) return -1;
85 return 0;
88 #define MP4SYS_MP3_MAX_FRAME_LENGTH (1152*(16/8)*2)
89 #define MP4SYS_MP3_HEADER_LENGTH 4
90 #define MP4SYS_MODE_IS_2CH( mode ) ((mode)!=3)
91 #define MP4SYS_LAYER_III 0x1
92 #define MP4SYS_LAYER_II 0x2
93 #define MP4SYS_LAYER_I 0x3
95 static const uint32_t mp4sys_mp3_frequency_tbl[2][3] = {
96 { 22050, 24000, 16000 }, /* MPEG-2 BC audio */
97 { 44100, 48000, 32000 } /* MPEG-1 audio */
100 static int mp4sys_mp3_samples_in_frame( mp4sys_mp3_header_t *header )
102 if( header->layer == MP4SYS_LAYER_I )
103 return 384;
104 else if( header->ID == 1 || header->layer == MP4SYS_LAYER_II )
105 return 1152;
106 else
107 return 576;
110 static lsmash_audio_summary_t *mp4sys_mp3_create_summary( mp4sys_mp3_header_t *header, int legacy_mode )
112 lsmash_audio_summary_t *summary = (lsmash_audio_summary_t *)lsmash_create_summary( LSMASH_SUMMARY_TYPE_AUDIO );
113 if( !summary )
114 return NULL;
115 summary->sample_type = ISOM_CODEC_TYPE_MP4A_AUDIO;
116 summary->max_au_length = MP4SYS_MP3_MAX_FRAME_LENGTH;
117 summary->frequency = mp4sys_mp3_frequency_tbl[header->ID][header->sampling_frequency];
118 summary->channels = MP4SYS_MODE_IS_2CH( header->mode ) + 1;
119 summary->sample_size = 16;
120 summary->samples_in_frame = mp4sys_mp3_samples_in_frame( header );
121 summary->aot = MP4A_AUDIO_OBJECT_TYPE_Layer_1 + (MP4SYS_LAYER_I - header->layer); /* no effect with Legacy Interface. */
122 summary->sbr_mode = MP4A_AAC_SBR_NOT_SPECIFIED; /* no effect */
123 #if !USE_MP4SYS_LEGACY_INTERFACE /* FIXME: This is very unstable. Many players crash with this. */
124 if( !legacy_mode )
126 summary->object_type_indication = MP4SYS_OBJECT_TYPE_Audio_ISO_14496_3;
127 if( lsmash_setup_AudioSpecificConfig( summary ) )
129 lsmash_cleanup_summary( summary );
130 return NULL;
133 uint32_t data_length;
134 uint8_t *data = mp4a_export_AudioSpecificConfig( MP4A_AUDIO_OBJECT_TYPE_Layer_1 + (MP4SYS_LAYER_I - header->layer),
135 summary->frequency, summary->channels, summary->sbr_mode,
136 NULL, 0, &data_length );
137 if( !data )
139 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
140 return NULL;
142 #endif
143 lsmash_codec_specific_t *specific = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_MP4SYS_DECODER_CONFIG,
144 LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED );
145 if( !specific )
147 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
148 #if !USE_MP4SYS_LEGACY_INTERFACE
149 lsmash_free( data );
150 #endif
151 return NULL;
153 lsmash_mp4sys_decoder_parameters_t *param = (lsmash_mp4sys_decoder_parameters_t *)specific->data.structured;
154 param->objectTypeIndication = header->ID ? MP4SYS_OBJECT_TYPE_Audio_ISO_11172_3 : MP4SYS_OBJECT_TYPE_Audio_ISO_13818_3;
155 param->streamType = MP4SYS_STREAM_TYPE_AudioStream;
156 #if !USE_MP4SYS_LEGACY_INTERFACE
157 if( lsmash_set_mp4sys_decoder_specific_info( param, data, data_length ) )
159 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
160 lsmash_destroy_codec_specific_data( specific );
161 lsmash_free( data );
162 return NULL;
164 lsmash_free( data );
165 #endif
166 if( lsmash_add_entry( &summary->opaque->list, specific ) )
168 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
169 lsmash_destroy_codec_specific_data( specific );
170 return NULL;
172 return summary;
175 typedef struct
177 importer_status status;
178 mp4sys_mp3_header_t header;
179 uint8_t raw_header[MP4SYS_MP3_HEADER_LENGTH];
180 uint32_t samples_in_frame;
181 uint32_t au_number;
182 uint16_t main_data_size[32]; /* size of main_data of the last 32 frames, FIFO */
183 uint16_t prev_preroll_count; /* number of dependent frames of *previous* frame */
184 uint16_t enc_delay;
185 uint16_t padding;
186 uint64_t valid_samples;
187 } mp4sys_mp3_info_t;
189 static int parse_xing_info_header( mp4sys_mp3_info_t *info, mp4sys_mp3_header_t *header, uint8_t *frame )
191 unsigned int sip = header->protection_bit ? 4 : 6;
192 unsigned int side_info_size;
193 if( header->ID == 1 )
194 side_info_size = MP4SYS_MODE_IS_2CH( header->mode ) ? 32 : 17;
195 else
196 side_info_size = MP4SYS_MODE_IS_2CH( header->mode ) ? 17 : 9;
198 uint8_t *mdp = frame + sip + side_info_size;
199 if( memcmp( mdp, "Info", 4 ) && memcmp( mdp, "Xing", 4 ) )
200 return 0;
201 uint32_t flags = LSMASH_GET_BE32( &mdp[4] );
202 uint32_t off = 8;
203 uint32_t frame_count = 0;
204 if( flags & 1 )
206 frame_count = LSMASH_GET_BE32( &mdp[8] );
207 info->valid_samples = (uint64_t)frame_count * mp4sys_mp3_samples_in_frame( header );
208 off += 4;
210 if( flags & 2 ) off += 4; /* file size */
211 if( flags & 4 ) off += 100; /* TOC */
212 if( flags & 8 ) off += 4; /* VBR quality */
214 if( mdp[off] == 'L' )
215 { /* LAME header present */
216 unsigned v = LSMASH_GET_BE24( &mdp[off + 21] );
217 info->enc_delay = v >> 12;
218 info->padding = v & 0xfff;
219 if( frame_count )
220 info->valid_samples -= info->enc_delay + info->padding;
222 return 1;
225 static int parse_vbri_header( mp4sys_mp3_info_t *info, mp4sys_mp3_header_t *header, uint8_t *frame )
227 return memcmp( frame + 36, "VBRI", 4 ) == 0;
230 static int mp4sys_mp3_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample )
232 debug_if( !importer || !importer->info || !buffered_sample->data || !buffered_sample->length )
233 return -1;
234 if( !importer->info || track_number != 1 )
235 return -1;
236 mp4sys_mp3_info_t *info = (mp4sys_mp3_info_t *)importer->info;
237 mp4sys_mp3_header_t *header = (mp4sys_mp3_header_t *)&info->header;
238 importer_status current_status = info->status;
240 const uint32_t bitrate_tbl[2][3][16] = {
241 { /* MPEG-2 BC audio */
242 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, /* Layer III */
243 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, /* Layer II */
244 { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 } /* Layer I */
246 { /* MPEG-1 audio */
247 { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 }, /* Layer III */
248 { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0 }, /* Layer II */
249 { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0 } /* Layer I */
252 uint32_t bitrate = bitrate_tbl[header->ID][header->layer-1][header->bitrate_index];
253 uint32_t frequency = mp4sys_mp3_frequency_tbl[header->ID][header->sampling_frequency];
254 debug_if( bitrate == 0 || frequency == 0 )
255 return -1;
256 uint32_t frame_size;
257 if( header->layer == MP4SYS_LAYER_I )
259 /* mp1's 'slot' is 4 bytes unit. see 11172-3, Audio Sequence General. */
260 frame_size = ( 12 * 1000 * bitrate / frequency + header->padding_bit ) * 4;
262 else
264 /* mp2/3's 'slot' is 1 bytes unit. */
265 uint32_t div = frequency;
266 if( header->layer == MP4SYS_LAYER_III && header->ID == 0 )
267 div <<= 1;
268 frame_size = 144 * 1000 * bitrate / div + header->padding_bit;
271 if( current_status == IMPORTER_ERROR || frame_size <= 4 || buffered_sample->length < frame_size )
272 return -1;
273 if( current_status == IMPORTER_EOF )
275 buffered_sample->length = 0;
276 return 0;
278 if( current_status == IMPORTER_CHANGE )
280 lsmash_audio_summary_t* summary = mp4sys_mp3_create_summary( header, 1 ); /* FIXME: use legacy mode. */
281 if( !summary )
282 return -1;
283 lsmash_entry_t* entry = lsmash_get_entry( importer->summaries, track_number );
284 if( !entry || !entry->data )
285 return -1;
286 lsmash_cleanup_summary( entry->data );
287 entry->data = summary;
288 info->samples_in_frame = summary->samples_in_frame;
290 /* read a frame's data. */
291 memcpy( buffered_sample->data, info->raw_header, MP4SYS_MP3_HEADER_LENGTH );
292 frame_size -= MP4SYS_MP3_HEADER_LENGTH;
293 if( fread( ((uint8_t*)buffered_sample->data)+MP4SYS_MP3_HEADER_LENGTH, 1, frame_size, importer->stream ) != frame_size )
295 info->status = IMPORTER_ERROR;
296 return -1;
298 buffered_sample->length = MP4SYS_MP3_HEADER_LENGTH + frame_size;
299 buffered_sample->dts = info->au_number++ * info->samples_in_frame;
300 buffered_sample->cts = buffered_sample->dts;
301 buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC;
302 buffered_sample->prop.pre_roll.distance = header->layer == MP4SYS_LAYER_III ? 1 : 0; /* Layer III uses MDCT */
304 int vbr_header_present = 0;
305 if( info->au_number == 1
306 && (parse_xing_info_header( info, header, buffered_sample->data )
307 || parse_vbri_header( info, header, buffered_sample->data )) )
309 vbr_header_present = 1;
310 info->au_number--;
313 /* handle additional inter-frame dependency due to bit reservoir */
314 if( !vbr_header_present && header->layer == MP4SYS_LAYER_III )
316 /* position of side_info */
317 unsigned int sip = header->protection_bit ? 4 : 6;
318 unsigned int main_data_begin = buffered_sample->data[sip];
319 if( header->ID == 1 )
321 main_data_begin <<= 1;
322 main_data_begin |= (buffered_sample->data[sip + 1] >> 7);
324 if( main_data_begin > 0 )
326 /* main_data_begin is a backpointer to the start of
327 * bit reservoir data for this frame.
328 * it contains total amount of bytes required from
329 * preceding frames.
330 * we just add up main_data size from history until it reaches
331 * the required amount.
333 unsigned int reservoir_data = 0;
334 unsigned int i;
335 for( i = 0; i < 32 && reservoir_data < main_data_begin; ++i )
337 reservoir_data += info->main_data_size[i];
338 if( info->main_data_size[i] == 0 )
339 break;
341 buffered_sample->prop.pre_roll.distance += info->prev_preroll_count;
342 info->prev_preroll_count = i;
344 uint16_t side_info_size;
345 if( header->ID == 1 )
346 side_info_size = MP4SYS_MODE_IS_2CH( header->mode ) ? 32 : 17;
347 else
348 side_info_size = MP4SYS_MODE_IS_2CH( header->mode ) ? 17 : 9;
350 /* pop back main_data_size[] and push main_data size of this frame
351 * to the front */
352 memmove( info->main_data_size + 1, info->main_data_size, sizeof(info->main_data_size) - sizeof( info->main_data_size[0] ) );
353 info->main_data_size[0] = frame_size - sip - side_info_size;
355 /* now we succeeded to read current frame, so "return" takes 0 always below. */
356 /* preparation for next frame */
358 uint8_t buf[MP4SYS_MP3_HEADER_LENGTH];
359 size_t ret = fread( buf, 1, MP4SYS_MP3_HEADER_LENGTH, importer->stream );
360 if( ret == 0 )
362 info->status = IMPORTER_EOF;
363 return 0;
365 if( ret >= 2 && (!memcmp( buf, "TA", 2 ) || !memcmp( buf, "AP", 2 )) )
367 /* ID3v1 or APE tag */
368 info->status = IMPORTER_EOF;
369 return 0;
371 if( ret == 1 && *buf == 0x00 )
373 /* NOTE: ugly hack for mp1 stream created with SCMPX. */
374 info->status = IMPORTER_EOF;
375 return 0;
377 if( ret != MP4SYS_MP3_HEADER_LENGTH )
379 info->status = IMPORTER_ERROR;
380 return 0;
383 mp4sys_mp3_header_t new_header = {0};
384 if( mp4sys_mp3_parse_header( buf, &new_header ) )
386 info->status = IMPORTER_ERROR;
387 return 0;
389 memcpy( info->raw_header, buf, MP4SYS_MP3_HEADER_LENGTH );
391 /* currently UNsupported "change(s)". */
392 if( header->layer != new_header.layer /* This means change of object_type_indication with Legacy Interface. */
393 || header->sampling_frequency != new_header.sampling_frequency ) /* This may change timescale. */
395 info->status = IMPORTER_ERROR;
396 return 0;
399 /* currently supported "change(s)". */
400 if( MP4SYS_MODE_IS_2CH( header->mode ) != MP4SYS_MODE_IS_2CH( new_header.mode ) )
401 info->status = IMPORTER_CHANGE;
402 else
403 info->status = IMPORTER_OK; /* no change which matters to mp4 muxing was found */
404 info->header = new_header;
406 if( vbr_header_present )
407 return mp4sys_mp3_get_accessunit( importer, track_number, buffered_sample );
408 return 0;
411 static int mp4sys_mp3_probe( importer_t *importer )
413 int c;
414 if( (c = getc( importer->stream )) == 'I'
415 && (c = getc( importer->stream )) == 'D'
416 && (c = getc( importer->stream )) == '3' )
418 lsmash_fseek( importer->stream, 3, SEEK_CUR );
419 uint32_t size = 0;
420 for( int i = 0 ; i < 4; i++ )
422 size <<= 7;
423 size |= getc( importer->stream );
425 lsmash_fseek( importer->stream, size, SEEK_CUR );
427 else
428 ungetc( c, importer->stream );
430 uint8_t buf[MP4SYS_MP3_HEADER_LENGTH];
431 if( fread( buf, 1, MP4SYS_MP3_HEADER_LENGTH, importer->stream ) != MP4SYS_MP3_HEADER_LENGTH )
432 return -1;
434 mp4sys_mp3_header_t header = {0};
435 if( mp4sys_mp3_parse_header( buf, &header ) )
436 return -1;
438 /* now the stream seems valid mp3 */
440 lsmash_audio_summary_t* summary = mp4sys_mp3_create_summary( &header, 1 ); /* FIXME: use legacy mode. */
441 if( !summary )
442 return -1;
444 /* importer status */
445 mp4sys_mp3_info_t* info = lsmash_malloc_zero( sizeof(mp4sys_mp3_info_t) );
446 if( !info )
448 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
449 return -1;
451 info->status = IMPORTER_OK;
452 info->header = header;
453 info->samples_in_frame = summary->samples_in_frame;
454 memcpy( info->raw_header, buf, MP4SYS_MP3_HEADER_LENGTH );
456 if( lsmash_add_entry( importer->summaries, summary ) )
458 lsmash_free( info );
459 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
460 return -1;
462 importer->info = info;
464 return 0;
467 static uint32_t mp4sys_mp3_get_last_delta( importer_t *importer, uint32_t track_number )
469 debug_if( !importer || !importer->info )
470 return 0;
471 mp4sys_mp3_info_t *info = (mp4sys_mp3_info_t *)importer->info;
472 if( !info || track_number != 1 || info->status != IMPORTER_EOF )
473 return 0;
474 return info->samples_in_frame;
477 const importer_functions mp4sys_mp3_importer =
479 { "MPEG-1/2BC_Audio_Legacy" },
481 mp4sys_mp3_probe,
482 mp4sys_mp3_get_accessunit,
483 mp4sys_mp3_get_last_delta,
484 mp4sys_mp3_cleanup