经过压缩后的帧分为:I帧,P帧和B帧:
I帧:关键帧,采用帧内压缩技术。 P帧:向前参考帧,在压缩时,只参考前面已经处理的帧。采用帧音压缩技术。 B帧:双向参考帧,在压缩时,它即参考前而的帧,又参考它后面的帧。采用帧间压缩技术。
理想情况下,一个视频流,从一个I帧开始后面轻微运动都是 P/B,直到遇到场景切换就再插一个I,如此往复。一般来说,P/B 参考范围不会越过I帧。
我们可以强行指定 P/B 参考不允许越过 I 帧,这样的I帧我们叫它 IDR 帧,每个 IDR 帧(Instantaneous Decoding Refresh)的间隔我们称作一个 GOP(Group of Pictures)。
上图中的箭头表示信息提供方向,二分方式确定Coding Order
帧内预测压缩,解决的是空域数据冗余问题。 帧间预测压缩(运动估计与补偿),解决的是时域数据冗徐问题。
大量统计表明,源 YUV 中两个相邻像素值相等、相似或者缓变概率极大,发生突变的几率是极小。(简单解释下,缓变图像:细量化,粗采样;突变图像:粗量化,细采样,处理细节丰富的图像)
通常,编码器会通过算法将图像划分为一块一块的,然后逐块进行后续的压缩处理。
假设当前的块不在图像边缘,我们可以用上方相邻块边界邻近值作为基础值,也就是上面一行中的每一个值,都垂直向下做拷贝,构建出和源 YUV 块一样大小的预测块,这种构建预测块的方式,我们叫做垂直预测模式,属于帧内预测模式的一种。与它相似的,还有水平预测模式、均值预测模式(也就是4x4的均值填充整个 4x4)等。
紧接着,用源YUV的数据和预测YUV的数据做差值,得到残差块,这样我们在码流中,就直接传输残差的数据和当前4x4块的预测模式的标志位就行,这极大地节省了码流。
举例:计算源块与预测块的残差
如果是帧间预测的话,编码器会以当前块空域相邻的位置,在时域参考帧上的同为块,作为起始点进行规则搜索,直到搜索完找到能够节省码流最大的块作为帧间预测块,当前块到预测块的位移称为运动矢量,这样我们在码流中传输运动矢量、帧间预测模式标志位、残差就可以。
H.264 中我们把 16x16 大小的块称作宏块,宏块也是 H.264 中最大的块,做帧内/帧间预测的时候可以分成8x8、4*4 这样的子块,都是要把它们最能节省码流的预测模式都算出来,然后比较出最优秀的划分模式进行传输。
整数离散余弦变换(DCT),将空间上的相关性变为频域上无关的数据然后进行量化。
大量统计表明,把经过预测后得到的残差经过DCT空频变换,直流和低频(相对平坦,图像或块中大部分占比)能量集中在左上,高频(细节,图像或块中少部分占比)能量集中在右下,DCT本身虽然没有压缩作用,却为以后压缩时的取舍,奠定了必不可少的基础。
变换后直流分量DC都集中在左上角,是整块像素的求和的均值。由于人眼对高频信号不敏感,我们可以定义这样一个变量QP=5,将变换块中所有的值都除以QP,这样做进一步节省传输码流位宽,同时主要去掉了高频分量的值,在解码端只需要将变换块中所有的值在乘QP就可以基本还原低频分量。
我们将QP运算的过程称为量化,可见量化值越大,丢掉的高频信息就越多,再加上编码器中都是用整形变量代表像素值,所以量化值最大还原的低频信息也会越不准确,即造成的失真就越大,块效应也会越大,视频编码的质量损失主要来源于此。
块效应
我们可以把滤波理解为一个在量化值波动特别大的时候的一个提升主观质量的操作。如果量化值波动特别大,有可能造成本不应该是真实边界的区域内有很明显的块效应。我们暂称为块效应边界。
真实边缘就比如说我们人脸和身后的背景,中间的这一条线。那假边界就是图中人脸区域的一个一个小块当中的这样的一个线。
为了优化这种情况我们需要对块效应边界两边的值进行补偿操作,让块效应边界两边的值差异不要过大,从而降低块效应,提升质量。
具体的操作,我们分三步。我会细致给大家梳理下。这部分很重要,有需要或者感兴趣的同学可以参考:
1、初步估算块效应边界强度。
2、区分真假边界。
3、计算差值。
我们在真实网络传输的过程中肯定都是二进制码,所以我们需要将当前的像素值进一步压缩成二进制流
到这里,走完一整个编码流程,生成的数据就是压缩后的结果,我们也可将它送到适应我们的网络中去。
先是我们计算过没有经过编码压缩的视频需要极大的带宽,所以我们必须进行编码。后来又说道编码的各个过程,输入的原始YUV进来,采用帧类型分析得到IDR、I、P、B类型,然后采用帧内/帧间预测+块划分得到残差,再采用变换+量化进行进一步压缩,接着采用滤波去除方块效应,然后采用熵编码将像素值转换为二进制流进一步压缩,输出压缩后可传输的码流。
最后和音频编码出来的码流一起封装成我们常见的mp4等格式。
无损压缩技术大家最熟悉的可能就是哈夫曼编码了,给高频的词一个短码,给低频词一个长码从而达到数据压缩的目的。MPEG-2中使用的VLC就是这种算法,我们以 A-Z 作为例子,A属于高频数据,Z属于低频数据。
CABAC也是给高频数据短码,给低频数据长码。同时还会根据上下文相关性进行压缩,这种方式又比VLC高效很多。其效果如下:
从上面这张图中明显可以看出采用 CACBA 的无损压缩方案要比 VLC 高效的多。
1、软编码只适用短时间摄像,并且应用多样化的场景,如秒拍、美拍等;
2、硬编码用于长时间摄像,但是只能用于适应性好的手机,如高通CPU的手机系列
1.硬编的好处主要在于速度快,而且系统自带不需要引入外部的库,但是特性支持有限,而且硬编的压缩率一般偏低, 2.而对于软编码来说,虽然速度较慢,但是压缩率比较高,而且支持的H264特性也会比硬编码多很多,相对来说比较可控。就可用性而言, 3.在4.4+的系统上,MediaCodec的可用性是能够基本保证的,但是不同等级的机器的编码器能力会有不少差别,建议可以根据机器的配置,选择不同的编码器配置。视频流合流然后包装到mp4文件