Tool/software: Linux
Hello,
I've been using the ducatijpegdec GStreamer plugin for some time, and I've noticed what I believe is a compatibility issue with the VPE driver. When decoding a 1080p image (jpeg), the decoder will frequently add 8 extra lines of image, where GStreamer, and the VPE driver recognize it as a 1088-line image. Seen below are the caps negotiation process in GStreamer, as well as some kernel debug messages from the VPE driver for the following GStreamer pipelines:
Sender Pipeline:
gst-launch-1.0 videotestsrc ! video/x-raw, format=I420, width=1920, height=1080, framerate=30/1 ! jpegenc ! rtpjpegpay mtu=1472 ! udpsink host=192.168.1.233 multicast-iface=enp0s31f6 port=1234
Receiver Pipeline (AM572x EVM):
gst-launch-1.0 udpsrc multicast-iface=eth0 port=1234 ! application/x-rtp, encoding-name=JPEG, payload=26 ! rtpjpegdepay ! jpegparse ! ducatijpegdec ! vpe ! video/x-raw, format=NV12, width=1920, height=1080 ! appsink
GStreamer Caps Negotiation:
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = "application/x-rtp\,\ encoding-name\=\(string\)JPEG\,\ payload\=\(int\)26\,\ media\=\(string\)video\,\ clock-rate\=\(int\)90000"
/GstPipeline:pipeline0/GstRtpJPEGDepay:rtpjpegdepay0.GstPad:sink: caps = "application/x-rtp\,\ encoding-name\=\(string\)JPEG\,\ payload\=\(int\)26\,\ media\=\(string\)video\,\ clock-rate\=\(int\)90000"
(gst-launch-1.0:1594): GStreamer-WARNING **: ../../gstreamer-1.6.3/gst/gstpad.c:4943:store_sticky_event:<rtpjpegdepay0:src> Sticky event misordering, got 'segment' before 'caps'
/GstPipeline:pipeline0/GstRtpJPEGDepay:rtpjpegdepay0.GstPad:src: caps = "image/jpeg\,\ framerate\=\(fraction\)0/1\,\ width\=\(int\)1920\,\ height\=\(int\)1080"
(gst-launch-1.0:1594): GStreamer-WARNING **: ../../gstreamer-1.6.3/gst/gstpad.c:4943:store_sticky_event:<jpegparse0:sink> Sticky event misordering, got 'segment' before 'caps'
/GstPipeline:pipeline0/GstJpegParse:jpegparse0.GstPad:sink: caps = "image/jpeg\,\ framerate\=\(fraction\)0/1\,\ width\=\(int\)1920\,\ height\=\(int\)1080"
/GstPipeline:pipeline0/GstJpegParse:jpegparse0.GstPad:src: caps = "image/jpeg\,\ parsed\=\(boolean\)true\,\ format\=\(string\)I420\,\ width\=\(int\)1920\,\ height\=\(int\)1080\,\ framerate\=\(fraction\)0/1"
/GstPipeline:pipeline0/GstDucatiJpegDec:ducatijpegdec0.GstPad:src: caps = "video/x-raw\,\ format\=\(string\)NV12\,\ width\=\(int\)1920\,\ height\=\(int\)1088\,\ framerate\=\(fraction\)0/1\,\ drm_mem\=\(boolean\)true"
/GstPipeline:pipeline0/GstVpe:vpe0.GstPad:src: caps = "video/x-raw\,\ format\=\(string\)NV12\,\ width\=\(int\)1920\,\ height\=\(int\)1080\,\ framerate\=\(fraction\)0/1"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter1.GstPad:src: caps = "video/x-raw\,\ format\=\(string\)NV12\,\ width\=\(int\)1920\,\ height\=\(int\)1080\,\ framerate\=\(fraction\)0/1"
/GstPipeline:pipeline0/GstAppSink:appsink0.GstPad:sink: caps = "video/x-raw\,\ format\=\(string\)NV12\,\ width\=\(int\)1920\,\ height\=\(int\)1080\,\ framerate\=\(fraction\)0/1"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter1.GstPad:sink: caps = "video/x-raw\,\ format\=\(string\)NV12\,\ width\=\(int\)1920\,\ height\=\(int\)1080\,\ framerate\=\(fraction\)0/1"
/GstPipeline:pipeline0/GstVpe:vpe0.GstPad:sink: caps = "video/x-raw\,\ format\=\(string\)NV12\,\ width\=\(int\)1920\,\ height\=\(int\)1088\,\ framerate\=\(fraction\)0/1\,\ drm_mem\=\(boolean\)true"
/GstPipeline:pipeline0/GstDucatiJpegDec:ducatijpegdec0.GstPad:sink: caps = "image/jpeg\,\ parsed\=\(boolean\)true\,\ format\=\(string\)I420\,\ width\=\(int\)1920\,\ height\=\(int\)1080\,\ framerate\=\(fraction\)0/1"
/GstPipeline:pipeline0/GstDucatiJpegDec:ducatijpegdec0.GstPad:src: caps = "video/x-raw\,\ format\=\(string\)NV12\,\ width\=\(int\)1920\,\ height\=\(int\)1088\,\ framerate\=\(fraction\)0/1\,\ drm_mem\=\(boolean\)true\,\ max-ref-frames\=\(int\)1"
/GstPipeline:pipeline0/GstVpe:vpe0.GstPad:src: caps = "video/x-raw\,\ format\=\(string\)NV12\,\ width\=\(int\)1920\,\ height\=\(int\)1080\,\ framerate\=\(fraction\)0/1"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter1.GstPad:sink: caps = "video/x-raw\,\ format\=\(string\)NV12\,\ width\=\(int\)1920\,\ height\=\(int\)1080\,\ framerate\=\(fraction\)0/1"
/GstPipeline:pipeline0/GstVpe:vpe0.GstPad:sink: caps = "video/x-raw\,\ format\=\(string\)NV12\,\ width\=\(int\)1920\,\ height\=\(int\)1088\,\ framerate\=\(fraction\)0/1\,\ drm_mem\=\(boolean\)true\,\ max-ref-frames\=\(int\)1"
/GstPipeline:pipeline0/GstVpe:vpe0.GstPad:src: caps = "video/x-raw\,\ format\=\(string\)NV12\,\ width\=\(int\)1920\,\ height\=\(int\)1080\,\ framerate\=\(fraction\)0/1"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter1.GstPad:sink: caps = "video/x-raw\,\ format\=\(string\)NV12\,\ width\=\(int\)1920\,\ height\=\(int\)1080\,\ framerate\=\(fraction\)0/1"
VPE Kernel Debug Messages
[ 5451.226486] vpe 489d0000.vpe: Setting format for type 10, wxh: 1920x1088, fmt: 842094158 bpl_y 1920
[ 5451.226497] vpe 489d0000.vpe: bpl_uv 1920
[ 5451.226512] vpe 489d0000.vpe: hs config: src_w = 1920, dst_w = 1920, decimation = none, lin_acc_inc = 01000000
[ 5451.226523] vpe 489d0000.vpe: vs config(POLY): src_h = 1088, dst_h = 1080,row_acc_inc = 000101e5
[ 5451.226547] vpe 489d0000.vpe: Setting format for type 9, wxh: 1920x1080, fmt: 842094158 bpl_y 1920
[ 5451.226556] vpe 489d0000.vpe: bpl_uv 1920
[ 5451.226606] vpe 489d0000.vpe: get 32 buffer(s) of size 2088960
[ 5451.226615] vpe 489d0000.vpe: and 1044480
[ 5451.227248] vpe 489d0000.vpe: get 6 buffer(s) of size 2073600
[ 5451.227259] vpe 489d0000.vpe: and 1036800
The receiver pipeline immediately segfaults while trying to handle these buffers in the VPE driver. According to the VPE Adjusting the Sender Pipeline to output at 1280*720 remedies this issue. My guess is that this is due to the VPE not being able to accept larger than a 1080p image, which fits the specs that are listed in the AM572x Technical Reference Manual (SPRUHZ64 section 10.3.4.1, page 2364).
Here is a debug log from the Receiver GStreamer pipeline.
5751.jul13_nv12_appsink1080.log
Of note is that this is the commit that is used in the 03.03 version of the PSDK: e797c1d832cc8ee1dd66d1683991cb6d7316ed63.
EDIT 1:
I have been going through the gst-plugin-ducati repo, and I believe that the reason the 1088p image is created is due to the buffer alignment required to communicate with the IVA-HD. 1080 is not divisible by 16 or 32, and the buffer size, as well as the GStreamer caps, are negotiated by the ALIGN2 macro. 1088 is divisible by 16 and 32, so is 1920.
/* align x to next highest multiple of 2^n */ #define ALIGN2(x,n) (((x) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1))