Rust调用FFMPEG API实现YUV420P转RGB时输出异常问题排查
排查指引
- 优先排查帧行对齐问题
FFmpeg 解码得到的帧数据linesize(行步长)默认会做内存对齐优化,行实际有效字节数为width * 每像素字节数,但linesize通常会大于等于这个值,末尾会填充对齐字节。你当前保存ppm文件时直接写入整个frame.data(0),没有逐行截取有效数据,当视频宽度对应行字节数不满足对齐规则时就会出现画面错位、花屏的问题。
修改保存逻辑,逐行拷贝有效数据即可解决90%以上的同类问题:
fn save_file(frame: &Video, index: usize) -> std::result::Result<(), std::io::Error> { let mut file = File::create(format!("frame{}.ppm", index))?; file.write_all(format!("P6\n{} {}\n255\n", frame.width(), frame.height()).as_bytes())?; let line_bytes = (frame.width() * 3) as usize; // RGB24每像素占3字节 let linesize = frame.linesize(0) as usize; let data = frame.data(0); for y in 0..frame.height() as usize { let offset = y * linesize; file.write_all(&data[offset..offset + line_bytes])?; } Ok(()) }
- 校验色彩转换参数匹配
你初始化SwsContext时没有传入源视频的色彩范围、颜色矩阵等参数,两个测试视频一个为Full范围、一个为Limited范围,默认转换参数可能导致色彩偏差。可以从解码器参数中读取color_range、colorspace等属性,在创建缩放上下文时传入对应参数,保证色彩转换正确。 - 校验帧参数一致性
每次执行sws_scale前,校验实际解码得到的decoded帧的宽、高、像素格式是否和初始化scaler时的参数一致,部分特殊视频可能存在解码后帧参数和流层级参数不一致的情况,导致缩放转换异常。 - 确认输出像素格式
你代码中已经打印了rgb_frame.format(),可以对比正常、异常场景下的输出值是否和预期的Pixel::RGB24枚举值匹配,排除转换失败自动降级为其他像素格式的问题。
内容的提问来源于stack exchange,提问作者fasc8
相关产品推荐
相关产品推荐

