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
This commit is contained in:
Nicolas Dufresne 2013-11-28 17:07:05 -05:00
parent 7fd6dc08b9
commit cf32d6ec43
2 changed files with 86 additions and 26 deletions

View 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():

View 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 */