v4l2allocator: Workaround driver that don't support REQBUFS(0)
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Fri, 29 Aug 2014 21:09:30 +0000 (17:09 -0400)
committerNicolas Dufresne <nicolas.dufresne@collabora.co.uk>
Tue, 9 Sep 2014 22:45:34 +0000 (18:45 -0400)
There is still around 18 drivers not yet ported to videobuf2. These driver
don't support freeing buffetrs through REQBUFS(0) hence for these the
memory type probing fails. In order to gain back our previous behaviour in
presence of these, we implement a workaround that assuming MMAP is
supported. Note that an allocator is only created for device with
STREAMING support in the device capabilities. In such case one of MMAP,
USERPTR and DMABUF is required. Though DMABUF came afterward, so is
not an option and in practice none of these drivers will only do USERPTR.

https://bugzilla.gnome.org/show_bug.cgi?id=735660

Also-by: Hans de Goede <hdegoede@redhat.com>
sys/v4l2/gstv4l2allocator.c

index 68ce902..2bc51c4 100644 (file)
@@ -637,20 +637,20 @@ gst_v4l2_allocator_new (GstObject * parent, gint video_fd,
   flags |= GST_V4L2_ALLOCATOR_PROBE (allocator, USERPTR);
   flags |= GST_V4L2_ALLOCATOR_PROBE (allocator, DMABUF);
 
-  GST_OBJECT_FLAG_SET (allocator, flags);
 
-  if (flags == 0)
-    goto not_supported;
+  if (flags == 0) {
+    /* Drivers not ported from videobuf to videbuf2 don't allow freeing buffers
+     * using REQBUFS(0). This is a workaround to still support these drivers,
+     * which are known to have MMAP support. */
+    GST_WARNING_OBJECT (allocator, "Could not probe supported memory type, "
+        "assuming MMAP is supported, this is expected for older drivers not "
+        " yet ported to videobuf2 framework");
+    flags = GST_V4L2_ALLOCATOR_FLAG_MMAP_REQBUFS;
+  }
 
-  return allocator;
+  GST_OBJECT_FLAG_SET (allocator, flags);
 
-not_supported:
-  {
-    GST_ERROR_OBJECT (allocator,
-        "No memory model supported by GStreamer for this device");
-    g_object_unref (allocator);
-    return NULL;
-  }
+  return allocator;
 }
 
 guint
@@ -766,8 +766,10 @@ gst_v4l2_allocator_stop (GstV4l2Allocator * allocator)
       gst_v4l2_memory_group_free (group);
   }
 
+  /* Not all drivers support rebufs(0), so warn only */
   if (v4l2_ioctl (allocator->video_fd, VIDIOC_REQBUFS, &breq) < 0)
-    goto reqbufs_failed;
+    GST_WARNING_OBJECT (allocator,
+        "error releasing buffers buffers: %s", g_strerror (errno));
 
   allocator->count = 0;
 
@@ -776,14 +778,6 @@ gst_v4l2_allocator_stop (GstV4l2Allocator * allocator)
 done:
   GST_OBJECT_UNLOCK (allocator);
   return ret;
-
-reqbufs_failed:
-  {
-    GST_ERROR_OBJECT (allocator,
-        "error releasing buffers buffers: %s", g_strerror (errno));
-    ret = GST_V4L2_ERROR;
-    goto done;
-  }
 }
 
 GstV4l2MemoryGroup *