深入FFMPEG源码–FFMEPG和X264相关结构体和参数传递!!文末有彩蛋
前面几篇文章介绍了AQ的基本内容,有兴趣的可以翻阅一下:
编解码–x264/x265中的AQ模式真能提升画质吗?实测告诉你
本文来介绍一下FFMPEG和X264中是如何调用AQ并且生效的,好,让我们直接开始。
AQ模式定义
x264中的AQ常量定义
文件位置: x264-master\x264.h
AQ在X264中的定义和之前介绍的一样,相关变量定义如下:


x264_param_t结构中的AQ字段
文件位置: x264-master\x264.h
而AQ如何使用呢?是跟着RC模式一起的,所以这里也可以看出来,RC和AQ其实是相辅相成,并没有作用的冲突的,代码如下:

FFmpeg libx264封装中的AQ选项
文件位置:libavcodec\libx264.c

X264Context中的AQ字段
文件位置:libavcodec\libx264.c
FFMPEG向libx264中传递参数通过X264Context结构体传递,就包括了ap_mode,aq_strength等。


调用流程分析

1. 参数设置(编码器初始化)
文件:libavcodec\libx264.c

判断依据:
x4->aq_mode >= 0:用户明确指定了aq-modex4->aq_mode < 0:使用x264默认值(通常为AQ=2)
2. ROI检查(帧编码前)
文件: libavcodec\libx264.c

判断依据:
i_aq_mode为X264_AQ_NONE模式时,AQ被禁用了;在X264中ROI功能依赖AQ,因为X264认为ROI本质上是”手动AQ”,所以这边加了一个判断。这也是代码实现上的一个技巧,也可能是个坑?这个需要后续继续深入观察一下。
之后将aq相关参数传递到X264中,完成编码参数设置。关于X264编码器如何启动和打开,这部分的调用过程之前有做过介绍,可以参考如下链接:
这里就不再重复介绍了。

彩蛋
在搜索X264的AQ设置时候,偶然间发现X264中为了PSNR跑分,AQ选择时候也做不同的区别呀。


针对PSNR:将AQ的模式选为X264_AQ_NONE (也就是AQ Mode 0);同时关闭psy:
而Psy-RD (心理视觉优化) 的核心逻辑是“为了保留纹理细节,允许引入一点点数学上的失真(噪音)”。人眼喜欢纹理,觉得那是细节;但 PSNR 算法是个“死脑筋”,它只计算像素的数值差异。
针对SSIM:将AQ的模式选为X264_AQ_AUTOVARIANCE (也就是AQ Mode 2);同时关闭psy
这是最有趣的地方! 为什么SSIM不像PSNR一样关掉AQ,反而强制开启冷门的Mode 2?个人猜测SSIM (Structural Similarity) 是一种衡量“结构相似性”的指标,主要是模拟了人眼对结构信息的感知。SSIM从亮度、对比度、结构三个维度评价画质,更贴近人眼视觉感知,尤其重视纹理、边缘等图像结构信息的保留。
而X264_AQ_AUTOVARIANCE的核心逻辑是:计算每个宏块的局部亮度方差(方差越大,代表区域纹理越丰富、边缘越多):
-
对于高方差区域(纹理或者边缘部分)降低QP(保留细节)
-
对低方差区域(平坦区域)提高QP(节省码率)。
所以针对SSIM部分AQ选择X264_AQ_AUTOVARIANCE模式。

这篇就介绍到这里,下一篇,我们看看AQ以及RC如何在具体代码中生效,并最终影响码率和实际效果的,敬请期待。
我是一枚爱跑步的程序猿,维护公众号和知乎专栏《MediaStack》,有兴趣可以关注,一起学习音视频知识,时不时分享实战经验。
夜雨聆风
