mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-24 23:16:30 +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,
|
gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
|
||||||
guint32 pixelformat, gint * width, gint * height, gboolean * interlaced)
|
guint32 pixelformat, gint * width, gint * height, gboolean * interlaced)
|
||||||
{
|
{
|
||||||
struct v4l2_format fmt;
|
struct v4l2_format fmt, prevfmt;
|
||||||
int fd;
|
int fd;
|
||||||
int r;
|
int r;
|
||||||
|
int prevfmt_valid;
|
||||||
|
|
||||||
g_return_val_if_fail (width != NULL, FALSE);
|
g_return_val_if_fail (width != NULL, FALSE);
|
||||||
g_return_val_if_fail (height != 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;
|
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 */
|
/* get size delimiters */
|
||||||
memset (&fmt, 0, sizeof (fmt));
|
memset (&fmt, 0, sizeof (fmt));
|
||||||
fmt.type = v4l2object->type;
|
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
|
/* The driver might not implement TRY_FMT, in which case we will try
|
||||||
S_FMT to probe */
|
S_FMT to probe */
|
||||||
if (errno != ENOTTY)
|
if (errno != ENOTTY)
|
||||||
return FALSE;
|
goto error;
|
||||||
|
|
||||||
/* Only try S_FMT if we're not actively capturing yet, which we shouldn't
|
/* Only try S_FMT if we're not actively capturing yet, which we shouldn't
|
||||||
be, because we're still probing */
|
be, because we're still probing */
|
||||||
if (GST_V4L2_IS_ACTIVE (v4l2object))
|
if (GST_V4L2_IS_ACTIVE (v4l2object))
|
||||||
return FALSE;
|
goto error;
|
||||||
|
|
||||||
GST_LOG_OBJECT (v4l2object->element,
|
GST_LOG_OBJECT (v4l2object->element,
|
||||||
"Failed to probe size limit with VIDIOC_TRY_FMT, trying VIDIOC_S_FMT");
|
"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)
|
if (r < 0)
|
||||||
return FALSE;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_LOG_OBJECT (v4l2object->element,
|
GST_LOG_OBJECT (v4l2object->element,
|
||||||
|
@ -2073,10 +2079,17 @@ gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
|
||||||
GST_WARNING_OBJECT (v4l2object->element,
|
GST_WARNING_OBJECT (v4l2object->element,
|
||||||
"Unsupported field type for %" GST_FOURCC_FORMAT "@%ux%u",
|
"Unsupported field type for %" GST_FOURCC_FORMAT "@%ux%u",
|
||||||
GST_FOURCC_ARGS (pixelformat), *width, *height);
|
GST_FOURCC_ARGS (pixelformat), *width, *height);
|
||||||
return FALSE;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prevfmt_valid)
|
||||||
|
v4l2_ioctl (fd, VIDIOC_S_FMT, &prevfmt);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (prevfmt_valid)
|
||||||
|
v4l2_ioctl (fd, VIDIOC_S_FMT, &prevfmt);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue