parse AAC file with adts headers to extract out AAC |
![]() ![]() |
parse AAC file with adts headers to extract out AAC |
Jun 28 2012, 01:46
Post
#1
|
|
![]() Group: Members Posts: 2 Joined: 30-May 12 Member No.: 100271 |
I am writing some c code to read AAC files with ADTS headers
with goal of extracting just the AAC data for downstream hardware decompression into linear PCM. From command line this works : ffmpeg -i input.aac output.wav CODE ffmpeg version git-2012-06-13-4a6d790 Copyright © 2000-2012 the FFmpeg developers built on Jun 13 2012 14:43:00 with llvm_gcc 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00) configuration: libavutil 51. 58.100 / 51. 58.100 libavcodec 54. 25.100 / 54. 25.100 libavformat 54. 6.101 / 54. 6.101 libavdevice 54. 0.100 / 54. 0.100 libavfilter 2. 78.101 / 2. 78.101 libswscale 2. 1.100 / 2. 1.100 libswresample 0. 15.100 / 0. 15.100 [aac @ 0x7fc39a03d800] Format aac detected only with low score of 25, misdetection possible! [aac @ 0x7fc39a03fc00] channel element 0.5 is not allocated [aac @ 0x7fc39a03d800] max_analyze_duration 5000000 reached at 5013333 [aac @ 0x7fc39a03d800] Estimating duration from bitrate, this may be inaccurate Input #0, aac, from 'input.aac': Duration: 00:00:06.03, bitrate: 46 kb/s Stream #0:0: Audio: aac, 48000 Hz, mono, s16, 46 kb/s Output #0, wav, to 'output.wav': Metadata: encoder : Lavf54.6.101 Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, mono, s16, 768 kb/s Stream mapping: Stream #0:0 -> #0:0 (aac -> pcm_s16le) Press [q] to stop, [?] for help [aac @ 0x7fc39a03fc00] Number of scalefactor bands in group (56) exceeds limit (49). Error while decoding stream #0:0: Invalid data found when processing input [aac @ 0x7fc39a03fc00] channel element 2.10 is not allocated Error while decoding stream #0:0: Operation not permitted size= 540kB time=00:00:09.71 bitrate= 455.6kbits/s video:0kB audio:540kB global headers:0kB muxing overhead 0.008319% the output.wav plays OK using say ffplay or afplay interestingly my input.aac plays OK with ffplay yet fails to play using afplay : Error: AudioFileOpen failed ('sync') here is the input file : CODE mediainfo input.aac General Complete name : input.aac Format : ADTS Format/Info : Audio Data Transport Stream File size : 34.0 KiB Overall bit rate mode : Variable Audio Format : AAC Format/Info : Advanced Audio Codec Format version : Version 4 Format profile : LC Bit rate mode : Variable Bit rate : 47.1 Kbps Minimum bit rate : 39.8 Kbps Maximum bit rate : 55.5 Kbps Channel(s) : 1 channel Channel positions : Front: C Sampling rate : 48.0 KHz Compression mode : Lossy Stream size : 33.8 KiB (100%) here is output file after above ffmpeg conversion : CODE mediainfo output.wav General Complete name : output.wav Format : Wave File size : 540 KiB Duration : 5s 760ms Overall bit rate mode : Constant Overall bit rate : 768 Kbps Audio ID : 0 Format : PCM Format settings, Endianness : Little Codec ID : 1 Duration : 5s 760ms Bit rate mode : Constant Bit rate : 768 Kbps Channel(s) : 1 channel Sampling rate : 48.0 KHz Bit depth : 16 bits Stream size : 540 KiB (100%) to write my c code I am reading the AAC ISO spec 13818-7 however I am not sure at what point I have parsed out the AAC data format. Here is output from my code when parsing an input AAC file : CODE about to show values for fixed header 0 syncword fff 4095 1 ID 1 1 2 layer 3 3 3 protection_absent 1 1 4 profile 1 1 5 sampling_frequency_index 4 4 6 private_bit 0 0 7 channel_configuration 2 2 8 original/copy 0 0 9 home 0 0 about to show values for variable header 0 copyright_identification_bit 0 0 1 copyright_identification_start 0 0 2 frame_length 802 2050 3 adts_buffer_fullness 600 1536 4 number_of_raw_data_blocks_in_frame 0 0 So a few things might help : (1) some tool to breakdown my input.aac to indicate each frame or (2) other ISO spec relevant guideposts so I can confirm my code is correctly identifying just the AAC data. When I execute my code it reaches what the ISO spec calls the : raw_data_block. Do I just output the bytes of each frame and consider that the AAC data ? Once I can extract out the AAC data from my input.aac file I will then feed it into some Core Audio API call to decompress into linear PCM. thanks |
|
|
|
Jun 28 2012, 07:13
Post
#2
|
|
![]() Server Admin Group: Admin Posts: 4808 Joined: 24-September 01 Member No.: 13 |
|
|
|
|
Jun 28 2012, 17:30
Post
#3
|
|
![]() WavPack Developer Group: Developer (Donating) Posts: 1219 Joined: 3-January 02 From: San Francisco CA Member No.: 900 |
If your data does not start with a syncword (0xFFF), or you are trying to seek into the middle of a stream, then you have to scan for a syncword. But I’ve found that the raw data may contain syncwords randomly, so what I have done is confirm that a syncword is valid by parsing the rest of the header, verifying that the other info matches what’s known about the stream (like Garf says), and then looking ahead to where the next syncword would be (based on the frame length) and making sure there’s another syncword there. Then you can be sure that you haven’t gotten a false trigger.
|
|
|
|
Jul 12 2012, 17:33
Post
#4
|
|
![]() Group: Members Posts: 2 Joined: 30-May 12 Member No.: 100271 |
Nice - I am now successfully bit walking until I see a syncword (0xfff), stepping over an initial ADTS header, storing fixed header values for subsequent matching on followup frames to recognize frame false positives - when I output the entire frames from fixed header to next syncword, I can pass the data into an iOS hardware decompress which outputs linear PCM which my OpenAL can happily render into audio - thanks a bunch
|
|
|
|
![]() ![]() |
|
Lo-Fi Version | Time is now: 23rd May 2013 - 01:13 |