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