音视频篇|音频压缩AAC与原始数据PCM了解

本文继续学习并记录音视频相关基础知识

参考链接是B站UP北小菜,学习音视频讲解非常细致,对入门音视频和有编程基础的同学非常有用。

【音视频开发】《从零开始编写一个RTSP服务器》

《从零开始编写一个RTSP服务器》系列视频教程源码

音频原始数据PCM

PCM数据也被称之为脉冲编码调制数据,也指的是音频未经过压缩的原始数据。它是由模拟信号通过采样、编码、量化等步骤转换成标准的数字信号。

PCM数据的存储方式

如果是单声道音频文件,采样数据按照时间的先后顺序依次存入。如果是双声道则按照LRLRLR(左右左右声道)的方式存储。存储方式与大小端有关,大端存储方式如下(网络搜索图):

img

PCM数据采样的相关知识点

一段10分钟大小的PCM数据,采样率48000、采样深度8bit、采样2通道。那它的大小计算

1
2
3
4
48000*8*2*10*60/8/1024/1024 = 54MB

tips:计算每秒采样的大小总的Bit数(48000*8*2*10*60),在将其转换为MB
其中单位路径为Bit->byte->KB->MB

采样率

声音每秒中采样点的个数,比如44100HZ表示每秒有44100次采样。常见采样率有22000HZ(22KHZ)、44100(44.1KHZ)、48000HZ(48KHZ)、96000(96KHZ)

采样深度

采样深度指的是每个采样点的大小。通常来说,常用的采样深度是24bit、16Bit、8bit。

通道数

通道数常见有包括单通道、双通道、四声道等。

比特率

比特率指的是PCM原始音频数据每秒传输的位数(bit)。对于PCM数据来说,比特率的计算公式 = 采样率 采样深度 通道数。比如上面计算过程48000*8*2就是比特率的计算。

AAC音频数据

AAC数据格式

  • ADIF格式(Audio Data Interchage Format):音频数据交换格式,只有一个AAC头部,后续全部加入是裸数据,需要得到所有数据后进行解码。一般用于本地文件,通常运用在磁盘播放和文件存储。
  • ADTS格式(Audio Data Transport Stream):音视频传输流格式,每一帧是AAC头部+AAC裸数据,这种格式适合流媒体进行播放。其实可以类比于H.264编码数据,每一帧都有H.264头部+H.264数据(多个NALU)

本文也重点关注ADTS格式。

ADTS格式分析

image-20231217225809124

ADTS结构如上图,每一帧都是adts Header + aac es。与之前的H.264文章一样,从头部解析入手。

ADTS头部

ADTS的头部共有15个字段,总共占7个字节(byte),如果有校验位会在尾部增加2byteCRC校验。

一个AdtsHeader头部的定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct AdtsHeader {
unsigned int syncword; //12 bit 同步字 '1111 1111 1111',一个ADTS帧的开始
uint8_t id; //1 bit 0代表MPEG-4, 1代表MPEG-2。
uint8_t layer; //2 bit 必须为0
uint8_t protectionAbsent; //1 bit 1代表没有CRC,0代表有CRC
uint8_t profile; //1 bit AAC级别(MPEG-2 AAC中定义了3种profile,MPEG-4 AAC中定义了6种profile)
uint8_t samplingFreqIndex; //4 bit 采样率
uint8_t privateBit; //1bit 编码时设置为0,解码时忽略
uint8_t channelCfg; //3 bit 声道数量
uint8_t originalCopy; //1bit 编码时设置为0,解码时忽略
uint8_t home; //1 bit 编码时设置为0,解码时忽略

uint8_t copyrightIdentificationBit; //1 bit 编码时设置为0,解码时忽略
uint8_t copyrightIdentificationStart; //1 bit 编码时设置为0,解码时忽略
unsigned int aacFrameLength; //13 bit 一个ADTS帧的长度包括ADTS头和AAC原始流
unsigned int adtsBufferFullness; //11 bit 缓冲区充满度,0x7FF说明是码率可变的码流,不需要此字段。CBR可能需要此字段,不同编码器使用情况不同。这个在使用音频编码的时候需要注意。

/* 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数据块并不是说没有。(一个AAC原始帧包含一段时间内1024个采样及相关数据)
*/
uint8_t numberOfRawDataBlockInFrame; //2 bit
};
序号 字段 长度 说明
1 syncword 12bit 同步头,总是0xFFF,代表着⼀个ADTS帧的开始。
2 id 1bit 设置MPEG标识符,1bit,0标识MPEG-4,1标识MPEG-2。
3 layer 2bit 总是00。
4 protection_absent 1bit 误码校验,标识是否进行误码校验。0表示有CRC校验,1表示没有CRC校验。为0时头部7bytes后面+2bytesCRC检验位。
5 profile 2bit AAC级别,比如AAC LC=1。profile的值等于Audio Object Type的值减1。
6 sampling_frequency_index 4bit 采样率下标,下标对应的采样率如下 。
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
7 private_bit 1bit 私有位,编码时设置为0,解码时忽略。
8 channel_configuration 3bit 声道数。
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
9 orininal_copy 1bit 编码时设置为0,解码时忽略。
10 home 1bit 编码时设置为0,解码时忽略。
11 copyrigth_identification_bit 1bit 编码时设置为0,解码时忽略。
12 copyrigth_identification_stat 1bit 编码时设置为0,解码时忽略。
13 aac_frame_length 13bit 一个ADTS帧的⻓度,包括ADTS头和AAC原始流。
14 adts_bufferfullness 11bit 缓冲区充满度,0x7FF说明是码率可变的码流,不需要此字段。CBR可能需要此字段,不同编码器使用情况不同。具体查看附录。
15 number_of_raw_data_blocks_in_frame 2bit 表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧,为0表示说ADTS帧中只有一个AAC数据。

音视频入门相关知识总结第二波~

在跟着学学准备代码搞起来~