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