egl: add windowing support.

This provides for some basic EGL window abstraction.
This commit is contained in:
Gwenole Beauchesne 2015-01-27 16:21:04 +01:00
parent 23c489d8ee
commit aabb8c99c2
6 changed files with 710 additions and 2 deletions

View file

@ -280,12 +280,14 @@ libgstvaapi_egl_source_c = \
gstvaapisurface_egl.c \
gstvaapitexture_egl.c \
gstvaapiutils_egl.c \
gstvaapiwindow_egl.c \
$(NULL)
libgstvaapi_egl_source_h = \
gstvaapidisplay_egl.h \
gstvaapisurface_egl.h \
gstvaapitexture_egl.h \
gstvaapiwindow_egl.h \
$(NULL)
libgstvaapi_egl_source_priv_h = \

View file

@ -25,6 +25,8 @@
#include "gstvaapidisplay_egl.h"
#include "gstvaapidisplay_egl_priv.h"
#include "gstvaapiwindow.h"
#include "gstvaapiwindow_egl.h"
#include "gstvaapiwindow_priv.h"
#include "gstvaapitexture_egl.h"
GST_DEBUG_CATEGORY (gst_debug_vaapidisplay_egl);
@ -442,6 +444,24 @@ gst_vaapi_display_egl_get_size_mm (GstVaapiDisplayEGL * display,
klass->get_size_mm (display->display, width_ptr, height_ptr);
}
static guintptr
gst_vaapi_display_egl_get_visual_id (GstVaapiDisplayEGL * display,
GstVaapiWindow * window)
{
if (!ensure_context (display))
return 0;
return display->egl_context->config->visual_id;
}
static GstVaapiWindow *
gst_vaapi_display_egl_create_window (GstVaapiDisplay * display, GstVaapiID id,
guint width, guint height)
{
if (id != GST_VAAPI_ID_INVALID)
return NULL;
return gst_vaapi_window_egl_new (display, width, height);
}
static GstVaapiTexture *
gst_vaapi_display_egl_create_texture (GstVaapiDisplay * display, GstVaapiID id,
guint target, guint format, guint width, guint height)
@ -484,6 +504,10 @@ gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass)
gst_vaapi_display_egl_get_size;
dpy_class->get_size_mm = (GstVaapiDisplayGetSizeMFunc)
gst_vaapi_display_egl_get_size_mm;
dpy_class->get_visual_id = (GstVaapiDisplayGetVisualIdFunc)
gst_vaapi_display_egl_get_visual_id;
dpy_class->create_window = (GstVaapiDisplayCreateWindowFunc)
gst_vaapi_display_egl_create_window;
dpy_class->create_texture = (GstVaapiDisplayCreateTextureFunc)
gst_vaapi_display_egl_create_texture;
}

View file

