问题背景:算法
如今主流的封装格式支持的音视频编码标配是H264+AAC,其中像TS、RTP、FLV、MP4都支持音频的AAC编码方式。固然,后继者不乏Opus这种编码方式,它主要应用在互联网场景,好比如今谷歌的WebRTC音视频解决方案就用的Opus,最新发布的Android10支持的音视频编码方式就是AV1和Opus,可是AAC目前在广电,安防,电影院等仍是应用最多,Opus目前还不足以威胁到AAC的地位。本篇文章准备讲解下AAC的封装格式ADTS字段含义和解封装,顺便讲解下AAC编码的一些基本状况,若是你只关心解封装,直接看【AAC的封装格式】这节便可。网络
AAC基本概况:ide
l AAC(Advance Audio Coding):工具
即高级音频编码,出如今1997年,基于MPEG-2的音频编码技术,当时被称为MPEG-2 AAC,所以把其做为MPEG-2(MP2)标准的延伸。是由Fraunhofer IIS、杜比实验室、AT&T、Sony等公司共同开发,目的是取代MP3格式,随着MPEG-4(MP4)标准在2000年的成型,则为AAC也叫M4A。性能
l 和AC3编码关系:优化
和AC3关系不大,AC3早于AAC,是由AAC的发起单位杜比实验室和日本先锋合做研制的新编码方式。AAC能输出AC-3的任何码率,赛过AC-3,压缩率更高,但技术上更加复杂。ui
l AAC背景和发展:this
1997年制定了不兼容MPEG-1的音频标准MPEG-2 NBC即MPEG-2 AAC;编码
1999年AAC又增长了LTP和PNS工具,造成了MPEG-4 AAC V1;spa
2002年在MPEG-4 AAC v1增长了SBR和错误鲁棒性工具,造成了 HE-AAC;
2004年MPEG-4在HE-AAC引入了PS模块,提高降码率性能,造成了EAAC+;
对于1999年、2002年、2004年增长了SBR和PS等编码技术的统称为MPEG-4 AAC;
备注:上面这些SBR PS等缩写就是音频的编码算法代名词,网上比较多,感兴趣的能够进一步自行搜索。1. SBR技术即Spectral Band Replication(频段复制)音乐的主要频谱集中在低频段,高频段幅度很小,但很重要,决定了音质。若是对整个频段编码,如果为了保护高频就会形成低频段编码过细以至文件巨大;如果保存了低频的主要成分而失去高频成分就会丧失音质。SBR把频谱切割开来,低频单独编码保存主要成分,高频单独放大编码保存音质,“统筹兼顾”了,在减小文件大小的状况下还保存了音质,完美的化解这一矛盾。
l AAC编码技术参数:
采样率范围:8KHz-96KHz 范围比较广,就是一秒在模拟信号上进行多少次采样;
码率:8kbps-576kbps,支持范围比较宽,在压缩比和质量上都能考虑到;
声道:最多支持48个主声道,16个低频声道,声音细节更丰富,音乐场景也用的多;
采样精度:就是一个采样点须要在计算机表示占用的字节数,通常用2字节16bit表示;
l AAC编码的主要规格:
根据不一样的编码技术,AAC的编码分为九种规格,这和H264的编码规格大同小异。
目前使用最多的就是LC和HE(适合下降码率),流行的Nero AAC编码程序支持LC、HE、HEv2三种规格的,并且编码后的AAC音频,规格都显示LC。其中HE就是在AAC(LC)编码技术上增长SBR技术,HEv2就是AAC(LC)上技术上不只仅增长了SBR技术,同时也增长了PS技术。
因此通常的商业音频编码器只支持部分编码规格,这也是咱们选择编码器的重要考虑因素之一,由于不一样的编码规格支持的音频采样率,码率都不同,背后采用的编码技术和算法复杂度也不同。
l AAC编码方式特色:
AAC的封装格式:
n AAC封装类型:
ADTS的格式以下:
n AAC封装头字段:
ADIF的格式:
adif_sequence
adif_header + byte_alignment + raw_data_stream
adif_header + byte_alignment + raw_data_block......+ raw_data_block
ADIF Header头信息以下:
ADTS的格式:
adts_sequence
adts_frame + adts_frame + ...... + adts_frame
adts_fixed_header + adts_variable_header + error_check + raw_data_block + error_check
ADTS header 的固定头和可变头信息:
固定头意思就是一旦音频文件造成,全部帧的信息头字段意义都是同样的,可是可变头说的是每一个帧这里面字段都有不同的地方,不要理解为无关紧要的意思。
ADTS帧头各个字段和含义:
序号
域
长度bits
说明
解释
1
Syncword
12
all bits must be 1
老是0xFFF,表明一个ADTS帧的开始,做为分界符,用于同步每帧起始位置。
2
ID即MPEG version
1
0 for MPEG-4, 1 for MPEG-2
通常用0,由于都是属于MPEG的规范。
3
Layer
2
always 0
老是00
4
Protection Absent
1
set to 1 if there is no CRC and 0 if there is CRC
这里表明是否有CRC检验字段,1表明没有,0表明有。
5
Profile
2
the MPEG-4 Audio Object Type minus 1
表明使用哪一个级别和规范的AAC,其中01表明Low Complexity(LC),其中profile等于Audio Object Type的值减1,其中全部Audio Object Type值在下面所示。
6
Sampling Frequency Index
4
MPEG-4 Sampling Frequency Index (15 is forbidden)
采样率下标,因为AAC的采样率范围是8KHz-96KHz,因此具体用那个,这个字段决定。
7
Private Bit
1
set to 0 when encoding, ignore when decoding
通常默认0便可
8
Channel Configuration
3
MPEG-4 Channel Configuration (in the case of 0, the channel configuration is sent via an inband PCE)
通道配置即声道数,通常2表示立体声双声道。具体取值范围参考下表。
9
Originality copy
1
set to 0 when encoding, ignore when decoding
通常默认0便可
10
Home
1
set to 0 when encoding, ignore when decoding
通常默认0便可
11
Copyrighted identification bit
1
set to 0 when encoding, ignore when decoding
通常默认0便可
12
Copyrighted identification Start
1
set to 0 when encoding, ignore when decoding
通常默认0便可
13
Aac Frame Length
13
this value must include 7 or 9 bytes of header length: FrameLength = (ProtectionAbsent == 1 ? 7 : 9) + size(AACFrame)
一个ADTS帧的长度包括ADTS头和AAC原始流。用AAC原始流长度+7或者9。
当proection_ansent = 0 则+9
proection_ansent = 1 则+7
14
ADTS Buffer Fullness
11
buffer fullness
0x7FF 说明是码率可变的码流。
0x000表明是固定码率的码流。
15
Number of AAC Frames
2
number of AAC frames (RDBs) in ADTS frame minus 1, for maximum compatibility always use 1 AAC frame per ADTS frame
ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧。
因此说number_of_raw_data_blocks_in_frame == 0 表示说ADTS帧中有一个AAC数据块。
(一个AAC原始帧包含一段时间内1024个采样及相关数据)
16
CRC
16
CRC if protection absent is 0
校验字段,为可选字段。
ADTS各个字段的取值范围:
Object Type ID
Aduio Object Type
备注
1
AAC Main
2
AAC LC
最经常使用
3
AAC LTR
4
SBR
5
AAC scalable
Sampling frequency index
value
备注
0x0 即0000
96000
DVD-Audio、一些 LPCM DVD 音轨、Blu-ray Disc(蓝光盘)音轨、和 HD-DVD (高清晰度 DVD)音轨所用所用采样率
0x1 即0001
88000
0x2 即0010
64000
0x03即0011
48000
miniDV、数字电视、DVD、DAT、电影和专业音频所用的数字声音所用采样率
0x04即0100
44100
音频 CD, 也经常使用于 MPEG-1 音频(VCD, SVCD, MP3)所用采样率
0x05即0101
32000
0x06即0110
24000
0x07即0111
22000
0x08即1000
16000
0x09即1001
12000
0x0a即1010
11025
0x0b即1011
8000
电话所用采样率, 对于人的说话已经足够
0x0c即1100
7350
0x0d即1101
reserver
0x0e即1110
reserve
0x0f即1111
escape value
value
number of channels
Audio syntactic list in order received
tips
0
-
-
关于这些字段看下面raw_data_block基本码流组件说明
1
1
single_channel_element
1
2
2
channel_pair_element()
2
3
3
single_channel_element()
channel_pair_element()
1+2
4
4
single_channel_element()
channel_pair_element()
single_channel_element()
1+2+1
5
5
single_channel_element()
channel_pair_element()
channel_pair_element()
1+2+2
6
5+1
single_channel_element()
channel_pair_element()
channel_pair_element()
lfe_channel_element()
1+2+2+1
7
7+1
single_channel_element()
channel_pair_element()
channel_pair_element()
channel_pair_element()
lfe_channel_element()
1+2+2+2+1
8-15
-
-
保留
ADTS的raw_data_block基本码流组件,头部有3位标志位id_syn_ele,指示六种不一样类型的元素:
id_syn_ele
数据流
含义
注释
ID_SCE(0x0)
single_channel_element()
单通道元素基本上只由一个ICS组成。一个原始数据块最可能由16个SCE组成。
核心算法区
ID_CPE(0x1)
channel_pair_element()
由两个可能共享边信息的ICS和一些联合立体声编码信息组成。一个原始数据块最多可能由16个SCE组成。
核心算法区
ID_CCE(0x2)
coupling_channel_element()
藕合通道元素。表明一个块的多通道联合立体声信息或者多语种程序的对话信息。
核心算法区
ID_LFE(0x3)
lfe_channel_element()
低频元素。包含了一个增强低采样频率的通道。
核心算法区
ID_DSE(0x4)
data_stream_element()
数据流元素,包含了一些并不属于音频的附加信息。
扩展流或者用户数据,非核心算法区
ID_PCE(0x5)
program_config_element()
程序配置元素。包含了声道的配置信息。它可能出如今ADIF 头部信息中。
扩展流或者用户数据,非核心算法区
ID_FIL(0x6)
fill_element()
填充元素。包含了一些扩展信息。如SBR,动态范围控制信息等。
扩展流或者用户数据,非核心算法区
实例分析:
用MediaInfo工具能够查看AAC音频的基本信息
AAC Audio ES Viewer工具能够详细分析每个字节
分析各个字段含义
待分析数据:
固定头十六进制可变头十六进制
FF F1 4C 8 0 42 E0 00
固定头二进制可变头二进制
1111 1111 1111 0001 0100 1100 1000 0000 0100 0010 1110 0000 0000 0000
固定头字段含义
syncword :
十六进制:0x0FFF (12 bits) 分界符
二进制:1111 1111 1111
ID:
十进制0 (1 bit) 0 表明MPEG4的AAC
二进制0 (1 bit) 0
layer :
十进制0 (2 bits) 固定填充00,默认
二进制0 0
protection_absent:
十进制1 (1 bit),决定了头的长度,目前7字节
二进制:1
profile :
十进制:1 [Low Complexity profile (LC)] (2 bits)
二进制:01
sampling_frequency_index:
十进制:3 [48000 Hz] (4 bits)
二进制:0011
private_bit
十进制: 0 (1 bit)
二级制:0
channel_configuration
十进制: : 2 [2 - LF RF] (3 bits)
二级制:10
original/copy
十进制: 0 (1 bit),默认
二进制:0
home:
十进制:0 (1 bit),默认
二进制:0
可变头信息
copyright_identification_bit:
十进制:0 (1 bit),默认
二进制:0
copyright_identification_start :
十进制:0 (1 bit),默认
二进制:0
frame_length:
十进制:535 (13 bits) 长度,包括头和实际裸流数据535-7=528
二级制:00 0100 0010 111
adts_buffer_fullness:
十进制:0 (11 bits)
二进制:0 0000 0000 00 表明是固定码率0x000,可变码率是0x7FF
number_of_raw_data_blocks_in_frame:
十进制:0 (2 bits),表明后面的实际帧数0+1个AAC帧
二级制:00
AAC帧的裸流
raw_data_block()
核心代码参考:
咱们在开发中常常遇到这块就是AAC封装格式的解析,须要拿到裸流进行播放和提取里面的相应字段,或者将裸流打包为ADTS而后封装到TS、MP四、FLV中进行打包发送传输。下面的代码经过读取一个文件流,获取里面的ADTS信息和音频帧。
总结:
这篇文章初步讲解了AAC音频编码的基础知识,同时引出了AAC裸数据打包音频帧的两种方式,其实ADTS给出了用工具分析的实例和进行解封装的示意代码,对平时AAC打包FLV、MP四、TS等封装格式打下基础。
了解更多关于音视频IOT,欢迎关注公众号:智媒黑板报