vc1: Evaluate return value properly.
[L-SMASH.git] / cli / adts_imp.c
blob006bf82c6f0a223f0fd2c36575ef9e4f0e54aca2
1 /*****************************************************************************
2 * adts_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 #define LSMASH_IMPORTER_INTERNAL
27 #include "importer.h"
29 /***************************************************************************
30 ADTS importer
31 ***************************************************************************/
32 #include "codecs/mp4a.h"
34 #define MP4SYS_ADTS_FIXED_HEADER_LENGTH 4 /* this is partly a lie. actually 28 bits. */
35 #define MP4SYS_ADTS_BASIC_HEADER_LENGTH 7
36 #define MP4SYS_ADTS_MAX_FRAME_LENGTH ( ( 1 << 13 ) - 1 )
37 #define MP4SYS_ADTS_MAX_RAW_DATA_BLOCKS 4
39 typedef struct
41 uint16_t syncword; /* 12; */
42 uint8_t ID; /* 1; */
43 uint8_t layer; /* 2; */
44 uint8_t protection_absent; /* 1; */
45 uint8_t profile_ObjectType; /* 2; */
46 uint8_t sampling_frequency_index; /* 4; */
47 // uint8_t private_bit; /* 1; we don't care. */
48 uint8_t channel_configuration; /* 3; */
49 // uint8_t original_copy; /* 1; we don't care. */
50 // uint8_t home; /* 1; we don't care. */
52 } mp4sys_adts_fixed_header_t;
54 typedef struct
56 // uint8_t copyright_identification_bit; /* 1; we don't care. */
57 // uint8_t copyright_identification_start; /* 1; we don't care. */
58 uint16_t frame_length; /* 13; */
59 // uint16_t adts_buffer_fullness; /* 11; we don't care. */
60 uint8_t number_of_raw_data_blocks_in_frame; /* 2; */
61 // uint16_t adts_error_check; /* we don't support */
62 // uint16_t raw_data_block_position[MP4SYS_ADTS_MAX_RAW_DATA_BLOCKS-1]; /* we don't use this directly, and... */
63 uint16_t raw_data_block_size[MP4SYS_ADTS_MAX_RAW_DATA_BLOCKS]; /* use this instead of above. */
64 // uint16_t adts_header_error_check; /* we don't support, actually crc_check within this */
65 // uint16_t adts_raw_data_block_error_check[MP4SYS_ADTS_MAX_RAW_DATA_BLOCKS]; /* we don't support */
66 } mp4sys_adts_variable_header_t;
68 static void mp4sys_adts_parse_fixed_header( uint8_t* buf, mp4sys_adts_fixed_header_t* header )
70 /* FIXME: should we rewrite these code using bitstream reader? */
71 header->syncword = (buf[0] << 4) | (buf[1] >> 4);
72 header->ID = (buf[1] >> 3) & 0x1;
73 header->layer = (buf[1] >> 1) & 0x3;
74 header->protection_absent = buf[1] & 0x1;
75 header->profile_ObjectType = buf[2] >> 6;
76 header->sampling_frequency_index = (buf[2] >> 2) & 0xF;
77 // header->private_bit = (buf[2] >> 1) & 0x1; /* we don't care currently. */
78 header->channel_configuration = ((buf[2] << 2) | (buf[3] >> 6)) & 0x07;
79 // header->original_copy = (buf[3] >> 5) & 0x1; /* we don't care currently. */
80 // header->home = (buf[3] >> 4) & 0x1; /* we don't care currently. */
83 static int mp4sys_adts_check_fixed_header( mp4sys_adts_fixed_header_t* header )
85 if( header->syncword != 0xFFF ) return -1;
86 // if( header->ID != 0x0 ) return -1; /* we don't care. */
87 if( header->layer != 0x0 ) return -1; /* must be 0b00 for any type of AAC */
88 // if( header->protection_absent != 0x1 ) return -1; /* we don't care. */
89 if( header->profile_ObjectType != 0x1 ) return -1; /* FIXME: 0b00=Main, 0b01=LC, 0b10=SSR, 0b11=LTP. */
90 if( header->sampling_frequency_index > 0xB ) return -1; /* must not be > 0xB. */
91 if( header->channel_configuration == 0x0 ) return -1; /* FIXME: we do not support 0b000 currently. */
92 if( header->profile_ObjectType == 0x3 && header->ID != 0x0 ) return -1; /* LTP is valid only if ID==0. */
93 return 0;
96 static int mp4sys_adts_parse_variable_header( FILE* stream, uint8_t* buf, unsigned int protection_absent, mp4sys_adts_variable_header_t* header )
98 /* FIXME: should we rewrite these code using bitstream reader? */
99 // header->copyright_identification_bit = (buf[3] >> 3) & 0x1; /* we don't care. */
100 // header->copyright_identification_start = (buf[3] >> 2) & 0x1; /* we don't care. */
101 header->frame_length = ((buf[3] << 11) | (buf[4] << 3) | (buf[5] >> 5)) & 0x1FFF ;
102 // header->adts_buffer_fullness = ((buf[5] << 6) | (buf[6] >> 2)) 0x7FF ; /* we don't care. */
103 header->number_of_raw_data_blocks_in_frame = buf[6] & 0x3;
105 if( header->frame_length <= MP4SYS_ADTS_BASIC_HEADER_LENGTH + 2 * (protection_absent == 0) )
106 return -1; /* easy error check */
108 /* protection_absent and number_of_raw_data_blocks_in_frame relatives */
110 uint8_t buf2[2];
111 unsigned int number_of_blocks = header->number_of_raw_data_blocks_in_frame;
112 if( number_of_blocks == 0 )
114 header->raw_data_block_size[0] = header->frame_length - MP4SYS_ADTS_BASIC_HEADER_LENGTH;
115 /* skip adts_error_check() and subtract that from block_size */
116 if( protection_absent == 0 )
118 header->raw_data_block_size[0] -= 2;
119 if( fread( buf2, 1, 2, stream ) != 2 )
120 return -1;
122 return 0;
125 /* now we have multiple raw_data_block()s, so evaluate adts_header_error_check() */
127 uint16_t raw_data_block_position[MP4SYS_ADTS_MAX_RAW_DATA_BLOCKS];
128 uint16_t first_offset = MP4SYS_ADTS_BASIC_HEADER_LENGTH;
129 if( protection_absent == 0 )
131 /* process adts_header_error_check() */
132 for( int i = 0 ; i < number_of_blocks ; i++ ) /* 1-based in the spec, but we use 0-based */
134 if( fread( buf2, 1, 2, stream ) != 2 )
135 return -1;
136 raw_data_block_position[i] = LSMASH_GET_BE16( buf2 );
138 /* skip crc_check in adts_header_error_check().
139 Or might be sizeof( adts_error_check() ) if we share with the case number_of_raw_data_blocks_in_frame == 0 */
140 if( fread( buf2, 1, 2, stream ) != 2 )
141 return -1;
142 first_offset += ( 2 * number_of_blocks ) + 2; /* according to above */
144 else
147 * NOTE: We never support the case where number_of_raw_data_blocks_in_frame != 0 && protection_absent != 0,
148 * because we have to parse the raw AAC bitstream itself to find boundaries of raw_data_block()s in this case.
149 * Which is to say, that braindamaged spec requires us (mp4 muxer) to decode AAC once to split frames.
150 * L-SMASH is NOT AAC DECODER, so that we've just given up for this case.
151 * This is ISO/IEC 13818-7's sin which defines ADTS format originally.
153 return -1;
156 /* convert raw_data_block_position --> raw_data_block_size */
158 /* do conversion for first */
159 header->raw_data_block_size[0] = raw_data_block_position[0] - first_offset;
160 /* set dummy offset to tail for loop, do coversion for rest. */
161 raw_data_block_position[number_of_blocks] = header->frame_length;
162 for( int i = 1 ; i <= number_of_blocks ; i++ )
163 header->raw_data_block_size[i] = raw_data_block_position[i] - raw_data_block_position[i-1];
165 /* adjustment for adts_raw_data_block_error_check() */
166 if( protection_absent == 0 && number_of_blocks != 0 )
167 for( int i = 0 ; i <= number_of_blocks ; i++ )
168 header->raw_data_block_size[i] -= 2;
170 return 0;
173 static int mp4sys_adts_parse_headers( FILE* stream, uint8_t* buf, mp4sys_adts_fixed_header_t* header, mp4sys_adts_variable_header_t* variable_header )
175 mp4sys_adts_parse_fixed_header( buf, header );
176 if( mp4sys_adts_check_fixed_header( header ) )
177 return -1;
178 /* get payload length & skip extra(crc) header */
179 return mp4sys_adts_parse_variable_header( stream, buf, header->protection_absent, variable_header );
182 static lsmash_audio_summary_t *mp4sys_adts_create_summary( mp4sys_adts_fixed_header_t *header )
184 lsmash_audio_summary_t *summary = (lsmash_audio_summary_t *)lsmash_create_summary( LSMASH_SUMMARY_TYPE_AUDIO );
185 if( !summary )
186 return NULL;
187 summary->sample_type = ISOM_CODEC_TYPE_MP4A_AUDIO;
188 summary->max_au_length = MP4SYS_ADTS_MAX_FRAME_LENGTH;
189 summary->frequency = mp4a_sampling_frequency_table[header->sampling_frequency_index][1];
190 summary->channels = header->channel_configuration + ( header->channel_configuration == 0x07 ); /* 0x07 means 7.1ch */
191 summary->sample_size = 16;
192 summary->samples_in_frame = 1024;
193 summary->aot = header->profile_ObjectType + MP4A_AUDIO_OBJECT_TYPE_AAC_MAIN;
194 summary->sbr_mode = MP4A_AAC_SBR_NOT_SPECIFIED;
195 #if 0 /* FIXME: This is very unstable. Many players crash with this. */
196 if( header->ID != 0 )
199 * NOTE: This ADTS seems of ISO/IEC 13818-7 (MPEG-2 AAC).
200 * It has special object_type_indications, depending on it's profile (Legacy Interface).
201 * If ADIF header is not available, it should not have decoder specific information, so AudioObjectType neither.
202 * see ISO/IEC 14496-1, DecoderSpecificInfo and 14496-3 Subpart 9: MPEG-1/2 Audio in MPEG-4.
204 summary->object_type_indication = header->profile_ObjectType + MP4SYS_OBJECT_TYPE_Audio_ISO_13818_7_Main_Profile;
205 summary->aot = MP4A_AUDIO_OBJECT_TYPE_NULL;
206 summary->asc = NULL;
207 summary->asc_length = 0;
208 // summary->sbr_mode = MP4A_AAC_SBR_NONE; /* MPEG-2 AAC should not be HE-AAC, but we forgive them. */
209 return summary;
211 #endif
212 uint32_t data_length;
213 uint8_t *data = mp4a_export_AudioSpecificConfig( header->profile_ObjectType + MP4A_AUDIO_OBJECT_TYPE_AAC_MAIN,
214 summary->frequency, summary->channels, summary->sbr_mode,
215 NULL, 0, &data_length );
216 if( !data )
218 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
219 return NULL;
221 lsmash_codec_specific_t *specific = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_MP4SYS_DECODER_CONFIG,
222 LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED );
223 if( !specific )
225 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
226 lsmash_free( data );
227 return NULL;
229 lsmash_mp4sys_decoder_parameters_t *param = (lsmash_mp4sys_decoder_parameters_t *)specific->data.structured;
230 param->objectTypeIndication = MP4SYS_OBJECT_TYPE_Audio_ISO_14496_3;
231 param->streamType = MP4SYS_STREAM_TYPE_AudioStream;
232 if( lsmash_set_mp4sys_decoder_specific_info( param, data, data_length ) )
234 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
235 lsmash_destroy_codec_specific_data( specific );
236 lsmash_free( data );
237 return NULL;
239 lsmash_free( data );
240 if( lsmash_add_entry( &summary->opaque->list, specific ) )
242 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
243 lsmash_destroy_codec_specific_data( specific );
244 return NULL;
246 return summary;
249 typedef struct
251 importer_status status;
252 unsigned int raw_data_block_idx;
253 mp4sys_adts_fixed_header_t header;
254 mp4sys_adts_variable_header_t variable_header;
255 uint32_t samples_in_frame;
256 uint32_t au_number;
257 } mp4sys_adts_info_t;
259 static int mp4sys_adts_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample )
261 debug_if( !importer || !importer->info || !buffered_sample->data || !buffered_sample->length )
262 return -1;
263 if( !importer->info || track_number != 1 )
264 return -1;
265 mp4sys_adts_info_t* info = (mp4sys_adts_info_t*)importer->info;
266 importer_status current_status = info->status;
267 uint16_t raw_data_block_size = info->variable_header.raw_data_block_size[info->raw_data_block_idx];
268 if( current_status == IMPORTER_ERROR || buffered_sample->length < raw_data_block_size )
269 return -1;
270 if( current_status == IMPORTER_EOF )
272 buffered_sample->length = 0;
273 return 0;
275 if( current_status == IMPORTER_CHANGE )
277 lsmash_audio_summary_t* summary = mp4sys_adts_create_summary( &info->header );
278 if( !summary )
279 return -1;
280 lsmash_entry_t* entry = lsmash_get_entry( importer->summaries, track_number );
281 if( !entry || !entry->data )
282 return -1;
283 lsmash_cleanup_summary( entry->data );
284 entry->data = summary;
285 info->samples_in_frame = summary->samples_in_frame;
288 /* read a raw_data_block(), typically == payload of a ADTS frame */
289 if( fread( buffered_sample->data, 1, raw_data_block_size, importer->stream ) != raw_data_block_size )
291 info->status = IMPORTER_ERROR;
292 return -1;
294 buffered_sample->length = raw_data_block_size;
295 buffered_sample->dts = info->au_number++ * info->samples_in_frame;
296 buffered_sample->cts = buffered_sample->dts;
297 buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC;
298 buffered_sample->prop.pre_roll.distance = 1; /* MDCT */
300 /* now we succeeded to read current frame, so "return" takes 0 always below. */
302 /* skip adts_raw_data_block_error_check() */
303 if( info->header.protection_absent == 0
304 && info->variable_header.number_of_raw_data_blocks_in_frame != 0
305 && fread( buffered_sample->data, 1, 2, importer->stream ) != 2 )
307 info->status = IMPORTER_ERROR;
308 return 0;
310 /* current adts_frame() has any more raw_data_block()? */
311 if( info->raw_data_block_idx < info->variable_header.number_of_raw_data_blocks_in_frame )
313 info->raw_data_block_idx++;
314 info->status = IMPORTER_OK;
315 return 0;
317 info->raw_data_block_idx = 0;
319 /* preparation for next frame */
321 uint8_t buf[MP4SYS_ADTS_MAX_FRAME_LENGTH];
322 size_t ret = fread( buf, 1, MP4SYS_ADTS_BASIC_HEADER_LENGTH, importer->stream );
323 if( ret == 0 )
325 info->status = IMPORTER_EOF;
326 return 0;
328 if( ret != MP4SYS_ADTS_BASIC_HEADER_LENGTH )
330 info->status = IMPORTER_ERROR;
331 return 0;
334 * NOTE: About the spec of ADTS headers.
335 * By the spec definition, ADTS's fixed header cannot change in the middle of stream.
336 * But spec of MP4 allows that a stream(track) changes its properties in the middle of it.
339 * NOTE: About detailed check for ADTS headers.
340 * We do not ommit detailed check for fixed header by simply testing bits' identification,
341 * because there're some flags which does not matter to audio_summary (so AudioSpecificConfig neither)
342 * so that we can take them as no change and never make new ObjectDescriptor.
343 * I know that can be done with/by bitmask also and that should be fast, but L-SMASH project prefers
344 * even foolishly straightforward way.
347 * NOTE: About our reading algorithm for ADTS.
348 * It's rather simple if we retrieve payload of ADTS (i.e. raw AAC frame) at the same time to
349 * retrieve headers.
350 * But then we have to cache and memcpy every frame so that it requires more clocks and memory.
351 * To avoid them, I adopted this separate retrieving method.
353 mp4sys_adts_fixed_header_t header = {0};
354 mp4sys_adts_variable_header_t variable_header = {0};
355 if( mp4sys_adts_parse_headers( importer->stream, buf, &header, &variable_header ) )
357 info->status = IMPORTER_ERROR;
358 return 0;
360 info->variable_header = variable_header;
363 * NOTE: About our support for change(s) of properties within an ADTS stream.
364 * We have to modify these conditions depending on the features we support.
365 * For example, if we support copyright_identification_* in any way within any feature
366 * defined by/in any specs, such as ISO/IEC 14496-1 (MPEG-4 Systems), like...
367 * "8.3 Intellectual Property Management and Protection (IPMP)", or something similar,
368 * we have to check copyright_identification_* and treat them in audio_summary.
369 * "Change(s)" may result in MP4SYS_IMPORTER_ERROR or MP4SYS_IMPORTER_CHANGE
370 * depending on the features we support, and what the spec allows.
371 * Sometimes the "change(s)" can be allowed, while sometimes they're forbidden.
373 /* currently UNsupported "change(s)". */
374 if( info->header.profile_ObjectType != header.profile_ObjectType /* currently unsupported. */
375 || info->header.ID != header.ID /* In strict, this means change of object_type_indication. */
376 || info->header.sampling_frequency_index != header.sampling_frequency_index ) /* This may change timebase. */
378 info->status = IMPORTER_ERROR;
379 return 0;
381 /* currently supported "change(s)". */
382 if( info->header.channel_configuration != header.channel_configuration )
385 * FIXME: About conditions of VALID "change(s)".
386 * we have to check whether any "change(s)" affect to audioProfileLevelIndication
387 * in InitialObjectDescriptor (MP4_IOD) or not.
388 * If another type or upper level is required by the change(s), that is forbidden.
389 * Because ObjectDescriptor does not have audioProfileLevelIndication,
390 * so that it seems impossible to change audioProfileLevelIndication in the middle of the stream.
391 * Note also any other properties, such as AudioObjectType, object_type_indication.
394 * NOTE: updating summary must be done on next call,
395 * because user may retrieve summary right after this function call of this time,
396 * and that should be of current, before change, one.
398 info->header = header;
399 info->status = IMPORTER_CHANGE;
400 return 0;
402 /* no change which matters to mp4 muxing was found */
403 info->status = IMPORTER_OK;
404 return 0;
407 static void mp4sys_adts_cleanup( importer_t *importer )
409 debug_if( importer && importer->info )
410 lsmash_free( importer->info );
413 /* returns 0 if it seems adts. */
414 static int mp4sys_adts_probe( importer_t *importer )
416 uint8_t buf[MP4SYS_ADTS_MAX_FRAME_LENGTH];
417 if( fread( buf, 1, MP4SYS_ADTS_BASIC_HEADER_LENGTH, importer->stream ) != MP4SYS_ADTS_BASIC_HEADER_LENGTH )
418 return -1;
420 mp4sys_adts_fixed_header_t header = {0};
421 mp4sys_adts_variable_header_t variable_header = {0};
422 if( mp4sys_adts_parse_headers( importer->stream, buf, &header, &variable_header ) )
423 return -1;
425 /* now the stream seems valid ADTS */
427 lsmash_audio_summary_t* summary = mp4sys_adts_create_summary( &header );
428 if( !summary )
429 return -1;
431 /* importer status */
432 mp4sys_adts_info_t* info = lsmash_malloc_zero( sizeof(mp4sys_adts_info_t) );
433 if( !info )
435 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
436 return -1;
438 info->status = IMPORTER_OK;
439 info->raw_data_block_idx = 0;
440 info->header = header;
441 info->variable_header = variable_header;
442 info->samples_in_frame = summary->samples_in_frame;
444 if( lsmash_add_entry( importer->summaries, summary ) )
446 lsmash_free( info );
447 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
448 return -1;
450 importer->info = info;
452 return 0;
455 static uint32_t mp4sys_adts_get_last_delta( importer_t *importer, uint32_t track_number )
457 debug_if( !importer || !importer->info )
458 return 0;
459 mp4sys_adts_info_t *info = (mp4sys_adts_info_t *)importer->info;
460 if( !info || track_number != 1 || info->status != IMPORTER_EOF )
461 return 0;
462 return info->samples_in_frame;
465 const importer_functions mp4sys_adts_importer =
467 { "adts" },
469 mp4sys_adts_probe,
470 mp4sys_adts_get_accessunit,
471 mp4sys_adts_get_last_delta,
472 mp4sys_adts_cleanup