音视频封装格式:AAC音频基础和ADTS打包方案详解

问题背景:算法

如今主流的封装格式支持的音视频编码标配是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把频谱切割开来,低频单独编码保存主要成分,高频单独放大编码保存音质,“统筹兼顾”了,在减小文件大小的状况下还保存了音质,完美的化解这一矛盾。

  1. PS指“parametric stereo”(参数立体声)。原来的立体声文件文件大小是一个声道的两倍。可是两个声道的声音存在某种类似性,根据香农信息熵编码定理,相关性应该被去掉才能减少文件大小。因此PS技术存储了一个声道的所有信息,而后,花不多的字节用参数描述另外一个声道和它不一样的地方。

l AAC编码技术参数:

采样率范围:8KHz-96KHz 范围比较广,就是一秒在模拟信号上进行多少次采样;

码率:8kbps-576kbps,支持范围比较宽,在压缩比和质量上都能考虑到;

声道:最多支持48个主声道,16个低频声道,声音细节更丰富,音乐场景也用的多;

采样精度:就是一个采样点须要在计算机表示占用的字节数,通常用2字节16bit表示;

l AAC编码的主要规格:

根据不一样的编码技术,AAC的编码分为九种规格,这和H264的编码规格大同小异。

  1. MPEG-2 AAC LC低复杂度规格(Low Complexity)编码方式比较简单,没有增益控制,可是提升了编码效率,在中等码率的编码效率和音质方面,都能找到平衡点。
  2. MPEG-2 AAC Main 主规格
  3. MPEG-2 AAC SSR 可变采样率规格(Scaleable Sample Rate)
  4. MPEG-4 AAC LC 低复杂度规格(Low Complexity)
  5. MPEG-4 AAC Main 主规格--包含了除增益控制以外的所有功能,音质最好
  6. MPEG-4 AAC SSR 可变采样率规格(Scaleable Sample Rate)
  7. MPEG-4 AAC LTP 长时期预测规格(Long Term Prediction)
  8. MPEG-4 AAC LD 低延迟预测规格(Low Delay)
  9. MPEG-4 AAC HE 高效率规格(High Efficency)--这种规格适合用于低码率编码,有Nero-ACC编码器支持,是一种成熟的商用编码器。

目前使用最多的就是LC和HE(适合下降码率),流行的Nero AAC编码程序支持LC、HE、HEv2三种规格的,并且编码后的AAC音频,规格都显示LC。其中HE就是在AAC(LC)编码技术上增长SBR技术,HEv2就是AAC(LC)上技术上不只仅增长了SBR技术,同时也增长了PS技术。

因此通常的商业音频编码器只支持部分编码规格,这也是咱们选择编码器的重要考虑因素之一,由于不一样的编码规格支持的音频采样率,码率都不同,背后采用的编码技术和算法复杂度也不同。

l AAC编码方式特色:

  1. AAC高压缩比的音频编码方式,比G7xx、MP三、AC3系列的压缩比都高,而且质量和CD差很少,可是和比较新的Opus仍是差点,不过Opus目前还未充分普及;
  2. AAC也采用了变换编码算法,采用了更高的滤波器组,这是压缩高的缘由;
  3. AAC为了提升压缩比,还采用了噪声重整,反向自适应预测,联合立体声和量化霍夫曼编码算法等新技术;
  4. AAC支持了更多的采样率和比特率,支持了1-48个音轨和多达15个低频音轨,具备多种语言兼容能力;
  5. AAC支持了更宽的声音频率范围,从8KHz-96KHz,远宽于MP3的16KHz-48KHz范围;
  6. AAC特殊的算法能够保有声音频率甚高和甚低频率。声音细节更丰富更清晰更接近原声;
  7. AAC采用了优化算法,致使解码端简单,下降了解码端的处理复杂度;

AAC的封装格式:

n AAC封装类型:

  1. ADIF:Audio Data Interchange Format音频数据交换格式,这种格式通常应用在将音频经过写文件方式存储在磁盘里,不能进行随机访问,不容许在文件中间开始进行解码。只有拿到整个文件时才能开始进行渲染播放,这种暂时还没用到,不是这篇文章的重点。
  2. ADTS:Audio Data Transport Stream 音频数据传输流。这种格式的特征是用同步字节进行将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各个字段的取值范围:

  1. Profile 取值:

Object Type ID

Aduio Object Type

备注

1

AAC Main

2

AAC LC

最经常使用

3

AAC LTR

4

SBR

5

AAC scalable

  1. Sampling Frequency Index采样率取值

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

  1. Channel Configuration通道数取值

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信息和音频帧。

  1. 先定义ADTS头的结构体
  1. 读取文件流的第一个ADTS音频帧的头部数据,并解析里面的长度;
  1. 再根据长度读取里面的音频裸数据;
  1. 不断循环便可完成头部数据的解析和其裸数据的读取;

总结:

这篇文章初步讲解了AAC音频编码的基础知识,同时引出了AAC裸数据打包音频帧的两种方式,其实ADTS给出了用工具分析的实例和进行解封装的示意代码,对平时AAC打包FLV、MP四、TS等封装格式打下基础。

图片描述了解更多关于音视频IOT,欢迎关注公众号:智媒黑板报

相关文章
相关标签/搜索