1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2010-2015 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
29 /***************************************************************************
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
41 uint16_t syncword
; /* 12; */
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
;
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
;
70 unsigned int raw_data_block_idx
;
71 mp4sys_adts_fixed_header_t header
;
72 mp4sys_adts_variable_header_t variable_header
;
73 uint32_t samples_in_frame
;
75 } mp4sys_adts_importer_t
;
77 static void remove_mp4sys_adts_importer
79 mp4sys_adts_importer_t
*adts_imp
82 lsmash_free( adts_imp
);
85 static mp4sys_adts_importer_t
*create_mp4sys_adts_importer
90 return (mp4sys_adts_importer_t
*)lsmash_malloc_zero( sizeof(mp4sys_adts_importer_t
) );
93 static void mp4sys_adts_cleanup( importer_t
*importer
)
95 debug_if( importer
&& importer
->info
)
96 remove_mp4sys_adts_importer( importer
->info
);
99 static void mp4sys_adts_parse_fixed_header
102 mp4sys_adts_fixed_header_t
*header
105 /* FIXME: should we rewrite these code using bitstream reader? */
106 header
->syncword
= (buf
[0] << 4) | (buf
[1] >> 4);
107 header
->ID
= (buf
[1] >> 3) & 0x1;
108 header
->layer
= (buf
[1] >> 1) & 0x3;
109 header
->protection_absent
= buf
[1] & 0x1;
110 header
->profile_ObjectType
= buf
[2] >> 6;
111 header
->sampling_frequency_index
= (buf
[2] >> 2) & 0xF;
112 // header->private_bit = (buf[2] >> 1) & 0x1; /* we don't care currently. */
113 header
->channel_configuration
= ((buf
[2] << 2) | (buf
[3] >> 6)) & 0x07;
114 // header->original_copy = (buf[3] >> 5) & 0x1; /* we don't care currently. */
115 // header->home = (buf[3] >> 4) & 0x1; /* we don't care currently. */
118 static int mp4sys_adts_check_fixed_header
120 mp4sys_adts_fixed_header_t
*header
123 if( header
->syncword
!= 0xFFF ) return LSMASH_ERR_INVALID_DATA
;
124 // if( header->ID != 0x0 ) return LSMASH_ERR_NAMELESS; /* we don't care. */
125 if( header
->layer
!= 0x0 ) return LSMASH_ERR_INVALID_DATA
; /* must be 0b00 for any type of AAC */
126 // if( header->protection_absent != 0x1 ) return LSMASH_ERR_NAMELESS; /* we don't care. */
127 if( header
->profile_ObjectType
!= 0x1 ) return LSMASH_ERR_PATCH_WELCOME
; /* FIXME: 0b00=Main, 0b01=LC, 0b10=SSR, 0b11=LTP. */
128 if( header
->sampling_frequency_index
> 0xB ) return LSMASH_ERR_INVALID_DATA
; /* must not be > 0xB. */
129 if( header
->channel_configuration
== 0x0 ) return LSMASH_ERR_PATCH_WELCOME
; /* FIXME: we do not support 0b000 currently. */
130 if( header
->profile_ObjectType
== 0x3 && header
->ID
!= 0x0 ) return LSMASH_ERR_INVALID_DATA
; /* LTP is valid only if ID==0. */
134 static int mp4sys_adts_parse_variable_header
138 unsigned int protection_absent
,
139 mp4sys_adts_variable_header_t
*header
142 /* FIXME: should we rewrite these code using bitstream reader? */
143 // header->copyright_identification_bit = (buf[3] >> 3) & 0x1; /* we don't care. */
144 // header->copyright_identification_start = (buf[3] >> 2) & 0x1; /* we don't care. */
145 header
->frame_length
= ((buf
[3] << 11) | (buf
[4] << 3) | (buf
[5] >> 5)) & 0x1FFF ;
146 // header->adts_buffer_fullness = ((buf[5] << 6) | (buf[6] >> 2)) 0x7FF ; /* we don't care. */
147 header
->number_of_raw_data_blocks_in_frame
= buf
[6] & 0x3;
149 if( header
->frame_length
<= MP4SYS_ADTS_BASIC_HEADER_LENGTH
+ 2 * (protection_absent
== 0) )
150 return LSMASH_ERR_INVALID_DATA
; /* easy error check */
152 /* protection_absent and number_of_raw_data_blocks_in_frame relatives */
155 unsigned int number_of_blocks
= header
->number_of_raw_data_blocks_in_frame
;
156 if( number_of_blocks
== 0 )
158 header
->raw_data_block_size
[0] = header
->frame_length
- MP4SYS_ADTS_BASIC_HEADER_LENGTH
;
159 /* skip adts_error_check() and subtract that from block_size */
160 if( protection_absent
== 0 )
162 header
->raw_data_block_size
[0] -= 2;
163 if( lsmash_bs_get_bytes_ex( bs
, 2, buf2
) != 2 )
164 return LSMASH_ERR_INVALID_DATA
;
169 /* now we have multiple raw_data_block()s, so evaluate adts_header_error_check() */
171 uint16_t raw_data_block_position
[MP4SYS_ADTS_MAX_RAW_DATA_BLOCKS
];
172 uint16_t first_offset
= MP4SYS_ADTS_BASIC_HEADER_LENGTH
;
173 if( protection_absent
== 0 )
175 /* process adts_header_error_check() */
176 for( int i
= 0 ; i
< number_of_blocks
; i
++ ) /* 1-based in the spec, but we use 0-based */
178 if( lsmash_bs_get_bytes_ex( bs
, 2, buf2
) != 2 )
179 return LSMASH_ERR_INVALID_DATA
;
180 raw_data_block_position
[i
] = LSMASH_GET_BE16( buf2
);
182 /* skip crc_check in adts_header_error_check().
183 Or might be sizeof( adts_error_check() ) if we share with the case number_of_raw_data_blocks_in_frame == 0 */
184 if( lsmash_bs_get_bytes_ex( bs
, 2, buf2
) != 2 )
185 return LSMASH_ERR_INVALID_DATA
;
186 first_offset
+= ( 2 * number_of_blocks
) + 2; /* according to above */
191 * NOTE: We never support the case where number_of_raw_data_blocks_in_frame != 0 && protection_absent != 0,
192 * because we have to parse the raw AAC bitstream itself to find boundaries of raw_data_block()s in this case.
193 * Which is to say, that braindamaged spec requires us (mp4 muxer) to decode AAC once to split frames.
194 * L-SMASH is NOT AAC DECODER, so that we've just given up for this case.
195 * This is ISO/IEC 13818-7's sin which defines ADTS format originally.
197 return LSMASH_ERR_NAMELESS
;
200 /* convert raw_data_block_position --> raw_data_block_size */
202 /* do conversion for first */
203 header
->raw_data_block_size
[0] = raw_data_block_position
[0] - first_offset
;
204 /* set dummy offset to tail for loop, do coversion for rest. */
205 raw_data_block_position
[number_of_blocks
] = header
->frame_length
;
206 for( int i
= 1 ; i
<= number_of_blocks
; i
++ )
207 header
->raw_data_block_size
[i
] = raw_data_block_position
[i
] - raw_data_block_position
[i
-1];
209 /* adjustment for adts_raw_data_block_error_check() */
210 if( protection_absent
== 0 && number_of_blocks
!= 0 )
211 for( int i
= 0 ; i
<= number_of_blocks
; i
++ )
212 header
->raw_data_block_size
[i
] -= 2;
217 static int mp4sys_adts_parse_headers
221 mp4sys_adts_fixed_header_t
*header
,
222 mp4sys_adts_variable_header_t
*variable_header
225 mp4sys_adts_parse_fixed_header( buf
, header
);
226 int err
= mp4sys_adts_check_fixed_header( header
);
229 /* get payload length & skip extra(crc) header */
230 return mp4sys_adts_parse_variable_header( bs
, buf
, header
->protection_absent
, variable_header
);
233 static lsmash_audio_summary_t
*mp4sys_adts_create_summary
235 mp4sys_adts_fixed_header_t
*header
238 lsmash_audio_summary_t
*summary
= (lsmash_audio_summary_t
*)lsmash_create_summary( LSMASH_SUMMARY_TYPE_AUDIO
);
241 summary
->sample_type
= ISOM_CODEC_TYPE_MP4A_AUDIO
;
242 summary
->max_au_length
= MP4SYS_ADTS_MAX_FRAME_LENGTH
;
243 summary
->frequency
= mp4a_sampling_frequency_table
[header
->sampling_frequency_index
][1];
244 summary
->channels
= header
->channel_configuration
+ ( header
->channel_configuration
== 0x07 ); /* 0x07 means 7.1ch */
245 summary
->sample_size
= 16;
246 summary
->samples_in_frame
= 1024;
247 summary
->aot
= header
->profile_ObjectType
+ MP4A_AUDIO_OBJECT_TYPE_AAC_MAIN
;
248 summary
->sbr_mode
= MP4A_AAC_SBR_NOT_SPECIFIED
;
249 #if 0 /* FIXME: This is very unstable. Many players crash with this. */
250 if( header
->ID
!= 0 )
253 * NOTE: This ADTS seems of ISO/IEC 13818-7 (MPEG-2 AAC).
254 * It has special object_type_indications, depending on it's profile (Legacy Interface).
255 * If ADIF header is not available, it should not have decoder specific information, so AudioObjectType neither.
256 * see ISO/IEC 14496-1, DecoderSpecificInfo and 14496-3 Subpart 9: MPEG-1/2 Audio in MPEG-4.
258 summary
->object_type_indication
= header
->profile_ObjectType
+ MP4SYS_OBJECT_TYPE_Audio_ISO_13818_7_Main_Profile
;
259 summary
->aot
= MP4A_AUDIO_OBJECT_TYPE_NULL
;
261 summary
->asc_length
= 0;
262 // summary->sbr_mode = MP4A_AAC_SBR_NONE; /* MPEG-2 AAC should not be HE-AAC, but we forgive them. */
266 uint32_t data_length
;
267 uint8_t *data
= mp4a_export_AudioSpecificConfig( header
->profile_ObjectType
+ MP4A_AUDIO_OBJECT_TYPE_AAC_MAIN
,
268 summary
->frequency
, summary
->channels
, summary
->sbr_mode
,
269 NULL
, 0, &data_length
);
272 lsmash_cleanup_summary( (lsmash_summary_t
*)summary
);
275 lsmash_codec_specific_t
*specific
= lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_MP4SYS_DECODER_CONFIG
,
276 LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED
);
279 lsmash_cleanup_summary( (lsmash_summary_t
*)summary
);
283 lsmash_mp4sys_decoder_parameters_t
*param
= (lsmash_mp4sys_decoder_parameters_t
*)specific
->data
.structured
;
284 param
->objectTypeIndication
= MP4SYS_OBJECT_TYPE_Audio_ISO_14496_3
;
285 param
->streamType
= MP4SYS_STREAM_TYPE_AudioStream
;
286 if( lsmash_set_mp4sys_decoder_specific_info( param
, data
, data_length
) < 0 )
288 lsmash_cleanup_summary( (lsmash_summary_t
*)summary
);
289 lsmash_destroy_codec_specific_data( specific
);
294 if( lsmash_add_entry( &summary
->opaque
->list
, specific
) < 0 )
296 lsmash_cleanup_summary( (lsmash_summary_t
*)summary
);
297 lsmash_destroy_codec_specific_data( specific
);
303 static int mp4sys_adts_get_accessunit
305 importer_t
*importer
,
306 uint32_t track_number
,
307 lsmash_sample_t
**p_sample
310 if( !importer
->info
)
311 return LSMASH_ERR_NAMELESS
;
312 if( track_number
!= 1 )
313 return LSMASH_ERR_FUNCTION_PARAM
;
314 mp4sys_adts_importer_t
*adts_imp
= (mp4sys_adts_importer_t
*)importer
->info
;
315 importer_status current_status
= importer
->status
;
316 uint16_t raw_data_block_size
= adts_imp
->variable_header
.raw_data_block_size
[ adts_imp
->raw_data_block_idx
];
317 if( current_status
== IMPORTER_ERROR
)
318 return LSMASH_ERR_NAMELESS
;
319 if( current_status
== IMPORTER_EOF
)
321 if( current_status
== IMPORTER_CHANGE
)
323 lsmash_entry_t
*entry
= lsmash_get_entry( importer
->summaries
, track_number
);
324 if( !entry
|| !entry
->data
)
325 return LSMASH_ERR_NAMELESS
;
326 lsmash_audio_summary_t
*summary
= mp4sys_adts_create_summary( &adts_imp
->header
);
328 return LSMASH_ERR_NAMELESS
;
329 lsmash_cleanup_summary( entry
->data
);
330 entry
->data
= summary
;
331 adts_imp
->samples_in_frame
= summary
->samples_in_frame
;
333 lsmash_bs_t
*bs
= importer
->bs
;
334 /* read a raw_data_block(), typically == payload of a ADTS frame */
335 lsmash_sample_t
*sample
= lsmash_create_sample( raw_data_block_size
);
337 return LSMASH_ERR_MEMORY_ALLOC
;
339 if( lsmash_bs_get_bytes_ex( bs
, raw_data_block_size
, sample
->data
) != raw_data_block_size
)
341 importer
->status
= IMPORTER_ERROR
;
342 return LSMASH_ERR_INVALID_DATA
;
344 sample
->length
= raw_data_block_size
;
345 sample
->dts
= adts_imp
->au_number
++ * adts_imp
->samples_in_frame
;
346 sample
->cts
= sample
->dts
;
347 sample
->prop
.ra_flags
= ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC
;
348 sample
->prop
.pre_roll
.distance
= 1; /* MDCT */
350 /* now we succeeded to read current frame, so "return" takes 0 always below. */
352 /* skip adts_raw_data_block_error_check() */
353 if( adts_imp
->header
.protection_absent
== 0
354 && adts_imp
->variable_header
.number_of_raw_data_blocks_in_frame
!= 0
355 && lsmash_bs_get_bytes_ex( bs
, 2, sample
->data
) != 2 )
357 importer
->status
= IMPORTER_ERROR
;
360 /* current adts_frame() has any more raw_data_block()? */
361 if( adts_imp
->raw_data_block_idx
< adts_imp
->variable_header
.number_of_raw_data_blocks_in_frame
)
363 adts_imp
->raw_data_block_idx
++;
364 importer
->status
= IMPORTER_OK
;
367 adts_imp
->raw_data_block_idx
= 0;
369 /* preparation for next frame */
371 uint8_t buf
[MP4SYS_ADTS_MAX_FRAME_LENGTH
];
372 int64_t ret
= lsmash_bs_get_bytes_ex( bs
, MP4SYS_ADTS_BASIC_HEADER_LENGTH
, buf
);
375 importer
->status
= IMPORTER_EOF
;
378 if( ret
!= MP4SYS_ADTS_BASIC_HEADER_LENGTH
)
380 importer
->status
= IMPORTER_ERROR
;
384 * NOTE: About the spec of ADTS headers.
385 * By the spec definition, ADTS's fixed header cannot change in the middle of stream.
386 * But spec of MP4 allows that a stream(track) changes its properties in the middle of it.
389 * NOTE: About detailed check for ADTS headers.
390 * We do not ommit detailed check for fixed header by simply testing bits' identification,
391 * because there're some flags which does not matter to audio_summary (so AudioSpecificConfig neither)
392 * so that we can take them as no change and never make new ObjectDescriptor.
393 * I know that can be done with/by bitmask also and that should be fast, but L-SMASH project prefers
394 * even foolishly straightforward way.
397 * NOTE: About our reading algorithm for ADTS.
398 * It's rather simple if we retrieve payload of ADTS (i.e. raw AAC frame) at the same time to
400 * But then we have to cache and memcpy every frame so that it requires more clocks and memory.
401 * To avoid them, I adopted this separate retrieving method.
403 mp4sys_adts_fixed_header_t header
= { 0 };
404 mp4sys_adts_variable_header_t variable_header
= { 0 };
405 if( mp4sys_adts_parse_headers( bs
, buf
, &header
, &variable_header
) < 0 )
407 importer
->status
= IMPORTER_ERROR
;
410 adts_imp
->variable_header
= variable_header
;
412 * NOTE: About our support for change(s) of properties within an ADTS stream.
413 * We have to modify these conditions depending on the features we support.
414 * For example, if we support copyright_identification_* in any way within any feature
415 * defined by/in any specs, such as ISO/IEC 14496-1 (MPEG-4 Systems), like...
416 * "8.3 Intellectual Property Management and Protection (IPMP)", or something similar,
417 * we have to check copyright_identification_* and treat them in audio_summary.
418 * "Change(s)" may result in MP4SYS_IMPORTER_ERROR or MP4SYS_IMPORTER_CHANGE
419 * depending on the features we support, and what the spec allows.
420 * Sometimes the "change(s)" can be allowed, while sometimes they're forbidden.
422 /* currently UNsupported "change(s)". */
423 if( adts_imp
->header
.profile_ObjectType
!= header
.profile_ObjectType
/* currently unsupported. */
424 || adts_imp
->header
.ID
!= header
.ID
/* In strict, this means change of object_type_indication. */
425 || adts_imp
->header
.sampling_frequency_index
!= header
.sampling_frequency_index
) /* This may change timebase. */
427 importer
->status
= IMPORTER_ERROR
;
430 /* currently supported "change(s)". */
431 if( adts_imp
->header
.channel_configuration
!= header
.channel_configuration
)
434 * FIXME: About conditions of VALID "change(s)".
435 * we have to check whether any "change(s)" affect to audioProfileLevelIndication
436 * in InitialObjectDescriptor (MP4_IOD) or not.
437 * If another type or upper level is required by the change(s), that is forbidden.
438 * Because ObjectDescriptor does not have audioProfileLevelIndication,
439 * so that it seems impossible to change audioProfileLevelIndication in the middle of the stream.
440 * Note also any other properties, such as AudioObjectType, object_type_indication.
443 * NOTE: updating summary must be done on next call,
444 * because user may retrieve summary right after this function call of this time,
445 * and that should be of current, before change, one.
447 adts_imp
->header
= header
;
448 importer
->status
= IMPORTER_CHANGE
;
451 /* no change which matters to mp4 muxing was found */
452 importer
->status
= IMPORTER_OK
;
456 /* returns 0 if it seems adts. */
457 static int mp4sys_adts_probe
462 mp4sys_adts_importer_t
*adts_imp
= create_mp4sys_adts_importer( importer
);
464 return LSMASH_ERR_MEMORY_ALLOC
;
466 uint8_t buf
[MP4SYS_ADTS_MAX_FRAME_LENGTH
];
467 if( lsmash_bs_get_bytes_ex( importer
->bs
, MP4SYS_ADTS_BASIC_HEADER_LENGTH
, buf
) != MP4SYS_ADTS_BASIC_HEADER_LENGTH
)
469 err
= LSMASH_ERR_INVALID_DATA
;
472 mp4sys_adts_fixed_header_t header
= { 0 };
473 mp4sys_adts_variable_header_t variable_header
= { 0 };
474 if( (err
= mp4sys_adts_parse_headers( importer
->bs
, buf
, &header
, &variable_header
)) < 0 )
476 /* now the stream seems valid ADTS */
477 lsmash_audio_summary_t
*summary
= mp4sys_adts_create_summary( &header
);
480 err
= LSMASH_ERR_NAMELESS
;
483 /* importer status */
484 if( lsmash_add_entry( importer
->summaries
, summary
) < 0 )
486 lsmash_cleanup_summary( (lsmash_summary_t
*)summary
);
487 err
= LSMASH_ERR_MEMORY_ALLOC
;
490 adts_imp
->raw_data_block_idx
= 0;
491 adts_imp
->header
= header
;
492 adts_imp
->variable_header
= variable_header
;
493 adts_imp
->samples_in_frame
= summary
->samples_in_frame
;
494 importer
->info
= adts_imp
;
495 importer
->status
= IMPORTER_OK
;
498 remove_mp4sys_adts_importer( adts_imp
);
502 static uint32_t mp4sys_adts_get_last_delta
504 importer_t
*importer
,
505 uint32_t track_number
508 debug_if( !importer
|| !importer
->info
)
510 mp4sys_adts_importer_t
*adts_imp
= (mp4sys_adts_importer_t
*)importer
->info
;
511 if( !adts_imp
|| track_number
!= 1 || importer
->status
!= IMPORTER_EOF
)
513 return adts_imp
->samples_in_frame
;
516 const importer_functions mp4sys_adts_importer
=
521 mp4sys_adts_get_accessunit
,
522 mp4sys_adts_get_last_delta
,