Gstreamer 1.18.4, v4l2src <-> v4l2jpegdec dmabuf issue

Nicolas Dufresne nicolas at ndufresne.ca
Mon Nov 29 16:06:23 UTC 2021


Le lundi 29 novembre 2021 à 14:34 +0100, Pascal Speck via gstreamer-devel a
écrit :
> Dear List,
> I'm currently experiencing problems in connecting a v4l2src with an edp-camera connected (uvcvideo) with a v4l2jpegdec in dmabuf mode.
> Hardware is an imx6 with coda jpeg decoder. Kernel is 5.10.78.
> 
> First Approach, First Issue:
> 
> I tried to export the dmabuf from v4l2src and import it into v4ljpegdec. The whole pipeline looks like:
> 
> gst-launch-1.0 -vvvv v4l2src device=/dev/video9 ! image/jpeg,width=800,height=600,framerate=15/1 ! v4l2jpegdec output-io-mode=dmabuf-import ! v4l2convert output-io-mode=dmabuf-import !
> video/x-raw,colorimetry=bt709 ! v4l2h264enc output-io-mode=dmabuf-import ! 'video/x-h264,level=(string)3.2' ! fakesink
> 
> Here I'm experiencing the following errors:
> 
> 0:00:01.611648352 13845  0x131e240 ERROR          v4l2allocator gstv4l2allocator.c:1272:gst_v4l2_allocator_qbuf:<v4l2jpegdec0:pool0:sink:allocator> failed queueing buffer 0: Invalid argument
> 
> With enabled videobuf2 debugging i also get the following output which seems to lead to the "invalid argument":
> 
> [ 5560.133292] videobuf2_common: [out-f47947fc] __prepare_dmabuf: invalid dmabuf length 960589 for plane 0, minimum length 962560
> [ 5560.145143] videobuf2_common: [out-f47947fc] __buf_prepare: buffer preparation failed: -22
> [ 5560.155418] videobuf2_common: [cap-a0a730c6] vb2_core_expbuf: queue is not currently set up for mmap

