kmssink: Add skip-vsync property
authorBill Hofmann <bill.hofmann@gmail.com>
Mon, 21 Nov 2022 20:48:49 +0000 (15:48 -0500)
committerNicolas Dufresne <nicolas.dufresne@collabora.com>
Mon, 21 Nov 2022 22:55:20 +0000 (17:55 -0500)
The legacy emulation in DRM/KMS drivers badly interact with GStreamer and
may cause the framerate to be halved. With this property, users can disable
vsync (which is handled internally by the emulation) in order to regain the
full framerate.

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

subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json
subprojects/gst-plugins-bad/sys/kms/gstkmssink.c
subprojects/gst-plugins-bad/sys/kms/gstkmssink.h

index 778557a..92604f1 100644 (file)
                         "readable": true,
                         "type": "gboolean",
                         "writable": true
+                    },
+                    "skip-vsync": {
+                        "blurb": "When enabled will not wait internally for vsync. Should be used for atomic drivers to avoid double vsync.",
+                        "conditionally-available": false,
+                        "construct": true,
+                        "construct-only": false,
+                        "controllable": false,
+                        "default": "false",
+                        "mutable": "null",
+                        "readable": true,
+                        "type": "gboolean",
+                        "writable": true
                     }
                 },
                 "rank": "secondary"
index cba6a36..e929d28 100644 (file)
@@ -98,6 +98,7 @@ enum
   PROP_CONNECTOR_PROPS,
   PROP_PLANE_PROPS,
   PROP_FD,
+  PROP_SKIP_VSYNC,
   PROP_N,
 };
 
@@ -1683,7 +1684,7 @@ retry_set_plane:
 
 sync_frame:
   /* Wait for the previous frame to complete redraw */
-  if (!gst_kms_sink_sync (self)) {
+  if (!self->skip_vsync && !gst_kms_sink_sync (self)) {
     GST_OBJECT_UNLOCK (self);
     goto bail;
   }
@@ -1884,6 +1885,9 @@ gst_kms_sink_set_property (GObject * object, guint prop_id,
     case PROP_FD:
       _validate_and_set_external_fd (sink, g_value_get_int (value));
       break;
+    case PROP_SKIP_VSYNC:
+      sink->skip_vsync = g_value_get_boolean (value);
+      break;
     default:
       if (!gst_video_overlay_set_property (object, PROP_N, prop_id, value))
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1940,6 +1944,9 @@ gst_kms_sink_get_property (GObject * object, guint prop_id,
     case PROP_FD:
       g_value_set_int (value, sink->fd);
       break;
+    case PROP_SKIP_VSYNC:
+      g_value_set_boolean (value, sink->skip_vsync);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1973,6 +1980,7 @@ gst_kms_sink_init (GstKMSSink * sink)
   gst_poll_fd_init (&sink->pollfd);
   sink->poll = gst_poll_new (TRUE);
   gst_video_info_init (&sink->vinfo);
+  sink->skip_vsync = FALSE;
 }
 
 static void
@@ -2152,6 +2160,20 @@ gst_kms_sink_class_init (GstKMSSinkClass * klass)
       "DRM file descriptor", -1, G_MAXINT, -1,
       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
 
+  /**
+   * kmssink:skip-vsync:
+   *
+   *  For some cases, to suppress internal vsync, which can drop framerate
+   *  in half, set this to 1.
+   *
+   *  Since: 1.22
+   */
+  g_properties[PROP_SKIP_VSYNC] =
+      g_param_spec_boolean ("skip-vsync", "Skip Internal VSync",
+      "When enabled will not wait internally for vsync. "
+      "Should be used for atomic drivers to avoid double vsync.", FALSE,
+      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
+
   g_object_class_install_properties (gobject_class, PROP_N, g_properties);
 
   gst_video_overlay_install_properties (gobject_class, PROP_N);
index 536b0a7..e20e2c3 100644 (file)
@@ -95,6 +95,7 @@ struct _GstKMSSink {
   gboolean reconfigure;
 
   gboolean is_internal_fd;
+  gboolean skip_vsync;
 };
 
 struct _GstKMSSinkClass {