v4l2src: Reset the compose window to the default after setting format
authorDamian Hobson-Garcia <dhobsong@igel.co.jp>
Fri, 15 Oct 2021 06:32:22 +0000 (15:32 +0900)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 3 Mar 2022 13:28:31 +0000 (13:28 +0000)
When the size of V4L2 capture or output is changes with VIDIOC_S_FMT,
the device is only required to update the compisition window to fit
inside the new frame size.  This can result in captured data only being
updated on a portion of the frame after a resize.

Update the composition window to the default value determined by the
V4L2 device driver whenever the format is changed to make sure that
all image data is composed to its full size.

Fixes #765

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1806>

subprojects/gst-plugins-good/sys/v4l2/gstv4l2object.c

index 1866516..c739f17 100644 (file)
@@ -3170,6 +3170,41 @@ no_supported_capture_method:
   }
 }
 
+static gboolean
+gst_v4l2_object_reset_compose_region (GstV4l2Object * obj)
+{
+  struct v4l2_selection sel = { 0 };
+
+  GST_V4L2_CHECK_OPEN (obj);
+  GST_V4L2_CHECK_NOT_ACTIVE (obj);
+
+  sel.type = obj->type;
+  sel.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
+
+  if (obj->ioctl (obj->video_fd, VIDIOC_G_SELECTION, &sel) < 0) {
+    if (errno == ENOTTY) {
+      /* No-op when selection API is not supported */
+      return TRUE;
+    } else {
+      GST_WARNING_OBJECT (obj->dbg_obj,
+          "Failed to get default compose rectangle with VIDIOC_G_SELECTION: %s",
+          g_strerror (errno));
+      return FALSE;
+    }
+  }
+
+  sel.target = V4L2_SEL_TGT_COMPOSE;
+
+  if (obj->ioctl (obj->video_fd, VIDIOC_S_SELECTION, &sel) < 0) {
+    GST_WARNING_OBJECT (obj->dbg_obj,
+        "Failed to set default compose rectangle with VIDIOC_S_SELECTION: %s",
+        g_strerror (errno));
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
 static void
 gst_v4l2_object_set_stride (GstVideoInfo * info, GstVideoAlignment * align,
     gint plane, gint stride)
@@ -3979,6 +4014,9 @@ done:
   /* add boolean return, so we can fail on drivers bugs */
   gst_v4l2_object_save_format (v4l2object, fmtdesc, &format, &info, &align);
 
+  /* reset composition region to match the S_FMT size */
+  gst_v4l2_object_reset_compose_region (v4l2object);
+
   /* now configure the pool */
   if (!gst_v4l2_object_setup_pool (v4l2object, caps))
     goto pool_failed;