Visual Studio FFmpeg c API为Windows上的AV_CODEC_ID_H264崩溃创建编码器

qf9go6mv  于 2023-05-01  发布在  Windows
关注(0)|答案(1)|浏览(149)

我使用的是ffmpeg(版本5.1.2)剪辑一个mp4视频每帧,所以我需要解码和编码它。然而,当我为它的视频流创建编码器时,程序总是在调用avio_open2()时崩溃,在H264给出以下错误消息之后:

[h264_mf @ 0000025C1EBC1900] could not set output type (80004005)

编码器的编解码器上下文的配置(time_base,pix_fmt,width,height)是从解码器复制的,我检查像素格式是否支持codec->pix_fmts
我发现这个问题并不涉及我的所有其他代码,因为这个最小的程序可以复制相同的问题:

extern "C"
{
#include <libavcodec/avcodec.h>
}

int main()
{
    auto codec = avcodec_find_encoder(AV_CODEC_ID_H264);
    auto codec_ctx = avcodec_alloc_context3(codec);

    codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
    codec_ctx->width = 2560;
    codec_ctx->height = 1440;
    codec_ctx->time_base.num = 1; codec_ctx->time_base.den = 180000;

    avcodec_open2(codec_ctx, codec, NULL);

    return 0;
}

那我怀疑是不是ffmpeg的bug。我的环境是Windows 11 64位,Visual Studio 2022。ffmpeg库是从vcpkg获取的,如下图所示:

7vux5j2d

7vux5j2d1#

我发现这个问题是由一个太小的时间基准触发的。
更具体地说,我测试了,假设分子为1,当分母〈= 172时,可以毫无问题地创建编码器。然而,当分母〉172时,问题总是会发生。

我觉得这很奇怪,因为时基是直接从解码器复制的,它是直接从流设置复制的。也就是说,至少H264可以使用该时基来编码视频。我不明白为什么ffmpeg找到的这个特定编码器不支持它,但至少我可以继续我的工作。
编辑:我在AVCodecContext::time_base的评论中发现,对于解码,它是过时的,我应该使用帧率来实现这个目的(i.将流的r_frame_rate复制到codec_ctx->framerate)。该值为30/1,其倒数大于限值1/172。然而,对于编码来说,它是必须设置的,这是(某种程度上)我困惑的原因。然而,奇怪的是输入流的时基是1/90000〈1/127。

相关问题