介绍
在前面flv格式详解+实例剖析的文章中介绍了flv的格式,今天这章主要介绍ADTS格式
AAC的音频文件格式有ADIF & ADTS:
ADIF:Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。
ADTS:Audio Data Transport Stream。是AAC音频的传输流格式。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。
总结:ADTS可以在任意帧解码,也就是说它每一帧都有头信息。ADIF只有一个统一的头,所以必须得到所有的数据后解码。且这两种的header的格式也是不同的,目前一般编码后的和抽取出的都是ADTS格式的音频流。
ADTS 格式
从图上可以总结出两点:
- ADTS Frame = ADTS头+AAC ES(AAC音频数据)
- ADTS头包含了AAC文件的采样率、通道数、帧数据长度等信息。ADTS头分为固定头信息和可变头信息两个部分,固定头信息在每个帧中的是一样的,可变头信息在各个帧中并不是固定值。ADTS头一般是7个字节((28+28)/ 8)长度,如果需要对数据进行CRC校验,则会有2个Byte的校验码,所以ADTS头的实际长度
是7个字节或9个字节。
固定头信息:adts_fixed_header()
syncword :同步头 总是0xFFF, all bits must be 1,代表着一个ADTS帧的开始
- ID:MPEG Version: 0 for MPEG-4, 1 for MPEG-2
- Layer:always: '00'
- profile:表示使用哪个级别的AAC,有些芯片只支持AAC LC 。在MPEG-2 AAC中定义了3种:
- 0: AAC Main
- 1:AAC LC (Low Complexity)
- 2:AAC SSR (Scalable Sample Rate)
- 3:AAC LTP (Long Term Prediction)
- sampling_frequency_index:表示使用的采样率下标
- 0: 96000 Hz
- 1: 88200 Hz
- 2: 64000 Hz
- 3: 48000 Hz
- 4: 44100 Hz
- 5: 32000 Hz
- 6: 24000 Hz
- 7: 22050 Hz
- 8: 16000 Hz
- 9: 12000 Hz
- 10: 11025 Hz
- 11: 8000 Hz
- 12: 7350 Hz
- 13: Reserved
- 14: Reserved
- 15: frequency is written explictly
- channel_configuration: 表示声道数
- 0: Defined in AOT Specifc Config
- 1: 1 channel: front-center
- 2: 2 channels: front-left, front-right
- 3: 3 channels: front-center, front-left, front-right
- 4: 4 channels: front-center, front-left, front-right, back-center
- 5: 5 channels: front-center, front-left, front-right, back-left, back-right
- 6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
- 7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right,
可变头信息:adts_variable_header()
- copyrighted_id_bit:编码时设置为0,解码时忽略
- copyrighted_id_start:编码时设置为0,解码时忽略
- aac_frame_length:ADTS帧长度包括ADTS长度和AAC声音数据长度的和。即 - - aac_frame_length = (protection_absent == 0 ? 9 : 7) + audio_data_length
- adts_buffer_fullness:固定为0x7FF。表示是码率可变的码流
- number_of_raw_data_blocks_in_frame:表示当前帧有number_of_raw_data_blocks_in_frame + 1 个原始帧(一个AAC原始帧包含一段时间内1024个采样及相关数据)。
实例分析
前面文章介绍了flv格式详解+实例剖析,这里我们还是使用里面的资源《东风破》——周杰伦(下载)
D:\jianshu>ffprobe -show_format dongfengpo.flv
ffprobe version 4.4-full_build-www.gyan.dev Copyright (c) 2007-2021 the FFmpeg developers
built with gcc 10.2.0 (Rev6, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libglslang --enable-vulkan --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
Input #0, flv, from 'dongfengpo.flv':
Metadata:
encoder : Lavf57.41.100
Duration: 00:05:14.47, start: 0.000000, bitrate: 431 kb/s
Stream #0:0: Video: h264 (High), yuv420p(progressive), 352x240 [SAR 3675:3674 DAR 245:167], 283 kb/s, 29.97 fps, 29.97 tbr, 1k tbn, 59.94 tbc
Stream #0:1: Audio: aac (LC), 44100 Hz, stereo, fltp, 128 kb/s
[FORMAT]
filename=dongfengpo.flv
nb_streams=2
nb_programs=0
format_name=flv
format_long_name=FLV (Flash Video)
start_time=0.000000
duration=314.470000
size=16954257
bit_rate=431310
probe_score=100
TAG:encoder=Lavf57.41.100
[/FORMAT]
视频是flv格式的文件,我们先使用ffmpeg把aac抽取出来文件
ffmpeg -i dongfengpo.flv -acodec copy -vn dongfengpo.aac
查看一下信息
D:\jianshu>ffprobe -show_format dongfengpo.aac
ffprobe version 4.4-full_build-www.gyan.dev Copyright (c) 2007-2021 the FFmpeg developers
built with gcc 10.2.0 (Rev6, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libglslang --enable-vulkan --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
[aac @ 000001da29bfa980] Estimating duration from bitrate, this may be inaccurate
Input #0, aac, from 'dongfengpo.aac':
Duration: 00:04:58.38, bitrate: 139 kb/s
Stream #0:0: Audio: aac (LC), 44100 Hz, stereo, fltp, 139 kb/s
[FORMAT]
filename=dongfengpo.aac
nb_streams=1
nb_programs=0
format_name=aac
format_long_name=raw ADTS AAC (Advanced Audio Coding)
start_time=N/A
duration=298.379710
size=5188301
bit_rate=139106
probe_score=51
[/FORMAT]
使用Binary Viewer打开
我们看前7个字节
FFF1508003DFFC
按照前面的格式分析
- 固定头部分
syncword = 0xFFF
ID = 0
layer = 00
protection_absent = 1
profile = 01 也就是AAC
sampling_frequency_index = 0100 也就是44100HZ
channel_configuration = 010 - 可变头部分
aac_frame_length = 0000000011110 = 30
adts_buffer_fullness = 11111111111 = 0x7FF
我们找到下一个同步字0xFFF的位置正好是在30。符合aac_frame_length
最后我们用工具Projects (p23.nl)验证一下
到这里整个adts格式分析就结束了,大家可以自己尝试一下。