v4l2: Discrepancy between gst_buffer_map() returned frame size and expected size from GstV4l2BufferPool caps_info
The following pipeline gives me this error: gst_video_frame_map_id: invalid buffer size 768012 < 769160
root@qt5222:~# gst-launch-1.0 v4l2src device=/dev/video1 ! video/x-raw, width=446, height=574, framerate=25/1, format=RGB ! tcpserversink host=0.0.0.0 port=5000 -v --gst-debug=*:3
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
/GstPipeline:pipeline0/GstTCPServerSink:tcpserversink0: current-port = 5000
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
(gst-launch-1.0:2478): GStreamer-CRITICAL **: 13:34:55.647: gst_value_set_int_range_step: assertion 'end % step == 0' failed
(gst-launch-1.0:2478): GStreamer-CRITICAL **: 13:34:55.647: gst_value_set_int_range_step: assertion 'end % step == 0' failed
/GstPipeline:pipeline0/GstV4l2Src:v4l2src0.GstPad:src: caps = video/x-raw, width=(int)446, height=(int)574, framerate=(fraction)25/1, format=(string)RGB, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)sRGB
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = video/x-raw, width=(int)446, height=(int)574, framerate=(fraction)25/1, format=(string)RGB, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)sRGB
/GstPipeline:pipeline0/GstTCPServerSink:tcpserversink0.GstPad:sink: caps = video/x-raw, width=(int)446, height=(int)574, framerate=(fraction)25/1, format=(string)RGB, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)sRGB
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = video/x-raw, width=(int)446, height=(int)574, framerate=(fraction)25/1, format=(string)RGB, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)sRGB
0:00:00.170945685 2478 0x55fc96e78e30 ERROR default video-frame.c:181:gst_video_frame_map_id: invalid buffer size 768012 < 769160
0:00:00.171062887 2478 0x55fc96e78e30 ERROR v4l2bufferpool gstv4l2bufferpool.c:162:gst_v4l2_buffer_pool_copy_buffer:<v4l2src0:pool0:src> could not map buffer
0:00:00.171086882 2478 0x55fc96e78e30 ERROR v4l2bufferpool gstv4l2bufferpool.c:2078:gst_v4l2_buffer_pool_process:<v4l2src0:pool0:src> failed to copy buffer
0:00:00.171115166 2478 0x55fc96e78e30 WARN basesrc gstbasesrc.c:3127:gst_base_src_loop:<v4l2src0> error: Internal data stream error.
0:00:00.171125335 2478 0x55fc96e78e30 WARN basesrc gstbasesrc.c:3127:gst_base_src_loop:<v4l2src0> error: streaming stopped, reason error (-5)
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data stream error.
Additional debug info:
../gstreamer-1.18.2/libs/gst/base/gstbasesrc.c(3127): gst_base_src_loop (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
streaming stopped, reason error (-5)
Execution ended after 0:00:00.084304722
Setting pipeline to NULL ...
Freeing pipeline ...
The same video caps width=446, height=574, framerate=25/1, format=RGB
work with non-gstreamer based applications.
If I change the width to a multiple of 4 (like 444 or 448) it works. And it gives the same error for any value not a multiple of 4 (as long as they are multiple of 2).
Note that this particular sensor accepts width and heights that are multiple of 2. As is reported by ENUM_FRAME_SIZE (step 2 for width and step 2 for height).
The size reported by gst_buffer_map()
=> 768012
is what I would expect: width*height*nbytes = 446*574*3
.
The size reported by GstV4l2BufferPool
caps_info
=> 769160
is 446*574*3 + 1148 = 446*574*3 + 2*574 = 574*(2 + 3*446)
.
Which tells me it is padding the rows in order to get a stride multiple of 4.