简述x264几种码率控制方式的实现

简介:

x264的码率控制是基于libavcodec和经验的。这篇文章将尝试说明复杂的码率控制算法背后的理论基础。

几点理论:

1、固定质量并不等价于PSNR或QP完全恒定。复杂场景或者高速场景中难以辨别的细节会被选择性省略,以节省码率;
2、如果运动预测生效,将获得更好的质量:低速场景中,1个错误可能扩散到好几秒钟中。此时如果运动预测启用,只需要更改一个帧,就能增进整个场景的质量;
3、如果有一个帧的一个QP的编码结果,就可以预测这个帧其它QP编码将消耗的空间。QP差距越大,预测越不准确;
4、帧的重要性取决于参照它的帧的数量。因此I帧将根据最近的可被参考帧的复杂程度来调正自己的QP。用作参考帧的B帧(自由B帧)的QP高于P帧,参考的B帧的QP则介于P帧和用作参考帧的B帧之间。

几种码率控制模式:

2pass:指定目标码率,2趟编码
在第1趟编码(比如下面提到的ABR)时为每一帧生成一些统计信息,以助在第2趟编码中时为每一帧找到最好的量化参数。第2趟编码包含以下三部分:
1、第2趟编码开始之前,拿出一些空间用于在帧间灵活分配。空间大小的计算与目标码率无关,只是一个使用恒定QP编码的码率的比值,一般是0.6;
2、用(1)得出来的值和目标码率计算每一帧要使用的QP。使用VBV是方法之一,VBV是一个迭代的过程,因为使用VBV和QP会互相影响;
3、现在开始编码。每编完一帧,按照还剩下的空间重新计算后面将要使用的QP,如果编码过程中第2趟编码的实际码率偏离了目标码率(因为第二趟编码用了更慢的参数)(译者按:也就是使用了快速第一趟编码,所以通常是低于目标码率),会在随后的帧里做出变化(译者按:通常是增大码率)以纠正错误趋势。另外,还会有个小处理,会保证我们不在视频的开始或结束的阶段远远偏离目标码率。

ABR:1趟编码,平均码率
目标是达到和2趟编码同样的效果,但没有第1趟编码的帮助,所以只能一边编码一边控制码率:
1、和2趟编码的(1)过程一样,但因为没有第1趟编码的帧信息,所以把帧缩小为一半分辨率后用一个快速预测算法和SATD(译者按:sum of absolute transform differences绝对变换差值和)(此计算也用于P帧B帧决策)做一个预测来代替。而且也不知道后面的GOP(译者按:图像组)的大小和复杂度,所以I帧的决策基于之前的帧;
2、因为不知道后面帧的复杂度,所以只根据前面的帧来测算QP。测算的因数将定为如果应用于目前所有帧则可以满足目标比特率的数;
3、和2趟编码一样有溢出补偿,调节补偿力度可以得到很接近2趟编码的质量(但大小将在接近正负10%的范围内浮动),通过这种方式可以在一定程度上控制住文件大小而又不太牺牲视频质量。

CBR:1趟编码,恒定码率(用VBV限制)
1、同ABR;
2、测算因子基于一个范围内(由VBV buffer大小决定)的均值,而不是之前所有帧;
3、溢出补偿更加严格,而且在VBV接近0时将会强制限制QP。但在VBV没用完时并不会强制限制QP,所以CBR的结果多少会比目标码率低一点。还要注意的是,如果在所有机制过后,一个帧还是超出了VBV的限制,那它是不会被重新编码的。

CRF:1趟编码,恒定码率因子(译者注:就是crf参数,crf = constant rate factor)
1、同ABR;
2、换算因子恒定为 –crf参数的值;
3、没有溢出补偿。

CQP:恒定量化参数
QP只简单地和帧类型相关。

以上所有类型:
H.264规范允许每个宏块使用不同的QP。x264目前没有实现这一特性,码率控制算法只会为每一帧生成一个QP。

目录
相关文章
|
3月前
|
缓存
KVCache原理简述
KVCache原理简述
|
17天前
|
小程序 JavaScript
小程序bindtap 和 catchtap 的区别以及如何使用
小程序bindtap 和 catchtap 的区别以及如何使用
19 0
|
30天前
|
Unix Linux 测试技术
C++封装详解——从原理到实践
C++封装详解——从原理到实践
40 0
|
3月前
|
Java
详解多线程启动涉及的知识点
详解多线程启动涉及的知识点
23 0
|
9月前
|
JSON 小程序 JavaScript
小程序学习笔记 | 如何实现左滑删除效果?
小程序学习笔记 | 如何实现左滑删除效果?
|
11月前
|
缓存
如何实现一个每日打卡功能
在游戏中经常能看到每日签到,每日打卡或者每日送奖励这样的功能,这些功能每天只能使用一次,然后等到下一天才能再使用。 如何实现这样每日只能使用一次的功能呢?今天的这篇教程我们就来学习一下每日打开功能的实现原理和方法。 要实现每日打卡功能,我们需要借助一块“获取当前日期”的积木,以及“缓存插件”。“获取当前日期”可以用于获得当前的时间,例如年,月,日,时,分,秒等,“缓存插件”可以帮助我们把游戏中的数据缓存在本地。
188 0
|
设计模式 算法 程序员
java-23种设计模式概述【软件设计模式基本介绍(是什么、作用、优点)、模式的分类和介绍】
java-23种设计模式概述【软件设计模式基本介绍(是什么、作用、优点)、模式的分类和介绍】
226 0
|
Java 数据安全/隐私保护
简述java三大特性中的封装的概念及用法
简述java三大特性中的封装的概念及用法
93 0
简述for in 和 for of 的区别
1、推荐在循环对象属性的时候使用 for...in,在遍历数组的时候的时候使用 for...of 2、for...in 循环出的是 key,for...of 循环出的是 value
120 0
简述for in 和 for of 的区别
个人简述
以下是我的个人简述