我使用的是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获取的,如下图所示:
1条答案
按热度按时间7vux5j2d1#
我发现这个问题是由一个太小的时间基准触发的。
更具体地说,我测试了,假设分子为1,当分母〈= 172时,可以毫无问题地创建编码器。然而,当分母〉172时,问题总是会发生。
我觉得这很奇怪,因为时基是直接从解码器复制的,它是直接从流设置复制的。也就是说,至少H264可以使用该时基来编码视频。我不明白为什么ffmpeg找到的这个特定编码器不支持它,但至少我可以继续我的工作。
编辑:我在
AVCodecContext::time_base
的评论中发现,对于解码,它是过时的,我应该使用帧率来实现这个目的(i.将流的r_frame_rate
复制到codec_ctx->framerate
)。该值为30/1,其倒数大于限值1/172。然而,对于编码来说,它是必须设置的,这是(某种程度上)我困惑的原因。然而,奇怪的是输入流的时基是1/90000〈1/127。