[prev in list] [next in list] [prev in thread] [next in thread]
List: gstreamer-cvs
Subject: [1.4] gst-plugins-good: v4l2: get_nearest_size: Fix " Unsupported field type" errors
From: nicolasd () kemper ! freedesktop ! org (Nicolas Dufresne)
Date: 2014-08-29 20:52:37
Message-ID: 20140829205238.16B17761EF () kemper ! freedesktop ! org
[Download RAW message or body]
Module: gst-plugins-good
Branch: 1.4
Commit: 355c12bec3b58cb8110eb8b45e9bb4998218b94d
URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=355c12bec3b58cb8110eb8b45e9bb4998218b94d
Author: Hans de Goede <hdegoede@redhat.com>
Date: Fri Aug 29 12:01:27 2014 +0200
v4l2: get_nearest_size: Fix "Unsupported field type" errors
Most V4L2 ioctls like try_fmt will adjust input fields to match what the
hardware can do rather then returning -EINVAL. As is docmented here:
http://linuxtv.org/downloads/v4l-dvb-apis/vidioc-g-fmt.html
EINVAL is only returned if the buffer type field is invalid or not supported.
So upon requesting V4L2_FIELD_NONE devices which can only do interlaced
mode will change the field value to e.g. V4L2_FIELD_BOTTOM as only returning
half the lines is the closest they can do to progressive modes.
In essence this means that we've failed to get a (usable) progessive mode
and should fall back to interlaced mode.
This commit adds a check for having gotten a usable field value after the first
try_fmt, to force fallback to interlaced mode even if the try_fmt succeeded,
thereby fixing get_nearest_size failing on these devices.
https://bugzilla.gnome.org/show_bug.cgi?id=735660
---
sys/v4l2/gstv4l2object.c | 44 +++++++++++++++++++++++++++-----------------
1 file changed, 27 insertions(+), 17 deletions(-)
diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c
index 881a52d..ef77e71 100644
--- a/sys/v4l2/gstv4l2object.c
+++ b/sys/v4l2/gstv4l2object.c
@@ -2141,6 +2141,24 @@ default_frame_sizes:
}
static gboolean
+gst_v4l2_object_get_interlace (int field, gboolean * interlaced)
+{
+ switch (field) {
+ case V4L2_FIELD_ANY:
+ case V4L2_FIELD_NONE:
+ *interlaced = FALSE;
+ return TRUE;
+ case V4L2_FIELD_INTERLACED:
+ case V4L2_FIELD_INTERLACED_TB:
+ case V4L2_FIELD_INTERLACED_BT:
+ *interlaced = TRUE;
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+static gboolean
gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
guint32 pixelformat, gint * width, gint * height, gboolean * interlaced)
{
@@ -2169,7 +2187,8 @@ gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
fmt.fmt.pix.field = V4L2_FIELD_NONE;
r = v4l2_ioctl (fd, VIDIOC_TRY_FMT, &fmt);
- if (r < 0 && errno == EINVAL) {
+ if ((r < 0 && errno == EINVAL) ||
+ !gst_v4l2_object_get_interlace (fmt.fmt.pix.field, interlaced)) {
/* try again with interlaced video */
memset (&fmt, 0, sizeof (fmt));
fmt.type = v4l2object->type;
@@ -2202,7 +2221,8 @@ gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
fmt.fmt.pix.field = V4L2_FIELD_NONE;
r = v4l2_ioctl (fd, VIDIOC_S_FMT, &fmt);
- if (r < 0 && errno == EINVAL) {
+ if ((r < 0 && errno == EINVAL) ||
+ !gst_v4l2_object_get_interlace (fmt.fmt.pix.field, interlaced)) {
/* try again with interlaced video */
memset (&fmt, 0, sizeof (fmt));
fmt.type = v4l2object->type;
@@ -2223,21 +2243,11 @@ gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
*width = fmt.fmt.pix.width;
*height = fmt.fmt.pix.height;
- switch (fmt.fmt.pix.field) {
- case V4L2_FIELD_ANY:
- case V4L2_FIELD_NONE:
- *interlaced = FALSE;
- break;
- case V4L2_FIELD_INTERLACED:
- case V4L2_FIELD_INTERLACED_TB:
- case V4L2_FIELD_INTERLACED_BT:
- *interlaced = TRUE;
- break;
- default:
- GST_WARNING_OBJECT (v4l2object->element,
- "Unsupported field type for %" GST_FOURCC_FORMAT "@%ux%u",
- GST_FOURCC_ARGS (pixelformat), *width, *height);
- goto error;
+ if (!gst_v4l2_object_get_interlace (fmt.fmt.pix.field, interlaced)) {
+ GST_WARNING_OBJECT (v4l2object->element,
+ "Unsupported field type for %" GST_FOURCC_FORMAT "@%ux%u: %u",
+ GST_FOURCC_ARGS (pixelformat), *width, *height, fmt.fmt.pix.field);
+ goto error;
}
ret = TRUE;
_______________________________________________
gstreamer-commits mailing list
gstreamer-commits@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/gstreamer-commits
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic