上一篇 中介绍了音视频开发中的基础知识,本篇介绍下音频帧、视频帧的主要参数和分析方法以及音视频的同步等,主要内容如下:
- 音频帧
- 视频帧
- PTS 与 DTS
- 音视频同步
音频帧#
音频帧的概念没有视频帧那么清晰,几乎所有视频编码格式都可以简单的认为一帧就是编码后的一副图像,而音频帧会因编码格式的不同而不同,如 PCM 音频流可以直接进行播放,下面以 MPEG 音频帧格式为例介绍音频帧。
帧大小#
帧大小指每帧的采样数,这个值的恒定的,具体如下:
MPEG 1 | MPEG 2 | MPEG 2.5 | |
---|---|---|---|
Layer Ⅰ | 384 | 384 | 384 |
Layer Ⅱ | 1152 | 1152 | 1152 |
Layer Ⅲ | 1152 | 576 | 576 |
帧长度#
帧长度指压缩时每一帧的长度,包括帧头及填充位,因为有填充和比特率变换,所以帧长度不是恒定的,这个填充位具体从帧头中第 9 位获取,如果是 0 则无填充位,如果是 1 则有填充位,来看下关于填充位的说明:
Padding is used to fit the bit rates exactly. For an example: 128k 44.1kHz layer II uses a lot of 418 bytes and some of 417 bytes long frames to get the exact 128k bitrate. For Layer I slot is 32 bits long, for Layer II and Layer III slot is 8 bits long.
可知,Layer Ⅰ 的填充位是 4 字节,Layer Ⅱ 和 Layer Ⅲ 的填充位是 1 字节,当读取 MPEG 文件时必须计算该值以便找到相邻的帧,帧长度的计算公式如下:
// Layer I(SampleSize = 384) 单位:byte
FrameLengthInBytes = SampleSize / 8 * BitRate / SampleRate + Padding * 4
FrameLengthInBytes = 48 * BitRate / SampleRate + Padding * 4
// Layer II & III(SampleSize = 1152) 单位:byte
FrameLengthInBytes = SampleSize / 8 / SampleRate + Padding
FrameLengthInBytes = 144 * BitRate / SampleRate + Padding
其中 SampleSize 表示每帧采样数,其值是固定的,可在帧大小小节中查看,Padding 表示填充位,BitRate 表示比特率,SampleRate 表示采样率,比特率和采样率的值可在帧头中获取。
如果一个 MP3 音频文件比特率为 320kbps、采样率为 44.1KHz、无填充位,则该文件的帧长度为 144 x 320 / 44.1 ≈ 1044 字节。
波特率#
可以从 MPEG 音频帧头 12~15 位获取波特率,单位 kbps,参考如下:
bits | V1,L1 | V1,L2 | V1,L3 | V2,L1 | V2,L2 & L3 |
---|---|---|---|---|---|
0000 | free | free | free | free | free |
0001 | 32 | 32 | 32 | 32 | 8 |
0010 | 64 | 48 | 40 | 48 | 16 |
0011 | 96 | 56 | 48 | 56 | 24 |
0100 | 128 | 64 | 56 | 64 | 32 |
0101 | 160 | 80 | 64 | 80 | 40 |
0110 | 192 | 96 | 80 | 96 | 48 |
0111 | 224 | 112 | 96 | 112 | 56 |
1000 | 256 | 128 | 112 | 128 | 64 |
1001 | 288 | 160 | 128 | 144 | 80 |
1010 | 320 | 192 | 160 | 160 | 96 |
1011 | 352 | 224 | 192 | 176 | 112 |
1100 | 384 | 256 | 224 | 192 | 128 |
1101 | 416 | 320 | 256 | 224 | 144 |
1110 | 448 | 384 | 320 | 256 | 160 |
1111 | bad | bad | bad | bad | bad |
针对表格中的说明:
- V1:MPEG Version 1
- V2:MPEG Version 2 and Version 2.5
- L1:Layer Ⅰ
- L2:Layer Ⅱ
- L3:Layer Ⅲ
MPEG 文件可能具有可变的比特率,意味着比特率会发生变化,这里知道比特率的获取即可。
采样率#
可以从 MPEG 音频帧头 10~11 位获取采样率,单位 Hz,参考如下:
bits | MPEG1 | MPEG2 | MPEG2.5 |
---|---|---|---|
00 | 44100 | 22050 | 11025 |
01 | 48000 | 24000 | 12000 |
10 | 32000 | 16000 | 8000 |
11 | reserv. | reserv. | reserv. |
每帧的持续时间#
一帧持续时间计算公式如下:
// 单位 ms
FrameTime = SampleSize / SampleRate * 1000
其中 SampleSize 表示采样数,也就是帧大小,SampleRate 表示采样率。
如采样率为 44.1KHz 的 MP3 音频文件每帧的持续时间为 1152 / 44100 * 1000 ≈ 26 ms,这就是经常听到的 mp3 每帧播放时间固定为 26ms 的由来。
视频帧#
在视频压缩技术中,视频帧采用不同的压缩算法来减少数据量,通常只编码图像之间的差异之处,相同的元素信息则不必重复发送,视频帧的不同算法一般称之为图片类型(picture types)或者帧类型(frame types),主要的三种图片类型分别是 I、P 和 B,其特征如下:
- I 帧:帧内编码帧,通常是每个 GOP(下文介绍) 的第一帧,可压缩性最低,无需其他视频帧即可解码,可以说是一张完整的图片,通常,I 帧用于随机访问,并用作其他图片解码的参考。
- P 帧:前向预测帧,表示与前一帧(I 或 P 帧)之间的差别,需要参考前面的 I 帧或 P 帧才能生成完整的图片,相较 I 帧更具压缩性,节省了空间,所以 P 帧也成为增量帧。
- B 帧:双向预测编码帧,表示与前后两帧的差异,需要参考前面的 I 帧或 P 帧及后面的 P 帧来生成一张完成的图片,压缩性最大。
上面说的帧或图片通常会分为几个宏块(Macroblock),宏块是运动预测的基本单位,一个完整的图像通常被分为几个宏块,如 MPEG-2 和较早期的编解码器定义宏块都是 8×8 像素,以宏块为基准选择特定的预测类型,而非整个图像都使用相同的预测类型,具体如下:
- I 帧:只包含节点宏块。
- P 帧:可含有节点宏区块或预测宏区块。
- B 帧:可含有节点、预测和前后预测宏区块。
下面来看下 I 帧、P 帧、B 帧的示意图如下:
在 H.264 / MPEG-4 AVC 标准中,预测类型的粒度降低到切片(Slice)级别,切片是帧的空间上不同的区域,该区域与同一帧中的任何其他区域分开进行编码,I 切片,P 切片和 B 切片取代了 I、P 和 B 帧,这部分内容暂时了解这么多。
前面提到了 GOP,它是 Group of pictures 的缩写,可译为图片组,每个 GOP 都以 I 帧为起始点,其他为 P 帧和 B 帧,如下图所示:
上图中显示的顺序为:
I1、B2、B3、B4、P5、B6、B7、B8、P9、B10、B11、B12、I13
编解码顺序为:
I1、P5、B2、B3、B4、P9、B6、B7、B8、I13、B10、B11、B12
其中下标数字表示在原始帧数据中 PTS,这里可以理解为 GOP 中的位置。
DTS 与 PTS#
- DTS (Decoding Time Stamp):解码时间戳,表示压缩帧的解码时间,相当于告诉播放器什么时候解码这一帧的数据
- PTS (Presentation Time Stamp):显示时间戳,表示将压缩帧解码后得到的原始帧的显示时间,相当于告诉播放时什么时候显示这一阵的数据。
对于音频来说,DTS 和 PTS 是相同的,对于视频来说,由于 B 帧是双向预测帧,这就导致 DTS 与 PTS 不同,如果每个 GOP 没有 B 帧,则 DTS 和 PTS 相同,反之则 DTS 与 PTS 不同,举例如下:
I | B | B | P | B | P | |
---|---|---|---|---|---|---|
显示顺序 | I1 | B2 | B3 | P4 | B5 | P6 |
编解码顺序 | I1 | P4 | B2 | B3 | P6 | B5 |
PTS | 1 | 2 | 3 | 4 | 5 | 6 |
DTS | 1 | 4 | 2 | 3 | 6 | 5 |
当接收端接收到码流进行解码后的帧的顺序显然不是正确的顺序,需要根据 PTS 进行重新排序再显示。
音视频同步#
先大概介绍一下视频播放的过程,麦克风和摄像头采集数据后,分别通过音频、视频编码,再通过复用,也就是将音视频进行格式封装生成媒体文件,当收到一个媒体文件,需要解复用将音视频分开,再分别通过音频、视频解码,然后音视频独立播放,因为播放速率的差异就会出现音视频不同的问题,音频和视频播放对应的两个指标如下:
- 音频:采样率
- 视频:帧率
声卡和显卡一般是按照每帧数据进行播放的,所以要计算音频和视频每帧的播放时长,还是一样,举个例子:
从上文中已知采样率为 44.1KHz 的 MP3 音频文件的每帧持续时长为 26 ms,如果此时视频的帧率为 30fps,则视频帧的每帧持续时长为 1000 / 30 ≈ 33ms,如果在理想情况下能够按照计算出了数值进行播放,则音视频可以看做是同步的。
实际情况是因为各种原因导致音视频不同步,如每帧解码和渲染的时长有差别,色彩丰富的视频帧可能就比色彩单一的视频帧解码渲染更慢以及计算的误差等,音视频同步方式主要有三种:
- 视频同步到音频
- 音频同步到视频
- 音视频同步到外部时钟
一般是把视频同步到音频时钟,主要是因为,对于延迟以及卡顿,人的听觉较视觉更为敏感,需尽量保持音频正常输出,这里说的音视频同步是允许一定延迟的,即延迟要在可接收的延迟范围内,相当于一个反馈机制,当视频慢于音频就要加快视频的播放速度,可以适当丢帧弥补追上音频,如果已经有延迟减小延迟也可以,反之则减小视频的播放速度。