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
相关产品推荐
相关产品推荐

