使用libav转码MJPEG到VP9 WebM出现条纹及丢帧问题排查
MJPEG转VP9 WebM转码问题排查与修复建议
我有MJPEG格式的视频,想转码为VP9编码的WebM视频。用FFmpeg命令行执行以下指令能得到正常结果:
ffmpeg -loglevel verbose -i "input.yuvj422p" -pix_fmt yuv420p -c:v libvpx-vp9 -crf 20 -b:v 0 constantQualityExample.webm
对应的日志显示转码流程正常,但基于FFmpeg官方transcode.c示例修改的libav代码(已移除音频及多视频流处理能力)转码后,生成的视频出现画面条纹且丢失最后一帧。相关日志及代码已提供,以下是需要检查修改的代码部分:
像素格式转换与色彩空间处理
命令行明确指定了转码为yuv420p,要确保代码里正确处理MJPEG的YUVJ422P(全范围YUV)到YUV420P的转换:- 创建
sws_getContext转换上下文时,源格式要设为AV_PIX_FMT_YUVJ422P,目标格式设为AV_PIX_FMT_YUV420P - YUVJ系列是JPEG风格的全范围色彩,转换时得用
sws_setColorspaceDetails设置正确的色彩范围参数,不然容易出画面条纹
- 创建
VP9编码器参数对齐
命令行用了-crf 20 -b:v 0的恒定质量模式,代码里要同步配置这些参数:- 调用
av_opt_set_int给编码器上下文设置crf=20和b:v=0 - 确认编码器上下文的
pix_fmt被设为AV_PIX_FMT_YUV420P,和命令行完全一致 - 检查编码器初始化流程,
avcodec_open2调用前要把所有必要参数设置完毕
- 调用
帧输出逻辑补全
丢失最后一帧大概率是没处理编码器的延迟帧:- 所有输入帧送完编码器后,要循环调用
avcodec_receive_packet,直到返回AVERROR_EOF,把编码器缓存的帧全部输出 - 检查帧的PTS/DTS时间戳是否正确设置,时间戳错了也会导致帧丢失或播放异常
- 确认输入帧的宽高、像素格式和编码器要求完全匹配,不匹配很容易出现画面条纹
- 所有输入帧送完编码器后,要循环调用
日志对比找差异
把libav代码的日志和命令行的verbose日志对比:- 重点看像素格式转换、编码器参数初始化、帧处理的每一步日志,找出代码和命令行的差异点
- 检查有没有未处理的错误码,比如
sws_scale或avcodec_send_frame返回的错误,这些可能导致帧处理异常
内容的提问来源于stack exchange,提问作者anon
相关产品推荐
相关产品推荐

