h264编码原理

编码的目的是为了压缩,各种视频编码算法都是为了让视频体积变得更小,减少对存储空间和传输带宽的占用。编码的核心是去除冗余信息,通过以下 几 种冗余来达到压缩视频的目的:
1.空间冗余 图像相邻像素之间有较强的相关性, 比如一帧图像划分成 多 个 16x16 的块之后,相邻的块很多时候都有比较明显的相似性。
2.时间冗余: 视频序列的相邻前后帧图像之间内容相似,比如帧率为 25fps 的视频中前后两帧图像相差只有 40ms ,前后两张图像的变化较小,相似性很高。
3.视觉冗余: 我们的眼睛对某些细节不敏感,对图像中高频信息的敏感度小于低频信息的。可以去除图像中的一些高频信息,人眼看起来跟不去除高频信息差别不大(有损压缩)。
4.编码冗余(信息熵冗余): 一幅图像中不同像素出现的概率是不同的。对出现次数比较多的像素,用少的位数来编码。对出现次数比较少的像素,用多的位数来编码,能够减少编码的大小。比如哈夫曼编码。

H264中的I帧、P帧和B帧

H26使⽤帧内压缩和帧间压缩的⽅式提⾼编码压缩率;H264采⽤了独特的I帧、P帧和B帧策略 来实现连续帧之间的压缩;

I帧(帧内编码帧 intra picture):I帧通常是每个GOP的第一个帧,经过适度地压缩,做为随机访问的参考点,⾃身可以通过视频解压算法解压成⼀张单独的完整的图⽚

P帧(前向预测编码帧 predictive-frame):通过充分将低于图像序列中前⾯已编码帧的时间冗余信息来 压缩传输数据量的编码图像,也叫预测帧。需要参考其前⾯的⼀个I frame 或者P frame来⽣成⼀张完整的图⽚。

B帧(双向预测帧 bi-directional interpolated prediction frame):既考虑与源图像序列前⾯已编码帧,也顾及源图像序列后⾯已编码帧之间的时间冗余信息来压缩传输数据量的编码图像,也叫双向预测帧。要参考其前⼀个I或者P帧及其后⾯的⼀个P帧来⽣成⼀张完整的图⽚。

GOP(Group of Pictures)和 GOP 长度

一个序列的第一个图像叫做 IDR 图像(立即刷新图像, IDR 图像都是 I 帧图像。在视频编码序列中,GOP 即 Group of picture 图像组 ,指两个IDR 帧之间的距离 。GOP 长度越大,视频压缩效率越高,但视频质量和视频流恢复能力也越差,反之亦然。

GOP越大,编码的 I 帧就会越少。相比而言, P 帧、 B 帧的压缩率更高,因此整个视频的编码效率就会越高。但是 GOP 太大,也会导致 IDR 帧距离太大,点播场景时进行视频的seek 操作就会不方便。比如你拖动一个视频,当前帧是一个P帧或B帧,这时播放器会先向前找到当前GOP的IDR帧进行解码作为后续解码的参考帧,如果GOP设置过大,等待的时间就过长。

H264编码原理

对于每一帧图像,是划分为一个个块进行编码,就是我们说的宏块。

宏块扫描

对于一个 YUV 图像,可以把划分成一个个 16x16 的宏块(以 H264 为例), Y 、 U 、 V 分量的大小分别是 16x16 、 8x8 、 8x8 。这里我们只对 Y 分量进行分析( U 、 V 分量同理)。假设 Y 分量这16x16 个像素就是一个个数字,采用“之”字方式扫描每一个像素值,则可以得到一个“像素串”。

压缩的目的是使得编码器当前的字符出现连续相同的字符,比如1,1,1,1,1,1,1,1 ,我们可以描述为 8 个 1.数字越小越容易用更少的bit 做压缩,比如一连串数字很小(比如 0 1 2 1 0 )的“像素串 ”,因为 0 在二进制中只占 1 个位, 2 只占 2 个位即可。如何做到将这串像素值变成有很多0 的“像素串”呢?

帧内预测

1.帧内预测就是在当前编码图像内部已经编码完成的块中找到与将要编码的块相邻的块。一般就是即将编码块的左边块、上边块、左上角块和右上角块,通过将这些块与编码块相邻的像素经过多种不同的算法得到多个不同的预测块。
2.然后我们再用编码块减去每一个预测块得到一个个残差块。最后,我们取这些算法得到的残差块中像素的绝对值加起来最小的块为预测块。而得到这个预测块的算法为帧内预测模式。

如图,我们要编码X,选取一个参考X',经过帧内预测算法得到预测值Xp,将原始值X减去预测值Xp得到差值d,我们只需要保存这个差值d就行。在解码时,已知差值d和参考X',就能得到原始值X=Xp+d

我们编码一个4x4块,选用水平预测模式(预测算法有多种,一般都试一遍选差值最小的模式),每行值等于左块最右边的值得到预测块,将编码块减去预测块得到残差块。

帧间预测

同理 帧间预测也是一样的 。 我们在前面已经编码完成的图像中 循环遍历每一个块 将它作为预测块用当前的编码块与这个块做差值 得到残差块 取残差块中像素值的绝对值加起来最小的块为预测块 预测块所在的已经编码的图像称为参考帧 。 预测块在参考帧中的坐标值 (x 0 y 0 与编码块在编码帧中的坐标值 (x 1 y 1 的差值 (x 0 x 1 y 0 y 1 称之为运动矢量 。
而在参考帧中去寻找预测块的过程称之为运动搜索 。 事实上编码过程中真正的运动搜索不是一个个块去遍历寻找的 而是有快速的运动搜索算法的 。
通过预测得到的 残差块的像素值 相比编码块的像素值 去除了大部分空间冗余信息和时间冗余信息 这样得到的像素值更小。如果把这个残差块做扫描得到的像素串送去做行程编码是不是相比直接拿编码块的像素串去做编码更有可能得到更大的压缩率?

DCT变换

在 H.264 编码中,DCT 变换是一个关键步骤,通过将空间域的像素数据转换为频率域的数据,实现更高效的压缩。

量化步长

由于人眼对高频信息不太敏感 如果我们通过一种手段去除掉大部分高频信息 也就是将大部分高频信息置为 0 但又不太影响人的观感 是不是就可以达到我们最初的目标 即可以得到有一连串 0 的像素串 这就涉及到量化操作了 。
我们让变换块的系数都 同时除以一个值 这个值我们称之为量化步长 也就是 QStep(QStep 是
编码器内部的概念 用户一般使用量化参数 QP 这个值 QP 和 QStep 得到的结果就是量化后的
系数 )。 QStep 越大,得到量化后的系数就会越小。 同时相同的 QStep 值 高频系数值相比低频
系数值更小 量化后就更容易变成 0 。 这样一来 将大部分高频系数变成 0 。 如下图所示:

QP=28,QStep=16

解码的时候 需要将 QStep 乘以量化后的系数得到变换系数 很明显这个变换系数和原始没有量
化的变换系数是不一样的,这个就是常说的有损编码 。
而到底损失多少呢 其由 QStep 来控制 QStep 越大 损失就越大 。 QStep 跟 QP一一对应 。 从
编码器应用角度来看 QP 值越大 损失就越大 从而画面的清晰度就会越低 。 同时 QP 值越大
系数被量化成 0 的概率就越大 这样编码之后码流大小就会越小 压缩就会越高 。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值