mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 23:06:49 +00:00
Try to improve switch to fullscreen mode.
This commit is contained in:
parent
1c647d1f69
commit
3136cdc991
5 changed files with 100 additions and 77 deletions
|
@ -39,7 +39,6 @@ libgstvaapi_source_h = \
|
|||
libgstvaapi_source_priv_h = \
|
||||
gstvaapidebug.h \
|
||||
gstvaapiutils.h \
|
||||
gstvaapiwindow_priv.h \
|
||||
$(NULL)
|
||||
|
||||
libgstvaapi_x11_source_c = \
|
||||
|
|
|
@ -25,13 +25,26 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "gstvaapiwindow.h"
|
||||
#include "gstvaapiwindow_priv.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, G_TYPE_OBJECT);
|
||||
|
||||
#define GST_VAAPI_WINDOW_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
|
||||
GST_VAAPI_TYPE_WINDOW, \
|
||||
GstVaapiWindowPrivate))
|
||||
|
||||
struct _GstVaapiWindowPrivate {
|
||||
GstVaapiDisplay *display;
|
||||
guint width;
|
||||
guint height;
|
||||
gboolean is_constructed : 1;
|
||||
guint is_fullscreen : 1;
|
||||
guint is_fullscreen_changed : 1;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
|
@ -41,6 +54,25 @@ enum {
|
|||
PROP_FULLSCREEN
|
||||
};
|
||||
|
||||
static void
|
||||
gst_vaapi_window_ensure_size(GstVaapiWindow *window)
|
||||
{
|
||||
GstVaapiWindowPrivate * const priv = window->priv;
|
||||
GstVaapiWindowClass * const klass = GST_VAAPI_WINDOW_GET_CLASS(window);
|
||||
guint display_width, display_height;
|
||||
|
||||
if (!priv->is_fullscreen_changed)
|
||||
return;
|
||||
|
||||
if (klass->get_geometry)
|
||||
klass->get_geometry(window, NULL, NULL, &priv->width, &priv->height);
|
||||
|
||||
gst_vaapi_display_get_size(priv->display, &display_width, &display_height);
|
||||
priv->is_fullscreen_changed = FALSE;
|
||||
priv->is_fullscreen = (priv->width == display_width &&
|
||||
priv->height == display_height);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_window_destroy(GstVaapiWindow *window)
|
||||
{
|
||||
|
@ -218,6 +250,7 @@ gst_vaapi_window_init(GstVaapiWindow *window)
|
|||
priv->height = 1;
|
||||
priv->is_constructed = FALSE;
|
||||
priv->is_fullscreen = FALSE;
|
||||
priv->is_fullscreen_changed = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -281,6 +314,8 @@ gst_vaapi_window_get_fullscreen(GstVaapiWindow *window)
|
|||
{
|
||||
g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), FALSE);
|
||||
|
||||
gst_vaapi_window_ensure_size(window);
|
||||
|
||||
return window->priv->is_fullscreen;
|
||||
}
|
||||
|
||||
|
@ -291,12 +326,6 @@ gst_vaapi_window_get_fullscreen(GstVaapiWindow *window)
|
|||
*
|
||||
* Requests to place the @window in fullscreen or unfullscreen states.
|
||||
*/
|
||||
void
|
||||
_gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen)
|
||||
{
|
||||
window->priv->is_fullscreen = fullscreen;
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen)
|
||||
{
|
||||
|
@ -307,8 +336,10 @@ gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen)
|
|||
klass = GST_VAAPI_WINDOW_GET_CLASS(window);
|
||||
|
||||
if (window->priv->is_fullscreen != fullscreen && klass->set_fullscreen) {
|
||||
_gst_vaapi_window_set_fullscreen(window, fullscreen);
|
||||
klass->set_fullscreen(window, fullscreen);
|
||||
if (klass->set_fullscreen(window, fullscreen)) {
|
||||
window->priv->is_fullscreen = fullscreen;
|
||||
window->priv->is_fullscreen_changed = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,6 +357,8 @@ gst_vaapi_window_get_width(GstVaapiWindow *window)
|
|||
g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), 0);
|
||||
g_return_val_if_fail(window->priv->is_constructed, 0);
|
||||
|
||||
gst_vaapi_window_ensure_size(window);
|
||||
|
||||
return window->priv->width;
|
||||
}
|
||||
|
||||
|
@ -343,6 +376,8 @@ gst_vaapi_window_get_height(GstVaapiWindow *window)
|
|||
g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), 0);
|
||||
g_return_val_if_fail(window->priv->is_constructed, 0);
|
||||
|
||||
gst_vaapi_window_ensure_size(window);
|
||||
|
||||
return window->priv->height;
|
||||
}
|
||||
|
||||
|
@ -360,6 +395,8 @@ gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight)
|
|||
g_return_if_fail(GST_VAAPI_IS_WINDOW(window));
|
||||
g_return_if_fail(window->priv->is_constructed);
|
||||
|
||||
gst_vaapi_window_ensure_size(window);
|
||||
|
||||
if (pwidth)
|
||||
*pwidth = window->priv->width;
|
||||
|
||||
|
@ -405,25 +442,17 @@ gst_vaapi_window_set_height(GstVaapiWindow *window, guint height)
|
|||
*
|
||||
* Resizes the @window to match the specified @width and @height.
|
||||
*/
|
||||
gboolean
|
||||
_gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height)
|
||||
{
|
||||
if (width == window->priv->width && height == window->priv->height)
|
||||
return FALSE;
|
||||
|
||||
window->priv->width = width;
|
||||
window->priv->height = height;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height)
|
||||
{
|
||||
g_return_if_fail(GST_VAAPI_IS_WINDOW(window));
|
||||
|
||||
if (!_gst_vaapi_window_set_size(window, width, height))
|
||||
if (width == window->priv->width && height == window->priv->height)
|
||||
return;
|
||||
|
||||
window->priv->width = width;
|
||||
window->priv->height = height;
|
||||
|
||||
if (window->priv->is_constructed)
|
||||
GST_VAAPI_WINDOW_GET_CLASS(window)->resize(window, width, height);
|
||||
}
|
||||
|
|
|
@ -89,6 +89,9 @@ struct _GstVaapiWindowClass {
|
|||
void (*destroy)(GstVaapiWindow *window);
|
||||
gboolean (*show) (GstVaapiWindow *window);
|
||||
gboolean (*hide) (GstVaapiWindow *window);
|
||||
gboolean (*get_geometry) (GstVaapiWindow *window,
|
||||
gint *px, gint *py,
|
||||
guint *pwidth, guint *pheight);
|
||||
gboolean (*set_fullscreen)(GstVaapiWindow *window, gboolean fullscreen);
|
||||
gboolean (*resize) (GstVaapiWindow *window, guint width, guint height);
|
||||
gboolean (*render) (GstVaapiWindow *window,
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* gstvaapiwindow_priv.h - VA window abstraction (private API)
|
||||
*
|
||||
* gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_WINDOW_PRIVATE_H
|
||||
#define GST_VAAPI_WINDOW_PRIVATE_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_WINDOW_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
|
||||
GST_VAAPI_TYPE_WINDOW, \
|
||||
GstVaapiWindowPrivate))
|
||||
|
||||
struct _GstVaapiWindowPrivate {
|
||||
GstVaapiDisplay *display;
|
||||
guint width;
|
||||
guint height;
|
||||
gboolean is_constructed : 1;
|
||||
guint is_fullscreen : 1;
|
||||
};
|
||||
|
||||
void
|
||||
_gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen)
|
||||
attribute_hidden;
|
||||
|
||||
gboolean
|
||||
_gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height)
|
||||
attribute_hidden;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_WINDOW_H */
|
|
@ -131,10 +131,8 @@ timed_wait_event(GstVaapiWindow *window, int type, guint64 end_time, XEvent *e)
|
|||
GST_VAAPI_DISPLAY_LOCK(priv->display);
|
||||
got_event = XCheckTypedWindowEvent(dpy, priv->xid, type, e);
|
||||
GST_VAAPI_DISPLAY_UNLOCK(priv->display);
|
||||
if (got_event) {
|
||||
g_print("HERE\n");
|
||||
if (got_event)
|
||||
return TRUE;
|
||||
}
|
||||
g_get_current_time(&now);
|
||||
now_time = (guint64)now.tv_sec * 1000000 + now.tv_usec;
|
||||
} while (now_time < end_time);
|
||||
|
@ -163,6 +161,10 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window)
|
|||
wait_event(window, MapNotify);
|
||||
|
||||
priv->is_mapped = TRUE;
|
||||
|
||||
if (priv->fullscreen_on_map)
|
||||
gst_vaapi_window_set_fullscreen(window, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -244,12 +246,30 @@ gst_vaapi_window_x11_destroy(GstVaapiWindow *window)
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_window_x11_get_geometry(
|
||||
GstVaapiWindow *window,
|
||||
gint *px,
|
||||
gint *py,
|
||||
guint *pwidth,
|
||||
guint *pheight)
|
||||
{
|
||||
GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv;
|
||||
Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
|
||||
|
||||
return x11_get_geometry(dpy, priv->xid, px, py, pwidth, pheight);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen)
|
||||
{
|
||||
GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv;
|
||||
Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
|
||||
XEvent e;
|
||||
guint width, height;
|
||||
gboolean has_errors;
|
||||
GTimeVal now;
|
||||
guint64 end_time;
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK(priv->display);
|
||||
x11_trap_errors();
|
||||
|
@ -291,9 +311,31 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen)
|
|||
);
|
||||
}
|
||||
}
|
||||
XSync(dpy, False);
|
||||
has_errors = x11_untrap_errors() != 0;
|
||||
GST_VAAPI_DISPLAY_UNLOCK(priv->display);
|
||||
return !has_errors;
|
||||
if (has_errors)
|
||||
return FALSE;
|
||||
|
||||
/* Try to wait for the completion of the fullscreen mode switch */
|
||||
if (priv->create_window && priv->is_mapped) {
|
||||
const guint DELAY = 100000; /* 100 ms */
|
||||
g_get_current_time(&now);
|
||||
end_time = DELAY + ((guint64)now.tv_sec * 1000000 + now.tv_usec);
|
||||
while (timed_wait_event(window, ConfigureNotify, end_time, &e)) {
|
||||
if (fullscreen) {
|
||||
gst_vaapi_display_get_size(priv->display, &width, &height);
|
||||
if (e.xconfigure.width == width && e.xconfigure.height == height)
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
gst_vaapi_window_get_size(window, &width, &height);
|
||||
if (e.xconfigure.width != width || e.xconfigure.height != height)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -442,6 +484,7 @@ gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass)
|
|||
window_class->destroy = gst_vaapi_window_x11_destroy;
|
||||
window_class->show = gst_vaapi_window_x11_show;
|
||||
window_class->hide = gst_vaapi_window_x11_hide;
|
||||
window_class->get_geometry = gst_vaapi_window_x11_get_geometry;
|
||||
window_class->set_fullscreen = gst_vaapi_window_x11_set_fullscreen;
|
||||
window_class->resize = gst_vaapi_window_x11_resize;
|
||||
window_class->render = gst_vaapi_window_x11_render;
|
||||
|
|
Loading…
Reference in a new issue