You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用avcodec_open2返回-22(无效参数)的FFmpeg视频转换问题

排查FFmpeg avcodec_open2返回-22(无效参数)的问题

核心问题:编码器上下文缺少必要参数

avcodec_open2返回-22的本质是输出编码器上下文outputCodecContext的配置不符合编码器要求,以下是必须补充和修正的关键项:

1. 必须添加帧率(framerate)和GOP大小(gop_size)

绝大多数视频编码器需要明确的帧率和关键帧间隔,否则会判定参数无效:

// 从输入上下文推导帧率(或直接设置固定值如{30,1}表示30fps)
outputCodecContext->framerate = av_inv_q(inputCodecContext->time_base);
// 设置关键帧间隔,例如每10帧生成一个关键帧
outputCodecContext->gop_size = 10;
// 可选:设置B帧数量,根据编码器支持情况调整
outputCodecContext->max_b_frames = 1;

2. 安全获取像素格式

直接取outputCodec->pix_fmts[0]可能拿到无效值(部分编码器的格式数组开头是AV_PIX_FMT_NONE),需要先验证:

if (outputCodec->pix_fmts && outputCodec->pix_fmts[0] != AV_PIX_FMT_NONE) {
    outputCodecContext->pix_fmt = outputCodec->pix_fmts[0];
} else {
    // fallback到通用兼容格式YUV420P
    outputCodecContext->pix_fmt = AV_PIX_FMT_YUV420P;
}

3. 修正Time_base的设置逻辑

部分编码器要求time_base与帧率严格对应,建议通过输入流的实际帧率推导,而非直接复用输入的time_base:

// 获取输入流的实际帧率
AVRational input_frame_rate = av_guess_frame_rate(inputFormatContext, inputFormatContext->streams[videoStreamIndex], NULL);
// 编码器的time_base通常设为帧率的倒数
outputCodecContext->time_base = av_inv_q(input_frame_rate);

修正后的编码器配置完整代码

const AVCodec* outputCodec = avcodec_find_encoder_by_name(codecName.c_str());

if (!outputCodec)
{
    std::cout << "Zielformat-Codec nicht gefunden" << std::endl;
    return -1;
}

AVCodecContext* outputCodecContext = avcodec_alloc_context3(outputCodec);
outputCodecContext->bit_rate = bitRate;
outputCodecContext->width = inputCodecContext->width;
outputCodecContext->height = inputCodecContext->height;

// 安全设置像素格式
if (outputCodec->pix_fmts && outputCodec->pix_fmts[0] != AV_PIX_FMT_NONE) {
    outputCodecContext->pix_fmt = outputCodec->pix_fmts[0];
} else {
    outputCodecContext->pix_fmt = AV_PIX_FMT_YUV420P;
}

// 设置帧率和time_base
AVRational input_frame_rate = av_guess_frame_rate(inputFormatContext, inputFormatContext->streams[videoStreamIndex], NULL);
outputCodecContext->framerate = input_frame_rate;
outputCodecContext->time_base = av_inv_q(input_frame_rate);

// 添加关键帧间隔和B帧配置
outputCodecContext->gop_size = 10;
outputCodecContext->max_b_frames = 1;

int errorCode = avcodec_open2(outputCodecContext, outputCodec, NULL);
if (errorCode != 0)
{
    char errbuf[AV_ERROR_MAX_STRING_SIZE];
    av_strerror(errorCode, errbuf, AV_ERROR_MAX_STRING_SIZE);
    std::cout << "Fehler beim Öffnen des Zielformat-Codecs: " << errbuf << std::endl;
    return -1;
}

额外优化:打印详细错误信息

添加av_strerror可以获取更具体的错误描述,帮助定位问题:

char errbuf[AV_ERROR_MAX_STRING_SIZE];
av_strerror(errorCode, errbuf, AV_ERROR_MAX_STRING_SIZE);
std::cout << "Fehler beim Öffnen des Zielformat-Codecs: " << errbuf << std::endl;

内容的提问来源于stack exchange,提问作者stupidbutseeking

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:07:03