当通过 ffmpeg 从视频中提取图像时,可以得到如下消息。
frame= 1 fps=0.0 q=2.5 Lsize=N/A time=00:00:00.03 bitrate=N/A
而 'q' 值表示“编码帧的质量”。我通过搜索代码 ffmpeg.c 找到了这个。(参考链接:http://www.ffmpeg.org/doxygen/trunk/frame_8h_source.html#l00205)
通常它的值在 0.0 到 6.0 之间。但问题是它可以通过引用获得更高的值。
代码说,
fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, enc->coded_frame->quality / (float)FF_QP2LAMBDA);
质量值的范围是 1 到 32,767。而 FF_QP2LAMBDA 是 118。所以我们可以得到 %2.1f 的最大值超过 277。这非常可疑(因为“%2.1f”)。
答案1
无需过多了解视频编码的细节,您可以查看量化参数 (QP) 或 Lambda 参数来表达编码帧的质量。
此图取自Xiaoyin, Cheng – 主观优化的 HDTV 视频编码,2009 年。你可以将 Lambda 视为率失真优化过程。
如果你取一个宏块并用低 QP 对其进行编码,则失真(德)与原始图像相比会较低,但比特率(R)会很高。同样,如果选择高 QP,失真会很高,但比特率会很低。因此,压缩一帧的成本计算如下:J=D+λR– 并且需要尽量降低这一成本。
就您的具体情况而言,我相当确定enc->coded_frame->quality
编码器分配了 Lambda 值。使用常量,FF_QP2LAMBDA
您可以将其转换为 Lambda 单位,例如让量化参数 = 21, 然后λ = 21 ×FF_QP2LAMBDA
反过来,你可以通过以下方式获得 QPQP = λ /FF_QP2LAMBDA
,这就是您在输出中看到的内容。
例如,在H.264中,基本关系是λ = 0.85 × 2 (QP-12)/3。由于 QP 值的范围是 0 到 51,因此您可以获得 0.053 到 6,963.2 之间的 Lambda 值 - 但 FFmpeg 无论如何都会通过将 Lambda 转换回 QP 来输出 QP 值。
现在,当您说“质量值的范围是 1 到 32,767”时,您指的是 Lambda 值的可能范围。由于拉格朗日函数只发挥作用后QP 应用于编码宏块时,coded_picture->quality
可以获得的最大数量存在实际限制。例如,在 MPEG-4 第 2 部分中,QP 值从 1 到 31,而正如我上面所说,在 MPEG-4 第 10 部分中,QP 值从 0 到 51。作为回报,将q=
再次输出正确的 QP,因为可能的 Lambda 值受您之前选择的 QP 限制。