mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
v4l2: take care not to change the current format where appropriate
Some drivers are buggy are will change the current format when processing VIDIOC_TRY_FMT. Save and restore the current format to ensure the format is kept unchanged. https://bugzilla.gnome.org/show_bug.cgi?id=649067
This commit is contained in:
parent
8edb15d12f
commit
639abf01f9
1 changed files with 18 additions and 5 deletions
|
@ -1991,9 +1991,10 @@ static gboolean
|
|||
gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
|
||||
guint32 pixelformat, gint * width, gint * height, gboolean * interlaced)
|
||||
{
|
||||
struct v4l2_format fmt;
|
||||
struct v4l2_format fmt, prevfmt;
|
||||
int fd;
|
||||
int r;
|
||||
int prevfmt_valid;
|
||||
|
||||
g_return_val_if_fail (width != NULL, FALSE);
|
||||
g_return_val_if_fail (height != NULL, FALSE);
|
||||
|
@ -2004,6 +2005,11 @@ gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
|
|||
|
||||
fd = v4l2object->video_fd;
|
||||
|
||||
/* Some drivers are buggy and will modify the currently set format
|
||||
when processing VIDIOC_TRY_FMT, so we remember what is set at the
|
||||
minute, and will reset it when done. */
|
||||
prevfmt_valid = (v4l2_ioctl (fd, VIDIOC_G_FMT, &prevfmt) >= 0);
|
||||
|
||||
/* get size delimiters */
|
||||
memset (&fmt, 0, sizeof (fmt));
|
||||
fmt.type = v4l2object->type;
|
||||
|
@ -2026,12 +2032,12 @@ gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
|
|||
/* The driver might not implement TRY_FMT, in which case we will try
|
||||
S_FMT to probe */
|
||||
if (errno != ENOTTY)
|
||||
return FALSE;
|
||||
goto error;
|
||||
|
||||
/* Only try S_FMT if we're not actively capturing yet, which we shouldn't
|
||||
be, because we're still probing */
|
||||
if (GST_V4L2_IS_ACTIVE (v4l2object))
|
||||
return FALSE;
|
||||
goto error;
|
||||
|
||||
GST_LOG_OBJECT (v4l2object->element,
|
||||
"Failed to probe size limit with VIDIOC_TRY_FMT, trying VIDIOC_S_FMT");
|
||||
|
@ -2050,7 +2056,7 @@ gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
|
|||
}
|
||||
|
||||
if (r < 0)
|
||||
return FALSE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (v4l2object->element,
|
||||
|
@ -2073,10 +2079,17 @@ gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
|
|||
GST_WARNING_OBJECT (v4l2object->element,
|
||||
"Unsupported field type for %" GST_FOURCC_FORMAT "@%ux%u",
|
||||
GST_FOURCC_ARGS (pixelformat), *width, *height);
|
||||
return FALSE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (prevfmt_valid)
|
||||
v4l2_ioctl (fd, VIDIOC_S_FMT, &prevfmt);
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
if (prevfmt_valid)
|
||||
v4l2_ioctl (fd, VIDIOC_S_FMT, &prevfmt);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue