1*4882a593SmuzhiyunFrom e1f73551e144f25cac6953bbab9201b6a2f47fcb Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com>
3*4882a593SmuzhiyunDate: Fri, 28 Apr 2023 18:34:49 +0800
4*4882a593SmuzhiyunSubject: [PATCH 16/16] xvimagesink: Apply toplevel window's position
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunTested on RK3588 evb with:
7*4882a593Smuzhiyungst-launch-1.0 videotestsrc ! xvimagesink render-rectangle='<100,200,300,400>'
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
10*4882a593Smuzhiyun---
11*4882a593Smuzhiyun sys/xvimage/xvcontext.c        | 18 +++++++++++---
12*4882a593Smuzhiyun sys/xvimage/xvcontext.h        |  1 +
13*4882a593Smuzhiyun sys/xvimage/xvimageallocator.c | 45 ++++++++++++++++++++++------------
14*4882a593Smuzhiyun sys/xvimage/xvimagesink.c      | 20 ++++++++++++---
15*4882a593Smuzhiyun 4 files changed, 60 insertions(+), 24 deletions(-)
16*4882a593Smuzhiyun
17*4882a593Smuzhiyundiff --git a/sys/xvimage/xvcontext.c b/sys/xvimage/xvcontext.c
18*4882a593Smuzhiyunindex 97962d9..5fd1c85 100644
19*4882a593Smuzhiyun--- a/sys/xvimage/xvcontext.c
20*4882a593Smuzhiyun+++ b/sys/xvimage/xvcontext.c
21*4882a593Smuzhiyun@@ -1048,19 +1048,21 @@ gst_xv_touchdevice_free (GstXvTouchDevice * device)
22*4882a593Smuzhiyun #endif
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun GstXWindow *
25*4882a593Smuzhiyun-gst_xvcontext_create_xwindow (GstXvContext * context, gint width, gint height,
26*4882a593Smuzhiyun-    gboolean decorations)
27*4882a593Smuzhiyun+gst_xvcontext_create_xwindow (GstXvContext * context, gint x, gint y,
28*4882a593Smuzhiyun+    gint width, gint height, gboolean decorations)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun   GstXWindow *window;
31*4882a593Smuzhiyun   Atom wm_delete;
32*4882a593Smuzhiyun   Atom hints_atom = None;
33*4882a593Smuzhiyun+  XSizeHints hints;
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun   g_return_val_if_fail (GST_IS_XVCONTEXT (context), NULL);
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun   window = g_slice_new0 (GstXWindow);
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun   window->context = gst_xvcontext_ref (context);
40*4882a593Smuzhiyun-  window->render_rect.x = window->render_rect.y = 0;
41*4882a593Smuzhiyun+  window->render_rect.x = x;
42*4882a593Smuzhiyun+  window->render_rect.y = y;
43*4882a593Smuzhiyun   window->render_rect.w = width;
44*4882a593Smuzhiyun   window->render_rect.h = height;
45*4882a593Smuzhiyun   window->have_render_rect = FALSE;
46*4882a593Smuzhiyun@@ -1079,7 +1081,15 @@ gst_xvcontext_create_xwindow (GstXvContext * context, gint width, gint height,
47*4882a593Smuzhiyun   g_mutex_lock (&context->lock);
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun   window->win = XCreateSimpleWindow (context->disp,
50*4882a593Smuzhiyun-      context->root, 0, 0, width, height, 0, 0, context->black);
51*4882a593Smuzhiyun+      context->root, x, y, width, height, 0, 0, context->black);
52*4882a593Smuzhiyun+
53*4882a593Smuzhiyun+  /* Apply size hints */
54*4882a593Smuzhiyun+  hints.flags  = USPosition | USSize;
55*4882a593Smuzhiyun+  hints.x = x;
56*4882a593Smuzhiyun+  hints.y = y;
57*4882a593Smuzhiyun+  hints.width  = width;
58*4882a593Smuzhiyun+  hints.height = height;
59*4882a593Smuzhiyun+  XSetWMNormalHints (context->disp, window->win, &hints);
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun   /* We have to do that to prevent X from redrawing the background on
62*4882a593Smuzhiyun    * ConfigureNotify. This takes away flickering of video when resizing. */
63*4882a593Smuzhiyundiff --git a/sys/xvimage/xvcontext.h b/sys/xvimage/xvcontext.h
64*4882a593Smuzhiyunindex 1fb7614..9f535ae 100644
65*4882a593Smuzhiyun--- a/sys/xvimage/xvcontext.h
66*4882a593Smuzhiyun+++ b/sys/xvimage/xvcontext.h
67*4882a593Smuzhiyun@@ -287,6 +287,7 @@ struct _GstXvTouchDevice {
68*4882a593Smuzhiyun G_END_DECLS
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun GstXWindow *   gst_xvcontext_create_xwindow     (GstXvContext * context,
71*4882a593Smuzhiyun+                                                 gint x, gint y,
72*4882a593Smuzhiyun                                                  gint width, gint height,
73*4882a593Smuzhiyun                                                  gboolean decorations);
74*4882a593Smuzhiyun GstXWindow *   gst_xvcontext_create_xwindow_from_xid (GstXvContext * context, XID xid);
75*4882a593Smuzhiyundiff --git a/sys/xvimage/xvimageallocator.c b/sys/xvimage/xvimageallocator.c
76*4882a593Smuzhiyunindex a6d8432..e5264b7 100644
77*4882a593Smuzhiyun--- a/sys/xvimage/xvimageallocator.c
78*4882a593Smuzhiyun+++ b/sys/xvimage/xvimageallocator.c
79*4882a593Smuzhiyun@@ -590,46 +590,48 @@ xattach_failed:
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun /* We are called with the x_lock taken */
82*4882a593Smuzhiyun static void
83*4882a593Smuzhiyun-gst_xwindow_draw_borders (GstXWindow * window, GstVideoRectangle * rect)
84*4882a593Smuzhiyun+gst_xwindow_draw_borders (GstXWindow * window, GstVideoRectangle * render_rect,
85*4882a593Smuzhiyun+    GstVideoRectangle * video_rect)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun   gint t1, t2;
88*4882a593Smuzhiyun   GstXvContext *context;
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun   g_return_if_fail (window != NULL);
91*4882a593Smuzhiyun-  g_return_if_fail (rect != NULL);
92*4882a593Smuzhiyun+  g_return_if_fail (render_rect != NULL);
93*4882a593Smuzhiyun+  g_return_if_fail (video_rect != NULL);
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun   context = window->context;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun   XSetForeground (context->disp, window->gc, context->black);
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun   /* Left border */
100*4882a593Smuzhiyun-  if (rect->x > window->render_rect.x) {
101*4882a593Smuzhiyun+  if (video_rect->x > render_rect->x) {
102*4882a593Smuzhiyun     XFillRectangle (context->disp, window->win, window->gc,
103*4882a593Smuzhiyun-        window->render_rect.x, window->render_rect.y,
104*4882a593Smuzhiyun-        rect->x - window->render_rect.x, window->render_rect.h);
105*4882a593Smuzhiyun+        render_rect->x, render_rect->y,
106*4882a593Smuzhiyun+        video_rect->x - render_rect->x, render_rect->h);
107*4882a593Smuzhiyun   }
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun   /* Right border */
110*4882a593Smuzhiyun-  t1 = rect->x + rect->w;
111*4882a593Smuzhiyun-  t2 = window->render_rect.x + window->render_rect.w;
112*4882a593Smuzhiyun+  t1 = video_rect->x + video_rect->w;
113*4882a593Smuzhiyun+  t2 = render_rect->x + render_rect->w;
114*4882a593Smuzhiyun   if (t1 < t2) {
115*4882a593Smuzhiyun     XFillRectangle (context->disp, window->win, window->gc,
116*4882a593Smuzhiyun-        t1, window->render_rect.y, t2 - t1, window->render_rect.h);
117*4882a593Smuzhiyun+        t1, render_rect->y, t2 - t1, render_rect->h);
118*4882a593Smuzhiyun   }
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun   /* Top border */
121*4882a593Smuzhiyun-  if (rect->y > window->render_rect.y) {
122*4882a593Smuzhiyun+  if (video_rect->y > render_rect->y) {
123*4882a593Smuzhiyun     XFillRectangle (context->disp, window->win, window->gc,
124*4882a593Smuzhiyun-        window->render_rect.x, window->render_rect.y,
125*4882a593Smuzhiyun-        window->render_rect.w, rect->y - window->render_rect.y);
126*4882a593Smuzhiyun+        render_rect->x, render_rect->y,
127*4882a593Smuzhiyun+        render_rect->w, video_rect->y - render_rect->y);
128*4882a593Smuzhiyun   }
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun   /* Bottom border */
131*4882a593Smuzhiyun-  t1 = rect->y + rect->h;
132*4882a593Smuzhiyun-  t2 = window->render_rect.y + window->render_rect.h;
133*4882a593Smuzhiyun+  t1 = video_rect->y + video_rect->h;
134*4882a593Smuzhiyun+  t2 = render_rect->y + render_rect->h;
135*4882a593Smuzhiyun   if (t1 < t2) {
136*4882a593Smuzhiyun     XFillRectangle (context->disp, window->win, window->gc,
137*4882a593Smuzhiyun-        window->render_rect.x, t1, window->render_rect.w, t2 - t1);
138*4882a593Smuzhiyun+        render_rect->x, t1, render_rect->w, t2 - t1);
139*4882a593Smuzhiyun   }
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun@@ -639,15 +641,26 @@ gst_xvimage_memory_render (GstXvImageMemory * mem, GstVideoRectangle * src_crop,
143*4882a593Smuzhiyun {
144*4882a593Smuzhiyun   GstXvContext *context;
145*4882a593Smuzhiyun   XvImage *xvimage;
146*4882a593Smuzhiyun+  GstVideoRectangle render_rect;
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun   context = window->context;
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun   g_mutex_lock (&context->lock);
151*4882a593Smuzhiyun   xvimage = gst_xvimage_memory_get_xvimage (mem);
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun-  if (draw_border) {
154*4882a593Smuzhiyun-    gst_xwindow_draw_borders (window, dst_crop);
155*4882a593Smuzhiyun+  render_rect = window->render_rect;
156*4882a593Smuzhiyun+  if (window->internal) {
157*4882a593Smuzhiyun+    XMoveResizeWindow (context->disp, window->win,
158*4882a593Smuzhiyun+        window->render_rect.x, window->render_rect.y,
159*4882a593Smuzhiyun+        window->render_rect.w, window->render_rect.h);
160*4882a593Smuzhiyun+    dst_crop->x -= window->render_rect.x;
161*4882a593Smuzhiyun+    dst_crop->y -= window->render_rect.y;
162*4882a593Smuzhiyun+    render_rect.x = render_rect.y = 0;
163*4882a593Smuzhiyun   }
164*4882a593Smuzhiyun+
165*4882a593Smuzhiyun+  if (draw_border)
166*4882a593Smuzhiyun+    gst_xwindow_draw_borders (window, &render_rect, dst_crop);
167*4882a593Smuzhiyun+
168*4882a593Smuzhiyun #ifdef HAVE_XSHM
169*4882a593Smuzhiyun   if (context->use_xshm) {
170*4882a593Smuzhiyun     GST_LOG ("XvShmPutImage with image %dx%d and window %dx%d, from xvimage %p",
171*4882a593Smuzhiyundiff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c
172*4882a593Smuzhiyunindex a0fa468..9f8b594 100644
173*4882a593Smuzhiyun--- a/sys/xvimage/xvimagesink.c
174*4882a593Smuzhiyun+++ b/sys/xvimage/xvimagesink.c
175*4882a593Smuzhiyun@@ -548,7 +548,7 @@ gst_xv_image_sink_xwindow_set_title (GstXvImageSink * xvimagesink,
176*4882a593Smuzhiyun /* This function handles a GstXWindow creation
177*4882a593Smuzhiyun  * The width and height are the actual pixel size on the display */
178*4882a593Smuzhiyun static GstXWindow *
179*4882a593Smuzhiyun-gst_xv_image_sink_xwindow_new (GstXvImageSink * xvimagesink,
180*4882a593Smuzhiyun+gst_xv_image_sink_xwindow_new (GstXvImageSink * xvimagesink, gint x, gint y,
181*4882a593Smuzhiyun     gint width, gint height)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun   GstXWindow *xwindow = NULL;
184*4882a593Smuzhiyun@@ -558,7 +558,7 @@ gst_xv_image_sink_xwindow_new (GstXvImageSink * xvimagesink,
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun   context = xvimagesink->context;
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun-  xwindow = gst_xvcontext_create_xwindow (context, width, height,
189*4882a593Smuzhiyun+  xwindow = gst_xvcontext_create_xwindow (context, x, y, width, height,
190*4882a593Smuzhiyun       xvimagesink->decorations);
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun   /* set application name as a title */
193*4882a593Smuzhiyun@@ -1156,9 +1156,21 @@ gst_xv_image_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
194*4882a593Smuzhiyun   if (!xvimagesink->xwindow_id) {
195*4882a593Smuzhiyun     GST_WARNING_OBJECT (xvimagesink, "overlay window not ready");
196*4882a593Smuzhiyun   } else if (!xvimagesink->xwindow) {
197*4882a593Smuzhiyun+    gint x, y, w, h;
198*4882a593Smuzhiyun+
199*4882a593Smuzhiyun+    if (xvimagesink->pending_render_rect) {
200*4882a593Smuzhiyun+      x = xvimagesink->render_rect.x;
201*4882a593Smuzhiyun+      y = xvimagesink->render_rect.y;
202*4882a593Smuzhiyun+      w = xvimagesink->render_rect.w;
203*4882a593Smuzhiyun+      h = xvimagesink->render_rect.h;
204*4882a593Smuzhiyun+    } else {
205*4882a593Smuzhiyun+      x = y = 0;
206*4882a593Smuzhiyun+      w = GST_VIDEO_SINK_WIDTH (xvimagesink);
207*4882a593Smuzhiyun+      h = GST_VIDEO_SINK_HEIGHT (xvimagesink);
208*4882a593Smuzhiyun+    }
209*4882a593Smuzhiyun+
210*4882a593Smuzhiyun     xvimagesink->xwindow = gst_xv_image_sink_xwindow_new (xvimagesink,
211*4882a593Smuzhiyun-        GST_VIDEO_SINK_WIDTH (xvimagesink),
212*4882a593Smuzhiyun-        GST_VIDEO_SINK_HEIGHT (xvimagesink));
213*4882a593Smuzhiyun+        x, y, w, h);
214*4882a593Smuzhiyun   }
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun   if (xvimagesink->pending_render_rect) {
217*4882a593Smuzhiyun--
218*4882a593Smuzhiyun2.20.1
219*4882a593Smuzhiyun
220