mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-04 13:32:29 +00:00
Add VA context abstraction.
This commit is contained in:
parent
6cb6c387e9
commit
ecf60d2284
2 changed files with 794 additions and 0 deletions
662
gst-libs/gst/vaapi/gstvaapicontext.c
Normal file
662
gst-libs/gst/vaapi/gstvaapicontext.c
Normal file
|
@ -0,0 +1,662 @@
|
|||
/*
|
||||
* gstvaapicontext.c - VA context abstraction
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstvaapicontext
|
||||
* @short_description: VA context abstraction
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <assert.h>
|
||||
#include "gstvaapicompat.h"
|
||||
#include "gstvaapicontext.h"
|
||||
#include "gstvaapisurfacepool.h"
|
||||
#include "gstvaapiutils.h"
|
||||
#include "gstvaapi_priv.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
G_DEFINE_TYPE(GstVaapiContext, gst_vaapi_context, GST_VAAPI_TYPE_OBJECT);
|
||||
|
||||
#define GST_VAAPI_CONTEXT_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
|
||||
GST_VAAPI_TYPE_CONTEXT, \
|
||||
GstVaapiContextPrivate))
|
||||
|
||||
/* XXX: optimize for the effective number of reference frames */
|
||||
struct _GstVaapiContextPrivate {
|
||||
VAConfigID config_id;
|
||||
GPtrArray *surfaces;
|
||||
GstVaapiVideoPool *surfaces_pool;
|
||||
GstVaapiProfile profile;
|
||||
GstVaapiEntrypoint entrypoint;
|
||||
guint width;
|
||||
guint height;
|
||||
guint is_constructed : 1;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
PROP_PROFILE,
|
||||
PROP_ENTRYPOINT,
|
||||
PROP_WIDTH,
|
||||
PROP_HEIGHT
|
||||
};
|
||||
|
||||
static void
|
||||
unref_surface_cb(gpointer data, gpointer user_data)
|
||||
{
|
||||
g_object_unref(GST_VAAPI_SURFACE(data));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_context_destroy_surfaces(GstVaapiContext *context)
|
||||
{
|
||||
GstVaapiContextPrivate * const priv = context->priv;
|
||||
|
||||
if (priv->surfaces) {
|
||||
g_ptr_array_foreach(priv->surfaces, unref_surface_cb, NULL);
|
||||
g_ptr_array_free(priv->surfaces, TRUE);
|
||||
priv->surfaces = NULL;
|
||||
}
|
||||
|
||||
if (priv->surfaces_pool) {
|
||||
g_object_unref(priv->surfaces_pool);
|
||||
priv->surfaces_pool = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_context_destroy(GstVaapiContext *context)
|
||||
{
|
||||
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context);
|
||||
GstVaapiContextPrivate * const priv = context->priv;
|
||||
VAContextID context_id;
|
||||
VAStatus status;
|
||||
|
||||
context_id = GST_VAAPI_OBJECT_ID(context);
|
||||
GST_DEBUG("context %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(context_id));
|
||||
|
||||
if (context_id != VA_INVALID_ID) {
|
||||
GST_VAAPI_DISPLAY_LOCK(display);
|
||||
status = vaDestroyContext(
|
||||
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
||||
context_id
|
||||
);
|
||||
GST_VAAPI_DISPLAY_UNLOCK(display);
|
||||
if (!vaapi_check_status(status, "vaDestroyContext()"))
|
||||
g_warning("failed to destroy context %" GST_VAAPI_ID_FORMAT,
|
||||
GST_VAAPI_ID_ARGS(context_id));
|
||||
GST_VAAPI_OBJECT_ID(context) = VA_INVALID_ID;
|
||||
}
|
||||
|
||||
if (priv->config_id != VA_INVALID_ID) {
|
||||
GST_VAAPI_DISPLAY_LOCK(display);
|
||||
status = vaDestroyConfig(
|
||||
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
||||
priv->config_id
|
||||
);
|
||||
GST_VAAPI_DISPLAY_UNLOCK(display);
|
||||
if (!vaapi_check_status(status, "vaDestroyConfig()"))
|
||||
g_warning("failed to destroy config %" GST_VAAPI_ID_FORMAT,
|
||||
GST_VAAPI_ID_ARGS(priv->config_id));
|
||||
priv->config_id = VA_INVALID_ID;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_context_create_surfaces(GstVaapiContext *context)
|
||||
{
|
||||
GstVaapiContextPrivate * const priv = context->priv;
|
||||
GstCaps *caps;
|
||||
GstVaapiSurface *surface;
|
||||
guint i, num_ref_frames, num_surfaces;
|
||||
|
||||
/* Number of scratch surfaces beyond those used as reference */
|
||||
const guint SCRATCH_SURFACES_COUNT = 4;
|
||||
|
||||
if (!priv->surfaces) {
|
||||
priv->surfaces = g_ptr_array_new();
|
||||
if (!priv->surfaces)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!priv->surfaces_pool) {
|
||||
caps = gst_caps_new_simple(
|
||||
"video/x-vaapi-surface",
|
||||
"width", G_TYPE_INT, priv->width,
|
||||
"height", G_TYPE_INT, priv->height,
|
||||
NULL
|
||||
);
|
||||
if (!caps)
|
||||
return FALSE;
|
||||
priv->surfaces_pool = gst_vaapi_surface_pool_new(
|
||||
GST_VAAPI_OBJECT_DISPLAY(context),
|
||||
caps
|
||||
);
|
||||
gst_caps_unref(caps);
|
||||
if (!priv->surfaces_pool)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
num_ref_frames = 2;
|
||||
if (gst_vaapi_profile_get_codec(priv->profile) == GST_VAAPI_CODEC_H264)
|
||||
num_ref_frames = 16;
|
||||
num_surfaces = num_ref_frames + SCRATCH_SURFACES_COUNT;
|
||||
|
||||
gst_vaapi_video_pool_set_capacity(priv->surfaces_pool, num_surfaces);
|
||||
|
||||
for (i = priv->surfaces->len; i < num_surfaces; i++) {
|
||||
surface = gst_vaapi_surface_new(
|
||||
GST_VAAPI_OBJECT_DISPLAY(context),
|
||||
GST_VAAPI_CHROMA_TYPE_YUV420,
|
||||
priv->width, priv->height
|
||||
);
|
||||
if (!surface)
|
||||
return FALSE;
|
||||
g_ptr_array_add(priv->surfaces, surface);
|
||||
if (!gst_vaapi_video_pool_add_object(priv->surfaces_pool, surface))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_context_create(GstVaapiContext *context)
|
||||
{
|
||||
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context);
|
||||
GstVaapiContextPrivate * const priv = context->priv;
|
||||
VAProfile va_profile;
|
||||
VAEntrypoint va_entrypoint;
|
||||
VAConfigAttrib attrib;
|
||||
VAContextID context_id;
|
||||
VASurfaceID surface_id;
|
||||
VAStatus status;
|
||||
GArray *surfaces = NULL;
|
||||
gboolean success = FALSE;
|
||||
guint i;
|
||||
|
||||
if (!priv->surfaces && !gst_vaapi_context_create_surfaces(context))
|
||||
goto end;
|
||||
|
||||
surfaces = g_array_sized_new(
|
||||
FALSE,
|
||||
FALSE,
|
||||
sizeof(VASurfaceID),
|
||||
priv->surfaces->len
|
||||
);
|
||||
if (!surfaces)
|
||||
goto end;
|
||||
|
||||
for (i = 0; i < priv->surfaces->len; i++) {
|
||||
GstVaapiSurface * const surface = g_ptr_array_index(priv->surfaces, i);
|
||||
if (!surface)
|
||||
goto end;
|
||||
surface_id = GST_VAAPI_OBJECT_ID(surface);
|
||||
g_array_append_val(surfaces, surface_id);
|
||||
}
|
||||
assert(surfaces->len == priv->surfaces->len);
|
||||
|
||||
if (!priv->profile || !priv->entrypoint)
|
||||
goto end;
|
||||
va_profile = gst_vaapi_profile_get_va_profile(priv->profile);
|
||||
va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint(priv->entrypoint);
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK(display);
|
||||
attrib.type = VAConfigAttribRTFormat;
|
||||
status = vaGetConfigAttributes(
|
||||
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
||||
va_profile,
|
||||
va_entrypoint,
|
||||
&attrib, 1
|
||||
);
|
||||
GST_VAAPI_DISPLAY_UNLOCK(display);
|
||||
if (!vaapi_check_status(status, "vaGetConfigAttributes()"))
|
||||
goto end;
|
||||
if (!(attrib.value & VA_RT_FORMAT_YUV420))
|
||||
goto end;
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK(display);
|
||||
status = vaCreateConfig(
|
||||
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
||||
va_profile,
|
||||
va_entrypoint,
|
||||
&attrib, 1,
|
||||
&priv->config_id
|
||||
);
|
||||
GST_VAAPI_DISPLAY_UNLOCK(display);
|
||||
if (!vaapi_check_status(status, "vaCreateConfig()"))
|
||||
goto end;
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK(display);
|
||||
status = vaCreateContext(
|
||||
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
||||
priv->config_id,
|
||||
priv->width, priv->height,
|
||||
VA_PROGRESSIVE,
|
||||
(VASurfaceID *)surfaces->data, surfaces->len,
|
||||
&context_id
|
||||
);
|
||||
GST_VAAPI_DISPLAY_UNLOCK(display);
|
||||
if (!vaapi_check_status(status, "vaCreateContext()"))
|
||||
goto end;
|
||||
|
||||
GST_DEBUG("context %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(context_id));
|
||||
GST_VAAPI_OBJECT_ID(context) = context_id;
|
||||
success = TRUE;
|
||||
end:
|
||||
if (surfaces)
|
||||
g_array_free(surfaces, TRUE);
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_context_finalize(GObject *object)
|
||||
{
|
||||
GstVaapiContext * const context = GST_VAAPI_CONTEXT(object);
|
||||
|
||||
gst_vaapi_context_destroy(context);
|
||||
gst_vaapi_context_destroy_surfaces(context);
|
||||
|
||||
G_OBJECT_CLASS(gst_vaapi_context_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_context_set_property(
|
||||
GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec
|
||||
)
|
||||
{
|
||||
GstVaapiContext * const context = GST_VAAPI_CONTEXT(object);
|
||||
GstVaapiContextPrivate * const priv = context->priv;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PROFILE:
|
||||
gst_vaapi_context_set_profile(context, g_value_get_uint(value));
|
||||
break;
|
||||
case PROP_ENTRYPOINT:
|
||||
priv->entrypoint = g_value_get_uint(value);
|
||||
break;
|
||||
case PROP_WIDTH:
|
||||
priv->width = g_value_get_uint(value);
|
||||
break;
|
||||
case PROP_HEIGHT:
|
||||
priv->height = g_value_get_uint(value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_context_get_property(
|
||||
GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec
|
||||
)
|
||||
{
|
||||
GstVaapiContext * const context = GST_VAAPI_CONTEXT(object);
|
||||
GstVaapiContextPrivate * const priv = context->priv;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PROFILE:
|
||||
g_value_set_uint(value, gst_vaapi_context_get_profile(context));
|
||||
break;
|
||||
case PROP_ENTRYPOINT:
|
||||
g_value_set_uint(value, gst_vaapi_context_get_entrypoint(context));
|
||||
break;
|
||||
case PROP_WIDTH:
|
||||
g_value_set_uint(value, priv->width);
|
||||
break;
|
||||
case PROP_HEIGHT:
|
||||
g_value_set_uint(value, priv->height);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_context_class_init(GstVaapiContextClass *klass)
|
||||
{
|
||||
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
g_type_class_add_private(klass, sizeof(GstVaapiContextPrivate));
|
||||
|
||||
object_class->finalize = gst_vaapi_context_finalize;
|
||||
object_class->set_property = gst_vaapi_context_set_property;
|
||||
object_class->get_property = gst_vaapi_context_get_property;
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class,
|
||||
PROP_PROFILE,
|
||||
g_param_spec_uint("profile",
|
||||
"Profile",
|
||||
"The profile used for decoding",
|
||||
0, G_MAXUINT32, 0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class,
|
||||
PROP_ENTRYPOINT,
|
||||
g_param_spec_uint("entrypoint",
|
||||
"Entrypoint",
|
||||
"The decoder entrypoint",
|
||||
0, G_MAXUINT32, 0,
|
||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class,
|
||||
PROP_WIDTH,
|
||||
g_param_spec_uint("width",
|
||||
"Width",
|
||||
"The width of decoded surfaces",
|
||||
0, G_MAXINT32, 0,
|
||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class,
|
||||
PROP_HEIGHT,
|
||||
g_param_spec_uint("height",
|
||||
"Height",
|
||||
"The height of the decoded surfaces",
|
||||
0, G_MAXINT32, 0,
|
||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_context_init(GstVaapiContext *context)
|
||||
{
|
||||
GstVaapiContextPrivate *priv = GST_VAAPI_CONTEXT_GET_PRIVATE(context);
|
||||
|
||||
context->priv = priv;
|
||||
priv->config_id = VA_INVALID_ID;
|
||||
priv->surfaces = NULL;
|
||||
priv->surfaces_pool = NULL;
|
||||
priv->profile = 0;
|
||||
priv->entrypoint = 0;
|
||||
priv->width = 0;
|
||||
priv->height = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_new:
|
||||
* @display: a #GstVaapiDisplay
|
||||
* @profile: a #GstVaapiProfile
|
||||
* @entrypoint: a #GstVaapiEntrypoint
|
||||
* @width: coded width from the bitstream
|
||||
* @height: coded height from the bitstream
|
||||
*
|
||||
* Creates a new #GstVaapiContext with the specified codec @profile
|
||||
* and @entrypoint.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiContext object
|
||||
*/
|
||||
GstVaapiContext *
|
||||
gst_vaapi_context_new(
|
||||
GstVaapiDisplay *display,
|
||||
GstVaapiProfile profile,
|
||||
GstVaapiEntrypoint entrypoint,
|
||||
unsigned int width,
|
||||
unsigned int height
|
||||
)
|
||||
{
|
||||
GstVaapiContext *context;
|
||||
|
||||
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
|
||||
g_return_val_if_fail(profile, NULL);
|
||||
g_return_val_if_fail(entrypoint, NULL);
|
||||
g_return_val_if_fail(width > 0, NULL);
|
||||
g_return_val_if_fail(height > 0, NULL);
|
||||
|
||||
context = g_object_new(
|
||||
GST_VAAPI_TYPE_CONTEXT,
|
||||
"display", display,
|
||||
"id", GST_VAAPI_ID(VA_INVALID_ID),
|
||||
"profile", profile,
|
||||
"entrypoint", entrypoint,
|
||||
"width", width,
|
||||
"height", height,
|
||||
NULL
|
||||
);
|
||||
if (!context->priv->is_constructed) {
|
||||
g_object_unref(context);
|
||||
return NULL;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_reset:
|
||||
* @context: a #GstVaapiContext
|
||||
* @profile: a #GstVaapiProfile
|
||||
* @entrypoint: a #GstVaapiEntrypoint
|
||||
* @width: coded width from the bitstream
|
||||
* @height: coded height from the bitstream
|
||||
*
|
||||
* Resets @context to the specified codec @profile and @entrypoint.
|
||||
* The surfaces will be reallocated if the coded size changed.
|
||||
*
|
||||
* Return value: %TRUE on success
|
||||
*/
|
||||
gboolean
|
||||
gst_vaapi_context_reset(
|
||||
GstVaapiContext *context,
|
||||
GstVaapiProfile profile,
|
||||
GstVaapiEntrypoint entrypoint,
|
||||
unsigned int width,
|
||||
unsigned int height
|
||||
)
|
||||
{
|
||||
GstVaapiContextPrivate * const priv = context->priv;
|
||||
gboolean size_changed, codec_changed;
|
||||
|
||||
size_changed = priv->width != width || priv->height != height;
|
||||
if (size_changed) {
|
||||
gst_vaapi_context_destroy_surfaces(context);
|
||||
priv->width = width;
|
||||
priv->height = height;
|
||||
}
|
||||
|
||||
codec_changed = priv->profile != profile || priv->entrypoint != entrypoint;
|
||||
if (codec_changed) {
|
||||
gst_vaapi_context_destroy(context);
|
||||
priv->profile = profile;
|
||||
priv->entrypoint = entrypoint;
|
||||
}
|
||||
|
||||
if (size_changed && !gst_vaapi_context_create_surfaces(context))
|
||||
return FALSE;
|
||||
|
||||
if (codec_changed && !gst_vaapi_context_create(context))
|
||||
return FALSE;
|
||||
|
||||
priv->is_constructed = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_get_id:
|
||||
* @context: a #GstVaapiContext
|
||||
*
|
||||
* Returns the underlying VAContextID of the @context.
|
||||
*
|
||||
* Return value: the underlying VA context id
|
||||
*/
|
||||
GstVaapiID
|
||||
gst_vaapi_context_get_id(GstVaapiContext *context)
|
||||
{
|
||||
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), VA_INVALID_ID);
|
||||
|
||||
return GST_VAAPI_OBJECT_ID(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_get_profile:
|
||||
* @context: a #GstVaapiContext
|
||||
*
|
||||
* Returns the VA profile used by the @context.
|
||||
*
|
||||
* Return value: the VA profile used by the @context
|
||||
*/
|
||||
GstVaapiProfile
|
||||
gst_vaapi_context_get_profile(GstVaapiContext *context)
|
||||
{
|
||||
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0);
|
||||
|
||||
return context->priv->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_set_profile:
|
||||
* @context: a #GstVaapiContext
|
||||
* @profile: the new #GstVaapiProfile to use
|
||||
*
|
||||
* Sets the new @profile to use with the @context. If @profile matches
|
||||
* the previous profile, this call has no effect. Otherwise, the
|
||||
* underlying VA context is recreated, while keeping the previously
|
||||
* allocated surfaces.
|
||||
*
|
||||
* Return value: %TRUE on success
|
||||
*/
|
||||
gboolean
|
||||
gst_vaapi_context_set_profile(GstVaapiContext *context, GstVaapiProfile profile)
|
||||
{
|
||||
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), FALSE);
|
||||
g_return_val_if_fail(profile, FALSE);
|
||||
|
||||
return gst_vaapi_context_reset(context,
|
||||
profile,
|
||||
context->priv->entrypoint,
|
||||
context->priv->width,
|
||||
context->priv->height);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_get_entrypoint:
|
||||
* @context: a #GstVaapiContext
|
||||
*
|
||||
* Returns the VA entrypoint used by the @context
|
||||
*
|
||||
* Return value: the VA entrypoint used by the @context
|
||||
*/
|
||||
GstVaapiEntrypoint
|
||||
gst_vaapi_context_get_entrypoint(GstVaapiContext *context)
|
||||
{
|
||||
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0);
|
||||
|
||||
return context->priv->entrypoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_get_size:
|
||||
* @context: a #GstVaapiContext
|
||||
* @pwidth: return location for the width, or %NULL
|
||||
* @pheight: return location for the height, or %NULL
|
||||
*
|
||||
* Retrieves the size of the surfaces attached to @context.
|
||||
*/
|
||||
void
|
||||
gst_vaapi_context_get_size(
|
||||
GstVaapiContext *context,
|
||||
guint *pwidth,
|
||||
guint *pheight
|
||||
)
|
||||
{
|
||||
g_return_if_fail(GST_VAAPI_IS_CONTEXT(context));
|
||||
|
||||
if (pwidth)
|
||||
*pwidth = context->priv->width;
|
||||
|
||||
if (pheight)
|
||||
*pheight = context->priv->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_get_surface:
|
||||
* @context: a #GstVaapiContext
|
||||
*
|
||||
* Acquires a free surface. The returned surface but be released with
|
||||
* gst_vaapi_context_put_surface(). This function returns %NULL if
|
||||
* there is no free surface available in the pool. The surfaces are
|
||||
* pre-allocated during context creation though.
|
||||
*
|
||||
* Return value: a free surface, or %NULL if none is available
|
||||
*/
|
||||
GstVaapiSurface *
|
||||
gst_vaapi_context_get_surface(GstVaapiContext *context)
|
||||
{
|
||||
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL);
|
||||
|
||||
return gst_vaapi_video_pool_get_object(context->priv->surfaces_pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_put_surface:
|
||||
* @context: a #GstVaapiContext
|
||||
* @surface: the #GstVaapiSurface to release
|
||||
*
|
||||
* Releases a surface acquired by gst_vaapi_context_get_surface().
|
||||
*/
|
||||
void
|
||||
gst_vaapi_context_put_surface(GstVaapiContext *context, GstVaapiSurface *surface)
|
||||
{
|
||||
g_return_if_fail(GST_VAAPI_IS_CONTEXT(context));
|
||||
g_return_if_fail(GST_VAAPI_IS_SURFACE(surface));
|
||||
|
||||
gst_vaapi_video_pool_put_object(context->priv->surfaces_pool, surface);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_find_surface_by_id:
|
||||
* @context: a #GstVaapiContext
|
||||
* @id: the VA surface id to find
|
||||
*
|
||||
* Finds VA surface by @id in the list of surfaces attached to the @context.
|
||||
*
|
||||
* Return value: the matching #GstVaapiSurface object, or %NULL if
|
||||
* none was found
|
||||
*/
|
||||
GstVaapiSurface *
|
||||
gst_vaapi_context_find_surface_by_id(GstVaapiContext *context, GstVaapiID id)
|
||||
{
|
||||
GstVaapiContextPrivate *priv;
|
||||
GstVaapiSurface *surface;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL);
|
||||
|
||||
priv = context->priv;
|
||||
g_return_val_if_fail(priv->surfaces, NULL);
|
||||
|
||||
for (i = 0; i < priv->surfaces->len; i++) {
|
||||
surface = g_ptr_array_index(priv->surfaces, i);
|
||||
if (GST_VAAPI_OBJECT_ID(surface) == id)
|
||||
return surface;
|
||||
}
|
||||
return NULL;
|
||||
}
|
132
gst-libs/gst/vaapi/gstvaapicontext.h
Normal file
132
gst-libs/gst/vaapi/gstvaapicontext.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* gstvaapicontext.h - VA context abstraction
|
||||
*
|
||||
* 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_CONTEXT_H
|
||||
#define GST_VAAPI_CONTEXT_H
|
||||
|
||||
#include <gst/vaapi/gstvaapiobject.h>
|
||||
#include <gst/vaapi/gstvaapiprofile.h>
|
||||
#include <gst/vaapi/gstvaapidisplay.h>
|
||||
#include <gst/vaapi/gstvaapisurface.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_TYPE_CONTEXT \
|
||||
(gst_vaapi_context_get_type())
|
||||
|
||||
#define GST_VAAPI_CONTEXT(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
||||
GST_VAAPI_TYPE_CONTEXT, \
|
||||
GstVaapiContext))
|
||||
|
||||
#define GST_VAAPI_CONTEXT_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass), \
|
||||
GST_VAAPI_TYPE_CONTEXT, \
|
||||
GstVaapiContextClass))
|
||||
|
||||
#define GST_VAAPI_IS_CONTEXT(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_CONTEXT))
|
||||
|
||||
#define GST_VAAPI_IS_CONTEXT_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_CONTEXT))
|
||||
|
||||
#define GST_VAAPI_CONTEXT_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS((obj), \
|
||||
GST_VAAPI_TYPE_CONTEXT, \
|
||||
GstVaapiContextClass))
|
||||
|
||||
typedef struct _GstVaapiContext GstVaapiContext;
|
||||
typedef struct _GstVaapiContextPrivate GstVaapiContextPrivate;
|
||||
typedef struct _GstVaapiContextClass GstVaapiContextClass;
|
||||
|
||||
/**
|
||||
* GstVaapiContext:
|
||||
*
|
||||
* A VA context wrapper.
|
||||
*/
|
||||
struct _GstVaapiContext {
|
||||
/*< private >*/
|
||||
GstVaapiObject parent_instance;
|
||||
|
||||
GstVaapiContextPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiContextClass:
|
||||
*
|
||||
* A VA context wrapper class.
|
||||
*/
|
||||
struct _GstVaapiContextClass {
|
||||
/*< private >*/
|
||||
GstVaapiObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType
|
||||
gst_vaapi_context_get_type(void);
|
||||
|
||||
GstVaapiContext *
|
||||
gst_vaapi_context_new(
|
||||
GstVaapiDisplay *display,
|
||||
GstVaapiProfile profile,
|
||||
GstVaapiEntrypoint entrypoint,
|
||||
guint width,
|
||||
guint height
|
||||
);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_context_reset(
|
||||
GstVaapiContext *context,
|
||||
GstVaapiProfile profile,
|
||||
GstVaapiEntrypoint entrypoint,
|
||||
unsigned int width,
|
||||
unsigned int height
|
||||
);
|
||||
|
||||
GstVaapiID
|
||||
gst_vaapi_context_get_id(GstVaapiContext *context);
|
||||
|
||||
GstVaapiProfile
|
||||
gst_vaapi_context_get_profile(GstVaapiContext *context);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_context_set_profile(GstVaapiContext *context, GstVaapiProfile profile);
|
||||
|
||||
GstVaapiEntrypoint
|
||||
gst_vaapi_context_get_entrypoint(GstVaapiContext *context);
|
||||
|
||||
void
|
||||
gst_vaapi_context_get_size(
|
||||
GstVaapiContext *context,
|
||||
guint *pwidth,
|
||||
guint *pheight
|
||||
);
|
||||
|
||||
GstVaapiSurface *
|
||||
gst_vaapi_context_get_surface(GstVaapiContext *context);
|
||||
|
||||
void
|
||||
gst_vaapi_context_put_surface(GstVaapiContext *context, GstVaapiSurface *surface);
|
||||
|
||||
GstVaapiSurface *
|
||||
gst_vaapi_context_find_surface_by_id(GstVaapiContext *context, GstVaapiID id);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_CONTEXT_H */
|
Loading…
Reference in a new issue