Kernel bug ? Why would the kernel impose a minimum size for compressed formats ?
I don't see why we'd have to increase the allocation size in v4l2src ...
> 
> I already added some more debugging to the buffer-creation and experiencing the following output:
> 
> 0:00:00.738544628 20814  0x127e258 WARN           v4l2allocator gstv4l2allocator.c:502:gst_v4l2_allocator_probe: CreateBufs w:800 h:600 fmt:JPEG, bpl:0
> /GstPipeline:pipeline0/GstV4l2Src:v4l2src0.GstPad:src: caps = image/jpeg, width=(int)800, height=(int)600, framerate=(fraction)15/1, parsed=(boolean)true, pixel-aspect-ratio=(fraction)1/1
> /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = image/jpeg, width=(int)800, height=(int)600, framerate=(fraction)15/1, parsed=(boolean)true, pixel-aspect-ratio=(fraction)1/1
> 0:00:00.748956214 20814  0x127e258 WARN           v4l2allocator gstv4l2allocator.c:502:gst_v4l2_allocator_probe: CreateBufs w:800 h:600 fmt:JPEG, bpl:0
> /GstPipeline:pipeline0/v4l2jpegdec:v4l2jpegdec0.GstPad:sink: caps = image/jpeg, width=(int)800, height=(int)600, framerate=(fraction)15/1, parsed=(boolean)true, pixel-aspect-ratio=(fraction)1/1
> /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = image/jpeg, width=(int)800, height=(int)600, framerate=(fraction)15/1, parsed=(boolean)true, pixel-aspect-ratio=(fraction)1/1
> 0:00:00.799220825 20814  0x127e258 WARN           v4l2allocator gstv4l2allocator.c:502:gst_v4l2_allocator_probe: CreateBufs w:800 h:600 fmt:JPEG, bpl:0
> 0:00:00.801473475 20814  0x127e258 WARN           v4l2allocator gstv4l2allocator.c:502:gst_v4l2_allocator_probe: CreateBufs w:800 h:600 fmt:JPEG, bpl:0
> 0:00:00.803116462 20814  0x127e258 WARN           v4l2allocator gstv4l2allocator.c:502:gst_v4l2_allocator_probe: CreateBufs w:800 h:600 fmt:JPEG, bpl:0
> 0:00:00.822653978 20814  0x127e258 WARN          v4l2bufferpool gstv4l2bufferpool.c:817:gst_v4l2_buffer_pool_start:<v4l2src0:pool0:src> Uncertain or not enough buffers, enabling copy threshold
> 0:00:01.916946190 20814  0x127e258 ERROR          v4l2allocator gstv4l2allocator.c:1274:gst_v4l2_allocator_qbuf:<v4l2jpegdec0:pool0:sink:allocator> failed queueing buffer 0: Invalid argument
> 0:00:01.917786516 20814  0x127e258 ERROR          v4l2allocator gstv4l2allocator.c:1277:gst_v4l2_allocator_qbuf:<v4l2jpegdec0:pool0:sink:allocator> buffer type 2, bytesused: 33880, flags 16384, field
> 1, sequence 0, memory 4, m.fd 24, length 960589
> 0:00:01.917952515 20814  0x127e258 ERROR         v4l2bufferpool gstv4l2bufferpool.c:1209:gst_v4l2_buffer_pool_qbuf:<v4l2jpegdec0:pool0:sink> could not queue a buffer 0
> 0:00:01.918065181 20814  0x127e258 ERROR         v4l2bufferpool gstv4l2bufferpool.c:2108:gst_v4l2_buffer_pool_process:<v4l2jpegdec0:pool0:sink> failed to queue buffer
> 0:00:01.930311086 20814  0x127e258 WARN           v4l2allocator gstv4l2allocator.c:502:gst_v4l2_allocator_probe: CreateBufs w:800 h:608 fmt:422P, bpl:800
> 0:00:01.942260327 20814  0x127e258 WARN           v4l2allocator gstv4l2allocator.c:502:gst_v4l2_allocator_probe: CreateBufs w:800 h:608 fmt:422P, bpl:800
> /GstPipeline:pipeline0/v4l2jpegdec:v4l2jpegdec0.GstPad:src: caps = video/x-raw, format=(string)Y42B, width=(int)800, height=(int)600, interlace-mode=(string)progressive, multiview-mode=(string)mono,
> multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono, pixel-aspect-ratio=(fraction)1/1,
> chroma-site=(string)mpeg2, colorimetry=(string)bt709, framerate=(fraction)15/1
> 0:00:01.947016291 20814  0x127e258 WARN           v4l2allocator gstv4l2allocator.c:502:gst_v4l2_allocator_probe: CreateBufs w:800 h:600 fmt:422P, bpl:800
> 0:00:01.959095864 20814  0x127e258 WARN           v4l2allocator gstv4l2allocator.c:502:gst_v4l2_allocator_probe: CreateBufs w:800 h:600 fmt:422P, bpl:800
> 0:00:01.971760433 20814  0x127e258 WARN           v4l2allocator gstv4l2allocator.c:502:gst_v4l2_allocator_probe: CreateBufs w:800 h:600 fmt:YU12, bpl:800
> 0:00:01.983937672 20814  0x127e258 WARN           v4l2allocator gstv4l2allocator.c:502:gst_v4l2_allocator_probe: CreateBufs w:800 h:600 fmt:YU12, bpl:800
> 
> So the buffer size provided from the uvc-camera is not accepted in the v4l2jpegdec. Another weired thing is that the v4l2jpegdec tries to allocate an output-buffer of 800x608 here (see log @
> 0:00:01.930311086 ) which seems wrong to me.
> 
> I'm now wondering who does the mistake here:
> 	1. I the size returned by the uvc-driver ( checked with v4l2-ctl ) which is 960589 wrong ( too small for jpeg 800x600) ?

Too small ? why ? its compressed, can't judge what is minimum buffer size for a
stream, I think leaving it to the camera make sense.

> 	2. Does v4l2jpegdec expect a too large buffer size on it's sink pad?
> 	3. Where do the 8 more pixels on v4l2jpegdec output come from?

Usually driver try_fmt dictates it. This driver looks largely untested to me and
confuses raw and compressed format, leading to validating and padding sizes
based on raw pictures.

