视频编码的原理是对视频信号进行冗余信息的消除和压缩,以减少数据量并方便存储和传输。 视频编码的实现通常依赖于具体的视频编码标准,如H.264、H.265等。这些标准规定了具体的编码算法和参数,以实现高效的视频压缩和传输。

以H.265编码协议为例,视频编码涉及以下关键步骤:
H.265首先将视频划分为若干个序列,一个序列划分为若干个图像组(GOP,Group of Picture),每个GOP代表一组连续的视频帧。
H.265使用空间预测来去除图像块之间的冗余信息。 如下图所示,从空间的角度看,单个视频帧内部的像素点之间的像素值相差很小。 从时间的角度看,两个连续的视频帧之间也有很多相同的像素点。
| 空间采样示意图像 | 时间采样示意图像 |
|---|---|
![]() | ![]() |
预测编码是基于图像统计特性进行数据压缩的一种方法,利用图像在时间和空间上的相关性,通过已经重建的像素数据预测当前正在编码的像素。
帧内预测是指用于预测的像素和当前正在编码的像素均处于同一个视频帧内,且一般都在邻近的区域内。 由于邻近的像素之间有很强的相关性,像素值一般都非常接近,发生突变的概率非常小,差值均为0或者非常小的数。 所以,帧内预测编码后传输的是预测值和真实值之间的差值,即0附近的值,称为预测误差或残差。 这样就可以用较少的比特传输,达到压缩的效果。
H.265帧内预测编码以块为单位,使用相邻已经重建的块的重建值对正在编码的块进行预测。 预测分量分为亮度和色度两个,对应的预测块分别是亮度预测块和色度预测块。 为了适应高清视频的内容特征,提高预测精度,H.265采用了更加丰富的预测块尺寸和预测模式。
帧间预测是指用于预测的像素和当前正在编码的像素不在同一个视频帧内,但是一般在相邻或附近的位置。一般情况下,帧间预测编码的压缩效果要比帧内预测好,主要原因是视频帧之间的相关性非常强。 如果视频帧中的运动物体变化速度很慢,那么视频帧之间的像素差值也就很小,时间冗余度就非常大。
帧间预测评估运动物体运动状况的方法是运动估计,它的主要思想就是对预测块从参考帧的给定范围中搜索匹配块,计算匹配块和预测块之间的相对位移,该相对位移就是运动矢量。 得到运动矢量后,需要对预测修正,也就是运动补偿。将运动矢量输入到运动补偿模块,"补偿"参考帧,即可得到当前编码帧的预测帧。预测帧和当前帧的差,就是帧间预测误差。
如果帧间预测只用到了前一帧图像,就称为前向帧间预测或单向预测。该预测帧也就是P帧,P帧可以参考前面的I帧或者P帧。
如果帧间预测不仅用到了前一帧图像预测当前块,还用到了后一帧图像,那么就是双向预测。该预测帧也就是B帧,B帧可以参考前面的I帧或P帧和后面的P帧。 由于P帧需要参考前面的I帧或P帧,而B帧需要参考前面I帧或P帧和后面的P帧,如果在一个视频流中,先到了B帧,而依赖的I帧、P帧还没有到, 那么该B帧还不能立即解码,那么应该怎么保证播放顺序呢?
其实,在视频编码时,会生成PTS和DTS。通常情况下,编码器在生成一个I帧后,会向后跳过几个帧,用前面的I帧作为参考帧对P帧编码,I帧和P帧之间的帧被编码为B帧。 推流的视频帧顺序在编码的时候就已经按照I帧、P帧、B帧的依赖顺序编好了,收到数据后直接解码即可。所以,不可能先收到B帧,再收到依赖的I帧和P帧。
| 示意图像 |
|---|
![]() |
在H.265中,变换和量化是用来进一步压缩数据的。通过将预测误差进行变换,可以将数据从时域转换到频域,从而更好地去除数据冗余。 然后,对变换后的数据进行量化,将数据映射到较低的精度,从而进一步压缩数据。其过程可参考JPEG编码过程。
4.熵编码
在编码过程的最后一步,H.265使用熵编码来对数据进行无损压缩。熵编码的主要目的是最小化编码后数据的冗余,以提高数据压缩效率。其过程可参考JPEG编码过程。
视频解码指将压缩的视频数据转换回原始视频格式的过程,视频解码的过程主要分为熵解码、逆量化、逆变换、运动补偿和解卷积以及后处理,每个步骤都是为了从高度压缩的数据中恢复尽可能接近原始视频的画面。 由于视频编码的目的是尽可能减少文件大小,解码过程必须精确地逆向执行编码过程中的每一个步骤,以恢复视频内容:
熵解码是将压缩数据转换回更易于处理的视频格式的过程。在视频编码的过程中,通常会使用霍夫曼编码或算术编码等熵编码技术来减少数据量, 而熵解码的目的就是为了恢复视频编码过程中使用的符号,为下一步的逆量化做准备。
逆量化是将量化(编码过程中减少数据精度以实现节省空间的步骤)翻转以便恢复原始数据精度的过程,该步骤对于恢复图像质量至关重要。
逆变换是逆转编码时使用的变化(例如离散余弦变换,DCT)以将数据从变换域(例如频率域)恢复到空间域(即原始图像)的过程,该步骤是图像重建的关键步骤。
运行补偿是指,对于预测帧(即基于前/后一帧生成的帧),需要使用运行矢量数据对完整帧进行重建。解卷积则是去除编码过程中产生的块效应(block artifacts)的过程。 这些步骤对于恢复流畅且连贯的视频播放至关重要。
后处理作为最后一步,会涉及一些去噪、锐化等提升视频质量的技术,该步骤可选,是否进行取决于视频播放的要求和硬件能力能否支撑。
详细接口信息请查看 hbVPVideoEncode 及 hbVPVideoDecode。
编码器支持H.264和H.265协议的码率控制,分别支持H.264和H.265编码通道的CBR、VBR、AVBR、FixQp和QpMap五种码率控制方式。 CBR能保证整体编码码率的稳定性;VBR确保编码图像质量的稳定性;AVBR兼顾码率和图像质量,使码率和图像质量相对稳定; FixQp固定每个I帧和P帧的QP值;QpMap为每帧图像中的每个块指定QP值,其中H.265的块大小为32x32,H.264的块大小为16x16。 以下以H.265协议为例介绍码率参数。
CBR表示恒定码率,能够保证整体的编码码率稳定。下面是CBR模式下各个参数含义:
| 数据项 | 描述 | 取值范围 | 默认值 |
|---|---|---|---|
intraPeriod | I帧间隔 | [0, 2047] | 28 |
intraQp | I帧的QP值 | [0, 51] | 30 |
bitRate | 目标平均比特率,单位是kbps | [0, 700000] | 1000 |
frameRate | 目标帧率,单位是fps | [1, 240] | 30 |
initialRcQp | 指定码率控制时的初始QP值。当该值不在[0,51]范围内,编码器内部会决定初始值 | [0, 63] | 63 |
vbvBufferSize | 指定VBVBuffer的大小,单位是ms;实际的VBVbuffer的空间大小为bit_rate*vbv_buffer_size/1000(kb),该buffer的大小会影响编码图像质量和码率控制精度。当该buffer比较小时,码率控制精确度高,但图像编码质量较差;当该buffer比较大时,图像编码质量高,但是码率波动大 | [10, 3000] | 10 |
ctuLevelRcEnable | H.265的码率控制可以工作在CTU级别的控制,该模式可以达到更高精度的码率控制,但会损失编码图像质量。当使能ROI编码时,该功能自动失效 | [0, 1] | 0 |
minQpI | I帧的最小QP值 | [0, 51] | 8 |
maxQpI | I帧的最大QP值 | [0, 51] | 8 |
minQpP | P帧的最小QP值 | [0, 51] | 8 |
maxQpP | P帧最小的QP值 | [0, 51] | 8 |
minQpB | B帧最小的QP值 | [0, 51] | 8 |
maxQpB | B帧最大的QP值 | [0, 51] | 8 |
hvsQpEnable | H265的码率控制可以工作在subCTU级别的控制,该模式会调整子宏块的QP值,进而提 高主观图像质量 | [0, 1] | 1 |
hvsQpScale | QP缩放因子,hvs_qp_enable参数使能后有效 | [0, 4] | 2 |
hvsMaxDeltaQp | hvs_qp值的最大偏差范围,hvs_qp_enable参数使能后有效 | [0, 12] | 10 |
qpMapEnable | 使能ROI编码时的QPmap | [0, 1] | 0 |
VBR表示可变码率,在简单场景下分配较大的QP,以实现较高的压缩率和图像质量; 在复杂场景下分配较小的QP,以保证编码图像的质量稳定。以下是VBR模式下各参数的含义:
| 数据项 | 描述 | 取值范围 | 默认值 |
|---|---|---|---|
intraPeriod | I帧间隔 | [0, 2047] | 28 |
intraQp | I帧的QP值 | [0, 51] | 30 |
frameRate | 目标帧率,单位是fps | [1, 240] | 30 |
qpMapEnable | 使能ROI编码时的QPmap | [0, 1] | 0 |
AVBR表示恒定平均目标码率,在简单场景下分配较低码率,在复杂场景下分配足够的码率,使有限的码率能够在不同场景下合理分配,类似于VBR。 同时,在一定时间内,平均码率接近设定的目标码率,控制输出文件大小,类似于CBR。 因此,AVBR可以被视为CBR和VBR的折中方案,生成码率和图像质量相对稳定的码流。以下是AVBR模式下各参数的含义:
| 数据项 | 描述 | 取值范围 | 默认值 |
|---|---|---|---|
intraPeriod | I帧间隔 | [0, 2047] | 28 |
intraQp | I帧的QP值 | [0, 51] | 30 |
bitRate | 目标平均比特率,单位是kbps | [0, 700000] | 1000 |
frameRate | 目标帧率,单位是fps | [1, 240] | 30 |
initialRcQp | 指定码率控制时的初始QP值。当该值不在[0,51]范围内,编码器内部会决定初始值 | [0, 63] | 63 |
vbvBufferSize | 指定VBVBuffer的大小,单位是ms;实际的VBVbuffer的空间大小为bit_rate*vbv_buffer_size/1000(kb),该buffer的大小会影响编码图像质量和码率控制精度。当该buffer比较小时,码率控制精确度高,但图像编码质量较差;当该buffer比较大时,图像编码质量高,但是码率波动大。 | [10, 3000] | 10 |
ctuLevelRcEnable | H.265的码率控制可以工作在CTU级别的控制,该模式可以达到更高精度的码率控制,但会损失编码图像质量。当使能ROI编码时,该功能自动失效 | [0, 1] | 0 |
minQpI | I帧的最小QP值 | [0, 51] | 8 |
maxQpI | I帧的最大QP值 | [0, 51] | 8 |
minQpP | P帧的最小QP值 | [0, 51] | 8 |
maxQpP | P帧最小的QP值 | [0, 51] | 8 |
minQpB | B帧最小的QP值 | [0, 51] | 8 |
maxQpB | B帧最大的QP值 | [0, 51] | 8 |
hvsQpEnable | H265的码率控制可以工作在subCTU级别的控制,该模式会调整子宏块的QP值,进而提 高主观图像质量 | [0, 1] | 1 |
hvsQpScale | QP缩放因子,hvs_qp_enable参数使能后有效 | [0, 4] | 2 |
hvsMaxDeltaQp | hvs_qp值的最大偏差范围,hvs_qp_enable参数使能后有效 | [0, 12] | 10 |
qpMapEnable | 使能ROI编码时的QPmap | [0, 1] | 0 |
FixQp表示固定每个I帧和P帧的QP值。以下是FixQp模式下各参数的含义:
| 数据项 | 描述 | 取值范围 | 默认值 |
|---|---|---|---|
intraPeriod | I帧间隔 | [0, 2047] | 28 |
frameRate | 目标帧率,单位是fps | [1, 240] | 30 |
qpI | 强制I帧的QP值 | [0, 51] | 0 |
qpP | 强制P帧的QP值 | [0, 51] | 0 |
qpB | 强制B帧的QP值 | [0, 51] | 0 |
QpMap 表示为一帧图像中的每一个块指定 QP 值,其中 H.265 的块大小为 32x32。以下是 QpMap 模式下各参数的含义:
| 数据项 | 描述 | 取值范围 | 默认值 |
|---|---|---|---|
intraPeriod | I帧间隔 | [0, 2047] | 28 |
frameRate | 目标帧率,单位是fps | [1, 240] | 30 |
qpMapArray | QPMap表,H.265的subCTU大小为32x32,需要为每一个subCTU指定一个QP值,每个QP值占一个字节,并且按照光栅扫描方向排序。 | 指针地址 | nullptr |
qpMapArrayCount | QPMap表的大小 | (ALIGN64(picWidth)>>5)*(ALIGN64(picHeight)>>5) | 0 |
H.264和H.265编码支持GOP结构的设置,用户可从预置的GOP结构中选择。以下为GOP预置结构介绍:
| GopPresetIdx | GOP Structure | Low Delay | GOP Size | Encoding Order | GOP结构说明 |
|---|---|---|---|---|---|
1 | I | Yes | 1 | I0-I1-I2-I3,… | 只有I帧,没有互相参考 |
2 | P | Yes | 1 | I-P0-P1-P2,… | 只有I帧和P帧,并且P帧参考2个前向参考帧 |
3 | B | Yes | 1 | I-B0-B1-B2,… | 只有I帧和B帧,并且B帧参考2个前向参考帧 |
6 | PPPP | Yes | 4 | I-P0-P1-P2-P3,… | 只有I帧和P帧,并且P帧参考2个前向参考帧 |
7 | BBBB | Yes | 4 | I-B0-B1-B2-B3,… | 只有I帧和B帧,并且B帧参考2个前向参考帧 |
9 | P | Yes | 1 | I-P0,… | 只有I帧和P帧,并且P帧参考1个前向参考帧 |