GStreamer转码Raw YUV422图像失败,请求排查管道问题
GStreamer转码YUV422图像报错问题分析
背景信息
我有一张1920x1080分辨率的YUV422格式Raw图像,用FFmpeg可成功转成JPG,命令如下:
ffmpeg -f rawvideo -s 1920x1080 -pix_fmt yuyv422 -i raw_data_0 test3.jpg
用FFmpeg生成测试YUV文件的命令:
ffmpeg -i Testimage.jpg -s 1920x1080 -pix_fmt yuv422p Testimage.yuv
验证YUV文件有效性的命令:
ffmpeg -pix_fmt yuv422p -s 1920x1080 -i Testimage.yuv Testimage2.jpg
问题描述
使用GStreamer 1.16.3转码时,执行以下管道命令:
GST_DEBUG=3 gst-launch-1.0 -v filesrc location="Testimage.yuv" ! "video/x-raw,format=YUY2,width=1920,height=1080,framerate=30/1" ! videoconvert ! x264enc ! "video/x-h264, stream-format=byte-stream" ! h264parse ! flvmux ! filesink location=test.mp4 > test.log
运行后报错,日志内容:
Setting pipeline to PAUSED ... Pipeline is PREROLLING ... /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = video/x-raw, format=(string)YUY2, width=(int)1920, height=(int)1080, framerate=(fraction)30/1 /GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:src: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, format=(string)Y42B Redistribute latency... /GstPipeline:pipeline0/GstX264Enc:x264enc0.GstPad:sink: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, format=(string)Y42B /GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:sink: caps = video/x-raw, format=(string)YUY2, width=(int)1920, height=(int)1080, framerate=(fraction)30/1 WARNING: from element /GstPipeline:pipeline0/GstVideoConvert:videoconvert0: Internal GStreamer error: code not implemented. Please file a bug at http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer. Additional debug info: gstvideofilter.c(292): gst_video_filter_transform (): /GstPipeline:pipeline0/GstVideoConvert:videoconvert0: invalid video buffer received WARNING: from element /GstPipeline:pipeline0/GstVideoConvert:videoconvert0: Internal GStreamer error: code not implemented.
问题根源
- 格式不匹配:FFmpeg生成的是
yuv422p(平面格式YUV422),但GStreamer管道指定的是YUY2(交错格式YUV422),两者存储结构完全不同:yuv422p为平面结构:先存所有Y分量,再存U分量,最后存V分量YUY2为交错结构:按Y-U-Y-V顺序逐像素交错存储
- 单帧处理逻辑错误:输入是单帧Raw图像,管道却指定
framerate=30/1,GStreamer按视频流方式处理单帧数据,易引发缓冲异常 - 版本兼容性问题:GStreamer 1.16.3版本较旧,
videoconvert对部分格式转换的支持不完善,报错信息里的"code not implemented"也印证了这一点
修复后的管道命令
方案1:匹配正确的YUV格式(yuv422p对应GStreamer格式为Y42B)
GST_DEBUG=3 gst-launch-1.0 -v filesrc location="Testimage.yuv" ! "video/x-raw,format=Y42B,width=1920,height=1080,framerate=1/1" ! videoconvert ! x264enc ! h264parse ! mp4mux ! filesink location=test.mp4
方案2:生成并处理YUY2格式文件
先通过FFmpeg生成YUY2格式的YUV文件:
ffmpeg -i Testimage.jpg -s 1920x1080 -pix_fmt yuyv422 Testimage_yuy2.yuv
再用对应GStreamer管道处理:
GST_DEBUG=3 gst-launch-1.0 -v filesrc location="Testimage_yuy2.yuv" ! "video/x-raw,format=YUY2,width=1920,height=1080,framerate=1/1" ! videoconvert ! x264enc ! h264parse ! mp4mux ! filesink location=test_yuy2.mp4
额外优化点
- 将
flvmux替换为mp4mux,更适合生成标准MP4文件 - 单帧处理时将帧率设为
1/1,避免不必要的流处理逻辑
内容的提问来源于stack exchange,提问作者Suresh Kumar
相关产品推荐
相关产品推荐

