diff options
author | Nicolas Dufresne <nicolas.dufresne@collabora.com> | 2013-11-28 17:07:05 -0500 |
---|---|---|
committer | Nicolas Dufresne <nicolas.dufresne@collabora.com> | 2014-01-10 17:13:22 -0500 |
commit | cf32d6ec4344ead1da7f56373b5805c5477e7ded (patch) | |
tree | 153e20f0efd77b7a74a0309f5d082228c739199f | |
parent | 7fd6dc08b975233c61c8f84b025f4b5f4c7edf22 (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.c | 111 | ||||
-rw-r--r-- | 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 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 */ |