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

FFmpeg C++无法获取正确音频流信息,计算缓冲区大小报错

问题分析与解决:FFmpeg音频通道数为0导致缓冲区计算失败

问题现象

在视频播放应用中集成FFmpeg时,无法获取正确的音频流数据,控制台输出错误:

Motion: Failed to calculating buffer size: Invalid argument

排查确认,错误由avcodec_alloc_context3(codec)->channels值为0导致,但目标视频文件实际包含有效音频通道。

问题根源

代码中仅调用avcodec_alloc_context3(codec)创建了音频解码器上下文,但未将视频流中已获取的codecpar参数复制到该上下文。在FFmpeg的现代API规范中,avformat_find_stream_info会将流的编码参数存储在streams[i]->codecpar中,而通过avcodec_alloc_context3创建的空上下文不会自动填充这些参数,导致channels、sample_rate等关键音频字段为默认值0。

修复方案

在创建音频解码器上下文后、打开解码器前,调用avcodec_parameters_to_context将codecpar的参数拷贝到解码器上下文中。

修改后的关键代码片段

if (HasAudio())
{
    AVStream* audioStream = m_data->formatContext->streams[m_data->audioStreamID];
    AVCodecParameters* codecParams = audioStream->codecpar;
    const AVCodec* codec = avcodec_find_decoder(codecParams->codec_id);
    std::cout << codecParams->codec_id << std::endl;
    
    m_data->audioContext = avcodec_alloc_context3(codec);
    if (!m_data->audioContext)
    {
        std::cout << "Motion: Failed to get audio codec context" << std::endl;
        m_data->audioStreamID = -1;
    }
    else
    {
        // --- 新增:将codecpar参数复制到解码器上下文 ---
        if (avcodec_parameters_to_context(m_data->audioContext, codecParams) < 0)
        {
            std::cout << "Motion: Failed to copy codec parameters to context" << std::endl;
            m_data->audioStreamID = -1;
            // 释放已分配的上下文避免内存泄漏
            avcodec_free_context(&m_data->audioContext);
            return false;
        }
        // --- 新增结束 ---
        
        m_data->audioCodec = codec;
        if (!m_data->audioCodec)
        {
            std::cout << "Motion: Failed to find audio codec" << std::endl;
            m_data->audioStreamID = -1;
        }
        else
        {
            if (avcodec_open2(m_data->audioContext, m_data->audioCodec, nullptr) != 0)
            {
                std::cout << "Motion: Failed to load audio codec" << std::endl;
                m_data->audioStreamID = -1;
            }
            // 后续原有代码保持不变
        }
    }
}

额外注意事项

  • 若参数复制失败,需及时释放已分配的解码器上下文,避免内存泄漏
  • 确保avformat_find_stream_info已成功执行,否则codecpar中的参数可能不完整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:14:53