v4l2object: Implement gst_v4l2_dup()
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Thu, 28 Nov 2013 22:07:05 +0000 (17:07 -0500)
committerNicolas Dufresne <nicolas.dufresne@collabora.com>
Fri, 10 Jan 2014 22:13:22 +0000 (17:13 -0500)
This will duplicated the FD from another object and copy over the probed result.

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

sys/v4l2/v4l2_calls.c
sys/v4l2/v4l2_calls.h

index ae44a1e..01c0e49 100644 (file)
@@ -470,6 +470,40 @@ gst_v4l2_empty_lists (GstV4l2Object * v4l2object)
   g_datalist_clear (&v4l2object->controls);
 }
 
+static void
+gst_v4l2_adjust_buf_type (GstV4l2Object * v4l2object)
+{
+  /* when calling gst_v4l2_object_new the user decides the initial type
+   * so adjust it if multi-planar is supported
+   * the driver should make it exclusive. So the driver should
+   * not support both MPLANE and non-PLANE.
+   * Because even when using MPLANE it still possibles to use it
+   * in a contiguous manner. In this case the first v4l2 plane
+   * contains all the gst planes.
+   */
+  switch (v4l2object->type) {
+    case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+      if (v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE
+          || v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_M2M_MPLANE) {
+        GST_DEBUG ("adjust type to multi-planar output");
+        v4l2object->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+      }
+      break;
+    case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+      if (v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE
+          || v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_M2M_MPLANE) {
+        /* FIXME: for now it's an untested case so just put a warning */
+        GST_WARNING ("untested V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE");
+
+        GST_DEBUG ("adjust type to multi-planar capture");
+        v4l2object->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+      }
+      break;
+    default:
+      break;
+  }
+}
+
 /******************************************************
  * gst_v4l2_open():
  *   open the video device (v4l2object->videodev)
@@ -534,33 +568,8 @@ gst_v4l2_open (GstV4l2Object * v4l2object)
               V4L2_CAP_VIDEO_OUTPUT_MPLANE)))
     goto not_output;
 
-  /* when calling gst_v4l2_object_new the user decides the initial type
-   * so adjust it if multi-planar is supported
-   * the driver should make it exclusive. So the driver should
-   * not support both MPLANE and non-PLANE.
-   * Because even when using MPLANE it still possibles to use it
-   * in a contiguous manner. In this case the first v4l2 plane
-   * contains all the gst planes.
-   */
-  switch (v4l2object->type) {
-    case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-      if (v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE) {
-        GST_DEBUG ("adjust type to multi-planar output");
-        v4l2object->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-      }
-      break;
-    case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-      if (v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) {
-        /* FIXME: for now it's an untested case so just put a warning */
-        GST_WARNING ("untested V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE");
 
-        GST_DEBUG ("adjust type to multi-planar capture");
-        v4l2object->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-      }
-      break;
-    default:
-      break;
-  }
+  gst_v4l2_adjust_buf_type (v4l2object);
 
   /* create enumerations, posts errors. */
   if (!gst_v4l2_fill_lists (v4l2object))
@@ -642,6 +651,56 @@ error:
   }
 }
 
+gboolean
+gst_v4l2_dup (GstV4l2Object * v4l2object, GstV4l2Object * other)
+{
+  GstPollFD pollfd = GST_POLL_FD_INIT;
+
+  GST_DEBUG_OBJECT (v4l2object->element, "Trying to dup device %s",
+      other->videodev);
+
+  GST_V4L2_CHECK_OPEN (other);
+  GST_V4L2_CHECK_NOT_OPEN (v4l2object);
+  GST_V4L2_CHECK_NOT_ACTIVE (other);
+  GST_V4L2_CHECK_NOT_ACTIVE (v4l2object);
+
+  v4l2object->vcap = other->vcap;
+  gst_v4l2_adjust_buf_type (v4l2object);
+
+  v4l2object->video_fd = v4l2_dup (other->video_fd);
+  if (!GST_V4L2_IS_OPEN (v4l2object))
+    goto not_open;
+
+  g_free (v4l2object->videodev);
+  v4l2object->videodev = g_strdup (other->videodev);
+
+  GST_INFO_OBJECT (v4l2object->element,
+      "Cloned device '%s' (%s) successfully",
+      v4l2object->vcap.card, v4l2object->videodev);
+
+  pollfd.fd = v4l2object->video_fd;
+  gst_poll_add_fd (v4l2object->poll, &pollfd);
+  if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+      || v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+    gst_poll_fd_ctl_read (v4l2object->poll, &pollfd, TRUE);
+  else
+    gst_poll_fd_ctl_write (v4l2object->poll, &pollfd, TRUE);
+
+  v4l2object->never_interlaced = other->never_interlaced;
+  v4l2object->can_poll_device = TRUE;
+
+  return TRUE;
+
+not_open:
+  {
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, OPEN_READ_WRITE,
+        (_("Could not dup device '%s' for reading and writing."),
+            v4l2object->videodev), GST_ERROR_SYSTEM);
+
+    return FALSE;
+  }
+}
+
 
 /******************************************************
  * gst_v4l2_close():
index 221d26e..3c85dae 100644 (file)
@@ -91,6 +91,7 @@
 
 /* open/close the device */
 gboolean       gst_v4l2_open                   (GstV4l2Object *v4l2object);
+gboolean       gst_v4l2_dup                    (GstV4l2Object *v4l2object, GstV4l2Object *other);
 gboolean       gst_v4l2_close                  (GstV4l2Object *v4l2object);
 
 /* norm/input/output */