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

使用ffvhuff编码写入AVI时FFmpeg像素格式异常问题

问题原因与修复方案

核心原因

  1. AVI容器格式限制:旧版AVI规范对YUV格式原生支持有限,FFmpeg的AVI muxer会默认将YUV像素格式映射为BGR系列写入文件头,导致ffprobe解析时误判格式,实际编码数据仍是YUV422P,进而播放乱码。
  2. 参数同步错误:手动设置stream->codecpar后,未将编码器上下文参数同步到流的codecpar中,导致流参数与实际编码参数不一致。
  3. 时间戳处理不当:手动覆盖packet的pts/dts会破坏编码器生成的正确时间戳,可能引发播放时序或格式解析错误。

修复步骤

1. 修正参数同步逻辑

删除所有手动设置m_stream->codecpar的代码,在打开编码器后调用avcodec_parameters_from_context同步参数:

// 打开编码器后添加以下代码
ret = avcodec_parameters_from_context(m_stream->codecpar, m_codec_context);
if (ret < 0) {
    throw std::runtime_error("failed to copy codec parameters to stream");
}

2. 强制AVI muxer使用YUV422P格式

在调用avformat_write_header前,添加格式参数指定像素格式:

AVDictionary* format_options = nullptr;
av_dict_set(&format_options, "pix_fmt", "yuv422p", 0);
ret = avformat_write_header(m_format_context, &format_options);
if (ret < 0) {
    throw std::runtime_error("header writing error");
}
av_dict_free(&format_options);

3. 修正时间戳处理

移除手动设置packet->pts和packet->dts的代码,仅保留时间戳转换:

// 删除以下两行
// m_packet->pts = m_frameNumber;
// m_packet->dts = m_frameNumber;
av_packet_rescale_ts(m_packet, m_codec_context->time_base, m_stream->time_base);

4. 统一尺寸变量

确保帧的width和height与编码器设置的变量一致,避免尺寸不匹配。

验证修复

修复后重新生成文件,ffprobe检测应显示正确的像素格式:

ffprobe ./test0.avi
# 预期输出:
# Stream #0:0: Video: ffvhuff (FFVH / 0x48564646), yuv422p, 1280x720, ...

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 19:59:51