【问题标题】:How to set ffmpeg qscale in C/C++ for image encoding如何在 C/C++ 中设置 ffmpeg qscale 进行图像编码
【发布时间】:2019-02-25 01:42:13
【问题描述】:

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

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

【问题讨论】:

  • C 和 C++ 是两个不同的东西。你想要 C++ 解决方案还是 C 解决方案?
  • Ffmpeg 是一个 C 库,所以我不相信会有 C++ 解决方案,只有 C,对吧?我只需要知道如何让 ffmpeg 表现良好。
  • 如果您使用 C++,您可以无缝地与 C 代码交互。如果您只使用 C,那么 C++ 解决方案是无关紧要的。 C 库也用于其他应用程序,但我们不会将 Python/C 或 Node.js/C 视为一回事。

标签: c encoding ffmpeg


【解决方案1】:

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

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

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

【讨论】:

  • 你,先生,是山羊。我一直在寻找这个 FAR 太久了。
  • 查看 ffmpeg 的源代码,这似乎不会影响 mpegvideo 编码器。您是否碰巧知道那里的全球质量是如何设定的?我还尝试在编码器上下文的 priv_data 上设置 qscale,但这似乎也无济于事。
  • 我终于想通了。必须将 AVFrame 的质量设置为与编码器上下文的 global_quality 相同。它在 ffmpeg.c 中,但我只使用了 libav* 的东西。
【解决方案2】:

当你使用接口函数如

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)line 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
    ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    • 2023-03-19
    • 2015-05-30
    • 2018-09-01
    • 2023-03-04
    • 1970-01-01
    • 2014-09-07
    相关资源
    最近更新 更多