Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: parse AAC file with adts headers to extract out AAC (Read 17661 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

parse AAC file with adts headers to extract out AAC

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: [Select]
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: [Select]
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: [Select]
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: [Select]

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

 

parse AAC file with adts headers to extract out AAC

Reply #1
Do I just output the bytes of each frame and consider that the AAC data ?


Yes.

You can confirm your parser is working correctly by checking that channels, samplerate etc stay constant over the file and correspond to what you know about the file.

parse AAC file with adts headers to extract out AAC

Reply #2
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.

parse AAC file with adts headers to extract out AAC

Reply #3
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