gl/dispmanx: Implements set_render_rectangle to adjust the position of window

We cannot set the x, y coordinate of the video frame at the dispmanx at
this point. We need to teach dispmanx backend to understand about
set_render_rectangle API to draw a video with other UI.

This patch keeps the current behavior which places video frame at the
center of the display if there is no set_render_rectangle call to the
dispmanx window.

https://bugzilla.gnome.org/show_bug.cgi?id=766018
This commit is contained in:
Gwang Yoon Hwang 2016-05-05 15:53:57 +09:00 committed by Matthew Waters
parent c200e47ef8
commit b75ec0c433
2 changed files with 37 additions and 7 deletions

View file

@ -57,7 +57,8 @@ static void gst_gl_window_dispmanx_egl_close (GstGLWindow * window);
static gboolean gst_gl_window_dispmanx_egl_open (GstGLWindow * window, static gboolean gst_gl_window_dispmanx_egl_open (GstGLWindow * window,
GError ** error); GError ** error);
static guintptr gst_gl_window_dispmanx_egl_get_display (GstGLWindow * window); static guintptr gst_gl_window_dispmanx_egl_get_display (GstGLWindow * window);
static gboolean gst_gl_window_dispmanx_egl_set_render_rectangle (GstGLWindow *
window, gint x, gint y, gint width, gint height);
static void window_resize (GstGLWindowDispmanxEGL * window_egl, guint width, static void window_resize (GstGLWindowDispmanxEGL * window_egl, guint width,
guint height, gboolean visible); guint height, gboolean visible);
@ -78,6 +79,8 @@ gst_gl_window_dispmanx_egl_class_init (GstGLWindowDispmanxEGLClass * klass)
GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_get_display); GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_get_display);
window_class->set_preferred_size = window_class->set_preferred_size =
GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_set_preferred_size); GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_set_preferred_size);
window_class->set_render_rectangle =
GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_set_render_rectangle);
} }
static void static void
@ -92,6 +95,10 @@ gst_gl_window_dispmanx_egl_init (GstGLWindowDispmanxEGL * window_egl)
window_egl->native.element = 0; window_egl->native.element = 0;
window_egl->native.width = 0; window_egl->native.width = 0;
window_egl->native.height = 0; window_egl->native.height = 0;
window_egl->render_rect.x = 0;
window_egl->render_rect.y = 0;
window_egl->render_rect.w = 0;
window_egl->render_rect.h = 0;
} }
/* Must be called in the gl thread */ /* Must be called in the gl thread */
@ -194,20 +201,27 @@ window_resize (GstGLWindowDispmanxEGL * window_egl, guint width, guint height,
if (window_egl->display) { if (window_egl->display) {
VC_RECT_T dst_rect; VC_RECT_T dst_rect;
VC_RECT_T src_rect; VC_RECT_T src_rect;
GstVideoRectangle src, dst, res; GstVideoRectangle src, res;
DISPMANX_UPDATE_HANDLE_T dispman_update; DISPMANX_UPDATE_HANDLE_T dispman_update;
uint32_t opacity = visible ? 255 : 0; uint32_t opacity = visible ? 255 : 0;
VC_DISPMANX_ALPHA_T alpha = VC_DISPMANX_ALPHA_T alpha =
{ DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, opacity, 0 }; { DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, opacity, 0 };
/* Center width*height frame inside dp_width*dp_height */
src.w = width; src.w = width;
src.h = height; src.h = height;
src.x = src.y = 0; src.x = src.y = 0;
/* If there is no render rectangle, center the width*height frame
* inside dp_width*dp_height */
if (window_egl->render_rect.w <= 0 || window_egl->render_rect.h <= 0) {
GstVideoRectangle dst;
dst.w = window_egl->dp_width; dst.w = window_egl->dp_width;
dst.h = window_egl->dp_height; dst.h = window_egl->dp_height;
dst.x = dst.y = 0; dst.x = dst.y = 0;
gst_video_sink_center_rect (src, dst, &res, FALSE); gst_video_sink_center_rect (src, dst, &res, FALSE);
} else {
gst_video_sink_center_rect (src, window_egl->render_rect, &res, FALSE);
}
dst_rect.x = res.x; dst_rect.x = res.x;
dst_rect.y = res.y; dst_rect.y = res.y;
@ -243,6 +257,21 @@ window_resize (GstGLWindowDispmanxEGL * window_egl, guint width, guint height,
window_egl->native.height = height; window_egl->native.height = height;
} }
static gboolean
gst_gl_window_dispmanx_egl_set_render_rectangle (GstGLWindow * window,
gint x, gint y, gint width, gint height)
{
GstGLWindowDispmanxEGL *window_egl = GST_GL_WINDOW_DISPMANX_EGL (window);
window_egl->render_rect.x = x;
window_egl->render_rect.y = x;
window_egl->render_rect.w = width;
window_egl->render_rect.h = height;
window_resize (window_egl, window_egl->render_rect.w,
window_egl->render_rect.h, TRUE);
return TRUE;
}
static void static void
gst_gl_window_dispmanx_egl_show (GstGLWindow * window) gst_gl_window_dispmanx_egl_show (GstGLWindow * window)
{ {

View file

@ -67,6 +67,7 @@ struct _GstGLWindowDispmanxEGL {
gint preferred_width; gint preferred_width;
gint preferred_height; gint preferred_height;
GstVideoRectangle render_rect;
gboolean visible; gboolean visible;