深入X264源码:AQ模式到底是如何决定画质的?
本文系微信公众号《MediaStack》原创文章,每周不定期更新,欢迎大家关注,随时进行交流。
前面几篇文章介绍了AQ的基本内容,有兴趣的可以翻阅一下:
编解码–参数揭秘:AQ模式如何让相同码率视频看起来更舒服?
编解码–x264/x265中的AQ模式真能提升画质吗?实测告诉你
问题汇总–AQ(自适应量化)与传统码率控制是否存在冲突?
上一篇介绍了FFMPEG和X264的结构体和参数如何传递到X264的,本文介绍AQ和RC是如何相辅相成,最终影响码流和实际效果的,Let‘s go!!!
validate_parameters
validate_parameters是x264编码器的参数校验与修正函数,在编码器初始化(x264_encoder_open)或参数修改时被调用。
x264编码器在CQP模式下的核心配置逻辑,核心是根据基础P帧QP和比例因子计算I/B帧QP,并校验合法性。
为了适配CQP模式,代码会设置QP上下限,并禁用AQ、MB-Tree等与CQP冲突的功能,清空比特率配置。
而下面这部分就是为了限制编码器关键参数的取值范围,避免非法值导致编码异常;同时保证参数逻辑一致性(比如AQ强度为0时就需要关闭AQ模式了);
这边就是前一篇发现的彩蛋的这是:X264在“主观视觉优化”和“客观指标测试”之间做了区分,避免在优化开启时误解PSNR/SSIM的数值意义;
重点的三个场景:psy开启测PSNR/SSIM、AQ关闭测SSIM、AQ开启测PSNR,这三种情况都会导致指标无效;
x264就给出这样的解决方案:若要基准测试PSNR/SSIM,需使用–tune psnr/–tune ssim参数,让编码器适配客观指标的计算规则。
MB-tree功能依赖AQ的底层计算框架,即使AQ强度为0也必须开启AQ模式。
高等级亚像素精度的兼容性校验:仅特定条件允许等级10,否则降级到9。
x264_adaptive_quant_frame是x264编码器中帧级AQ的核心实现函数,作用是为单帧图像的每个宏块计算量化偏移值,实现“区域差异化量化”,从而在保证主观画质的前提下优化码率分配。
函数内部会根据h->param.rc.i_aq_mode的不同,执行不同的计算逻辑:
(1)AQ模式0:函数几乎不做处理(偏移值全为0);
-
分析每一帧frame中每个宏块的纹理复杂度、方差、亮度等特征;结合h->param.rc.f_aq_strength调整计算权重;
-
为每个宏块计算一个浮点型偏移值(如-0.5、1.2等),写入quant_offsets;
-
偏移值为负:降低该宏块的QP(少量化,保留细节),通常用于纹理丰富的区域;
-
偏移值为正:提高该宏块的QP(多量化,节省码率),通常用于平坦区域。
上面代码AQ功能的退化场景兜底处理逻辑——当AQ模式关闭或强度为0时,代码会保证依赖AQ相关数据的功能(如MB-tree、加权预测)仍能正常运行,避免未初始化的内存导致编码崩溃,或功能异常。
消除整体亮度均值对SSD的干扰,让校正后的SSD能精准反映帧内像素的纹理/方差特征,为后续AQ、码率控制等功能提供更可靠的统计依据。
我是一枚爱跑步的程序猿,维护公众号和知乎专栏《MediaStack》,有兴趣可以关注,一起学习音视频知识,时不时分享实战经验。