summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2013-11-28 17:07:05 -0500
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2014-01-10 17:13:22 -0500
commitcf32d6ec4344ead1da7f56373b5805c5477e7ded (patch)
tree153e20f0efd77b7a74a0309f5d082228c739199f
parent7fd6dc08b975233c61c8f84b025f4b5f4c7edf22 (diff)
v4l2object: Implement gst_v4l2_dup()
This will duplicated the FD from another object and copy over the probed result. https://bugzilla.gnome.org/show_bug.cgi?id=720568
-rw-r--r--sys/v4l2/v4l2_calls.c111
-rw-r--r--sys/v4l2/v4l2_calls.h1
2 files changed, 86 insertions, 26 deletions
diff --git a/sys/v4l2/v4l2_calls.c b/sys/v4l2/v4l2_calls.c
index ae44a1eaa..01c0e49d6 100644
--- a/sys/v4l2/v4l2_calls.c
+++ b/sys/v4l2/v4l2_calls.c
@@ -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():
diff --git a/sys/v4l2/v4l2_calls.h b/sys/v4l2/v4l2_calls.h
index 221d26e07..3c85dae9f 100644
--- a/sys/v4l2/v4l2_calls.h
+++ b/sys/v4l2/v4l2_calls.h
@@ -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 */