@ -168,6 +168,7 @@ typedef struct egl_object_class_s EglConfigClass;
typedef struct egl_object_class_s EglContextClass;
typedef struct egl_object_class_s EglSurfaceClass;
typedef struct egl_object_class_s EglProgramClass;
typedef struct egl_object_class_s EglWindowClass;
EGL_OBJECT_DEFINE_CLASS (EglMessage, egl_message);
EGL_OBJECT_DEFINE_CLASS (EglVTable, egl_vtable);
@ -176,6 +177,7 @@ EGL_OBJECT_DEFINE_CLASS (EglConfig, egl_config);
EGL_OBJECT_DEFINE_CLASS (EglContext, egl_context);
EGL_OBJECT_DEFINE_CLASS (EglSurface, egl_surface);
EGL_OBJECT_DEFINE_CLASS (EglProgram, egl_program);
EGL_OBJECT_DEFINE_CLASS (EglWindow, egl_window);
/* ------------------------------------------------------------------------- */
// Desktop OpenGL and OpenGL|ES dispatcher (vtable)
@ -818,7 +820,7 @@ egl_surface_finalize (EglSurface * surface)
egl_object_replace (&surface->display, NULL);
}
EglSurface *
static EglSurface *
egl_surface_new_wrapped (EglDisplay * display, EGLSurface gl_surface)
{
EglSurface *surface;
@ -1088,7 +1090,7 @@ egl_context_get_vtable (EglContext * ctx, gboolean need_gl_symbols)
return ctx->vtable;
}
void
static void
egl_context_set_surface (EglContext * ctx, EglSurface * surface)
{
g_return_if_fail (ctx != NULL);
@ -1257,6 +1259,69 @@ error:
return NULL;
}
/* ------------------------------------------------------------------------- */
// EGL Window
static gboolean
egl_window_init (EglWindow * window, EglContext * ctx, gpointer native_window)
{
EGLSurface gl_surface;
window->context = egl_context_new (ctx->display, ctx->config, ctx);
if (!window->context)
return FALSE;
ctx = window->context;
gl_surface = eglCreateWindowSurface (ctx->display->base.handle.p,
ctx->config->base.handle.p, (EGLNativeWindowType) native_window, NULL);
if (!gl_surface)
return FALSE;
window->surface = egl_surface_new_wrapped (ctx->display, gl_surface);
if (!window->surface)
goto error_create_surface;
window->base.handle.p = gl_surface;
window->base.is_wrapped = FALSE;
egl_context_set_surface (ctx, window->surface);
return TRUE;
/* ERRORS */
error_create_surface:
GST_ERROR ("failed to create EGL wrapper surface");
eglDestroySurface (ctx->display->base.handle.p, gl_surface);
return FALSE;
}
static void
egl_window_finalize (EglWindow * window)
{
if (window->context && window->base.handle.p)
eglDestroySurface (window->context->display->base.handle.p,
window->base.handle.p);
egl_object_replace (&window->surface, NULL);
egl_object_replace (&window->context, NULL);
}
EglWindow *
egl_window_new (EglContext * ctx, gpointer native_window)
{
EglWindow *window;
g_return_val_if_fail (ctx != NULL, NULL);
g_return_val_if_fail (native_window != NULL, NULL);
window = egl_object_new0 (egl_window_class ());
if (!window || !egl_window_init (window, ctx, native_window))
goto error;
return window;
error:
egl_object_replace (&window, NULL);
return NULL;
}
/* ------------------------------------------------------------------------- */
// Misc utility functions

View file

@ -42,6 +42,7 @@ typedef struct egl_context_state_s EglContextState;
typedef struct egl_context_s EglContext;
typedef struct egl_surface_s EglSurface;
typedef struct egl_program_s EglProgram;
typedef struct egl_window_s EglWindow;
#define EGL_PROTO_BEGIN(NAME, TYPE, EXTENSION) \
typedef TYPE (*GL_PROTO_GEN_CONCAT3(Egl,NAME,Proc))
@ -171,6 +172,14 @@ struct egl_program_s
gint uniforms[EGL_MAX_UNIFORMS];
};
struct egl_window_s
{
EglObject base;
EglContext *context;
EglSurface *surface;
};
#define egl_object_ref(obj) \
((gpointer)gst_vaapi_mini_object_ref ((GstVaapiMiniObject *)(obj)))
#define egl_object_unref(obj) \
@ -222,6 +231,10 @@ EglProgram *
egl_program_new (EglContext * ctx, const gchar * frag_shader_text,
const gchar * vert_shader_text);
G_GNUC_INTERNAL
EglWindow *
egl_window_new (EglContext * ctx, gpointer native_window);
G_GNUC_INTERNAL
guint
egl_create_texture (EglContext * ctx, guint target, guint format,

View file

@ -0,0 +1,565 @@
/*
* gstvaapiwindow_egl.c - VA/EGL window abstraction
*
* Copyright (C) 2014 Intel Corporation
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
*
* 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_egl
* @short_description: VA/EGL window abstraction
*/
#include "sysdeps.h"
#include "gstvaapiwindow_egl.h"
#include "gstvaapiwindow_priv.h"
#include "gstvaapitexture_egl.h"
#include "gstvaapitexture_priv.h"
#include "gstvaapidisplay_egl_priv.h"
#define GST_VAAPI_WINDOW_EGL(obj) \
((GstVaapiWindowEGL *)(obj))
#define GST_VAAPI_WINDOW_EGL_CLASS(klass) \
((GstVaapiWindowEGLClass *)(klass))
#define GST_VAAPI_WINDOW_EGL_GET_CLASS(obj) \
GST_VAAPI_WINDOW_EGL_CLASS (GST_VAAPI_WINDOW_GET_CLASS (obj))
typedef struct _GstVaapiWindowEGL GstVaapiWindowEGL;
typedef struct _GstVaapiWindowEGLClass GstVaapiWindowEGLClass;
enum
{
RENDER_PROGRAM_VAR_PROJ = 0,
RENDER_PROGRAM_VAR_TEX0,
RENDER_PROGRAM_VAR_TEX1,
RENDER_PROGRAM_VAR_TEX2,
};
struct _GstVaapiWindowEGL
{
GstVaapiWindow parent_instance;
GstVaapiWindow *window;
GstVaapiTexture *texture;
EglWindow *egl_window;
EglVTable *egl_vtable;
EglProgram *render_program;
gfloat render_projection[16];
};
struct _GstVaapiWindowEGLClass
{
GstVaapiWindowClass parent_class;
};
typedef struct
{
GstVaapiWindowEGL *window;
guint width;
guint height;
EglContext *egl_context;
gboolean success; /* result */
} CreateObjectsArgs;
typedef struct
{
GstVaapiWindowEGL *window;
guint width;
guint height;
gboolean success; /* result */
} ResizeWindowArgs;
typedef struct
{
GstVaapiWindowEGL *window;
GstVaapiSurface *surface;
const GstVaapiRectangle *src_rect;
const GstVaapiRectangle *dst_rect;
guint flags;
gboolean success; /* result */
} UploadSurfaceArgs;
static const gchar *vert_shader_text =
"#ifdef GL_ES\n"
"precision mediump float;\n"
"#endif\n"
"\n"
"uniform mat4 proj;\n"
"\n"
"attribute vec2 position;\n"
"attribute vec2 texcoord;\n"
"varying vec2 v_texcoord;\n"
"\n"
"void main () {\n"
" gl_Position = proj * vec4 (position, 0.0, 1.0);\n"
" v_texcoord = texcoord;\n"
"}\n";
static const gchar *frag_shader_text_rgba =
"#ifdef GL_ES\n"
"precision mediump float;\n"
"#endif\n"
"\n"
"uniform sampler2D tex0;\n"
"\n"
"varying vec2 v_texcoord;\n"
"\n"
"void main () {\n"
" gl_FragColor = texture2D (tex0, v_texcoord);\n"
"}\n";
static gboolean
ensure_texture (GstVaapiWindowEGL * window, guint width, guint height)
{
GstVaapiTexture *texture;
if (window->texture &&
GST_VAAPI_TEXTURE_WIDTH (window->texture) == width &&
GST_VAAPI_TEXTURE_HEIGHT (window->texture) == height)
return TRUE;
texture = gst_vaapi_texture_egl_new (GST_VAAPI_OBJECT_DISPLAY (window),
GL_TEXTURE_2D, GL_RGBA, width, height);
gst_vaapi_texture_replace (&window->texture, texture);
gst_vaapi_texture_replace (&texture, NULL);
return window->texture != NULL;
}
static gboolean
ensure_shaders (GstVaapiWindowEGL * window)
{
EglVTable *const vtable = window->egl_vtable;
EglProgram *program;
GLuint prog_id;
g_return_val_if_fail (window->texture != NULL, FALSE);
g_return_val_if_fail (GST_VAAPI_TEXTURE_FORMAT (window->texture) == GL_RGBA,
FALSE);
if (window->render_program)
return TRUE;
program = egl_program_new (window->egl_window->context,
frag_shader_text_rgba, vert_shader_text);
if (!program)
return FALSE;
prog_id = program->base.handle.u;
vtable->glUseProgram (prog_id);
program->uniforms[RENDER_PROGRAM_VAR_PROJ] =
vtable->glGetUniformLocation (prog_id, "proj");
program->uniforms[RENDER_PROGRAM_VAR_TEX0] =
vtable->glGetUniformLocation (prog_id, "tex0");
program->uniforms[RENDER_PROGRAM_VAR_TEX1] =
vtable->glGetUniformLocation (prog_id, "tex1");
program->uniforms[RENDER_PROGRAM_VAR_TEX2] =
vtable->glGetUniformLocation (prog_id, "tex2");
vtable->glUseProgram (0);
egl_matrix_set_identity (window->render_projection);
egl_object_replace (&window->render_program, program);
egl_object_replace (&program, NULL);
return TRUE;
}
static gboolean
do_create_objects_unlocked (GstVaapiWindowEGL * window, guint width,
guint height, EglContext * egl_context)
{
EglWindow *egl_window;
EglVTable *egl_vtable;
egl_window = egl_window_new (egl_context,
GSIZE_TO_POINTER (GST_VAAPI_OBJECT_ID (window->window)));
if (!egl_window)
return FALSE;
window->egl_window = egl_window;
egl_vtable = egl_context_get_vtable (egl_window->context, TRUE);
if (!egl_vtable)
return FALSE;
window->egl_vtable = egl_object_ref (egl_vtable);
return TRUE;
}
static void
do_create_objects (CreateObjectsArgs * args)
{
GstVaapiWindowEGL *const window = args->window;
EglContextState old_cs;
args->success = FALSE;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window);
if (egl_context_set_current (args->egl_context, TRUE, &old_cs)) {
args->success = do_create_objects_unlocked (window, args->width,
args->height, args->egl_context);
egl_context_set_current (args->egl_context, FALSE, &old_cs);
}
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window);
}
static gboolean
gst_vaapi_window_egl_create (GstVaapiWindowEGL * window,
guint * width, guint * height)
{
GstVaapiDisplayEGL *const display =
GST_VAAPI_DISPLAY_EGL (GST_VAAPI_OBJECT_DISPLAY (window));
const GstVaapiDisplayClass *const native_dpy_class =
GST_VAAPI_DISPLAY_GET_CLASS (display->display);
CreateObjectsArgs args;
g_return_val_if_fail (native_dpy_class != NULL, FALSE);
window->window = native_dpy_class->create_window (GST_VAAPI_DISPLAY (display),
GST_VAAPI_ID_INVALID, *width, *height);
if (!window->window)
return FALSE;
gst_vaapi_window_get_size (window->window, width, height);
args.window = window;
args.width = *width;
args.height = *height;
args.egl_context = GST_VAAPI_DISPLAY_EGL_CONTEXT (display);
return egl_context_run (args.egl_context,
(EglContextRunFunc) do_create_objects, &args) && args.success;
}
static void
do_destroy_objects_unlocked (GstVaapiWindowEGL * window)
{
egl_object_replace (&window->render_program, NULL);
egl_object_replace (&window->egl_vtable, NULL);
egl_object_replace (&window->egl_window, NULL);
}
static void
do_destroy_objects (GstVaapiWindowEGL * window)
{
EglContext *const egl_context =
GST_VAAPI_DISPLAY_EGL_CONTEXT (GST_VAAPI_OBJECT_DISPLAY (window));
EglContextState old_cs;
if (!window->egl_window)
return;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window);
if (egl_context_set_current (egl_context, TRUE, &old_cs)) {
do_destroy_objects_unlocked (window);
egl_context_set_current (egl_context, FALSE, &old_cs);
}
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window);
}
static void
gst_vaapi_window_egl_destroy (GstVaapiWindowEGL * window)
{
egl_context_run (window->egl_window->context,
(EglContextRunFunc) do_destroy_objects, window);
gst_vaapi_window_replace (&window->window, NULL);
gst_vaapi_texture_replace (&window->texture, NULL);
}
static gboolean
gst_vaapi_window_egl_show (GstVaapiWindowEGL * window)
{
const GstVaapiWindowClass *const klass =
GST_VAAPI_WINDOW_GET_CLASS (window->window);
g_return_val_if_fail (klass->show, FALSE);
return klass->show (window->window);
}
static gboolean
gst_vaapi_window_egl_hide (GstVaapiWindowEGL * window)
{
const GstVaapiWindowClass *const klass =
GST_VAAPI_WINDOW_GET_CLASS (window->window);
g_return_val_if_fail (klass->hide, FALSE);
return klass->hide (window->window);
}
static gboolean
gst_vaapi_window_egl_get_geometry (GstVaapiWindowEGL * window,
gint * x_ptr, gint * y_ptr, guint * width_ptr, guint * height_ptr)
{
const GstVaapiWindowClass *const klass =
GST_VAAPI_WINDOW_GET_CLASS (window->window);
return klass->get_geometry ? klass->get_geometry (window->window,
x_ptr, y_ptr, width_ptr, height_ptr) : FALSE;
}
static gboolean
gst_vaapi_window_egl_set_fullscreen (GstVaapiWindowEGL * window,
gboolean fullscreen)
{
const GstVaapiWindowClass *const klass =
GST_VAAPI_WINDOW_GET_CLASS (window->window);
return klass->set_fullscreen ? klass->set_fullscreen (window->window,
fullscreen) : FALSE;
}
static gboolean
do_resize_window_unlocked (GstVaapiWindowEGL * window, guint width,
guint height)
{
EglVTable *const vtable = window->egl_vtable;
vtable->glViewport (0, 0, width, height);
vtable->glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
vtable->glClear (GL_COLOR_BUFFER_BIT);
return TRUE;
}
static void
do_resize_window (ResizeWindowArgs * args)
{
GstVaapiWindowEGL *const window = args->window;
EglContextState old_cs;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window);
if (egl_context_set_current (window->egl_window->context, TRUE, &old_cs)) {
args->success = do_resize_window_unlocked (window, args->width,
args->height);
egl_context_set_current (window->egl_window->context, FALSE, &old_cs);
}
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window);
}
static gboolean
gst_vaapi_window_egl_resize (GstVaapiWindowEGL * window, guint width,
guint height)
{
const GstVaapiWindowClass *const klass =
GST_VAAPI_WINDOW_GET_CLASS (window->window);
ResizeWindowArgs args = { window, width, height };
g_return_val_if_fail (klass->resize, FALSE);
if (!klass->resize (window->window, width, height))
return FALSE;
return egl_context_run (window->egl_window->context,
(EglContextRunFunc) do_resize_window, &args) && args.success;
}
static gboolean
do_render_texture (GstVaapiWindowEGL * window, const GstVaapiRectangle * rect)
{
const GLuint tex_id = GST_VAAPI_OBJECT_ID (window->texture);
EglVTable *const vtable = window->egl_vtable;
GLfloat x0, y0, x1, y1;
GLfloat texcoords[4][2];
GLfloat positions[4][2];
guint tex_width, tex_height;
if (!ensure_shaders (window))
return FALSE;
tex_width = GST_VAAPI_TEXTURE_WIDTH (window->texture);
tex_height = GST_VAAPI_TEXTURE_HEIGHT (window->texture);
// Source coords in VA surface
x0 = 0.0f;
y0 = 0.0f;
x1 = 1.0f;
y1 = 1.0f;
texcoords[0][0] = x0;
texcoords[0][1] = y1;
texcoords[1][0] = x1;
texcoords[1][1] = y1;
texcoords[2][0] = x1;
texcoords[2][1] = y0;
texcoords[3][0] = x0;
texcoords[3][1] = y0;
// Target coords in EGL surface
x0 = 2.0f * ((GLfloat) rect->x / tex_width) - 1.0f;
y1 = -2.0f * ((GLfloat) rect->y / tex_height) + 1.0f;
x1 = 2.0f * ((GLfloat) (rect->x + rect->width) / tex_width) - 1.0f;
y0 = -2.0f * ((GLfloat) (rect->y + rect->height) / tex_height) + 1.0f;
positions[0][0] = x0;
positions[0][1] = y0;
positions[1][0] = x1;
positions[1][1] = y0;
positions[2][0] = x1;
positions[2][1] = y1;
positions[3][0] = x0;
positions[3][1] = y1;
vtable->glClear (GL_COLOR_BUFFER_BIT);
if (G_UNLIKELY (window->egl_window->context->config->gles_version == 1)) {
vtable->glBindTexture (GST_VAAPI_TEXTURE_TARGET (window->texture), tex_id);
vtable->glEnableClientState (GL_VERTEX_ARRAY);
vtable->glVertexPointer (2, GL_FLOAT, 0, positions);
vtable->glEnableClientState (GL_TEXTURE_COORD_ARRAY);
vtable->glTexCoordPointer (2, GL_FLOAT, 0, texcoords);
vtable->glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
vtable->glDisableClientState (GL_VERTEX_ARRAY);
vtable->glDisableClientState (GL_TEXTURE_COORD_ARRAY);
} else {
EglProgram *const program = window->render_program;
vtable->glUseProgram (program->base.handle.u);
vtable->glUniformMatrix4fv (program->uniforms[RENDER_PROGRAM_VAR_PROJ],
1, GL_FALSE, window->render_projection);
vtable->glEnableVertexAttribArray (0);
vtable->glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, 0, positions);
vtable->glEnableVertexAttribArray (1);
vtable->glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, texcoords);
vtable->glBindTexture (GST_VAAPI_TEXTURE_TARGET (window->texture), tex_id);
vtable->glUniform1i (program->uniforms[RENDER_PROGRAM_VAR_TEX0], 0);
vtable->glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
vtable->glDisableVertexAttribArray (1);
vtable->glDisableVertexAttribArray (0);
vtable->glUseProgram (0);
}
eglSwapBuffers (window->egl_window->context->display->base.handle.p,
window->egl_window->base.handle.p);
return TRUE;
}
static gboolean
do_upload_surface_unlocked (GstVaapiWindowEGL * window,
GstVaapiSurface * surface, const GstVaapiRectangle * src_rect,
const GstVaapiRectangle * dst_rect, guint flags)
{
if (!ensure_texture (window, dst_rect->width, dst_rect->height))
return FALSE;
if (!gst_vaapi_texture_put_surface (window->texture, surface, src_rect,
flags))
return FALSE;
if (!do_render_texture (window, dst_rect))
return FALSE;
return TRUE;
}
static void
do_upload_surface (UploadSurfaceArgs * args)
{
GstVaapiWindowEGL *const window = args->window;
EglContextState old_cs;
args->success = FALSE;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window);
if (egl_context_set_current (window->egl_window->context, TRUE, &old_cs)) {
args->success = do_upload_surface_unlocked (window, args->surface,
args->src_rect, args->dst_rect, args->flags);
egl_context_set_current (window->egl_window->context, FALSE, &old_cs);
}
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window);
}
static gboolean
gst_vaapi_window_egl_render (GstVaapiWindowEGL * window,
GstVaapiSurface * surface, const GstVaapiRectangle * src_rect,
const GstVaapiRectangle * dst_rect, guint flags)
{
UploadSurfaceArgs args = { window, surface, src_rect, dst_rect, flags };
return egl_context_run (window->egl_window->context,
(EglContextRunFunc) do_upload_surface, &args) && args.success;
}
static gboolean
gst_vaapi_window_egl_render_pixmap (GstVaapiWindowEGL * window,
GstVaapiPixmap * pixmap,
const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect)
{
const GstVaapiWindowClass *const klass =
GST_VAAPI_WINDOW_GET_CLASS (window->window);
if (!klass->render_pixmap)
return FALSE;
return klass->render_pixmap (window->window, pixmap, src_rect, dst_rect);
}
void
gst_vaapi_window_egl_class_init (GstVaapiWindowEGLClass * klass)
{
GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass);
GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass);
object_class->finalize = (GstVaapiObjectFinalizeFunc)
gst_vaapi_window_egl_destroy;
window_class->create = (GstVaapiWindowCreateFunc)
gst_vaapi_window_egl_create;
window_class->show = (GstVaapiWindowShowFunc)
gst_vaapi_window_egl_show;
window_class->hide = (GstVaapiWindowHideFunc)
gst_vaapi_window_egl_hide;
window_class->get_geometry = (GstVaapiWindowGetGeometryFunc)
gst_vaapi_window_egl_get_geometry;
window_class->set_fullscreen = (GstVaapiWindowSetFullscreenFunc)
gst_vaapi_window_egl_set_fullscreen;
window_class->resize = (GstVaapiWindowResizeFunc)
gst_vaapi_window_egl_resize;
window_class->render = (GstVaapiWindowRenderFunc)
gst_vaapi_window_egl_render;
window_class->render_pixmap = (GstVaapiWindowRenderPixmapFunc)
gst_vaapi_window_egl_render_pixmap;
}
#define gst_vaapi_window_egl_finalize \
gst_vaapi_window_egl_destroy
GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowEGL,
gst_vaapi_window_egl, gst_vaapi_window_egl_class_init (&g_class));
/**
* gst_vaapi_window_egl_new:
* @display: a #GstVaapiDisplay
* @width: the requested window width, in pixels
* @height: the requested windo height, in pixels
*
* Creates a window with the specified @width and @height. The window
* will be attached to the @display and remains invisible to the user
* until gst_vaapi_window_show() is called.
*
* Return value: the newly allocated #GstVaapiWindow object
*/
GstVaapiWindow *
gst_vaapi_window_egl_new (GstVaapiDisplay * display, guint width, guint height)
{
GST_DEBUG ("new window, size %ux%u", width, height);
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), NULL);
return
gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS
(gst_vaapi_window_egl_class ()), display, GST_VAAPI_ID_INVALID, width,
height);
}

View file

@ -0,0 +1,39 @@
/*
* gstvaapiwindow_egl.h - VA/EGL window abstraction
*
* Copyright (C) 2014 Intel Corporation
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
*
* 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
*/
#ifndef GST_VAAPI_WINDOW_EGL_H
#define GST_VAAPI_WINDOW_EGL_H
#include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapiwindow.h>
G_BEGIN_DECLS
#define GST_VAAPI_WINDOW_EGL(obj) \
((GstVaapiWindowEGL *)(obj))
GstVaapiWindow *
gst_vaapi_window_egl_new (GstVaapiDisplay * display, guint width, guint height);
G_END_DECLS
#endif /* GST_VAAPI_WINDOW_EGL_H */