FFmpeg 之I、B、P帧的基本编码原理,Android开发框架

那什么是高频和低频呢?这里的高频数据是指,图像颜色的变化比较强烈的地方,比如人像画的轮廓与背景的交叉处,在这里的色值变化很快,所以称为高频。相对的低频就是指,颜色变化比较缓和的地方。所以DCT的作用并不是对数据进行压缩,而是为了方便后面的操作,比如量化、RLE行程编码、以及霍夫曼编码。

下一步就是量化,因为人眼对高频区域其实并不敏感,所以利用这一点,可以将高频部分数据进行压缩。这样一来,图块的数据就会呈现两部分,一部分是变化平滑的低频数据,另一部分是刚压缩过的高频部分,数值也变得差不多。而后再经过Zig-zig编排,数据就会呈现出连续几个值相同的的形式,比如23334551550000。这样一来,再经过RLE行程编码,就可以去掉连续值相同的冗余数据。

因为RLE在编码时,对相同的数值只编码一次,同时计算相同数值重复的次数,因此称为行程编码。而与RLE处于同级的DPCM,则主要是对图块与图块之间的差值进行编码。这样一来可以再次压缩数据,之后再通过霍夫曼编码或者算术编码,编码操作也就完成了。同样霍夫曼编码和算术编码,也可以单独写一篇文章出来。

2、P帧的基本编码原理

===========

P帧也就是预测图像P,与I帧不同的是,它不仅要从空间上去除冗余数据,还要从时间冗余方面上着手,因为它是以在它之前出现的I帧作为参考对象来编码的。与I帧不同的是,预测图像P的编码是以16x16像素的宏块为基本编码单元的。对于P帧,为了表示它与前面I帧的关系,我们会一直用预测图像和参考图像这两个词。

其实很好想象,因为对预测图像编码,就是对它和参考图像直接的差值进行编码。所以我们只需要做到以下两点即可:

  • 1、算出当前要编码的图像宏块,与参考图像宏块之间的差值

  • 2、计算出宏块的移动矢量

比如下图:

FFmpeg 之I、B、P帧的基本编码原理,Android开发框架

这张图应该一目了然,时刻1中的人像,在时刻2移动到了图像右侧。这个过程中变化的,不只是人像的位置,因为人在移动的时候,会有其他的动作,比如低头、转头、仰头等动作。所以我们并不仅仅要计算出人像变化之后的位置,也就是移动矢量,还要计算出两个宏块之间的差值。

当然这两者在编码过程中,是有个先后关系的。比如我要计算出宏块的移动矢量,那我得找到参考图像中的宏块,在预测图像中的位置吧。而更进一步,那我怎么找到预测图像相对于参考图像中,图块的位置呢?答案是预测图像中的某个宏块,与参考图像中的这个宏块的差值最小,也即最佳匹配宏块。

这就引起了一系列的搜索算法,去预测图像中去找这个宏块,比如二维对数搜索法、三步搜索法、对偶搜索法。而对预测图像P的编码所引起的时间,则主要是执行这个搜索算法所占用的时间。

等找到最佳匹配宏块后,计算出差值和移动矢量,剩下的操作就和对I帧的编码一致了。

FFmpeg 之I、B、P帧的基本编码原理,Android开发框架

预测图像P的压缩编码算法

3、B帧的基本编码原理

===========

B帧也是双向预测图像B,对它的编码,即是对它前后帧的像素值之差进行编码,具体的方法和对预测图像P的算法类似。

文末

不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊~

小编将自己6年以来的面试经验和学习笔记都整理成了一个**937页的PDF,**以及我学习进阶过程中看过的一些优质视频教程。**上传在我的GitHub中:Android架构视频+BATJ面试专题PDF+学习笔记**请君自取,无偿分享!

FFmpeg 之I、B、P帧的基本编码原理,Android开发框架

B%98%E8%96%AA%EF%BC%81.md)**请君自取,无偿分享!

[外链图片转存中…(img-kbbwCSD7-1644038193410)]

其实看到身边很多朋友抱怨自己的工资很低,包括笔者也是一样的,其原因是在面试过程中没有给面试官一个很好的答案。所以笔者会持续更新面试过程中遇到的问题,也希望大家和笔者一起进步,一起学习。

上一篇:判断二叉树的叶子是否在同一层 c++


下一篇:前端优秀作品展示,JavaScript 版水果忍者