From 76775efe71b8b7080613c0d7f80b5d30e2a1522f Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Sun, 1 Mar 2015 13:46:18 -0500 Subject: [PATCH] v4l2: Workaround driver not setting field correctly As it's very common, handle driver not setting field in buffers by using the field value from the format. This workaround a long time bug in UVC driver. For even buggier driver, we simply assume progressive as before. We also only warn once, to avoid spamming. --- sys/v4l2/gstv4l2bufferpool.c | 28 ++++++++++++++++++++++++++++ sys/v4l2/gstv4l2bufferpool.h | 3 +++ 2 files changed, 31 insertions(+) diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c index 1cb902d424..0e5c37a8a4 100644 --- a/sys/v4l2/gstv4l2bufferpool.c +++ b/sys/v4l2/gstv4l2bufferpool.c @@ -1164,6 +1164,34 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer) } #endif + /* Check for driver bug in reporting feild */ + if (group->buffer.field == V4L2_FIELD_ANY) { + /* Only warn once to avoid the spamming */ +#ifndef GST_DISABLE_GST_DEBUG + if (!pool->has_warned_on_buggy_field) { + pool->has_warned_on_buggy_field = TRUE; + GST_WARNING_OBJECT (pool, + "Driver should never set v4l2_buffer.field to ANY"); + } +#endif + + /* Use the value from the format (works for UVC bug) */ + group->buffer.field = obj->format.fmt.pix.field; + + /* If driver also has buggy S_FMT, assume progressive */ + if (group->buffer.field == V4L2_FIELD_ANY) { +#ifndef GST_DISABLE_GST_DEBUG + if (!pool->has_warned_on_buggy_field) { + pool->has_warned_on_buggy_field = TRUE; + GST_WARNING_OBJECT (pool, + "Driver should never set v4l2_format.pix.field to ANY"); + } +#endif + + group->buffer.field = V4L2_FIELD_NONE; + } + } + /* set top/bottom field first if v4l2_buffer has the information */ switch (group->buffer.field) { case V4L2_FIELD_NONE: diff --git a/sys/v4l2/gstv4l2bufferpool.h b/sys/v4l2/gstv4l2bufferpool.h index dc2999e7b3..4c2f5cdfb9 100644 --- a/sys/v4l2/gstv4l2bufferpool.h +++ b/sys/v4l2/gstv4l2bufferpool.h @@ -89,6 +89,9 @@ struct _GstV4l2BufferPool /* signal handlers */ gulong group_released_handler; + + /* Control to warn only once on buggy feild driver bug */ + gboolean has_warned_on_buggy_field; }; struct _GstV4l2BufferPoolClass