2
votes

I am trying to encode a RAW stream in UYVY colorspace to H264 using gstreamer vaapi encoder.

Source Pipeline:

gst-launch-1.0 -e videotestsrc ! video/x-raw, format=UYVY , framerate=60/1, width=1920, height=1080 ! filesink location=raw.yuv

Encoder pipeline:

gst-launch-1.0 -v filesrc location=raw.yuv ! videoparse format=uyvy width=1920 height=1080 framerate=60 ! vaapiencode_h264 tune=high-compression ! mpegtsmux ! filesink location=final.ts

If I try to encode it as I420 the pipepline works fine:

gst-launch-1.0 -v filesrc location=raw.yuv ! videoparse format=i420 width=1920 height=1080 framerate=60 ! vaapiencode_h264 tune=high-compression ! mpegtsmux ! filesink location=final.ts

On inspection: gst-inspect-1.0 vaapiencode_h264

I realized UYVY is not listed in under video/x-raw(memory:VASurface) capabilities, but it is listed in under video/x-raw.

video/x-raw(memory:VASurface)
                 format: { ENCODED, NV12, I420, YV12 }
                  width: [ 1, 2147483647 ]
                 height: [ 1, 2147483647 ]
              framerate: [ 0/1, 2147483647/1 ]
         interlace-mode: progressive
video/x-raw
                 format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32 }

I also tried to convert from UYVY colorspace to I420, using videoconvert but to no avail.

Is it possible to encode UYVY to h264 using gstreamer?

2
What was your pipeline with videoconvert? It should have worked. Does doing it a single pipeline work? Using videotestsrc and linking directly into the encoder?thiagoss
videoconvert pipepline: gst-launch-1.0 -v filesrc location=raw.yuv blocksize=1920000 ! video/x-raw,format=UYVY,width=1920,height=1080,framerate=15/1 ! videoconvert ! video/x-raw,format=I420,width=1920,height=1080,framerate=15/1 ! vaapiencode_h264 tune=high-compression ! mpegtsmux ! filesink location=final.ts Error: /GstPipeline:pipeline0/GstVideoConvert:videoconvert0: Internal GStreamer error: code not implemented. Please file a bug at bugzilla.gnome.org/enter_bug.cgi?product=GStreamer.Zain
Moreover, single pipeline fails as well. Pipeline used: gst-launch-1.0 -e videotestsrc ! video/x-raw, format=UYVY , framerate=60/1, width=1920, height=1080 ! vaapiencode_h264 tune=high-compression ! mpegtsmux ! filesink location=final.ts Error: ERROR: from element /GstPipeline:pipeline0/GstVaapiEncodeH264:vaapiencodeh264-0: GStreamer error: negotiation problem.Zain

2 Answers

3
votes

After much hit and trail I finally figured out the problem with videoconvert, turns out one needs a blocksize for it. The following pipeline worked for me:

gst-launch-1.0 -v filesrc location=raw.yuv blocksize=4147200 ! 
 videoparse format=uyvy width=1920 height=1080 framerate=60/1 ! 
 videoconvert ! video/x-raw,format=I420,width=1920,height=1080,framerate=60/1 ! 
 vaapiencode_h264 tune=high-compression ! mpegtsmux ! filesink location=final.ts
0
votes

Running your pipeline with GST_DEBUG=2 shows a warning:

vaapi gstvaapiencoder.c:591:set_context_info: We are only supporting YUV:4:2:0 for encoding,please try to use vaapipostproc to convert the input format!

So it suggests using vaapipostproc to convert formats before the encoder and it worked for me:

gst-launch-1.0 -e videotestsrc ! video/x-raw, format=UYVY , framerate=60/1, width=1920, height=1080 ! vaapipostproc ! vaapiencode_h264 tune=high-compression ! mpegtsmux ! filesink location=final.ts