From cf32d6ec4344ead1da7f56373b5805c5477e7ded Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Thu, 28 Nov 2013 17:07:05 -0500 Subject: [PATCH] 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 --- sys/v4l2/v4l2_calls.c | 111 ++++++++++++++++++++++++++++++++++++++------------ sys/v4l2/v4l2_calls.h | 1 + 2 files changed, 86 insertions(+), 26 deletions(-) diff --git a/sys/v4l2/v4l2_calls.c b/sys/v4l2/v4l2_calls.c index ae44a1e..01c0e49 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 221d26e..3c85dae 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 */ -- 2.7.4