1From a86f9dcec915d368bb46e311da18f1948493d074 Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Thu, 9 Jun 2022 12:01:28 +0800
4Subject: [PATCH 13/14] xvimagesink: Defer prepare window when getting zero
5 window handle
6
7The window might not ready when we requesting it.
8
9Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
10---
11 sys/xvimage/xvimagesink.c | 30 +++++++++++++++++-------------
12 sys/xvimage/xvimagesink.h |  2 ++
13 2 files changed, 19 insertions(+), 13 deletions(-)
14
15diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c
16index 44c98a9..fea70a5 100644
17--- a/sys/xvimage/xvimagesink.c
18+++ b/sys/xvimage/xvimagesink.c
19@@ -424,6 +424,10 @@ gst_xv_image_sink_xvimage_put (GstXvImageSink * xvimagesink,
20   GstVideoRectangle mem_crop;
21   GstXWindow *xwindow;
22
23+  /* Ask for window handle */
24+  if (G_UNLIKELY (!xvimagesink->xwindow))
25+    gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (xvimagesink));
26+
27   /* We take the flow_lock. If expose is in there we don't want to run
28      concurrently from the data flow thread */
29   g_mutex_lock (&xvimagesink->flow_lock);
30@@ -1147,7 +1151,9 @@ gst_xv_image_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
31     goto no_display_size;
32
33   g_mutex_lock (&xvimagesink->flow_lock);
34-  if (!xvimagesink->xwindow) {
35+  if (!xvimagesink->xwindow_id) {
36+    GST_WARNING_OBJECT (xvimagesink, "overlay window not ready");
37+  } else if (!xvimagesink->xwindow) {
38     xvimagesink->xwindow = gst_xv_image_sink_xwindow_new (xvimagesink,
39         GST_VIDEO_SINK_WIDTH (xvimagesink),
40         GST_VIDEO_SINK_HEIGHT (xvimagesink));
41@@ -1434,6 +1440,12 @@ invalid_buffer:
42   }
43 no_window:
44   {
45+    /* HACK: Defer window prepare when getting zero window handle */
46+    if (!xvimagesink->xwindow_id) {
47+      GST_WARNING_OBJECT (xvimagesink, "buffer dropped (window not ready)");
48+      goto done;
49+    }
50+
51     /* No Window available to put our image into */
52     GST_WARNING_OBJECT (xvimagesink, "could not output image - no window");
53     res = GST_FLOW_ERROR;
54@@ -1646,18 +1658,7 @@ gst_xv_image_sink_set_window_handle (GstVideoOverlay * overlay, guintptr id)
55     xvimagesink->xwindow = NULL;
56   }
57
58-  /* If the xid is 0 we go back to an internal window */
59-  if (xwindow_id == 0) {
60-    /* If no width/height caps nego did not happen window will be created
61-       during caps nego then */
62-    if (GST_VIDEO_SINK_WIDTH (xvimagesink)
63-        && GST_VIDEO_SINK_HEIGHT (xvimagesink)) {
64-      xwindow =
65-          gst_xv_image_sink_xwindow_new (xvimagesink,
66-          GST_VIDEO_SINK_WIDTH (xvimagesink),
67-          GST_VIDEO_SINK_HEIGHT (xvimagesink));
68-    }
69-  } else {
70+  if ((xvimagesink->xwindow_id = xwindow_id)) {
71     xwindow = gst_xvcontext_create_xwindow_from_xid (context, xwindow_id);
72     gst_xwindow_set_event_handling (xwindow, xvimagesink->handle_events);
73   }
74@@ -2306,6 +2307,9 @@ gst_xv_image_sink_init (GstXvImageSink * xvimagesink)
75   xvimagesink->handle_expose = TRUE;
76
77   xvimagesink->draw_borders = TRUE;
78+
79+  /* HACK: Use a non-zero initial ID to detect overlay mode */
80+  xvimagesink->xwindow_id = -1;
81 }
82
83 static void
84diff --git a/sys/xvimage/xvimagesink.h b/sys/xvimage/xvimagesink.h
85index 35a3081..c84eeea 100644
86--- a/sys/xvimage/xvimagesink.h
87+++ b/sys/xvimage/xvimagesink.h
88@@ -134,6 +134,8 @@ struct _GstXvImageSink
89   /* saved render rectangle until we have a window */
90   gboolean pending_render_rect;
91   GstVideoRectangle render_rect;
92+
93+  guintptr xwindow_id;
94 };
95
96 struct _GstXvImageSinkClass
97--
982.20.1
99
100