如何在 C/C++ 中设置 ffmpeg qscale 以进行图像编码



我有一个使用 ffmpeg 作为后端的 C++ 年工作的图像编码器。我正在拍摄视频并将帧保存为 jpeg,但我很难调整输出 jpeg 的质量。
我尝试过的事情:
设置AVCodecContextglobal_qualitycompression_level字段。
我也尝试使用AVDictionary选项设置qscale,但在那里也没有成功。

我知道这是可能的,因为使用命令行
我可以ffmpeg -i INPUT -q:v 2 output_frame_%02d.jpg并获得更高质量的图像。

-q选项的命令行影响两件事

enc_ctx->flags |= AV_CODEC_FLAG_QSCALE;
enc_ctx->global_quality = FF_QP2LAMBDA * qscale;

其中enc_ctx是输出流的 AVCodecContext,FF_QP2LAMBDA是 118

当您使用接口函数时,例如

avcodec_decode_video2
avcodec_encode_video2
avcodec_send_frame
avcodec_receive_packet

flagsglobal_quality不起作用。您应该在./libavcodec/mpegvideo_enc.cstatic int encode_picture(MpegEncContext *s, int picture_number)修改第3814 行

...
if (estimate_qp(s, 0) < 0)
return -1;
s->qscale = 5; //modify qscale here
if (s->qscale < 3 && s->max_qcoeff <= 128 &&
s->pict_type == AV_PICTURE_TYPE_I &&
!(s->avctx->flags & AV_CODEC_FLAG_QSCALE))
s->qscale= 3; //reduce clipping problems
...

就我而言,设置global_quality不起作用。

我更改了 qmin 而不是 global_quality它起作用了。

jpegContext->flags |= AV_CODEC_FLAG_QSCALE;
jpegContext->qmin = 3;

或更改 pFrame 的质量

jpegContext->flags |= AV_CODEC_FLAG_QSCALE;
pFrame->quality = FF_QP2LAMBDA * qscale;

有关实际示例,请参阅此项目

最新更新