GNOME Bugzilla – Bug 790940
v4l2src: selecting dmabuf io-mode on driver not supporting dmabuf
Last modified: 2017-11-29 15:15:57 UTC
Created attachment 364562 [details] error log Hello, It looks like latest master seems to auto-select dmabuf event if the device doesn't support it, without any falling back to a "safe" method (e.g. mmap). 0:00:00.037997607 441 0x5567a0579450 DEBUG v4l2bufferpool gstv4l2bufferpool.c:743:gst_v4l2_buffer_pool_start:<v4l2src0:pool:src> activating pool 0:00:00.038003304 441 0x5567a0579450 DEBUG v4l2bufferpool gstv4l2bufferpool.c:773:gst_v4l2_buffer_pool_start:<v4l2src0:pool:src> requesting 4 MMAP buffers 0:00:00.038012154 441 0x5567a0579450 DEBUG v4l2allocator gstv4l2allocator.c:692:gst_v4l2_allocator_start:<v4l2src0:pool:src:allocator> allocated 4 mmap buffers out of 4 requested 0:00:00.038027996 441 0x5567a0579450 WARN v4l2bufferpool gstv4l2bufferpool.c:790:gst_v4l2_buffer_pool_start:<v4l2src0:pool:src> Uncertain or not enough buffers, enabling copy threshold 0:00:00.038040788 441 0x5567a0579450 ERROR v4l2allocator gstv4l2allocator.c:906:gst_v4l2_allocator_alloc_dmabuf:<v4l2src0:pool:src:allocator> Failed to export DMABUF: Inappropriate ioctl for device 0:00:00.038045683 441 0x5567a0579450 ERROR v4l2bufferpool gstv4l2bufferpool.c:479:gst_v4l2_buffer_pool_alloc_buffer:<v4l2src0:pool:src> failed to allocate buffer 0:00:00.038050221 441 0x5567a0579450 ERROR v4l2bufferpool gstv4l2bufferpool.c:898:gst_v4l2_buffer_pool_start:<v4l2src0:pool:src> allocate failed 0:00:00.038053892 441 0x5567a0579450 ERROR bufferpool gstbufferpool.c:564:gst_buffer_pool_set_active:<v4l2src0:pool:src> start failed 0:00:00.038059392 441 0x5567a0579450 WARN v4l2src gstv4l2src.c:620:gst_v4l2src_decide_allocation:<v4l2src0> error: Failed to allocate required memory. 0:00:00.038063077 441 0x5567a0579450 WARN v4l2src gstv4l2src.c:620:gst_v4l2src_decide_allocation:<v4l2src0> error: Buffer pool activation failed ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Failed to allocate required memory. I can work around this by forcing io-mode=2 for instance, but why is 0 (auto) selecting dmabuf in the first place ? Attached is the output of: $ GST_DEBUG=v4l*:5 gst-launch-1.0 v4l2src device=/dev/video0 num-buffers=100 ! videoconvert ! videoscale ! "video/x-raw, format=(string)NV12, width=(int)1920, height=(int)1200, framerate=(fraction)30, colorimetry=(string)bt709" ! fakesink
Note that i don't see the issue with uvc (no mention of dmabuf in the logs with a uvc device), but with a proprietary driver.
UVC driver supports DMABuf exportation (always). The way detection works is not a fallback, but instead we call expbuf with invalid params. When it's supported, we get einval, and when it's not we expect enotty. Can you tell us what your driver do ? See gst_v4l2_object_is_dmabuf_supported() This trick works with all videobuf2 based drivers. But your driver is unknown to us. Falling back could be another way around, but will prevent further work, like dmabuf caps feature.
I see no mention of VIDIOC_EXPBUF in the driver source. lsmod shows dependencies to videobuf_vmalloc, videobuf_dma_sg, videobuf_core, does it imply it's videobuf2 based ?
I checked, and even though the ENOTTY is properly returned, the return value is still TRUE. static gboolean gst_v4l2_object_is_dmabuf_supported (GstV4l2Object * v4l2object) { gboolean ret = TRUE; struct v4l2_exportbuffer expbuf = { .type = v4l2object->type, .index = -1, .plane = -1, .flags = O_CLOEXEC | O_RDWR, }; /* Expected to fail, but ENOTTY tells us that it is not implemented. */ v4l2object->ioctl (v4l2object->video_fd, VIDIOC_EXPBUF, &expbuf); if (errno == -ENOTTY) ret = FALSE; GST_DEBUG_OBJECT (v4l2object->element, "dmabuf not supported"); GST_DEBUG ("ret: %d", ret); return ret; } 0:00:00.063954056 16815 0x5583aafec770 DEBUG v4l2 gstv4l2object.c:2870:gst_v4l2_object_is_dmabuf_supported:<v4l2src0> dmabuf not supported 0:00:00.063956958 16815 0x5583aafec770 DEBUG v4l2 gstv4l2object.c:2872:gst_v4l2_object_is_dmabuf_supported: ret: 1
(In reply to Florent Thiéry from comment #4) > if (errno == -ENOTTY) > ret = FALSE; > GST_DEBUG_OBJECT (v4l2object->element, "dmabuf not supported"); Missing curly braces mean the debug line is always printed. Which means that debug line is useless ;)
Indeed, just found out. So in the end my the ioctl returns ENOTTY instead of -ENOTTY. Shouldn't gst_v4l2_object_is_dmabuf_supported also return FALSE if errno == ENOTTY as well ?
(why -ENOTTY and not ENOTTY by the way) ?
Related #779466
Created attachment 364614 [details] [review] fix errno value check
Review of attachment 364614 [details] [review]: Yep, that's right. Thanks a lot for this.