> 
> Second Approach, Second Issue:
> In order to circumvent the issue with the "too-small" buffer I tried it the other way around, so exporting the buffer from v4l2jpegdec and importing on v4l2src with the following pipeline:
> 
> gst-launch-1.0 -vvvv v4l2src device=/dev/video9 io-mode=dmabuf-import ! image/jpeg,width=800,height=600,framerate=15/1 ! v4l2jpegdec output-io-mode=dmabuf ! v4l2convert output-io-mode=dmabuf-import !
> video/x-raw,colorimetry=bt709 ! v4l2h264enc output-io-mode=dmabuf-import ! 'video/x-h264,level=(string)3.2' ! fakesink
> 
> Whithin this issue I run into another error-situation:
> 
> 0:00:02.287877632  9461  0x1eb6040 WARN                    v4l2 gstv4l2object.c:4988:gst_v4l2_object_decide_allocation:<v4l2src0> error: No downstream pool to import from.
> 0:00:02.288214630  9461  0x1eb6040 WARN                    v4l2 gstv4l2object.c:4988:gst_v4l2_object_decide_allocation:<v4l2src0> error: When importing DMABUF or USERPTR, we need a pool to import from
> 
> When debugging into "gst_v4l2_object_decide_allocation" I realized that "gst_query_get_n_allocation_params (query)" returns 0 in that case. So no downstream pool is available.
> When scrolling up the log there is a message that is stating:

Decoders don't implement propose allocation. You'd have to implement that first.
Cases were this scenarios is possible is pretty rare, since demuxers and parser
do not use allocation queries.

> 
> 0:00:06.038903414 19866  0x24a0240 WARN               structure gststructure.c:2069:priv_gst_structure_append_to_gstring: No value transform to serialize field 'params' of type 'GstAllocationParams'
> 0:00:06.039072746 19866  0x24a0240 DEBUG         v4l2bufferpool gstv4l2bufferpool.c:512:gst_v4l2_buffer_pool_set_config:<v4l2jpegdec0:pool0:sink> config GstBufferPoolConfig,
> caps=(GstCaps)"image/jpeg\,\ width\=\(int\)800\,\ height\=\(int\)600\,\ framerate\=\(fraction\)15/1\,\ parsed\=\(boolean\)true\,\ pixel-aspect-ratio\=\(fraction\)1/1", size=(uint)962560,
> min-buffers=(uint)0, max-buffers=(uint)0, allocator=(GstAllocator)"NULL", params=(GstAllocationParams)NULL;
> 0:00:06.039426410 19866  0x24a0240 INFO          v4l2bufferpool gstv4l2bufferpool.c:560:gst_v4l2_buffer_pool_set_config:<v4l2jpegdec0:pool0:sink> increasing minimum buffers to 2
> 0:00:06.039562409 19866  0x24a0240 INFO          v4l2bufferpool gstv4l2bufferpool.c:573:gst_v4l2_buffer_pool_set_config:<v4l2jpegdec0:pool0:sink> reducing maximum buffers to 32
> 0:00:06.039729074 19866  0x24a0240 DEBUG             video-info video-info.c:410:gst_video_info_from_caps: parsing caps image/jpeg, width=(int)800, height=(int)600, framerate=(fraction)15/1,
> parsed=(boolean)true, pixel-aspect-ratio=(fraction)1/1
> 0:00:06.039913739 19866  0x24a0240 DEBUG             video-info video-info.c:532:gst_video_info_from_caps: no colorimetry, using default
> 0:00:06.040334070 19866  0x24a0240 WARN               structure gststructure.c:2069:priv_gst_structure_append_to_gstring: No value transform to serialize field 'params' of type 'GstAllocationParams'
> 
> For me it seems that the Allocation-Request is not returned successfully here.

Its not handled indeed. I'm not sure for the JPEG decoder, but iirc scenario 1
used to work with CODA / H264. CODA has a internal ring buffer, so it already
bounce the data and thus is very flexible on what can be imported. The error
looks like a kernel bug.

> 
> Maybe someone has an Idea to one of those 2 Issues / Approaches
> Thanks in advance
> Pascal Speck
> 



More information about the gstreamer-devel mailing list