音视频八股文(7)-- 音频aac adts三层结构
AAC介绍
AAC(Advanced Audio Coding)是一种现代的音频编码技术,用于数字音频的传输和存储领域。AAC是MPEG-2和MPEG-4标准中的一部分,可提供更高质量的音频数据,并且相比于MP3等旧有音频格式,AAC需要更少的比特率。
AAC通过使用一些高级的音频编码算法来实现更好的声音质量和更低的压缩比。其中最重要的算法是信号掩蔽技术、短时频谱分析和Psychoacoustic模型。这些算法使得AAC能够在较低的比特率下保持更好的音质,并且减少了由于压缩而引入的失真和噪音。
AAC支持多种采样率、声道数和比特率,以满足不同应用场景的需求。它可以实现从8 kbps到320 kbps的不同比特率的音频压缩,同时实现CD音质甚至更高的音乐体验。
AAC还具有很好的灵活性和可扩展性,包括高级音频编码(High Efficiency AAC,HE-AAC)、带有SBR的HE-AAC v2和LC-AAC(Low Complexity AAC)等变体。此外,AAC还支持与其他多媒体技术(如H.264或MPEG-4)集成使用,并且支持多种容器格式(如MP4、3GP、M4A和ADTS等)。
总之,AAC是一种现代的音频编码技术,具有高质量的音频数据、较低的比特率、灵活性和可扩展性等优点。由于其广泛应用于数字音频传输和存储领域,它已经成为音频压缩领域的标准之一。
AAC ADTS介绍
AAC(Advanced Audio Coding)是一种现代的音频编码技术,被广泛应用于数字音频传输和存储领域。AAC可以提供更高质量的音频数据,同时相比MP3等旧有音频格式,AAC需要更少的比特率。
ADTS(Audio Data Transport Stream)是AAC音频流的容器格式,它是一种通过网络传输音频流的标准格式之一。ADTS文件包含了AAC音频流中的各个元素,并且在音频数据中添加了额外的信息,如同步标记、采样率、通道数等。
ADTS文件由多个部分组成,其中最重要的是头部信息。头部信息通常占据了整个文件中的前7到9个字节,其中包括了一个固定的同步标记(syncword),该标记用于确定音频帧的边界位置。进一步的,头部还包含了一些AAC音频流的基础信息,如声道数、采样率、比特率和编码配置等。
在ADTS文件中,每个AAC音频帧都以一个长度为7或9个字节的ADTS帧头开始,其中包含了同步标记、帧大小、采样率、声道数和其他元数据。接下来是AAC编码的原始音频数据,这些数据会被添加到ADTS帧中,以形成完整的音频帧。
总之,ADTS是AAC音频流的容器格式,提供了一种便捷的方式来传输和存储AAC音频流。通过ADTS,可以轻松地对AAC音频进行封装和解封,以满足各种应用场景的需求。
AAC ADTS Header介绍
AAC ADTS(Audio Data Transport Stream)文件是AAC音频流的一种容器格式,其中最重要的部分之一就是ADTS头部信息。ADTS头部信息占据了整个文件中的前7或9个字节,其中包括了一个固定的同步标记(syncword),该标记用于确定音频帧的边界位置。以下是对ADTS头部信息中各个字段的详细介绍:
同步字(syncword):2个字节(16位)
同步字是ADTS文件的标志符,它用于确定音频帧的开始位置和结束位置,通常为0xFFF。ID (MPEG Version):1个字节(8位)
ID指示使用的MPEG版本。值为0表示MPEG-4,值为1表示MPEG-2。Layer:2个比特
Layer定义了音频流所属的层级,对于AAC来说,其值为0。Protection Absent:1个比特
Protection Absent指示是否启用CRC错误校验。当该比特为0时,表明音频数据经过CRC校验,否则未经过CRC校验。Profile:2个比特
Profile指示编码所使用的AAC规范类型,如AAC LC、AAC HE-AAC等。Sampling Frequency Index (Sampling Rate):4个比特
Sampling Frequency Index表示采样率的索引,它告诉解码器当前音频数据的采样率。这个值的范围是0到15,每个值表示一个特定的采样率。Private Bit:1个比特
Private Bit为私有比特,通常被设置为0,没有实际作用。Channel Configuration:3个比特
Channel Configuration指示音频的通道数,如单声道、立体声或多声道等。Originality:1个比特
Originality指示编码数据是否被原始产生,通常为0。Home:1个比特
Home bit通常被设置为0,没有实际作用。Emphasis:2个比特
Emphasis指示对信号进行强调处理的类型,一般不使用。
除了上述字段之外,ADTS头部还包括文件长度和帧长度等信息。其中,文件长度指整个AAC ADTS文件的长度,而帧长度则指当前ADTS帧所占的字节数。这些信息可以通过解析ADTS头部来确定音频帧的边界,从而提取出原始的AAC音频数据。
总之,AAC ADTS头部信息包括同步字、ID、Layer、Protection Absent、Profile、Sampling Frequency Index、Private Bit、Channel Configuration、Originality、Home、Emphasis等各个字段,通过这些字段可以读取AAC音频流中的基础信息,并确定音频帧的边界位置。
AAC ES介绍
AAC ES(AAC Elementary Stream)是AAC音频编码的一种基本数据格式,也是AAC音频数据在流式传输和文件存储中的常见格式之一。
AAC ES不同于其他容器格式(如MP4、M4A等),它不包含额外的元数据或结构信息,仅包含未经任何封装或压缩处理的原始音频数据。这些原始数据可以作为音频文件或流传输的基础,同时也可以用于对AAC音频进行转码、编辑或重组。
AAC ES 通常由一系列连续的AAC音频帧组成,每个帧以一个特定的标志符开始,该标志符表示这是一个AAC音频帧。在AAC ES中,每个音频帧拥有相同的长度,但是并不一定包含相同数量的采样点,因为采样率和声道数量可能会发生变化。
AAC ES 的另一个关键特征是其比特流顺序,即数字音频数据的组织方式。AAC ES 采用大端字节顺序,其中高位字节排在前面,低位字节排在后面。此外,在AAC ES中,音频数据按照从左到右、自上而下的顺序排列,与典型的文本文件不同。
总之,AAC ES 是AAC音频编码的一种基本数据格式,它通常由一系列AAC音频帧组成,并且不包含任何附加的元数据或结构信息。AAC ES 可以作为音频文件或流传输的基础,同时也可以用于对AAC音频进行转码、编辑或重组。由于其简单性和灵活性,AAC ES 受到了广泛的应用,并且成为了数字音频编码领域的标准之一。
AAC ADTS格式分析
AAC⾳频格式:Advanced Audio Coding(⾼级⾳频解码),是⼀种由MPEG-4标准定义的有损⾳频压缩格式,由Fraunhofer发展,Dolby, Sony和AT&T是主要的贡献者。
ADIF:Audio Data Interchange Format ⾳频数据交换格式。这种格式的特征是可以确定的找到这个⾳频数据的开始,不需进⾏在⾳频数据流中间开始的解码,即它的解码必须在明确定义的开始处进⾏。故这种格式常⽤在磁盘⽂件中。
ADTS的全称是Audio Data Transport Stream。是AAC⾳频的传输流格式。AAC⾳频格式在MPEG-2(ISO-13318-7 2003)中有定义。AAC后来⼜被采⽤到MPEG-4标准中。这种格式的特征是它是⼀个有同步字的⽐特流,解码可以在这个流中任何位置开始。它的特征类似于mp3数据流格式。
简单说,ADTS可以在任意帧解码,也就是说它每⼀帧都有头信息。ADIF只有⼀个统⼀的头,所以必须得到所有的数据后解码。
且这两种的header的格式也是不同的,⽬前⼀般编码后的和抽取出的都是ADTS格式的⾳频流。两者具体的组织结构如下所示:
AAC的ADIF格式⻅下图:
AAC的ADTS的⼀般格式⻅下图:
空⽩处表示前后帧
有的时候当你编码AAC裸流的时候,会遇到写出来的AAC⽂件并不能在PC和⼿机上播放,很⼤的可能就是AAC⽂件的每⼀帧⾥缺少了ADTS头信息⽂件的包装拼接。
只需要加⼊头⽂件ADTS即可。⼀个AAC原始数据块⻓度是可变的,对原始帧加上ADTS头进⾏ADTS的封装,就形成了ADTS帧。
AAC⾳频⽂件的每⼀帧由ADTS Header和AAC Audio Data组成。结构体如下:
每⼀帧的ADTS的头⽂件都包含了⾳频的采样率,声道,帧⻓度等信息,这样解码器才能解析读取。
⼀般情况下ADTS的头信息都是7个字节,分为2部分:
adts_fixed_header();
adts_variable_header();
其⼀为固定头信息,紧接着是可变头信息。固定头信息中的数据每⼀帧都相同,⽽可变头信息则在帧与帧之间可变。
syncword :同步头 总是0xFFF, all bits must be 1,代表着⼀个ADTS帧的开始
ID:MPEG标识符,0标识MPEG-4,1标识MPEG-2
Layer:always: ‘00’
protection_absent:表示是否误码校验。Warning, set to 1 if there is no CRC and 0 if there is CRC
profile:表示使⽤哪个级别的AAC,如01 Low Complexity(LC)— AAC LC。有些芯⽚只⽀持AAC LC 。
在MPEG-2 AAC中定义了3种:
profile的值等于 Audio Object Type的值减1
profile = MPEG-4 Audio Object Type - 1
sampling_frequency_index:表示使⽤的采样率下标,通过这个下标在Sampling Frequencies[ ]数组中查找得知采样率的值。
channel_configuration: 表示声道数,⽐如2表示⽴体声双声道
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, LFE-channel
8-15: Reserved
接下来看下adts_variable_header();
frame_length : ⼀个ADTS帧的⻓度包括ADTS头和AAC原始流.
frame length, this value must include 7 or 9 bytes of header length:
aac_frame_length = (protection_absent = = 1 ? 7 : 9) + size(AACFrame)
protection_absent=0时, header length=9bytes
protection_absent=1时, header length=7bytes
adts_buffer_fullness:0x7FF 说明是码率可变的码流。
number_of_raw_data_blocks_in_frame:表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧。
所以说number_of_raw_data_blocks_in_frame == 0 表示说ADTS帧中有⼀个AAC数据块。
下⾯是ADTS的AAC⽂件部分:
⾼字节开始
第⼀帧的帧头7个字节为:0xFF 0xF1 0x4C 0x40 0x20 0xFF 0xFC
分析各个关键数值:
111111111111
0
00
1
01
0011
0
001
0
0
0
0
0000100000111(帧⻓度)
11111111111
00
计算帧⻓度:将⼆进制 0000100000111 转换成⼗进制为263。观察第⼀帧的⻓
度确实为263个字节。
计算⽅法:(帧⻓度为13位,使⽤unsigned int来存储帧⻓数值)
unsigned int getFrameLength(unsigned char* str)
{
if ( !str )
{
return 0;
}
unsigned int len = 0;
int f_bit = str[3];
int m_bit = str[4];
int b_bit = str[5];
len += (b_bit>>5);
len += (m_bit<<3);
len += ((f_bit&3)<<11);
return len;
}
总结:AAC sequence三层
第一层:AAC sequence:多个AAC Frame。
第二层:AAC Frame:AAC header+AAC ES。
第三层:AAC ES。音频数据,不包含header;flv,mp4的音频数据来自这一层,也就是说不包含header。
注意:第2层的AAC Frame,一般下只有1个AAC ES,但也有可能有两个AAC ES。这取决于number_of_raw_data_blocks_in_frame的值,如果是0,代表1个AAC ES;如果死1,代表代表2个AAC ES。
音视频八股文(7)-- 音频aac adts三层结构的更多相关文章
- moviepy音视频开发:音频剪辑基类AudioClip
☞ ░ 前往老猿Python博文目录 ░ 一.背景知识介绍 1.1.声音三要素: 音调:人耳对声音高低的感觉称为音调(也叫音频).音调主要与声波的频率有关.声波的频率高,则音调也高. 音量:也就是响度 ...
- moviepy音视频开发:音频合成类CompositeAudioClip介绍
☞ ░ 前往老猿Python博文目录 ░ CompositeAudioClip是AudioClip的直接子类,用于将几个音频剪辑合成为一个音频剪辑.CompositeAudioClip类只有一个构造方 ...
- moviepy音视频开发:音频文件存取类AudioFileClip属性和方法介绍
☞ ░ 前往老猿Python博文目录 ░ 一.概述 AudioFileClip是AudioClip的直接子类,用于从一个音频文件或音频数组中读入音频到内存构建音频剪辑.但AudioFileClip并不 ...
- moviepy音视频开发:音频剪辑基类AudioClip详解
☞ ░ 前往老猿Python博文目录 ░ 一.背景知识介绍 1.1.声音三要素: 音调:人耳对声音高低的感觉称为音调(也叫音频).音调主要与声波的频率有关.声波的频率高,则音调也高. 音量:也就是响度 ...
- moviepy音视频开发:音频拼接函数concatenate_audioclips介绍
☞ ░ 前往老猿Python博文目录 ░ concatenate_audioclips函数用于将多个音频剪辑进行拼接合成一个顺序播放的剪辑. 调用语法: concatenate_audioclips( ...
- moviepy音视频开发:音频合成类AudioArrayClip介绍
☞ ░ 前往老猿Python博文目录 ░ AudioArrayClip类是AudioClip的直接子类,用于从一个numpy音频数组构建音频剪辑.AudioArrayClip类只有一个构造方法,在构造 ...
- C++实现RTMP协议发送H.264编码及AAC编码的音视频
http://www.cnblogs.com/haibindev/archive/2011/12/29/2305712.html C++实现RTMP协议发送H.264编码及AAC编码的音视频 RTMP ...
- C++实现RTMP协议发送H.264编码及AAC编码的音视频(转)
C++实现RTMP协议发送H.264编码及AAC编码的音视频(转) RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia ...
- 【转】C++实现RTMP协议发送H.264编码及AAC编码的音视频
RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系F ...
- RTMP协议发送H.264编码及AAC编码的音视频,实现摄像头直播
RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系F ...
随机推荐
- STM32使用DMA接收不定长数据
开启串口,是能串口全局中断 配置DMA并勾选Memory选项 继续配置工程并且生成代码 添加一些串口通讯使用的全局变量 #define BUFFER_SIZE 128 uint8_t Tx_Buf[5 ...
- 记一次yapi部署过程
一.为什么用yapi yapi基于文档注释生成,没有代码的入侵. 同一个工程的接口文档可以导出多个项目中,分权限查看. 可以本地化部署,统一的接口文档,支持其他的文档接入. 有idea插件支持,自动导 ...
- python数据结构转字符串_python2中字符不显示问题_python2_递归
# encoding:utf-8 def get_str(data): """将python数据转化为肉眼可见的字符串 :param data: str.dict.lis ...
- vue项目 运行内存溢出
运行vue项目报错,内存溢出!!! <--- Last few GCs ---> [10400:00000218A86135D0] 173902 ms: Mark-sweep (reduc ...
- Keepalived+HAProxy基于ACL实现单IP多域名负载功能
编译安装 HAProxy 新版 LTS 版本,编译安装 Keepalived 开启HAProxy多线程,线程数与CPU核心数保持一致,并绑定CPU核心 因业务较多避免配置文件误操作,需要按每业务一个配 ...
- 一个由public关键字引发的bug
先来看一段代码: @Service @Slf4j public class AopTestService { public String name = "真的吗"; @Retrya ...
- 使用 ApplicationContextAware 定义 SpringContextHolder 类
需求:使用 @autowired注入一些对象,但发现不可以直接使用@Autowired,因为方法是static的,要使用该方法当前对象也必须是static,正常情况下@Autowired无法注入静态的 ...
- 我的合肥 .NET 俱乐部线下活动之旅
一:背景 我是一个性格比较内向的人,天然抵触这种线下面对面的大型活动,我害怕上台之后紧张到语无伦次(有过类似经历),越语无伦次又会让我更紧张,刚好谋得程序员这种工作又特别适合我这种性格的人,所以没有刻 ...
- react中的虚拟DOM,jsx,diff算法。让代码更高效
在react中当你的状态发生改变时,并不是所有组件的内容销毁再重建,能复用的就复用 react 组件其实 就是按照层级划分的 找到两棵任意的树之间最小的修改是一个复杂度为 O(n^3) 的问题. 你可 ...
- 基于docker和cri-dockerd部署k8sv1.26.3
cri-dockerd是什么? 在 Kubernetes v1.24 及更早版本中,我们使用docker作为容器引擎在k8s上使用时,依赖一个dockershim的内置k8s组件:k8s v1.24发 ...