1From c51affbdf699b595ce8e06661795ca0da488c404 Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Fri, 25 Feb 2022 17:48:58 +0800
4Subject: [PATCH 31/41] kmssink: Support setting prefered frame syncing mode
5
6Tested with:
7gst-launch-1.0 videotestsrc ! kmssink sync-mode=vblank
8gst-launch-1.0 videotestsrc ! kmssink sync-mode=none
9
10Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
11---
12 sys/kms/gstkmssink.c | 55 +++++++++++++++++++++++++++++++++++++++++---
13 sys/kms/gstkmssink.h | 10 ++++++++
14 2 files changed, 62 insertions(+), 3 deletions(-)
15
16diff --git a/sys/kms/gstkmssink.c b/sys/kms/gstkmssink.c
17index 3740e57..0db743c 100644
18--- a/sys/kms/gstkmssink.c
19+++ b/sys/kms/gstkmssink.c
20@@ -107,11 +107,14 @@ enum
21   PROP_FD,
22   PROP_SKIP_VSYNC,
23   PROP_FORCE_ASPECT_RATIO,
24+  PROP_SYNC_MODE,
25   PROP_N,
26 };
27
28 static GParamSpec *g_properties[PROP_N] = { NULL, };
29
30+static GstKMSSyncMode DEFAULT_SYNC_MODE = GST_KMS_SYNC_AUTO;
31+
32 #ifdef HAVE_DRM_HDR
33 enum hdmi_metadata_type
34 {
35@@ -1805,7 +1808,7 @@ static gboolean
36 gst_kms_sink_sync (GstKMSSink * self)
37 {
38   gint ret;
39-  gboolean waiting;
40+  gboolean waiting, pageflip;
41   drmEventContext evctxt = {
42     .version = DRM_EVENT_CONTEXT_VERSION,
43     .page_flip_handler = sync_handler,
44@@ -1824,8 +1827,18 @@ gst_kms_sink_sync (GstKMSSink * self)
45   else if (self->pipe > 1)
46     vbl.request.type |= self->pipe << DRM_VBLANK_HIGH_CRTC_SHIFT;
47
48+  if (self->sync_mode == GST_KMS_SYNC_FLIP) {
49+    pageflip = TRUE;
50+  } else if (self->sync_mode == GST_KMS_SYNC_VBLANK) {
51+    pageflip = FALSE;
52+  } else if (self->sync_mode == GST_KMS_SYNC_AUTO) {
53+    pageflip = self->modesetting_enabled;
54+  } else {
55+    return TRUE;
56+  }
57+
58   waiting = TRUE;
59-  if (!self->has_async_page_flip && !self->modesetting_enabled) {
60+  if (!pageflip) {
61     ret = drmWaitVBlank (self->fd, &vbl);
62     if (ret)
63       goto vblank_failed;
64@@ -2235,7 +2248,8 @@ retry_set_plane:
65
66 sync_frame:
67   /* Wait for the previous frame to complete redraw */
68-  if (!self->skip_vsync && !gst_kms_sink_sync (self)) {
69+  if (!self->skip_vsync && self->sync_mode != GST_KMS_SYNC_NONE &&
70+      !gst_kms_sink_sync (self)) {
71     GST_OBJECT_UNLOCK (self);
72     goto bail;
73   }
74@@ -2445,6 +2459,9 @@ gst_kms_sink_set_property (GObject * object, guint prop_id,
75     case PROP_FORCE_ASPECT_RATIO:
76       sink->keep_aspect = g_value_get_boolean (value);
77       break;
78+    case PROP_SYNC_MODE:
79+      sink->sync_mode = g_value_get_enum (value);
80+      break;
81     default:
82       if (!gst_video_overlay_set_property (object, PROP_N, prop_id, value))
83         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
84@@ -2507,6 +2524,9 @@ gst_kms_sink_get_property (GObject * object, guint prop_id,
85     case PROP_FORCE_ASPECT_RATIO:
86       g_value_set_boolean (value, sink->keep_aspect);
87       break;
88+    case PROP_SYNC_MODE:
89+      g_value_set_enum (value, sink->sync_mode);
90+      break;
91     default:
92       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
93       break;
94@@ -2539,6 +2559,7 @@ gst_kms_sink_init (GstKMSSink * sink)
95   sink->saved_zpos = -1;
96   sink->can_scale = TRUE;
97   sink->keep_aspect = TRUE;
98+  sink->sync_mode = DEFAULT_SYNC_MODE;
99   gst_poll_fd_init (&sink->pollfd);
100   sink->poll = gst_poll_new (TRUE);
101   gst_video_info_init (&sink->vinfo);
102@@ -2556,6 +2577,25 @@ gst_kms_sink_init (GstKMSSink * sink)
103 #endif
104 }
105
106+#define GST_TYPE_KMS_SYNC_MODE (gst_kms_sync_mode_get_type ())
107+static GType
108+gst_kms_sync_mode_get_type (void)
109+{
110+  static GType mode = 0;
111+
112+  if (!mode) {
113+    static const GEnumValue modes[] = {
114+      {GST_KMS_SYNC_AUTO, "Sync with page flip or vblank event", "auto"},
115+      {GST_KMS_SYNC_FLIP, "Sync with page flip event", "flip"},
116+      {GST_KMS_SYNC_VBLANK, "Sync with vblank event", "vblank"},
117+      {GST_KMS_SYNC_NONE, "Ignore syncing", "none"},
118+      {0, NULL, NULL}
119+    };
120+    mode = g_enum_register_static ("GstKMSSyncMode", modes);
121+  }
122+  return mode;
123+}
124+
125 static void
126 gst_kms_sink_class_init (GstKMSSinkClass * klass)
127 {
128@@ -2752,6 +2792,15 @@ gst_kms_sink_class_init (GstKMSSinkClass * klass)
129       "When enabled, scaling will respect original aspect ratio", TRUE,
130       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
131
132+  if (g_getenv ("KMSSINK_DISABLE_VSYNC"))
133+    DEFAULT_SYNC_MODE = GST_KMS_SYNC_NONE;
134+
135+  g_properties[PROP_SYNC_MODE] =
136+      g_param_spec_enum ("sync-mode", "Sync mode",
137+      "Prefered frame syncing mode",
138+      GST_TYPE_KMS_SYNC_MODE, DEFAULT_SYNC_MODE,
139+      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
140+
141   g_object_class_install_properties (gobject_class, PROP_N, g_properties);
142
143   gst_video_overlay_install_properties (gobject_class, PROP_N);
144diff --git a/sys/kms/gstkmssink.h b/sys/kms/gstkmssink.h
145index 5fb712d..3e25665 100644
146--- a/sys/kms/gstkmssink.h
147+++ b/sys/kms/gstkmssink.h
148@@ -45,6 +45,14 @@ G_BEGIN_DECLS
149 typedef struct _GstKMSSink GstKMSSink;
150 typedef struct _GstKMSSinkClass GstKMSSinkClass;
151
152+typedef enum
153+{
154+  GST_KMS_SYNC_AUTO = 0,
155+  GST_KMS_SYNC_FLIP = 1,
156+  GST_KMS_SYNC_VBLANK = 2,
157+  GST_KMS_SYNC_NONE = 3,
158+} GstKMSSyncMode;
159+
160 struct _GstKMSSink {
161   GstVideoSink videosink;
162
163@@ -114,6 +122,8 @@ struct _GstKMSSink {
164   guintptr window_handle;
165
166   gboolean keep_aspect;
167+
168+  GstKMSSyncMode sync_mode;
169 };
170
171 struct _GstKMSSinkClass {
172--
1732.20.1
174
175