mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-26 02:00:33 +00:00
67eea92044
Drop obsolete GST_VAAPI_IS_xxx() helper macros since we are no longer deriving from GObject and so those were only checking for whether the argument was NULL or not. This is now irrelevant, and even confusing to some extent, because we no longer have type checking. Note: this incurs more type checking (review) but the libgstvaapi is rather small, so this is manageable.
438 lines
11 KiB
C
438 lines
11 KiB
C
/*
|
|
* gstvaapiwindow.c - VA window abstraction
|
|
*
|
|
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
|
* Copyright (C) 2011-2012 Intel Corporation
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
* as published by the Free Software Foundation; either version 2.1
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free
|
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
/**
|
|
* SECTION:gstvaapiwindow
|
|
* @short_description: VA window abstraction
|
|
*/
|
|
|
|
#include "sysdeps.h"
|
|
#include "gstvaapiwindow.h"
|
|
#include "gstvaapiwindow_priv.h"
|
|
|
|
#define DEBUG 1
|
|
#include "gstvaapidebug.h"
|
|
|
|
/* Ensure those symbols are actually defined in the resulting libraries */
|
|
#undef gst_vaapi_window_ref
|
|
#undef gst_vaapi_window_unref
|
|
#undef gst_vaapi_window_replace
|
|
|
|
static void
|
|
gst_vaapi_window_ensure_size(GstVaapiWindow *window)
|
|
{
|
|
const GstVaapiWindowClass * const klass =
|
|
GST_VAAPI_WINDOW_GET_CLASS(window);
|
|
|
|
if (!window->check_geometry)
|
|
return;
|
|
|
|
if (klass->get_geometry)
|
|
klass->get_geometry(window, NULL, NULL,
|
|
&window->width, &window->height);
|
|
|
|
window->check_geometry = FALSE;
|
|
window->is_fullscreen = (window->width == window->display_width &&
|
|
window->height == window->display_height);
|
|
}
|
|
|
|
static gboolean
|
|
gst_vaapi_window_create(GstVaapiWindow *window, guint width, guint height)
|
|
{
|
|
gst_vaapi_display_get_size(
|
|
GST_VAAPI_OBJECT_DISPLAY(window),
|
|
&window->display_width,
|
|
&window->display_height
|
|
);
|
|
|
|
if (!GST_VAAPI_WINDOW_GET_CLASS(window)->create(window, &width, &height))
|
|
return FALSE;
|
|
|
|
if (width != window->width || height != window->height) {
|
|
GST_DEBUG("backend resized window to %ux%u", width, height);
|
|
window->width = width;
|
|
window->height = height;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
GstVaapiWindow *
|
|
gst_vaapi_window_new(const GstVaapiWindowClass *window_class,
|
|
GstVaapiDisplay *display, guint width, guint height)
|
|
{
|
|
GstVaapiWindow *window;
|
|
|
|
g_return_val_if_fail(width > 0, NULL);
|
|
g_return_val_if_fail(height > 0, NULL);
|
|
|
|
window = gst_vaapi_object_new(GST_VAAPI_OBJECT_CLASS(window_class),
|
|
display);
|
|
if (!window)
|
|
return NULL;
|
|
|
|
GST_VAAPI_OBJECT_ID(window) = 0;
|
|
if (!gst_vaapi_window_create(window, width, height))
|
|
goto error;
|
|
return window;
|
|
|
|
error:
|
|
gst_vaapi_window_unref_internal(window);
|
|
return NULL;
|
|
}
|
|
|
|
GstVaapiWindow *
|
|
gst_vaapi_window_new_from_native(const GstVaapiWindowClass *window_class,
|
|
GstVaapiDisplay *display, gpointer native_window)
|
|
{
|
|
GstVaapiWindow *window;
|
|
|
|
window = gst_vaapi_object_new(GST_VAAPI_OBJECT_CLASS(window_class),
|
|
display);
|
|
if (!window)
|
|
return NULL;
|
|
|
|
GST_VAAPI_OBJECT_ID(window) = GPOINTER_TO_SIZE(native_window);
|
|
window->use_foreign_window = TRUE;
|
|
if (!gst_vaapi_window_create(window, 0, 0))
|
|
goto error;
|
|
return window;
|
|
|
|
error:
|
|
gst_vaapi_window_unref_internal(window);
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_ref:
|
|
* @window: a #GstVaapiWindow
|
|
*
|
|
* Atomically increases the reference count of the given @window by one.
|
|
*
|
|
* Returns: The same @window argument
|
|
*/
|
|
GstVaapiWindow *
|
|
gst_vaapi_window_ref(GstVaapiWindow *window)
|
|
{
|
|
return gst_vaapi_window_ref_internal(window);
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_unref:
|
|
* @window: a #GstVaapiWindow
|
|
*
|
|
* Atomically decreases the reference count of the @window by one. If
|
|
* the reference count reaches zero, the window will be free'd.
|
|
*/
|
|
void
|
|
gst_vaapi_window_unref(GstVaapiWindow *window)
|
|
{
|
|
gst_vaapi_window_unref_internal(window);
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_replace:
|
|
* @old_window_ptr: a pointer to a #GstVaapiWindow
|
|
* @new_window: a #GstVaapiWindow
|
|
*
|
|
* Atomically replaces the window window held in @old_window_ptr with
|
|
* @new_window. This means that @old_window_ptr shall reference a
|
|
* valid window. However, @new_window can be NULL.
|
|
*/
|
|
void
|
|
gst_vaapi_window_replace(GstVaapiWindow **old_window_ptr,
|
|
GstVaapiWindow *new_window)
|
|
{
|
|
gst_vaapi_window_replace_internal(old_window_ptr, new_window);
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_get_display:
|
|
* @window: a #GstVaapiWindow
|
|
*
|
|
* Returns the #GstVaapiDisplay this @window is bound to.
|
|
*
|
|
* Return value: the parent #GstVaapiDisplay object
|
|
*/
|
|
GstVaapiDisplay *
|
|
gst_vaapi_window_get_display(GstVaapiWindow *window)
|
|
{
|
|
g_return_val_if_fail(window != NULL, NULL);
|
|
|
|
return GST_VAAPI_OBJECT_DISPLAY(window);
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_show:
|
|
* @window: a #GstVaapiWindow
|
|
*
|
|
* Flags a window to be displayed. Any window that is not shown will
|
|
* not appear on the screen.
|
|
*/
|
|
void
|
|
gst_vaapi_window_show(GstVaapiWindow *window)
|
|
{
|
|
g_return_if_fail(window != NULL);
|
|
|
|
GST_VAAPI_WINDOW_GET_CLASS(window)->show(window);
|
|
window->check_geometry = TRUE;
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_hide:
|
|
* @window: a #GstVaapiWindow
|
|
*
|
|
* Reverses the effects of gst_vaapi_window_show(), causing the window
|
|
* to be hidden (invisible to the user).
|
|
*/
|
|
void
|
|
gst_vaapi_window_hide(GstVaapiWindow *window)
|
|
{
|
|
g_return_if_fail(window != NULL);
|
|
|
|
GST_VAAPI_WINDOW_GET_CLASS(window)->hide(window);
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_get_fullscreen:
|
|
* @window: a #GstVaapiWindow
|
|
*
|
|
* Retrieves whether the @window is fullscreen or not
|
|
*
|
|
* Return value: %TRUE if the window is fullscreen
|
|
*/
|
|
gboolean
|
|
gst_vaapi_window_get_fullscreen(GstVaapiWindow *window)
|
|
{
|
|
g_return_val_if_fail(window != NULL, FALSE);
|
|
|
|
gst_vaapi_window_ensure_size(window);
|
|
|
|
return window->is_fullscreen;
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_set_fullscreen:
|
|
* @window: a #GstVaapiWindow
|
|
* @fullscreen: %TRUE to request window to get fullscreen
|
|
*
|
|
* Requests to place the @window in fullscreen or unfullscreen states.
|
|
*/
|
|
void
|
|
gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen)
|
|
{
|
|
const GstVaapiWindowClass *klass;
|
|
|
|
g_return_if_fail(window != NULL);
|
|
|
|
klass = GST_VAAPI_WINDOW_GET_CLASS(window);
|
|
|
|
if (window->is_fullscreen != fullscreen &&
|
|
klass->set_fullscreen && klass->set_fullscreen(window, fullscreen)) {
|
|
window->is_fullscreen = fullscreen;
|
|
window->check_geometry = TRUE;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_get_width:
|
|
* @window: a #GstVaapiWindow
|
|
*
|
|
* Retrieves the width of a #GstVaapiWindow.
|
|
*
|
|
* Return value: the width of the @window, in pixels
|
|
*/
|
|
guint
|
|
gst_vaapi_window_get_width(GstVaapiWindow *window)
|
|
{
|
|
g_return_val_if_fail(window != NULL, 0);
|
|
|
|
gst_vaapi_window_ensure_size(window);
|
|
|
|
return window->width;
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_get_height:
|
|
* @window: a #GstVaapiWindow
|
|
*
|
|
* Retrieves the height of a #GstVaapiWindow
|
|
*
|
|
* Return value: the height of the @window, in pixels
|
|
*/
|
|
guint
|
|
gst_vaapi_window_get_height(GstVaapiWindow *window)
|
|
{
|
|
g_return_val_if_fail(window != NULL, 0);
|
|
|
|
gst_vaapi_window_ensure_size(window);
|
|
|
|
return window->height;
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_get_size:
|
|
* @window: a #GstVaapiWindow
|
|
* @pwidth: return location for the width, or %NULL
|
|
* @pheight: return location for the height, or %NULL
|
|
*
|
|
* Retrieves the dimensions of a #GstVaapiWindow.
|
|
*/
|
|
void
|
|
gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight)
|
|
{
|
|
g_return_if_fail(window != NULL);
|
|
|
|
gst_vaapi_window_ensure_size(window);
|
|
|
|
if (pwidth)
|
|
*pwidth = window->width;
|
|
|
|
if (pheight)
|
|
*pheight = window->height;
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_set_width:
|
|
* @window: a #GstVaapiWindow
|
|
* @width: requested new width for the window, in pixels
|
|
*
|
|
* Resizes the @window to match the specified @width.
|
|
*/
|
|
void
|
|
gst_vaapi_window_set_width(GstVaapiWindow *window, guint width)
|
|
{
|
|
g_return_if_fail(window != NULL);
|
|
|
|
gst_vaapi_window_set_size(window, width, window->height);
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_set_height:
|
|
* @window: a #GstVaapiWindow
|
|
* @height: requested new height for the window, in pixels
|
|
*
|
|
* Resizes the @window to match the specified @height.
|
|
*/
|
|
void
|
|
gst_vaapi_window_set_height(GstVaapiWindow *window, guint height)
|
|
{
|
|
g_return_if_fail(window != NULL);
|
|
|
|
gst_vaapi_window_set_size(window, window->width, height);
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_set_size:
|
|
* @window: a #GstVaapiWindow
|
|
* @width: requested new width for the window, in pixels
|
|
* @height: requested new height for the window, in pixels
|
|
*
|
|
* Resizes the @window to match the specified @width and @height.
|
|
*/
|
|
void
|
|
gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height)
|
|
{
|
|
g_return_if_fail(window != NULL);
|
|
|
|
if (width == window->width && height == window->height)
|
|
return;
|
|
|
|
if (!GST_VAAPI_WINDOW_GET_CLASS(window)->resize(window, width, height))
|
|
return;
|
|
|
|
window->width = width;
|
|
window->height = height;
|
|
}
|
|
|
|
static inline void
|
|
get_surface_rect(GstVaapiSurface *surface, GstVaapiRectangle *rect)
|
|
{
|
|
guint width, height;
|
|
|
|
gst_vaapi_surface_get_size(surface, &width, &height);
|
|
rect->x = 0;
|
|
rect->y = 0;
|
|
rect->width = width;
|
|
rect->height = height;
|
|
}
|
|
|
|
static inline void
|
|
get_window_rect(GstVaapiWindow *window, GstVaapiRectangle *rect)
|
|
{
|
|
guint width, height;
|
|
|
|
gst_vaapi_window_get_size(window, &width, &height);
|
|
rect->x = 0;
|
|
rect->y = 0;
|
|
rect->width = width;
|
|
rect->height = height;
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_window_put_surface:
|
|
* @window: a #GstVaapiWindow
|
|
* @surface: a #GstVaapiSurface
|
|
* @src_rect: the sub-rectangle of the source surface to
|
|
* extract and process. If %NULL, the entire surface will be used.
|
|
* @dst_rect: the sub-rectangle of the destination
|
|
* window into which the surface is rendered. If %NULL, the entire
|
|
* window will be used.
|
|
* @flags: postprocessing flags. See #GstVaapiSurfaceRenderFlags
|
|
*
|
|
* Renders the @surface region specified by @src_rect into the @window
|
|
* region specified by @dst_rect. The @flags specify how de-interlacing
|
|
* (if needed), color space conversion, scaling and other postprocessing
|
|
* transformations are performed.
|
|
*
|
|
* Return value: %TRUE on success
|
|
*/
|
|
gboolean
|
|
gst_vaapi_window_put_surface(
|
|
GstVaapiWindow *window,
|
|
GstVaapiSurface *surface,
|
|
const GstVaapiRectangle *src_rect,
|
|
const GstVaapiRectangle *dst_rect,
|
|
guint flags
|
|
)
|
|
{
|
|
const GstVaapiWindowClass *klass;
|
|
GstVaapiRectangle src_rect_default, dst_rect_default;
|
|
|
|
g_return_val_if_fail(window != NULL, FALSE);
|
|
g_return_val_if_fail(surface != NULL, FALSE);
|
|
|
|
klass = GST_VAAPI_WINDOW_GET_CLASS(window);
|
|
if (!klass->render)
|
|
return FALSE;
|
|
|
|
if (!src_rect) {
|
|
src_rect = &src_rect_default;
|
|
get_surface_rect(surface, &src_rect_default);
|
|
}
|
|
|
|
if (!dst_rect) {
|
|
dst_rect = &dst_rect_default;
|
|
get_window_rect(window, &dst_rect_default);
|
|
}
|
|
|
|
return klass->render(window, surface, src_rect, dst_rect, flags);
|
|
}
|