summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHou Qi <qi.hou@nxp.com>2021-04-22 15:01:32 +0800
committerTim-Philipp Müller <tim@centricular.com>2021-04-30 17:41:57 +0100
commitea1a6c47774c79e5054d4f2af870b11f1a56d668 (patch)
tree07c04ab849f874b5ba1a02104a5a4b0167e8a4d7
parent9155b21a552c2894561ebf11dc1bf5e42848c552 (diff)
downloadgstreamer-plugins-good-ea1a6c47774c79e5054d4f2af870b11f1a56d668.tar.gz
v4l2object: Add interlace-mode back to caps for camera
skip_try_fmt_probes is set to TRUE for v4l2src to skip interlace-mode and colorimetry when probe caps. gst_v4l2_object_set_format_full() will add colorimetry back to caps when iterating over the negotiated caps. There is one case that v4l2src is first in preview state then starts recording. v4l2src caps will change with an additional interlace-mode structure after renegotiation, then v4l2src needs to reset. But this camera driver can't orphan buffer pool, it causes require buffer failed as streaming is still in active state. To fix this, also need to add interlace-mode back to caps for camera to avoid reset. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/971>
-rw-r--r--sys/v4l2/gstv4l2object.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c
index 1e465af92..2fb9091b5 100644
--- a/sys/v4l2/gstv4l2object.c
+++ b/sys/v4l2/gstv4l2object.c
@@ -2005,7 +2005,7 @@ gst_v4l2_object_get_interlace_mode (enum v4l2_field field,
case V4L2_FIELD_ANY:
GST_ERROR
("Driver bug detected - check driver with v4l2-compliance from http://git.linuxtv.org/v4l-utils.git\n");
- /* fallthrough */
+ return FALSE;
case V4L2_FIELD_NONE:
*interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
return TRUE;
@@ -3465,6 +3465,7 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
enum v4l2_ycbcr_encoding matrix = 0;
enum v4l2_xfer_func transfer = 0;
GstStructure *s;
+ gboolean disable_interlacing = FALSE;
gboolean disable_colorimetry = FALSE;
g_return_val_if_fail (!v4l2object->skip_try_fmt_probes ||
@@ -3792,12 +3793,18 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
/* used to check colorimetry and interlace mode fields presence */
s = gst_caps_get_structure (caps, 0);
- if (!gst_v4l2_object_get_interlace_mode (format.fmt.pix.field,
- &info.interlace_mode))
- goto invalid_field;
- if (gst_structure_has_field (s, "interlace-mode")) {
- if (format.fmt.pix.field != field)
- goto invalid_field;
+ if (gst_v4l2_object_get_interlace_mode (format.fmt.pix.field,
+ &info.interlace_mode)) {
+ if (gst_structure_has_field (s, "interlace-mode")) {
+ if (format.fmt.pix.field != field)
+ goto invalid_field;
+ }
+ } else {
+ /* The driver (or libv4l2) is miss-behaving, just ignore interlace-mode from
+ * the TRY_FMT */
+ disable_interlacing = TRUE;
+ if (gst_structure_has_field (s, "interlace-mode"))
+ gst_structure_remove_field (s, "interlace-mode");
}
if (gst_v4l2_object_get_colorspace (v4l2object, &format, &info.colorimetry)) {
@@ -3814,8 +3821,12 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
}
/* In case we have skipped the try_fmt probes, we'll need to set the
- * colorimetry back into the caps. */
+ * interlace-mode and colorimetry back into the caps. */
if (v4l2object->skip_try_fmt_probes) {
+ if (!disable_interlacing && !gst_structure_has_field (s, "interlace-mode")) {
+ gst_structure_set (s, "interlace-mode", G_TYPE_STRING,
+ gst_video_interlace_mode_to_string (info.interlace_mode), NULL);
+ }
if (!disable_colorimetry && !gst_structure_has_field (s, "colorimetry")) {
gchar *str = gst_video_colorimetry_to_string (&info.colorimetry);
gst_structure_set (s, "colorimetry", G_TYPE_STRING, str, NULL);