介紹
在前面flv格式詳解+實例剖析的文章中介紹了flv的格式寥袭,今天這章主要介紹ADTS格式
AAC的音頻文件格式有ADIF & ADTS:
ADIF:Audio Data Interchange Format 音頻數(shù)據(jù)交換格式。這種格式的特征是可以確定的找到這個音頻數(shù)據(jù)的開始,不需進(jìn)行在音頻數(shù)據(jù)流中間開始的解碼杯活,即它的解碼必須在明確定義的開始處進(jìn)行狰腌。故這種格式常用在磁盤文件中柳畔。
ADTS:Audio Data Transport Stream鼎姐。是AAC音頻的傳輸流格式哪雕。這種格式的特征是它是一個有同步字的比特流船殉,解碼可以在這個流中任何位置開始。
總結(jié):ADTS可以在任意幀解碼斯嚎,也就是說它每一幀都有頭信息利虫。ADIF只有一個統(tǒng)一的頭,所以必須得到所有的數(shù)據(jù)后解碼堡僻。且這兩種的header的格式也是不同的糠惫,目前一般編碼后的和抽取出的都是ADTS格式的音頻流。
ADTS 格式
從圖上可以總結(jié)出兩點(diǎn):
- ADTS Frame = ADTS頭+AAC ES(AAC音頻數(shù)據(jù))
- ADTS頭包含了AAC文件的采樣率钉疫、通道數(shù)硼讽、幀數(shù)據(jù)長度等信息。ADTS頭分為固定頭信息和可變頭信息兩個部分陌选,固定頭信息在每個幀中的是一樣的理郑,可變頭信息在各個幀中并不是固定值蹄溉。ADTS頭一般是7個字節(jié)((28+28)/ 8)長度咨油,如果需要對數(shù)據(jù)進(jìn)行CRC校驗,則會有2個Byte的校驗碼柒爵,所以ADTS頭的實際長度
是7個字節(jié)或9個字節(jié)役电。
固定頭信息: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:表示使用的采樣率下標(biāo)
- 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: 表示聲道數(shù)
- 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:編碼時設(shè)置為0,解碼時忽略
- copyrighted_id_start:編碼時設(shè)置為0唁奢,解碼時忽略
- aac_frame_length:ADTS幀長度包括ADTS長度和AAC聲音數(shù)據(jù)長度的和霎挟。即 - - aac_frame_length = (protection_absent == 0 ? 9 : 7) + audio_data_length
- adts_buffer_fullness:固定為0x7FF。表示是碼率可變的碼流
- number_of_raw_data_blocks_in_frame:表示當(dāng)前幀有number_of_raw_data_blocks_in_frame + 1 個原始幀(一個AAC原始幀包含一段時間內(nèi)1024個采樣及相關(guān)數(shù)據(jù))麻掸。
實例分析
前面文章介紹了flv格式詳解+實例剖析酥夭,這里我們還是使用里面的資源《東風(fēng)破》——周杰倫(下載)
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把a(bǔ)ac抽取出來文件
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個字節(jié)
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格式分析就結(jié)束了熬北,大家可以自己嘗試一下。