mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
libs: use GstVaapiObject for VA objects.
This commit is contained in:
parent
1f15c28a1b
commit
6c46179709
11 changed files with 385 additions and 1182 deletions
|
@ -29,25 +29,46 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "gstvaapicompat.h"
|
#include "gstvaapicompat.h"
|
||||||
#include "gstvaapicontext.h"
|
#include "gstvaapicontext.h"
|
||||||
|
#include "gstvaapiobject_priv.h"
|
||||||
#include "gstvaapisurface.h"
|
#include "gstvaapisurface.h"
|
||||||
#include "gstvaapisurface_priv.h"
|
#include "gstvaapisurface_priv.h"
|
||||||
#include "gstvaapisurfacepool.h"
|
#include "gstvaapisurfacepool.h"
|
||||||
#include "gstvaapisurfaceproxy.h"
|
#include "gstvaapisurfaceproxy.h"
|
||||||
#include "gstvaapiimage.h"
|
#include "gstvaapiimage.h"
|
||||||
#include "gstvaapisubpicture.h"
|
#include "gstvaapisubpicture.h"
|
||||||
#include "gstvaapiminiobject.h"
|
|
||||||
#include "gstvaapiutils.h"
|
#include "gstvaapiutils.h"
|
||||||
#include "gstvaapi_priv.h"
|
|
||||||
|
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
#include "gstvaapidebug.h"
|
#include "gstvaapidebug.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE(GstVaapiContext, gst_vaapi_context, GST_VAAPI_TYPE_OBJECT)
|
typedef struct _GstVaapiContextClass GstVaapiContextClass;
|
||||||
|
|
||||||
#define GST_VAAPI_CONTEXT_GET_PRIVATE(obj) \
|
/**
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
|
* GstVaapiContext:
|
||||||
GST_VAAPI_TYPE_CONTEXT, \
|
*
|
||||||
GstVaapiContextPrivate))
|
* A VA context wrapper.
|
||||||
|
*/
|
||||||
|
struct _GstVaapiContext {
|
||||||
|
/*< private >*/
|
||||||
|
GstVaapiObject parent_instance;
|
||||||
|
|
||||||
|
GstVaapiContextInfo info;
|
||||||
|
VAConfigID config_id;
|
||||||
|
GPtrArray *surfaces;
|
||||||
|
GstVaapiVideoPool *surfaces_pool;
|
||||||
|
GPtrArray *overlays[2];
|
||||||
|
guint overlay_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstVaapiContextClass:
|
||||||
|
*
|
||||||
|
* A VA context wrapper class.
|
||||||
|
*/
|
||||||
|
struct _GstVaapiContextClass {
|
||||||
|
/*< private >*/
|
||||||
|
GstVaapiObjectClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct _GstVaapiOverlayRectangle GstVaapiOverlayRectangle;
|
typedef struct _GstVaapiOverlayRectangle GstVaapiOverlayRectangle;
|
||||||
struct _GstVaapiOverlayRectangle {
|
struct _GstVaapiOverlayRectangle {
|
||||||
|
@ -61,31 +82,6 @@ struct _GstVaapiOverlayRectangle {
|
||||||
guint is_associated : 1;
|
guint is_associated : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* XXX: optimize for the effective number of reference frames */
|
|
||||||
struct _GstVaapiContextPrivate {
|
|
||||||
VAConfigID config_id;
|
|
||||||
GPtrArray *surfaces;
|
|
||||||
GstVaapiVideoPool *surfaces_pool;
|
|
||||||
GPtrArray *overlays[2];
|
|
||||||
guint overlay_id;
|
|
||||||
GstVaapiProfile profile;
|
|
||||||
GstVaapiEntrypoint entrypoint;
|
|
||||||
guint width;
|
|
||||||
guint height;
|
|
||||||
guint ref_frames;
|
|
||||||
guint is_constructed : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PROP_0,
|
|
||||||
|
|
||||||
PROP_PROFILE,
|
|
||||||
PROP_ENTRYPOINT,
|
|
||||||
PROP_WIDTH,
|
|
||||||
PROP_HEIGHT,
|
|
||||||
PROP_REF_FRAMES
|
|
||||||
};
|
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
get_max_ref_frames(GstVaapiProfile profile)
|
get_max_ref_frames(GstVaapiProfile profile)
|
||||||
{
|
{
|
||||||
|
@ -188,7 +184,7 @@ overlay_rectangle_finalize(GstVaapiOverlayRectangle *overlay)
|
||||||
|
|
||||||
if (overlay->subpicture) {
|
if (overlay->subpicture) {
|
||||||
overlay_rectangle_deassociate(overlay);
|
overlay_rectangle_deassociate(overlay);
|
||||||
g_object_unref(overlay->subpicture);
|
gst_vaapi_object_unref(overlay->subpicture);
|
||||||
overlay->subpicture = NULL;
|
overlay->subpicture = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,7 +193,7 @@ static gboolean
|
||||||
overlay_rectangle_associate(GstVaapiOverlayRectangle *overlay)
|
overlay_rectangle_associate(GstVaapiOverlayRectangle *overlay)
|
||||||
{
|
{
|
||||||
GstVaapiSubpicture * const subpicture = overlay->subpicture;
|
GstVaapiSubpicture * const subpicture = overlay->subpicture;
|
||||||
GPtrArray * const surfaces = overlay->context->priv->surfaces;
|
GPtrArray * const surfaces = overlay->context->surfaces;
|
||||||
guint i, n_associated;
|
guint i, n_associated;
|
||||||
|
|
||||||
if (overlay->is_associated)
|
if (overlay->is_associated)
|
||||||
|
@ -219,7 +215,7 @@ static gboolean
|
||||||
overlay_rectangle_deassociate(GstVaapiOverlayRectangle *overlay)
|
overlay_rectangle_deassociate(GstVaapiOverlayRectangle *overlay)
|
||||||
{
|
{
|
||||||
GstVaapiSubpicture * const subpicture = overlay->subpicture;
|
GstVaapiSubpicture * const subpicture = overlay->subpicture;
|
||||||
GPtrArray * const surfaces = overlay->context->priv->surfaces;
|
GPtrArray * const surfaces = overlay->context->surfaces;
|
||||||
guint i, n_associated;
|
guint i, n_associated;
|
||||||
|
|
||||||
if (!overlay->is_associated)
|
if (!overlay->is_associated)
|
||||||
|
@ -388,11 +384,9 @@ overlay_reassociate(GPtrArray *overlays)
|
||||||
static void
|
static void
|
||||||
gst_vaapi_context_clear_overlay(GstVaapiContext *context)
|
gst_vaapi_context_clear_overlay(GstVaapiContext *context)
|
||||||
{
|
{
|
||||||
GstVaapiContextPrivate * const priv = context->priv;
|
overlay_clear(context->overlays[0]);
|
||||||
|
overlay_clear(context->overlays[1]);
|
||||||
overlay_clear(priv->overlays[0]);
|
context->overlay_id = 0;
|
||||||
overlay_clear(priv->overlays[1]);
|
|
||||||
priv->overlay_id = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -407,30 +401,26 @@ unref_surface_cb(gpointer data, gpointer user_data)
|
||||||
GstVaapiSurface * const surface = GST_VAAPI_SURFACE(data);
|
GstVaapiSurface * const surface = GST_VAAPI_SURFACE(data);
|
||||||
|
|
||||||
gst_vaapi_surface_set_parent_context(surface, NULL);
|
gst_vaapi_surface_set_parent_context(surface, NULL);
|
||||||
g_object_unref(surface);
|
gst_vaapi_object_unref(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vaapi_context_destroy_surfaces(GstVaapiContext *context)
|
gst_vaapi_context_destroy_surfaces(GstVaapiContext *context)
|
||||||
{
|
{
|
||||||
GstVaapiContextPrivate * const priv = context->priv;
|
|
||||||
|
|
||||||
gst_vaapi_context_destroy_overlay(context);
|
gst_vaapi_context_destroy_overlay(context);
|
||||||
|
|
||||||
if (priv->surfaces) {
|
if (context->surfaces) {
|
||||||
g_ptr_array_foreach(priv->surfaces, unref_surface_cb, NULL);
|
g_ptr_array_foreach(context->surfaces, unref_surface_cb, NULL);
|
||||||
g_ptr_array_free(priv->surfaces, TRUE);
|
g_ptr_array_free(context->surfaces, TRUE);
|
||||||
priv->surfaces = NULL;
|
context->surfaces = NULL;
|
||||||
}
|
}
|
||||||
|
g_clear_object(&context->surfaces_pool);
|
||||||
g_clear_object(&priv->surfaces_pool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vaapi_context_destroy(GstVaapiContext *context)
|
gst_vaapi_context_destroy(GstVaapiContext *context)
|
||||||
{
|
{
|
||||||
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context);
|
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context);
|
||||||
GstVaapiContextPrivate * const priv = context->priv;
|
|
||||||
VAContextID context_id;
|
VAContextID context_id;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
|
|
||||||
|
@ -450,26 +440,24 @@ gst_vaapi_context_destroy(GstVaapiContext *context)
|
||||||
GST_VAAPI_OBJECT_ID(context) = VA_INVALID_ID;
|
GST_VAAPI_OBJECT_ID(context) = VA_INVALID_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->config_id != VA_INVALID_ID) {
|
if (context->config_id != VA_INVALID_ID) {
|
||||||
GST_VAAPI_DISPLAY_LOCK(display);
|
GST_VAAPI_DISPLAY_LOCK(display);
|
||||||
status = vaDestroyConfig(
|
status = vaDestroyConfig(
|
||||||
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
||||||
priv->config_id
|
context->config_id
|
||||||
);
|
);
|
||||||
GST_VAAPI_DISPLAY_UNLOCK(display);
|
GST_VAAPI_DISPLAY_UNLOCK(display);
|
||||||
if (!vaapi_check_status(status, "vaDestroyConfig()"))
|
if (!vaapi_check_status(status, "vaDestroyConfig()"))
|
||||||
g_warning("failed to destroy config %" GST_VAAPI_ID_FORMAT,
|
g_warning("failed to destroy config %" GST_VAAPI_ID_FORMAT,
|
||||||
GST_VAAPI_ID_ARGS(priv->config_id));
|
GST_VAAPI_ID_ARGS(context->config_id));
|
||||||
priv->config_id = VA_INVALID_ID;
|
context->config_id = VA_INVALID_ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vaapi_context_create_overlay(GstVaapiContext *context)
|
gst_vaapi_context_create_overlay(GstVaapiContext *context)
|
||||||
{
|
{
|
||||||
GstVaapiContextPrivate * const priv = context->priv;
|
if (!context->overlays[0] || !context->overlays[1])
|
||||||
|
|
||||||
if (!priv->overlays[0] || !priv->overlays[1])
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
gst_vaapi_context_clear_overlay(context);
|
gst_vaapi_context_clear_overlay(context);
|
||||||
|
@ -479,7 +467,7 @@ gst_vaapi_context_create_overlay(GstVaapiContext *context)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vaapi_context_create_surfaces(GstVaapiContext *context)
|
gst_vaapi_context_create_surfaces(GstVaapiContext *context)
|
||||||
{
|
{
|
||||||
GstVaapiContextPrivate * const priv = context->priv;
|
const GstVaapiContextInfo * const cip = &context->info;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstVaapiSurface *surface;
|
GstVaapiSurface *surface;
|
||||||
guint i, num_surfaces;
|
guint i, num_surfaces;
|
||||||
|
@ -490,45 +478,45 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context)
|
||||||
if (!gst_vaapi_context_create_overlay(context))
|
if (!gst_vaapi_context_create_overlay(context))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!priv->surfaces) {
|
if (!context->surfaces) {
|
||||||
priv->surfaces = g_ptr_array_new();
|
context->surfaces = g_ptr_array_new();
|
||||||
if (!priv->surfaces)
|
if (!context->surfaces)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!priv->surfaces_pool) {
|
if (!context->surfaces_pool) {
|
||||||
caps = gst_caps_new_simple(
|
caps = gst_caps_new_simple(
|
||||||
GST_VAAPI_SURFACE_CAPS_NAME,
|
GST_VAAPI_SURFACE_CAPS_NAME,
|
||||||
"type", G_TYPE_STRING, "vaapi",
|
"type", G_TYPE_STRING, "vaapi",
|
||||||
"width", G_TYPE_INT, priv->width,
|
"width", G_TYPE_INT, cip->width,
|
||||||
"height", G_TYPE_INT, priv->height,
|
"height", G_TYPE_INT, cip->height,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (!caps)
|
if (!caps)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
priv->surfaces_pool = gst_vaapi_surface_pool_new(
|
context->surfaces_pool = gst_vaapi_surface_pool_new(
|
||||||
GST_VAAPI_OBJECT_DISPLAY(context),
|
GST_VAAPI_OBJECT_DISPLAY(context),
|
||||||
caps
|
caps
|
||||||
);
|
);
|
||||||
gst_caps_unref(caps);
|
gst_caps_unref(caps);
|
||||||
if (!priv->surfaces_pool)
|
if (!context->surfaces_pool)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_surfaces = priv->ref_frames + SCRATCH_SURFACES_COUNT;
|
num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT;
|
||||||
gst_vaapi_video_pool_set_capacity(priv->surfaces_pool, num_surfaces);
|
gst_vaapi_video_pool_set_capacity(context->surfaces_pool, num_surfaces);
|
||||||
|
|
||||||
for (i = priv->surfaces->len; i < num_surfaces; i++) {
|
for (i = context->surfaces->len; i < num_surfaces; i++) {
|
||||||
surface = gst_vaapi_surface_new(
|
surface = gst_vaapi_surface_new(
|
||||||
GST_VAAPI_OBJECT_DISPLAY(context),
|
GST_VAAPI_OBJECT_DISPLAY(context),
|
||||||
GST_VAAPI_CHROMA_TYPE_YUV420,
|
GST_VAAPI_CHROMA_TYPE_YUV420,
|
||||||
priv->width, priv->height
|
cip->width, cip->height
|
||||||
);
|
);
|
||||||
if (!surface)
|
if (!surface)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
gst_vaapi_surface_set_parent_context(surface, context);
|
gst_vaapi_surface_set_parent_context(surface, context);
|
||||||
g_ptr_array_add(priv->surfaces, surface);
|
g_ptr_array_add(context->surfaces, surface);
|
||||||
if (!gst_vaapi_video_pool_add_object(priv->surfaces_pool, surface))
|
if (!gst_vaapi_video_pool_add_object(context->surfaces_pool, surface))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -537,8 +525,8 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vaapi_context_create(GstVaapiContext *context)
|
gst_vaapi_context_create(GstVaapiContext *context)
|
||||||
{
|
{
|
||||||
|
const GstVaapiContextInfo * const cip = &context->info;
|
||||||
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context);
|
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context);
|
||||||
GstVaapiContextPrivate * const priv = context->priv;
|
|
||||||
VAProfile va_profile;
|
VAProfile va_profile;
|
||||||
VAEntrypoint va_entrypoint;
|
VAEntrypoint va_entrypoint;
|
||||||
VAConfigAttrib attrib;
|
VAConfigAttrib attrib;
|
||||||
|
@ -549,31 +537,32 @@ gst_vaapi_context_create(GstVaapiContext *context)
|
||||||
gboolean success = FALSE;
|
gboolean success = FALSE;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
if (!priv->surfaces && !gst_vaapi_context_create_surfaces(context))
|
if (!context->surfaces && !gst_vaapi_context_create_surfaces(context))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
surfaces = g_array_sized_new(
|
surfaces = g_array_sized_new(
|
||||||
FALSE,
|
FALSE,
|
||||||
FALSE,
|
FALSE,
|
||||||
sizeof(VASurfaceID),
|
sizeof(VASurfaceID),
|
||||||
priv->surfaces->len
|
context->surfaces->len
|
||||||
);
|
);
|
||||||
if (!surfaces)
|
if (!surfaces)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
for (i = 0; i < priv->surfaces->len; i++) {
|
for (i = 0; i < context->surfaces->len; i++) {
|
||||||
GstVaapiSurface * const surface = g_ptr_array_index(priv->surfaces, i);
|
GstVaapiSurface * const surface =
|
||||||
|
g_ptr_array_index(context->surfaces, i);
|
||||||
if (!surface)
|
if (!surface)
|
||||||
goto end;
|
goto end;
|
||||||
surface_id = GST_VAAPI_OBJECT_ID(surface);
|
surface_id = GST_VAAPI_OBJECT_ID(surface);
|
||||||
g_array_append_val(surfaces, surface_id);
|
g_array_append_val(surfaces, surface_id);
|
||||||
}
|
}
|
||||||
assert(surfaces->len == priv->surfaces->len);
|
assert(surfaces->len == context->surfaces->len);
|
||||||
|
|
||||||
if (!priv->profile || !priv->entrypoint)
|
if (!cip->profile || !cip->entrypoint)
|
||||||
goto end;
|
goto end;
|
||||||
va_profile = gst_vaapi_profile_get_va_profile(priv->profile);
|
va_profile = gst_vaapi_profile_get_va_profile(cip->profile);
|
||||||
va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint(priv->entrypoint);
|
va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint(cip->entrypoint);
|
||||||
|
|
||||||
GST_VAAPI_DISPLAY_LOCK(display);
|
GST_VAAPI_DISPLAY_LOCK(display);
|
||||||
attrib.type = VAConfigAttribRTFormat;
|
attrib.type = VAConfigAttribRTFormat;
|
||||||
|
@ -595,7 +584,7 @@ gst_vaapi_context_create(GstVaapiContext *context)
|
||||||
va_profile,
|
va_profile,
|
||||||
va_entrypoint,
|
va_entrypoint,
|
||||||
&attrib, 1,
|
&attrib, 1,
|
||||||
&priv->config_id
|
&context->config_id
|
||||||
);
|
);
|
||||||
GST_VAAPI_DISPLAY_UNLOCK(display);
|
GST_VAAPI_DISPLAY_UNLOCK(display);
|
||||||
if (!vaapi_check_status(status, "vaCreateConfig()"))
|
if (!vaapi_check_status(status, "vaCreateConfig()"))
|
||||||
|
@ -604,8 +593,8 @@ gst_vaapi_context_create(GstVaapiContext *context)
|
||||||
GST_VAAPI_DISPLAY_LOCK(display);
|
GST_VAAPI_DISPLAY_LOCK(display);
|
||||||
status = vaCreateContext(
|
status = vaCreateContext(
|
||||||
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
||||||
priv->config_id,
|
context->config_id,
|
||||||
priv->width, priv->height,
|
cip->width, cip->height,
|
||||||
VA_PROGRESSIVE,
|
VA_PROGRESSIVE,
|
||||||
(VASurfaceID *)surfaces->data, surfaces->len,
|
(VASurfaceID *)surfaces->data, surfaces->len,
|
||||||
&context_id
|
&context_id
|
||||||
|
@ -623,160 +612,25 @@ end:
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static inline void
|
||||||
gst_vaapi_context_finalize(GObject *object)
|
gst_vaapi_context_init(GstVaapiContext *context, const GstVaapiContextInfo *cip)
|
||||||
{
|
{
|
||||||
GstVaapiContext * const context = GST_VAAPI_CONTEXT(object);
|
context->info = *cip;
|
||||||
GstVaapiContextPrivate * const priv = context->priv;
|
context->config_id = VA_INVALID_ID;
|
||||||
|
context->overlays[0] = overlay_new();
|
||||||
|
context->overlays[1] = overlay_new();
|
||||||
|
}
|
||||||
|
|
||||||
overlay_destroy(&priv->overlays[0]);
|
static void
|
||||||
overlay_destroy(&priv->overlays[1]);
|
gst_vaapi_context_finalize(GstVaapiContext *context)
|
||||||
|
{
|
||||||
|
overlay_destroy(&context->overlays[0]);
|
||||||
|
overlay_destroy(&context->overlays[1]);
|
||||||
gst_vaapi_context_destroy(context);
|
gst_vaapi_context_destroy(context);
|
||||||
gst_vaapi_context_destroy_surfaces(context);
|
gst_vaapi_context_destroy_surfaces(context);
|
||||||
|
|
||||||
G_OBJECT_CLASS(gst_vaapi_context_parent_class)->finalize(object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiContext, gst_vaapi_context)
|
||||||
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;
|
|
||||||
case PROP_REF_FRAMES:
|
|
||||||
priv->ref_frames = 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;
|
|
||||||
case PROP_REF_FRAMES:
|
|
||||||
g_value_set_uint(value, priv->ref_frames);
|
|
||||||
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));
|
|
||||||
|
|
||||||
g_object_class_install_property
|
|
||||||
(object_class,
|
|
||||||
PROP_REF_FRAMES,
|
|
||||||
g_param_spec_uint("ref-frames",
|
|
||||||
"Reference Frames",
|
|
||||||
"The number of reference frames",
|
|
||||||
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->overlays[0] = overlay_new();
|
|
||||||
priv->overlays[1] = overlay_new();
|
|
||||||
priv->profile = 0;
|
|
||||||
priv->entrypoint = 0;
|
|
||||||
priv->width = 0;
|
|
||||||
priv->height = 0;
|
|
||||||
priv->ref_frames = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_vaapi_context_new:
|
* gst_vaapi_context_new:
|
||||||
|
@ -822,32 +676,28 @@ gst_vaapi_context_new(
|
||||||
* Return value: the newly allocated #GstVaapiContext object
|
* Return value: the newly allocated #GstVaapiContext object
|
||||||
*/
|
*/
|
||||||
GstVaapiContext *
|
GstVaapiContext *
|
||||||
gst_vaapi_context_new_full(GstVaapiDisplay *display, GstVaapiContextInfo *cip)
|
gst_vaapi_context_new_full(GstVaapiDisplay *display,
|
||||||
|
const GstVaapiContextInfo *cip)
|
||||||
{
|
{
|
||||||
GstVaapiContext *context;
|
GstVaapiContext *context;
|
||||||
|
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
|
|
||||||
g_return_val_if_fail(cip->profile, NULL);
|
g_return_val_if_fail(cip->profile, NULL);
|
||||||
g_return_val_if_fail(cip->entrypoint, NULL);
|
g_return_val_if_fail(cip->entrypoint, NULL);
|
||||||
g_return_val_if_fail(cip->width > 0, NULL);
|
g_return_val_if_fail(cip->width > 0, NULL);
|
||||||
g_return_val_if_fail(cip->height > 0, NULL);
|
g_return_val_if_fail(cip->height > 0, NULL);
|
||||||
|
|
||||||
context = g_object_new(
|
context = gst_vaapi_object_new(gst_vaapi_context_class(), display);
|
||||||
GST_VAAPI_TYPE_CONTEXT,
|
if (!context)
|
||||||
"display", display,
|
|
||||||
"id", GST_VAAPI_ID(VA_INVALID_ID),
|
|
||||||
"profile", cip->profile,
|
|
||||||
"entrypoint", cip->entrypoint,
|
|
||||||
"width", cip->width,
|
|
||||||
"height", cip->height,
|
|
||||||
"ref-frames", cip->ref_frames,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
if (!context->priv->is_constructed) {
|
|
||||||
g_object_unref(context);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
gst_vaapi_context_init(context, cip);
|
||||||
|
if (!gst_vaapi_context_create(context))
|
||||||
|
goto error;
|
||||||
return context;
|
return context;
|
||||||
|
|
||||||
|
error:
|
||||||
|
gst_vaapi_object_unref(context);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -872,14 +722,13 @@ gst_vaapi_context_reset(
|
||||||
unsigned int height
|
unsigned int height
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
GstVaapiContextPrivate * const priv = context->priv;
|
|
||||||
GstVaapiContextInfo info;
|
GstVaapiContextInfo info;
|
||||||
|
|
||||||
info.profile = profile;
|
info.profile = profile;
|
||||||
info.entrypoint = entrypoint;
|
info.entrypoint = entrypoint;
|
||||||
info.width = width;
|
info.width = width;
|
||||||
info.height = height;
|
info.height = height;
|
||||||
info.ref_frames = priv->ref_frames;
|
info.ref_frames = context->info.ref_frames;
|
||||||
|
|
||||||
return gst_vaapi_context_reset_full(context, &info);
|
return gst_vaapi_context_reset_full(context, &info);
|
||||||
}
|
}
|
||||||
|
@ -887,32 +736,35 @@ gst_vaapi_context_reset(
|
||||||
/**
|
/**
|
||||||
* gst_vaapi_context_reset_full:
|
* gst_vaapi_context_reset_full:
|
||||||
* @context: a #GstVaapiContext
|
* @context: a #GstVaapiContext
|
||||||
* @cip: a pointer to the new #GstVaapiContextInfo details
|
* @new_cip: a pointer to the new #GstVaapiContextInfo details
|
||||||
*
|
*
|
||||||
* Resets @context to the configuration specified by @cip, thus
|
* Resets @context to the configuration specified by @new_cip, thus
|
||||||
* including profile, entry-point, encoded size and maximum number of
|
* including profile, entry-point, encoded size and maximum number of
|
||||||
* reference frames reported by the bitstream.
|
* reference frames reported by the bitstream.
|
||||||
*
|
*
|
||||||
* Return value: %TRUE on success
|
* Return value: %TRUE on success
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gst_vaapi_context_reset_full(GstVaapiContext *context, GstVaapiContextInfo *cip)
|
gst_vaapi_context_reset_full(GstVaapiContext *context,
|
||||||
|
const GstVaapiContextInfo *new_cip)
|
||||||
{
|
{
|
||||||
GstVaapiContextPrivate * const priv = context->priv;
|
GstVaapiContextInfo * const cip = &context->info;
|
||||||
gboolean size_changed, codec_changed;
|
gboolean size_changed, codec_changed;
|
||||||
|
|
||||||
size_changed = priv->width != cip->width || priv->height != cip->height;
|
size_changed = cip->width != new_cip->width ||
|
||||||
|
cip->height != new_cip->height;
|
||||||
if (size_changed) {
|
if (size_changed) {
|
||||||
gst_vaapi_context_destroy_surfaces(context);
|
gst_vaapi_context_destroy_surfaces(context);
|
||||||
priv->width = cip->width;
|
cip->width = new_cip->width;
|
||||||
priv->height = cip->height;
|
cip->height = new_cip->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
codec_changed = priv->profile != cip->profile || priv->entrypoint != cip->entrypoint;
|
codec_changed = cip->profile != new_cip->profile ||
|
||||||
|
cip->entrypoint != new_cip->entrypoint;
|
||||||
if (codec_changed) {
|
if (codec_changed) {
|
||||||
gst_vaapi_context_destroy(context);
|
gst_vaapi_context_destroy(context);
|
||||||
priv->profile = cip->profile;
|
cip->profile = new_cip->profile;
|
||||||
priv->entrypoint = cip->entrypoint;
|
cip->entrypoint = new_cip->entrypoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size_changed && !gst_vaapi_context_create_surfaces(context))
|
if (size_changed && !gst_vaapi_context_create_surfaces(context))
|
||||||
|
@ -921,7 +773,6 @@ gst_vaapi_context_reset_full(GstVaapiContext *context, GstVaapiContextInfo *cip)
|
||||||
if (codec_changed && !gst_vaapi_context_create(context))
|
if (codec_changed && !gst_vaapi_context_create(context))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
priv->is_constructed = TRUE;
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -954,7 +805,7 @@ gst_vaapi_context_get_profile(GstVaapiContext *context)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0);
|
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0);
|
||||||
|
|
||||||
return context->priv->profile;
|
return context->info.profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -977,9 +828,9 @@ gst_vaapi_context_set_profile(GstVaapiContext *context, GstVaapiProfile profile)
|
||||||
|
|
||||||
return gst_vaapi_context_reset(context,
|
return gst_vaapi_context_reset(context,
|
||||||
profile,
|
profile,
|
||||||
context->priv->entrypoint,
|
context->info.entrypoint,
|
||||||
context->priv->width,
|
context->info.width,
|
||||||
context->priv->height);
|
context->info.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -995,7 +846,7 @@ gst_vaapi_context_get_entrypoint(GstVaapiContext *context)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0);
|
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0);
|
||||||
|
|
||||||
return context->priv->entrypoint;
|
return context->info.entrypoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1016,10 +867,10 @@ gst_vaapi_context_get_size(
|
||||||
g_return_if_fail(GST_VAAPI_IS_CONTEXT(context));
|
g_return_if_fail(GST_VAAPI_IS_CONTEXT(context));
|
||||||
|
|
||||||
if (pwidth)
|
if (pwidth)
|
||||||
*pwidth = context->priv->width;
|
*pwidth = context->info.width;
|
||||||
|
|
||||||
if (pheight)
|
if (pheight)
|
||||||
*pheight = context->priv->height;
|
*pheight = context->info.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1043,7 +894,7 @@ gst_vaapi_context_get_surface_proxy(GstVaapiContext *context)
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL);
|
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL);
|
||||||
|
|
||||||
return gst_vaapi_surface_proxy_new_from_pool(
|
return gst_vaapi_surface_proxy_new_from_pool(
|
||||||
GST_VAAPI_SURFACE_POOL(context->priv->surfaces_pool));
|
GST_VAAPI_SURFACE_POOL(context->surfaces_pool));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1059,7 +910,7 @@ gst_vaapi_context_get_surface_count(GstVaapiContext *context)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0);
|
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0);
|
||||||
|
|
||||||
return gst_vaapi_video_pool_get_size(context->priv->surfaces_pool);
|
return gst_vaapi_video_pool_get_size(context->surfaces_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1081,16 +932,13 @@ gst_vaapi_context_apply_composition(
|
||||||
GstVideoOverlayComposition *composition
|
GstVideoOverlayComposition *composition
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
GstVaapiContextPrivate *priv;
|
|
||||||
GPtrArray *curr_overlay, *next_overlay;
|
GPtrArray *curr_overlay, *next_overlay;
|
||||||
guint i, n_rectangles;
|
guint i, n_rectangles;
|
||||||
gboolean reassociate = FALSE;
|
gboolean reassociate = FALSE;
|
||||||
|
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), FALSE);
|
||||||
|
|
||||||
priv = context->priv;
|
if (!context->surfaces)
|
||||||
|
|
||||||
if (!priv->surfaces)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!composition) {
|
if (!composition) {
|
||||||
|
@ -1098,8 +946,8 @@ gst_vaapi_context_apply_composition(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
curr_overlay = priv->overlays[priv->overlay_id];
|
curr_overlay = context->overlays[context->overlay_id];
|
||||||
next_overlay = priv->overlays[priv->overlay_id ^ 1];
|
next_overlay = context->overlays[context->overlay_id ^ 1];
|
||||||
overlay_clear(next_overlay);
|
overlay_clear(next_overlay);
|
||||||
|
|
||||||
n_rectangles = gst_video_overlay_composition_n_rectangles(composition);
|
n_rectangles = gst_video_overlay_composition_n_rectangles(composition);
|
||||||
|
@ -1126,7 +974,7 @@ gst_vaapi_context_apply_composition(
|
||||||
}
|
}
|
||||||
|
|
||||||
overlay_clear(curr_overlay);
|
overlay_clear(curr_overlay);
|
||||||
priv->overlay_id ^= 1;
|
context->overlay_id ^= 1;
|
||||||
|
|
||||||
if (reassociate && !overlay_reassociate(next_overlay))
|
if (reassociate && !overlay_reassociate(next_overlay))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -31,34 +31,14 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define GST_VAAPI_TYPE_CONTEXT \
|
|
||||||
(gst_vaapi_context_get_type())
|
|
||||||
|
|
||||||
#define GST_VAAPI_CONTEXT(obj) \
|
#define GST_VAAPI_CONTEXT(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
((GstVaapiContext *)(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) \
|
#define GST_VAAPI_IS_CONTEXT(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_CONTEXT))
|
((obj) != NULL)
|
||||||
|
|
||||||
#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 _GstVaapiContext GstVaapiContext;
|
||||||
typedef struct _GstVaapiContextInfo GstVaapiContextInfo;
|
typedef struct _GstVaapiContextInfo GstVaapiContextInfo;
|
||||||
typedef struct _GstVaapiContextPrivate GstVaapiContextPrivate;
|
|
||||||
typedef struct _GstVaapiContextClass GstVaapiContextClass;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstVaapiContextInfo:
|
* GstVaapiContextInfo:
|
||||||
|
@ -75,31 +55,6 @@ struct _GstVaapiContextInfo {
|
||||||
guint ref_frames;
|
guint ref_frames;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 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) G_GNUC_CONST;
|
|
||||||
|
|
||||||
GstVaapiContext *
|
GstVaapiContext *
|
||||||
gst_vaapi_context_new(
|
gst_vaapi_context_new(
|
||||||
GstVaapiDisplay *display,
|
GstVaapiDisplay *display,
|
||||||
|
@ -110,7 +65,8 @@ gst_vaapi_context_new(
|
||||||
);
|
);
|
||||||
|
|
||||||
GstVaapiContext *
|
GstVaapiContext *
|
||||||
gst_vaapi_context_new_full(GstVaapiDisplay *display, GstVaapiContextInfo *cip);
|
gst_vaapi_context_new_full(GstVaapiDisplay *display,
|
||||||
|
const GstVaapiContextInfo *cip);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_vaapi_context_reset(
|
gst_vaapi_context_reset(
|
||||||
|
@ -122,7 +78,8 @@ gst_vaapi_context_reset(
|
||||||
);
|
);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_vaapi_context_reset_full(GstVaapiContext *context, GstVaapiContextInfo *cip);
|
gst_vaapi_context_reset_full(GstVaapiContext *context,
|
||||||
|
const GstVaapiContextInfo *new_cip);
|
||||||
|
|
||||||
GstVaapiID
|
GstVaapiID
|
||||||
gst_vaapi_context_get_id(GstVaapiContext *context);
|
gst_vaapi_context_get_id(GstVaapiContext *context);
|
||||||
|
|
|
@ -472,7 +472,7 @@ gst_vaapi_decoder_finalize(GObject *object)
|
||||||
priv->frames = NULL;
|
priv->frames = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_clear_object(&priv->context);
|
gst_vaapi_object_replace(&priv->context, NULL);
|
||||||
priv->va_context = VA_INVALID_ID;
|
priv->va_context = VA_INVALID_ID;
|
||||||
|
|
||||||
g_clear_object(&priv->display);
|
g_clear_object(&priv->display);
|
||||||
|
|
|
@ -30,19 +30,22 @@
|
||||||
#include "gstvaapicompat.h"
|
#include "gstvaapicompat.h"
|
||||||
#include "gstvaapiutils.h"
|
#include "gstvaapiutils.h"
|
||||||
#include "gstvaapiimage.h"
|
#include "gstvaapiimage.h"
|
||||||
#include "gstvaapi_priv.h"
|
#include "gstvaapiobject_priv.h"
|
||||||
|
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
#include "gstvaapidebug.h"
|
#include "gstvaapidebug.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, GST_VAAPI_TYPE_OBJECT)
|
typedef struct _GstVaapiImageClass GstVaapiImageClass;
|
||||||
|
|
||||||
#define GST_VAAPI_IMAGE_GET_PRIVATE(obj) \
|
/**
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
|
* GstVaapiImage:
|
||||||
GST_VAAPI_TYPE_IMAGE, \
|
*
|
||||||
GstVaapiImagePrivate))
|
* A VA image wrapper
|
||||||
|
*/
|
||||||
|
struct _GstVaapiImage {
|
||||||
|
/*< private >*/
|
||||||
|
GstVaapiObject parent_instance;
|
||||||
|
|
||||||
struct _GstVaapiImagePrivate {
|
|
||||||
VAImage internal_image;
|
VAImage internal_image;
|
||||||
VAImage image;
|
VAImage image;
|
||||||
guchar *image_data;
|
guchar *image_data;
|
||||||
|
@ -50,18 +53,17 @@ struct _GstVaapiImagePrivate {
|
||||||
GstVaapiImageFormat format;
|
GstVaapiImageFormat format;
|
||||||
guint width;
|
guint width;
|
||||||
guint height;
|
guint height;
|
||||||
guint create_image : 1;
|
|
||||||
guint is_constructed : 1;
|
|
||||||
guint is_linear : 1;
|
guint is_linear : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
/**
|
||||||
PROP_0,
|
* GstVaapiImageClass:
|
||||||
|
*
|
||||||
PROP_IMAGE,
|
* A VA image wrapper class
|
||||||
PROP_FORMAT,
|
*/
|
||||||
PROP_WIDTH,
|
struct _GstVaapiImageClass {
|
||||||
PROP_HEIGHT
|
/*< private >*/
|
||||||
|
GstVaapiObjectClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SWAP_UINT(a, b) do { \
|
#define SWAP_UINT(a, b) do { \
|
||||||
|
@ -83,35 +85,6 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image);
|
||||||
* VAImage wrapper
|
* VAImage wrapper
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VAAPI_TYPE_IMAGE vaapi_image_get_type()
|
|
||||||
|
|
||||||
static gpointer
|
|
||||||
vaapi_image_copy(gpointer va_image)
|
|
||||||
{
|
|
||||||
return g_slice_dup(VAImage, va_image);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vaapi_image_free(gpointer va_image)
|
|
||||||
{
|
|
||||||
if (G_LIKELY(va_image))
|
|
||||||
g_slice_free(VAImage, va_image);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GType
|
|
||||||
vaapi_image_get_type(void)
|
|
||||||
{
|
|
||||||
static GType type = 0;
|
|
||||||
|
|
||||||
if (G_UNLIKELY(type == 0))
|
|
||||||
type = g_boxed_type_register_static(
|
|
||||||
"VAImage",
|
|
||||||
vaapi_image_copy,
|
|
||||||
vaapi_image_free
|
|
||||||
);
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
vaapi_image_is_linear(const VAImage *va_image)
|
vaapi_image_is_linear(const VAImage *va_image)
|
||||||
{
|
{
|
||||||
|
@ -173,7 +146,6 @@ static gboolean
|
||||||
_gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format)
|
_gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format)
|
||||||
{
|
{
|
||||||
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image);
|
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image);
|
||||||
GstVaapiImagePrivate * const priv = image->priv;
|
|
||||||
const VAImageFormat *va_format;
|
const VAImageFormat *va_format;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
|
|
||||||
|
@ -188,30 +160,29 @@ _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format)
|
||||||
status = vaCreateImage(
|
status = vaCreateImage(
|
||||||
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
||||||
(VAImageFormat *)va_format,
|
(VAImageFormat *)va_format,
|
||||||
priv->width,
|
image->width,
|
||||||
priv->height,
|
image->height,
|
||||||
&priv->internal_image
|
&image->internal_image
|
||||||
);
|
);
|
||||||
GST_VAAPI_DISPLAY_UNLOCK(display);
|
GST_VAAPI_DISPLAY_UNLOCK(display);
|
||||||
if (status != VA_STATUS_SUCCESS ||
|
if (status != VA_STATUS_SUCCESS ||
|
||||||
priv->internal_image.format.fourcc != va_format->fourcc)
|
image->internal_image.format.fourcc != va_format->fourcc)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
priv->internal_format = format;
|
image->internal_format = format;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vaapi_image_create(GstVaapiImage *image)
|
gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format,
|
||||||
|
guint width, guint height)
|
||||||
{
|
{
|
||||||
GstVaapiImagePrivate * const priv = image->priv;
|
|
||||||
GstVaapiImageFormat format = priv->format;
|
|
||||||
const VAImageFormat *va_format;
|
const VAImageFormat *va_format;
|
||||||
VAImageID image_id;
|
VAImageID image_id;
|
||||||
|
|
||||||
if (!priv->create_image)
|
image->format = format;
|
||||||
return (priv->image.image_id != VA_INVALID_ID &&
|
image->width = width;
|
||||||
priv->image.buf != VA_INVALID_ID);
|
image->height = height;
|
||||||
|
|
||||||
if (!_gst_vaapi_image_create(image, format)) {
|
if (!_gst_vaapi_image_create(image, format)) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
|
@ -228,25 +199,25 @@ gst_vaapi_image_create(GstVaapiImage *image)
|
||||||
if (!format || !_gst_vaapi_image_create(image, format))
|
if (!format || !_gst_vaapi_image_create(image, format))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
priv->image = priv->internal_image;
|
image->image = image->internal_image;
|
||||||
image_id = priv->image.image_id;
|
image_id = image->image.image_id;
|
||||||
|
|
||||||
if (priv->format != priv->internal_format) {
|
if (image->format != image->internal_format) {
|
||||||
switch (priv->format) {
|
switch (image->format) {
|
||||||
case GST_VAAPI_IMAGE_YV12:
|
case GST_VAAPI_IMAGE_YV12:
|
||||||
case GST_VAAPI_IMAGE_I420:
|
case GST_VAAPI_IMAGE_I420:
|
||||||
va_format = gst_vaapi_image_format_get_va_format(priv->format);
|
va_format = gst_vaapi_image_format_get_va_format(image->format);
|
||||||
if (!va_format)
|
if (!va_format)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
priv->image.format = *va_format;
|
image->image.format = *va_format;
|
||||||
SWAP_UINT(priv->image.offsets[1], priv->image.offsets[2]);
|
SWAP_UINT(image->image.offsets[1], image->image.offsets[2]);
|
||||||
SWAP_UINT(priv->image.pitches[1], priv->image.pitches[2]);
|
SWAP_UINT(image->image.pitches[1], image->image.pitches[2]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
priv->is_linear = vaapi_image_is_linear(&priv->image);
|
image->is_linear = vaapi_image_is_linear(&image->image);
|
||||||
|
|
||||||
GST_DEBUG("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id));
|
GST_DEBUG("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id));
|
||||||
GST_VAAPI_OBJECT_ID(image) = image_id;
|
GST_VAAPI_OBJECT_ID(image) = image_id;
|
||||||
|
@ -254,168 +225,28 @@ gst_vaapi_image_create(GstVaapiImage *image)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vaapi_image_finalize(GObject *object)
|
gst_vaapi_image_init(GstVaapiImage *image)
|
||||||
{
|
{
|
||||||
gst_vaapi_image_destroy(GST_VAAPI_IMAGE(object));
|
image->internal_image.image_id = VA_INVALID_ID;
|
||||||
|
image->internal_image.buf = VA_INVALID_ID;
|
||||||
G_OBJECT_CLASS(gst_vaapi_image_parent_class)->finalize(object);
|
image->image.image_id = VA_INVALID_ID;
|
||||||
}
|
image->image.buf = VA_INVALID_ID;
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vaapi_image_set_property(
|
|
||||||
GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
const GValue *value,
|
|
||||||
GParamSpec *pspec
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GstVaapiImage * const image = GST_VAAPI_IMAGE(object);
|
|
||||||
GstVaapiImagePrivate * const priv = image->priv;
|
|
||||||
|
|
||||||
switch (prop_id) {
|
|
||||||
case PROP_IMAGE: {
|
|
||||||
const VAImage * const va_image = g_value_get_boxed(value);
|
|
||||||
if (va_image)
|
|
||||||
_gst_vaapi_image_set_image(image, va_image);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PROP_FORMAT:
|
|
||||||
if (priv->create_image)
|
|
||||||
priv->format = g_value_get_uint(value);
|
|
||||||
break;
|
|
||||||
case PROP_WIDTH:
|
|
||||||
if (priv->create_image)
|
|
||||||
priv->width = g_value_get_uint(value);
|
|
||||||
break;
|
|
||||||
case PROP_HEIGHT:
|
|
||||||
if (priv->create_image)
|
|
||||||
priv->height = g_value_get_uint(value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vaapi_image_get_property(
|
|
||||||
GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GstVaapiImage * const image = GST_VAAPI_IMAGE(object);
|
|
||||||
|
|
||||||
switch (prop_id) {
|
|
||||||
case PROP_IMAGE:
|
|
||||||
g_value_set_boxed(value, &image->priv->image);
|
|
||||||
break;
|
|
||||||
case PROP_FORMAT:
|
|
||||||
g_value_set_uint(value, gst_vaapi_image_get_format(image));
|
|
||||||
break;
|
|
||||||
case PROP_WIDTH:
|
|
||||||
g_value_set_uint(value, gst_vaapi_image_get_width(image));
|
|
||||||
break;
|
|
||||||
case PROP_HEIGHT:
|
|
||||||
g_value_set_uint(value, gst_vaapi_image_get_height(image));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vaapi_image_constructed(GObject *object)
|
|
||||||
{
|
|
||||||
GstVaapiImage * const image = GST_VAAPI_IMAGE(object);
|
|
||||||
GObjectClass *parent_class;
|
|
||||||
|
|
||||||
image->priv->is_constructed = gst_vaapi_image_create(image);
|
|
||||||
|
|
||||||
parent_class = G_OBJECT_CLASS(gst_vaapi_image_parent_class);
|
|
||||||
if (parent_class->constructed)
|
|
||||||
parent_class->constructed(object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vaapi_image_class_init(GstVaapiImageClass *klass)
|
gst_vaapi_image_class_init(GstVaapiImageClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
|
GstVaapiObjectClass * const object_class =
|
||||||
|
GST_VAAPI_OBJECT_CLASS(klass);
|
||||||
|
|
||||||
g_type_class_add_private(klass, sizeof(GstVaapiImagePrivate));
|
object_class->init = (GstVaapiObjectInitFunc)gst_vaapi_image_init;
|
||||||
|
|
||||||
object_class->finalize = gst_vaapi_image_finalize;
|
|
||||||
object_class->set_property = gst_vaapi_image_set_property;
|
|
||||||
object_class->get_property = gst_vaapi_image_get_property;
|
|
||||||
object_class->constructed = gst_vaapi_image_constructed;
|
|
||||||
|
|
||||||
g_object_class_install_property
|
|
||||||
(object_class,
|
|
||||||
PROP_IMAGE,
|
|
||||||
g_param_spec_boxed("image",
|
|
||||||
"Image",
|
|
||||||
"The underlying VA image",
|
|
||||||
VAAPI_TYPE_IMAGE,
|
|
||||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
|
||||||
|
|
||||||
g_object_class_install_property
|
|
||||||
(object_class,
|
|
||||||
PROP_WIDTH,
|
|
||||||
g_param_spec_uint("width",
|
|
||||||
"width",
|
|
||||||
"The image width",
|
|
||||||
0, G_MAXUINT32, 0,
|
|
||||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
|
||||||
|
|
||||||
g_object_class_install_property
|
|
||||||
(object_class,
|
|
||||||
PROP_HEIGHT,
|
|
||||||
g_param_spec_uint("height",
|
|
||||||
"heighr",
|
|
||||||
"The image height",
|
|
||||||
0, G_MAXUINT32, 0,
|
|
||||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVaapiImage:format:
|
|
||||||
*
|
|
||||||
* The #GstVaapiImageFormat of the image
|
|
||||||
*/
|
|
||||||
g_object_class_install_property
|
|
||||||
(object_class,
|
|
||||||
PROP_FORMAT,
|
|
||||||
g_param_spec_uint("format",
|
|
||||||
"Format",
|
|
||||||
"The underlying image format",
|
|
||||||
0, G_MAXUINT32, 0,
|
|
||||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
#define gst_vaapi_image_finalize gst_vaapi_image_destroy
|
||||||
gst_vaapi_image_init(GstVaapiImage *image)
|
GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE(
|
||||||
{
|
GstVaapiImage,
|
||||||
GstVaapiImagePrivate *priv = GST_VAAPI_IMAGE_GET_PRIVATE(image);
|
gst_vaapi_image,
|
||||||
|
gst_vaapi_image_class_init(&g_class))
|
||||||
image->priv = priv;
|
|
||||||
priv->image_data = NULL;
|
|
||||||
priv->width = 0;
|
|
||||||
priv->height = 0;
|
|
||||||
priv->internal_format = 0;
|
|
||||||
priv->format = 0;
|
|
||||||
priv->create_image = TRUE;
|
|
||||||
priv->is_constructed = FALSE;
|
|
||||||
priv->is_linear = FALSE;
|
|
||||||
|
|
||||||
memset(&priv->internal_image, 0, sizeof(priv->internal_image));
|
|
||||||
priv->internal_image.image_id = VA_INVALID_ID;
|
|
||||||
priv->internal_image.buf = VA_INVALID_ID;
|
|
||||||
|
|
||||||
memset(&priv->image, 0, sizeof(priv->image));
|
|
||||||
priv->image.image_id = VA_INVALID_ID;
|
|
||||||
priv->image.buf = VA_INVALID_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_vaapi_image_new:
|
* gst_vaapi_image_new:
|
||||||
|
@ -439,30 +270,23 @@ gst_vaapi_image_new(
|
||||||
{
|
{
|
||||||
GstVaapiImage *image;
|
GstVaapiImage *image;
|
||||||
|
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
|
|
||||||
g_return_val_if_fail(width > 0, NULL);
|
g_return_val_if_fail(width > 0, NULL);
|
||||||
g_return_val_if_fail(height > 0, NULL);
|
g_return_val_if_fail(height > 0, NULL);
|
||||||
|
|
||||||
GST_DEBUG("format %" GST_FOURCC_FORMAT ", size %ux%u",
|
GST_DEBUG("format %" GST_FOURCC_FORMAT ", size %ux%u",
|
||||||
GST_FOURCC_ARGS(format), width, height);
|
GST_FOURCC_ARGS(format), width, height);
|
||||||
|
|
||||||
image = g_object_new(
|
image = gst_vaapi_object_new(gst_vaapi_image_class(), display);
|
||||||
GST_VAAPI_TYPE_IMAGE,
|
|
||||||
"display", display,
|
|
||||||
"id", GST_VAAPI_ID(VA_INVALID_ID),
|
|
||||||
"format", format,
|
|
||||||
"width", width,
|
|
||||||
"height", height,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
if (!image)
|
if (!image)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!image->priv->is_constructed) {
|
if (!gst_vaapi_image_create(image, format, width, height))
|
||||||
g_object_unref(image);
|
goto error;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return image;
|
return image;
|
||||||
|
|
||||||
|
error:
|
||||||
|
gst_vaapi_object_unref(image);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -482,7 +306,6 @@ gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image)
|
||||||
{
|
{
|
||||||
GstVaapiImage *image;
|
GstVaapiImage *image;
|
||||||
|
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
|
|
||||||
g_return_val_if_fail(va_image, NULL);
|
g_return_val_if_fail(va_image, NULL);
|
||||||
g_return_val_if_fail(va_image->image_id != VA_INVALID_ID, NULL);
|
g_return_val_if_fail(va_image->image_id != VA_INVALID_ID, NULL);
|
||||||
g_return_val_if_fail(va_image->buf != VA_INVALID_ID, NULL);
|
g_return_val_if_fail(va_image->buf != VA_INVALID_ID, NULL);
|
||||||
|
@ -492,21 +315,17 @@ gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image)
|
||||||
GST_FOURCC_ARGS(va_image->format.fourcc),
|
GST_FOURCC_ARGS(va_image->format.fourcc),
|
||||||
va_image->width, va_image->height);
|
va_image->width, va_image->height);
|
||||||
|
|
||||||
image = g_object_new(
|
image = gst_vaapi_object_new(gst_vaapi_image_class(), display);
|
||||||
GST_VAAPI_TYPE_IMAGE,
|
|
||||||
"display", display,
|
|
||||||
"id", GST_VAAPI_ID(va_image->image_id),
|
|
||||||
"image", va_image,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
if (!image)
|
if (!image)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!image->priv->is_constructed) {
|
if (!_gst_vaapi_image_set_image(image, va_image))
|
||||||
g_object_unref(image);
|
goto error;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return image;
|
return image;
|
||||||
|
|
||||||
|
error:
|
||||||
|
gst_vaapi_object_unref(image);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -521,7 +340,6 @@ GstVaapiID
|
||||||
gst_vaapi_image_get_id(GstVaapiImage *image)
|
gst_vaapi_image_get_id(GstVaapiImage *image)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), VA_INVALID_ID);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), VA_INVALID_ID);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, VA_INVALID_ID);
|
|
||||||
|
|
||||||
return GST_VAAPI_OBJECT_ID(image);
|
return GST_VAAPI_OBJECT_ID(image);
|
||||||
}
|
}
|
||||||
|
@ -539,10 +357,9 @@ gboolean
|
||||||
gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image)
|
gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, FALSE);
|
|
||||||
|
|
||||||
if (va_image)
|
if (va_image)
|
||||||
*va_image = image->priv->image;
|
*va_image = image->image;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -564,29 +381,26 @@ gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image)
|
||||||
gboolean
|
gboolean
|
||||||
_gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image)
|
_gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image)
|
||||||
{
|
{
|
||||||
GstVaapiImagePrivate * const priv = image->priv;
|
|
||||||
GstVaapiImageFormat format;
|
GstVaapiImageFormat format;
|
||||||
VAImage alt_va_image;
|
VAImage alt_va_image;
|
||||||
const VAImageFormat *alt_va_format;
|
const VAImageFormat *alt_va_format;
|
||||||
|
|
||||||
if (!va_image)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
format = gst_vaapi_image_format(&va_image->format);
|
format = gst_vaapi_image_format(&va_image->format);
|
||||||
if (!format)
|
if (!format)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
priv->create_image = FALSE;
|
image->internal_image = *va_image;
|
||||||
priv->internal_image = *va_image;
|
image->internal_format = format;
|
||||||
priv->internal_format = format;
|
image->is_linear = vaapi_image_is_linear(va_image);
|
||||||
priv->is_linear = vaapi_image_is_linear(va_image);
|
image->image = *va_image;
|
||||||
priv->image = *va_image;
|
image->format = format;
|
||||||
priv->format = format;
|
image->width = va_image->width;
|
||||||
priv->width = va_image->width;
|
image->height = va_image->height;
|
||||||
priv->height = va_image->height;
|
|
||||||
|
GST_VAAPI_OBJECT_ID(image) = va_image->image_id;
|
||||||
|
|
||||||
/* Try to linearize image */
|
/* Try to linearize image */
|
||||||
if (!priv->is_linear) {
|
if (!image->is_linear) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case GST_VAAPI_IMAGE_I420:
|
case GST_VAAPI_IMAGE_I420:
|
||||||
format = GST_VAAPI_IMAGE_YV12;
|
format = GST_VAAPI_IMAGE_YV12;
|
||||||
|
@ -605,9 +419,9 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image)
|
||||||
SWAP_UINT(alt_va_image.offsets[1], alt_va_image.offsets[2]);
|
SWAP_UINT(alt_va_image.offsets[1], alt_va_image.offsets[2]);
|
||||||
SWAP_UINT(alt_va_image.pitches[1], alt_va_image.pitches[2]);
|
SWAP_UINT(alt_va_image.pitches[1], alt_va_image.pitches[2]);
|
||||||
if (vaapi_image_is_linear(&alt_va_image)) {
|
if (vaapi_image_is_linear(&alt_va_image)) {
|
||||||
priv->image = alt_va_image;
|
image->image = alt_va_image;
|
||||||
priv->format = format;
|
image->format = format;
|
||||||
priv->is_linear = TRUE;
|
image->is_linear = TRUE;
|
||||||
GST_DEBUG("linearized image to %" GST_FOURCC_FORMAT " format",
|
GST_DEBUG("linearized image to %" GST_FOURCC_FORMAT " format",
|
||||||
GST_FOURCC_ARGS(format));
|
GST_FOURCC_ARGS(format));
|
||||||
}
|
}
|
||||||
|
@ -628,9 +442,8 @@ GstVaapiImageFormat
|
||||||
gst_vaapi_image_get_format(GstVaapiImage *image)
|
gst_vaapi_image_get_format(GstVaapiImage *image)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, 0);
|
|
||||||
|
|
||||||
return image->priv->format;
|
return image->format;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -645,9 +458,8 @@ guint
|
||||||
gst_vaapi_image_get_width(GstVaapiImage *image)
|
gst_vaapi_image_get_width(GstVaapiImage *image)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, 0);
|
|
||||||
|
|
||||||
return image->priv->width;
|
return image->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -662,9 +474,8 @@ guint
|
||||||
gst_vaapi_image_get_height(GstVaapiImage *image)
|
gst_vaapi_image_get_height(GstVaapiImage *image)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, 0);
|
|
||||||
|
|
||||||
return image->priv->height;
|
return image->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -679,13 +490,12 @@ void
|
||||||
gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight)
|
gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight)
|
||||||
{
|
{
|
||||||
g_return_if_fail(GST_VAAPI_IS_IMAGE(image));
|
g_return_if_fail(GST_VAAPI_IS_IMAGE(image));
|
||||||
g_return_if_fail(image->priv->is_constructed);
|
|
||||||
|
|
||||||
if (pwidth)
|
if (pwidth)
|
||||||
*pwidth = image->priv->width;
|
*pwidth = image->width;
|
||||||
|
|
||||||
if (pheight)
|
if (pheight)
|
||||||
*pheight = image->priv->height;
|
*pheight = image->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -702,9 +512,8 @@ gboolean
|
||||||
gst_vaapi_image_is_linear(GstVaapiImage *image)
|
gst_vaapi_image_is_linear(GstVaapiImage *image)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, FALSE);
|
|
||||||
|
|
||||||
return image->priv->is_linear;
|
return image->is_linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -718,14 +527,13 @@ gst_vaapi_image_is_linear(GstVaapiImage *image)
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
_gst_vaapi_image_is_mapped(GstVaapiImage *image)
|
_gst_vaapi_image_is_mapped(GstVaapiImage *image)
|
||||||
{
|
{
|
||||||
return image->priv->image_data != NULL;
|
return image->image_data != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_vaapi_image_is_mapped(GstVaapiImage *image)
|
gst_vaapi_image_is_mapped(GstVaapiImage *image)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, FALSE);
|
|
||||||
|
|
||||||
return _gst_vaapi_image_is_mapped(image);
|
return _gst_vaapi_image_is_mapped(image);
|
||||||
}
|
}
|
||||||
|
@ -743,7 +551,6 @@ gboolean
|
||||||
gst_vaapi_image_map(GstVaapiImage *image)
|
gst_vaapi_image_map(GstVaapiImage *image)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, FALSE);
|
|
||||||
|
|
||||||
return _gst_vaapi_image_map(image, NULL);
|
return _gst_vaapi_image_map(image, NULL);
|
||||||
}
|
}
|
||||||
|
@ -751,7 +558,6 @@ gst_vaapi_image_map(GstVaapiImage *image)
|
||||||
gboolean
|
gboolean
|
||||||
_gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image)
|
_gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image)
|
||||||
{
|
{
|
||||||
GstVaapiImagePrivate * const priv = image->priv;
|
|
||||||
GstVaapiDisplay *display;
|
GstVaapiDisplay *display;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
guint i;
|
guint i;
|
||||||
|
@ -766,8 +572,8 @@ _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image)
|
||||||
GST_VAAPI_DISPLAY_LOCK(display);
|
GST_VAAPI_DISPLAY_LOCK(display);
|
||||||
status = vaMapBuffer(
|
status = vaMapBuffer(
|
||||||
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
||||||
priv->image.buf,
|
image->image.buf,
|
||||||
(void **)&priv->image_data
|
(void **)&image->image_data
|
||||||
);
|
);
|
||||||
GST_VAAPI_DISPLAY_UNLOCK(display);
|
GST_VAAPI_DISPLAY_UNLOCK(display);
|
||||||
if (!vaapi_check_status(status, "vaMapBuffer()"))
|
if (!vaapi_check_status(status, "vaMapBuffer()"))
|
||||||
|
@ -775,13 +581,13 @@ _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image)
|
||||||
|
|
||||||
map_success:
|
map_success:
|
||||||
if (raw_image) {
|
if (raw_image) {
|
||||||
const VAImage * const va_image = &priv->image;
|
const VAImage * const va_image = &image->image;
|
||||||
raw_image->format = priv->format;
|
raw_image->format = image->format;
|
||||||
raw_image->width = va_image->width;
|
raw_image->width = va_image->width;
|
||||||
raw_image->height = va_image->height;
|
raw_image->height = va_image->height;
|
||||||
raw_image->num_planes = va_image->num_planes;
|
raw_image->num_planes = va_image->num_planes;
|
||||||
for (i = 0; i < raw_image->num_planes; i++) {
|
for (i = 0; i < raw_image->num_planes; i++) {
|
||||||
raw_image->pixels[i] = (guchar *)priv->image_data +
|
raw_image->pixels[i] = (guchar *)image->image_data +
|
||||||
va_image->offsets[i];
|
va_image->offsets[i];
|
||||||
raw_image->stride[i] = va_image->pitches[i];
|
raw_image->stride[i] = va_image->pitches[i];
|
||||||
}
|
}
|
||||||
|
@ -802,7 +608,6 @@ gboolean
|
||||||
gst_vaapi_image_unmap(GstVaapiImage *image)
|
gst_vaapi_image_unmap(GstVaapiImage *image)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, FALSE);
|
|
||||||
|
|
||||||
return _gst_vaapi_image_unmap(image);
|
return _gst_vaapi_image_unmap(image);
|
||||||
}
|
}
|
||||||
|
@ -823,13 +628,13 @@ _gst_vaapi_image_unmap(GstVaapiImage *image)
|
||||||
GST_VAAPI_DISPLAY_LOCK(display);
|
GST_VAAPI_DISPLAY_LOCK(display);
|
||||||
status = vaUnmapBuffer(
|
status = vaUnmapBuffer(
|
||||||
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
||||||
image->priv->image.buf
|
image->image.buf
|
||||||
);
|
);
|
||||||
GST_VAAPI_DISPLAY_UNLOCK(display);
|
GST_VAAPI_DISPLAY_UNLOCK(display);
|
||||||
if (!vaapi_check_status(status, "vaUnmapBuffer()"))
|
if (!vaapi_check_status(status, "vaUnmapBuffer()"))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
image->priv->image_data = NULL;
|
image->image_data = NULL;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -846,10 +651,9 @@ guint
|
||||||
gst_vaapi_image_get_plane_count(GstVaapiImage *image)
|
gst_vaapi_image_get_plane_count(GstVaapiImage *image)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, FALSE);
|
|
||||||
g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
|
g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
|
||||||
|
|
||||||
return image->priv->image.num_planes;
|
return image->image.num_planes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -866,11 +670,10 @@ guchar *
|
||||||
gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane)
|
gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, FALSE);
|
|
||||||
g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), NULL);
|
g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), NULL);
|
||||||
g_return_val_if_fail(plane < image->priv->image.num_planes, NULL);
|
g_return_val_if_fail(plane < image->image.num_planes, NULL);
|
||||||
|
|
||||||
return image->priv->image_data + image->priv->image.offsets[plane];
|
return image->image_data + image->image.offsets[plane];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -887,11 +690,10 @@ guint
|
||||||
gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane)
|
gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, FALSE);
|
|
||||||
g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
|
g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
|
||||||
g_return_val_if_fail(plane < image->priv->image.num_planes, 0);
|
g_return_val_if_fail(plane < image->image.num_planes, 0);
|
||||||
|
|
||||||
return image->priv->image.pitches[plane];
|
return image->image.pitches[plane];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -908,9 +710,8 @@ guint
|
||||||
gst_vaapi_image_get_data_size(GstVaapiImage *image)
|
gst_vaapi_image_get_data_size(GstVaapiImage *image)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, FALSE);
|
|
||||||
|
|
||||||
return image->priv->image.data_size;
|
return image->image.data_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GST_CHECK_VERSION(1,0,0)
|
#if GST_CHECK_VERSION(1,0,0)
|
||||||
|
@ -1175,21 +976,17 @@ gst_vaapi_image_get_buffer(
|
||||||
GstVaapiRectangle *rect
|
GstVaapiRectangle *rect
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
GstVaapiImagePrivate *priv;
|
|
||||||
GstVaapiImageRaw dst_image, src_image;
|
GstVaapiImageRaw dst_image, src_image;
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, FALSE);
|
|
||||||
g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE);
|
g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE);
|
||||||
|
|
||||||
priv = image->priv;
|
|
||||||
|
|
||||||
if (!init_image_from_buffer(&dst_image, buffer))
|
if (!init_image_from_buffer(&dst_image, buffer))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (dst_image.format != priv->format)
|
if (dst_image.format != image->format)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (dst_image.width != priv->width || dst_image.height != priv->height)
|
if (dst_image.width != image->width || dst_image.height != image->height)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!_gst_vaapi_image_map(image, &src_image))
|
if (!_gst_vaapi_image_map(image, &src_image))
|
||||||
|
@ -1226,7 +1023,6 @@ gst_vaapi_image_get_raw(
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, FALSE);
|
|
||||||
|
|
||||||
if (!_gst_vaapi_image_map(image, &src_image))
|
if (!_gst_vaapi_image_map(image, &src_image))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1258,21 +1054,17 @@ gst_vaapi_image_update_from_buffer(
|
||||||
GstVaapiRectangle *rect
|
GstVaapiRectangle *rect
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
GstVaapiImagePrivate *priv;
|
|
||||||
GstVaapiImageRaw dst_image, src_image;
|
GstVaapiImageRaw dst_image, src_image;
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, FALSE);
|
|
||||||
g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE);
|
g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE);
|
||||||
|
|
||||||
priv = image->priv;
|
|
||||||
|
|
||||||
if (!init_image_from_buffer(&src_image, buffer))
|
if (!init_image_from_buffer(&src_image, buffer))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (src_image.format != priv->format)
|
if (src_image.format != image->format)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (src_image.width != priv->width || src_image.height != priv->height)
|
if (src_image.width != image->width || src_image.height != image->height)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!_gst_vaapi_image_map(image, &dst_image))
|
if (!_gst_vaapi_image_map(image, &dst_image))
|
||||||
|
@ -1310,7 +1102,6 @@ gst_vaapi_image_update_from_raw(
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
||||||
g_return_val_if_fail(image->priv->is_constructed, FALSE);
|
|
||||||
|
|
||||||
if (!_gst_vaapi_image_map(image, &dst_image))
|
if (!_gst_vaapi_image_map(image, &dst_image))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -30,29 +30,11 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define GST_VAAPI_TYPE_IMAGE \
|
|
||||||
(gst_vaapi_image_get_type())
|
|
||||||
|
|
||||||
#define GST_VAAPI_IMAGE(obj) \
|
#define GST_VAAPI_IMAGE(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
((GstVaapiImage *)(obj))
|
||||||
GST_VAAPI_TYPE_IMAGE, \
|
|
||||||
GstVaapiImage))
|
|
||||||
|
|
||||||
#define GST_VAAPI_IMAGE_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_CAST((klass), \
|
|
||||||
GST_VAAPI_TYPE_IMAGE, \
|
|
||||||
GstVaapiImageClass))
|
|
||||||
|
|
||||||
#define GST_VAAPI_IS_IMAGE(obj) \
|
#define GST_VAAPI_IS_IMAGE(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_IMAGE))
|
((obj) != NULL)
|
||||||
|
|
||||||
#define GST_VAAPI_IS_IMAGE_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_IMAGE))
|
|
||||||
|
|
||||||
#define GST_VAAPI_IMAGE_GET_CLASS(obj) \
|
|
||||||
(G_TYPE_INSTANCE_GET_CLASS((obj), \
|
|
||||||
GST_VAAPI_TYPE_IMAGE, \
|
|
||||||
GstVaapiImageClass))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GST_VAAPI_IMAGE_FORMAT:
|
* GST_VAAPI_IMAGE_FORMAT:
|
||||||
|
@ -79,32 +61,8 @@ G_BEGIN_DECLS
|
||||||
#define GST_VAAPI_IMAGE_HEIGHT(image) gst_vaapi_image_get_height(image)
|
#define GST_VAAPI_IMAGE_HEIGHT(image) gst_vaapi_image_get_height(image)
|
||||||
|
|
||||||
typedef struct _GstVaapiImage GstVaapiImage;
|
typedef struct _GstVaapiImage GstVaapiImage;
|
||||||
typedef struct _GstVaapiImagePrivate GstVaapiImagePrivate;
|
|
||||||
typedef struct _GstVaapiImageClass GstVaapiImageClass;
|
|
||||||
typedef struct _GstVaapiImageRaw GstVaapiImageRaw;
|
typedef struct _GstVaapiImageRaw GstVaapiImageRaw;
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVaapiImage:
|
|
||||||
*
|
|
||||||
* A VA image wrapper
|
|
||||||
*/
|
|
||||||
struct _GstVaapiImage {
|
|
||||||
/*< private >*/
|
|
||||||
GstVaapiObject parent_instance;
|
|
||||||
|
|
||||||
GstVaapiImagePrivate *priv;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVaapiImageClass:
|
|
||||||
*
|
|
||||||
* A VA image wrapper class
|
|
||||||
*/
|
|
||||||
struct _GstVaapiImageClass {
|
|
||||||
/*< private >*/
|
|
||||||
GstVaapiObjectClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstVaapiImageRaw:
|
* GstVaapiImageRaw:
|
||||||
*
|
*
|
||||||
|
@ -120,9 +78,6 @@ struct _GstVaapiImageRaw {
|
||||||
guint stride[3];
|
guint stride[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
GType
|
|
||||||
gst_vaapi_image_get_type(void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
GstVaapiImage *
|
GstVaapiImage *
|
||||||
gst_vaapi_image_new(
|
gst_vaapi_image_new(
|
||||||
GstVaapiDisplay *display,
|
GstVaapiDisplay *display,
|
||||||
|
|
|
@ -30,37 +30,41 @@
|
||||||
#include "gstvaapicompat.h"
|
#include "gstvaapicompat.h"
|
||||||
#include "gstvaapiutils.h"
|
#include "gstvaapiutils.h"
|
||||||
#include "gstvaapisubpicture.h"
|
#include "gstvaapisubpicture.h"
|
||||||
#include "gstvaapi_priv.h"
|
#include "gstvaapiobject_priv.h"
|
||||||
|
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
#include "gstvaapidebug.h"
|
#include "gstvaapidebug.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, GST_VAAPI_TYPE_OBJECT)
|
typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass;
|
||||||
|
|
||||||
#define GST_VAAPI_SUBPICTURE_GET_PRIVATE(obj) \
|
/**
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
|
* GstVaapiSubpicture:
|
||||||
GST_VAAPI_TYPE_SUBPICTURE, \
|
*
|
||||||
GstVaapiSubpicturePrivate))
|
* A VA subpicture wrapper
|
||||||
|
*/
|
||||||
|
struct _GstVaapiSubpicture {
|
||||||
|
/*< private >*/
|
||||||
|
GstVaapiObject parent_instance;
|
||||||
|
|
||||||
struct _GstVaapiSubpicturePrivate {
|
|
||||||
GstVaapiImage *image;
|
GstVaapiImage *image;
|
||||||
guint flags;
|
guint flags;
|
||||||
gfloat global_alpha;
|
gfloat global_alpha;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
/**
|
||||||
PROP_0,
|
* GstVaapiSubpictureClass:
|
||||||
|
*
|
||||||
PROP_FLAGS,
|
* A VA subpicture wrapper class
|
||||||
PROP_GLOBAL_ALPHA,
|
*/
|
||||||
PROP_IMAGE
|
struct _GstVaapiSubpictureClass {
|
||||||
|
/*< private >*/
|
||||||
|
GstVaapiObjectClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture)
|
gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture)
|
||||||
{
|
{
|
||||||
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture);
|
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture);
|
||||||
GstVaapiSubpicturePrivate * const priv = subpicture->priv;
|
|
||||||
VASubpictureID subpicture_id;
|
VASubpictureID subpicture_id;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
|
|
||||||
|
@ -82,25 +86,21 @@ gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture)
|
||||||
}
|
}
|
||||||
GST_VAAPI_OBJECT_ID(subpicture) = VA_INVALID_ID;
|
GST_VAAPI_OBJECT_ID(subpicture) = VA_INVALID_ID;
|
||||||
}
|
}
|
||||||
|
gst_vaapi_object_replace(&subpicture->image, NULL);
|
||||||
g_clear_object(&priv->image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture)
|
gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture,
|
||||||
|
GstVaapiImage *image)
|
||||||
{
|
{
|
||||||
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture);
|
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture);
|
||||||
GstVaapiSubpicturePrivate * const priv = subpicture->priv;
|
|
||||||
VASubpictureID subpicture_id;
|
VASubpictureID subpicture_id;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
|
|
||||||
if (!priv->image)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
GST_VAAPI_DISPLAY_LOCK(display);
|
GST_VAAPI_DISPLAY_LOCK(display);
|
||||||
status = vaCreateSubpicture(
|
status = vaCreateSubpicture(
|
||||||
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
||||||
GST_VAAPI_OBJECT_ID(priv->image),
|
GST_VAAPI_OBJECT_ID(image),
|
||||||
&subpicture_id
|
&subpicture_id
|
||||||
);
|
);
|
||||||
GST_VAAPI_DISPLAY_UNLOCK(display);
|
GST_VAAPI_DISPLAY_UNLOCK(display);
|
||||||
|
@ -110,134 +110,12 @@ gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture)
|
||||||
GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT,
|
GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT,
|
||||||
GST_VAAPI_ID_ARGS(subpicture_id));
|
GST_VAAPI_ID_ARGS(subpicture_id));
|
||||||
GST_VAAPI_OBJECT_ID(subpicture) = subpicture_id;
|
GST_VAAPI_OBJECT_ID(subpicture) = subpicture_id;
|
||||||
|
subpicture->image = gst_vaapi_object_ref(image);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
#define gst_vaapi_subpicture_finalize gst_vaapi_subpicture_destroy
|
||||||
gst_vaapi_subpicture_finalize(GObject *object)
|
GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiSubpicture, gst_vaapi_subpicture)
|
||||||
{
|
|
||||||
gst_vaapi_subpicture_destroy(GST_VAAPI_SUBPICTURE(object));
|
|
||||||
|
|
||||||
G_OBJECT_CLASS(gst_vaapi_subpicture_parent_class)->finalize(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vaapi_subpicture_set_property(
|
|
||||||
GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
const GValue *value,
|
|
||||||
GParamSpec *pspec
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object);
|
|
||||||
|
|
||||||
switch (prop_id) {
|
|
||||||
case PROP_FLAGS:
|
|
||||||
subpicture->priv->flags = g_value_get_uint(value);
|
|
||||||
break;
|
|
||||||
case PROP_GLOBAL_ALPHA:
|
|
||||||
gst_vaapi_subpicture_set_global_alpha(subpicture,
|
|
||||||
g_value_get_float(value));
|
|
||||||
break;
|
|
||||||
case PROP_IMAGE:
|
|
||||||
gst_vaapi_subpicture_set_image(subpicture, g_value_get_object(value));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vaapi_subpicture_get_property(
|
|
||||||
GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object);
|
|
||||||
|
|
||||||
switch (prop_id) {
|
|
||||||
case PROP_FLAGS:
|
|
||||||
g_value_set_uint(value, subpicture->priv->flags);
|
|
||||||
break;
|
|
||||||
case PROP_GLOBAL_ALPHA:
|
|
||||||
g_value_set_float(value,
|
|
||||||
gst_vaapi_subpicture_get_global_alpha(subpicture));
|
|
||||||
break;
|
|
||||||
case PROP_IMAGE:
|
|
||||||
g_value_set_object(value, gst_vaapi_subpicture_get_image(subpicture));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vaapi_subpicture_class_init(GstVaapiSubpictureClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
|
|
||||||
|
|
||||||
g_type_class_add_private(klass, sizeof(GstVaapiSubpicturePrivate));
|
|
||||||
|
|
||||||
object_class->finalize = gst_vaapi_subpicture_finalize;
|
|
||||||
object_class->set_property = gst_vaapi_subpicture_set_property;
|
|
||||||
object_class->get_property = gst_vaapi_subpicture_get_property;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVaapiSubpicture:flags:
|
|
||||||
*
|
|
||||||
* The #GstVaapiSubpictureFlags this subpicture requires.
|
|
||||||
*/
|
|
||||||
g_object_class_install_property
|
|
||||||
(object_class,
|
|
||||||
PROP_FLAGS,
|
|
||||||
g_param_spec_uint("flags",
|
|
||||||
"Flags",
|
|
||||||
"The GstVaapiSubpictureFlags this subpicture requires",
|
|
||||||
0, G_MAXUINT32, 0,
|
|
||||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVaapiSubpicture:global-alpha:
|
|
||||||
*
|
|
||||||
* The global-alpha value associated with this subpicture.
|
|
||||||
*/
|
|
||||||
g_object_class_install_property
|
|
||||||
(object_class,
|
|
||||||
PROP_GLOBAL_ALPHA,
|
|
||||||
g_param_spec_float("global-alpha",
|
|
||||||
"Global Alpha",
|
|
||||||
"The global-alpha value associated with this subpicture",
|
|
||||||
0.0f, 1.0f, 1.0f,
|
|
||||||
G_PARAM_READWRITE));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVaapiSubpicture:image:
|
|
||||||
*
|
|
||||||
* The #GstVaapiImage this subpicture is bound to.
|
|
||||||
*/
|
|
||||||
g_object_class_install_property
|
|
||||||
(object_class,
|
|
||||||
PROP_IMAGE,
|
|
||||||
g_param_spec_object("image",
|
|
||||||
"Image",
|
|
||||||
"The GstVaapiImage this subpicture is bound to",
|
|
||||||
GST_VAAPI_TYPE_IMAGE,
|
|
||||||
G_PARAM_READWRITE));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture)
|
|
||||||
{
|
|
||||||
GstVaapiSubpicturePrivate *priv = GST_VAAPI_SUBPICTURE_GET_PRIVATE(subpicture);
|
|
||||||
|
|
||||||
subpicture->priv = priv;
|
|
||||||
priv->image = NULL;
|
|
||||||
priv->global_alpha = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_vaapi_subpicture_new:
|
* gst_vaapi_subpicture_new:
|
||||||
|
@ -252,6 +130,7 @@ gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture)
|
||||||
GstVaapiSubpicture *
|
GstVaapiSubpicture *
|
||||||
gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags)
|
gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags)
|
||||||
{
|
{
|
||||||
|
GstVaapiSubpicture *subpicture;
|
||||||
GstVaapiDisplay *display;
|
GstVaapiDisplay *display;
|
||||||
GstVaapiImageFormat format;
|
GstVaapiImageFormat format;
|
||||||
guint va_flags;
|
guint va_flags;
|
||||||
|
@ -268,13 +147,18 @@ gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags)
|
||||||
if (flags & ~va_flags)
|
if (flags & ~va_flags)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return g_object_new(GST_VAAPI_TYPE_SUBPICTURE,
|
subpicture = gst_vaapi_object_new(gst_vaapi_subpicture_class(), display);
|
||||||
"display", GST_VAAPI_OBJECT_DISPLAY(image),
|
if (!subpicture)
|
||||||
"id", GST_VAAPI_ID(VA_INVALID_ID),
|
return NULL;
|
||||||
"flags", flags,
|
|
||||||
"global-alpha", 1.0f,
|
subpicture->global_alpha = 1.0f;
|
||||||
"image", image,
|
if (!gst_vaapi_subpicture_set_image(subpicture, image))
|
||||||
NULL);
|
goto error;
|
||||||
|
return subpicture;
|
||||||
|
|
||||||
|
error:
|
||||||
|
gst_vaapi_object_unref(subpicture);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -358,12 +242,12 @@ gst_vaapi_subpicture_new_from_overlay_rectangle(
|
||||||
raw_image.stride[0] = stride;
|
raw_image.stride[0] = stride;
|
||||||
if (!gst_vaapi_image_update_from_raw(image, &raw_image, NULL)) {
|
if (!gst_vaapi_image_update_from_raw(image, &raw_image, NULL)) {
|
||||||
GST_WARNING("could not update VA image with subtitle data");
|
GST_WARNING("could not update VA image with subtitle data");
|
||||||
g_object_unref(image);
|
gst_vaapi_object_unref(image);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
subpicture = gst_vaapi_subpicture_new(image, flags);
|
subpicture = gst_vaapi_subpicture_new(image, flags);
|
||||||
g_object_unref(image);
|
gst_vaapi_object_unref(image);
|
||||||
#if GST_CHECK_VERSION(1,0,0)
|
#if GST_CHECK_VERSION(1,0,0)
|
||||||
gst_video_meta_unmap(vmeta, 0, &map_info);
|
gst_video_meta_unmap(vmeta, 0, &map_info);
|
||||||
#endif
|
#endif
|
||||||
|
@ -407,7 +291,7 @@ gst_vaapi_subpicture_get_flags(GstVaapiSubpicture *subpicture)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), 0);
|
g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), 0);
|
||||||
|
|
||||||
return subpicture->priv->flags;
|
return subpicture->flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -423,7 +307,7 @@ gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), NULL);
|
g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), NULL);
|
||||||
|
|
||||||
return subpicture->priv->image;
|
return subpicture->image;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -433,20 +317,18 @@ gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture)
|
||||||
*
|
*
|
||||||
* Binds a new #GstVaapiImage to the @subpicture. The reference to the
|
* Binds a new #GstVaapiImage to the @subpicture. The reference to the
|
||||||
* previous image is released and a new one is acquired on @image.
|
* previous image is released and a new one is acquired on @image.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE on success
|
||||||
*/
|
*/
|
||||||
void
|
gboolean
|
||||||
gst_vaapi_subpicture_set_image(
|
gst_vaapi_subpicture_set_image(GstVaapiSubpicture *subpicture,
|
||||||
GstVaapiSubpicture *subpicture,
|
GstVaapiImage *image)
|
||||||
GstVaapiImage *image
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
g_return_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture));
|
g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE);
|
||||||
g_return_if_fail(GST_VAAPI_IS_IMAGE(image));
|
g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
|
||||||
|
|
||||||
gst_vaapi_subpicture_destroy(subpicture);
|
gst_vaapi_subpicture_destroy(subpicture);
|
||||||
|
return gst_vaapi_subpicture_create(subpicture, image);
|
||||||
subpicture->priv->image = g_object_ref(image);
|
|
||||||
gst_vaapi_subpicture_create(subpicture);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -462,7 +344,7 @@ gst_vaapi_subpicture_get_global_alpha(GstVaapiSubpicture *subpicture)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), 1.0);
|
g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), 1.0);
|
||||||
|
|
||||||
return subpicture->priv->global_alpha;
|
return subpicture->global_alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -480,18 +362,15 @@ gboolean
|
||||||
gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture,
|
gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture,
|
||||||
gfloat global_alpha)
|
gfloat global_alpha)
|
||||||
{
|
{
|
||||||
GstVaapiSubpicturePrivate *priv;
|
|
||||||
GstVaapiDisplay *display;
|
GstVaapiDisplay *display;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
|
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE);
|
||||||
|
|
||||||
priv = subpicture->priv;
|
if (!(subpicture->flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA))
|
||||||
|
|
||||||
if (!(priv->flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (priv->global_alpha == global_alpha)
|
if (subpicture->global_alpha == global_alpha)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
display = GST_VAAPI_OBJECT_DISPLAY(subpicture);
|
display = GST_VAAPI_OBJECT_DISPLAY(subpicture);
|
||||||
|
@ -506,6 +385,6 @@ gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture,
|
||||||
if (!vaapi_check_status(status, "vaSetSubpictureGlobalAlpha()"))
|
if (!vaapi_check_status(status, "vaSetSubpictureGlobalAlpha()"))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
priv->global_alpha = global_alpha;
|
subpicture->global_alpha = global_alpha;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,33 +30,13 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define GST_VAAPI_TYPE_SUBPICTURE \
|
|
||||||
(gst_vaapi_subpicture_get_type())
|
|
||||||
|
|
||||||
#define GST_VAAPI_SUBPICTURE(obj) \
|
#define GST_VAAPI_SUBPICTURE(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
((GstVaapiSubpicture *)(obj))
|
||||||
GST_VAAPI_TYPE_SUBPICTURE, \
|
|
||||||
GstVaapiSubpicture))
|
|
||||||
|
|
||||||
#define GST_VAAPI_SUBPICTURE_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_CAST((klass), \
|
|
||||||
GST_VAAPI_TYPE_SUBPICTURE, \
|
|
||||||
GstVaapiSubpictureClass))
|
|
||||||
|
|
||||||
#define GST_VAAPI_IS_SUBPICTURE(obj) \
|
#define GST_VAAPI_IS_SUBPICTURE(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SUBPICTURE))
|
((obj) != NULL)
|
||||||
|
|
||||||
#define GST_VAAPI_IS_SUBPICTURE_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SUBPICTURE))
|
|
||||||
|
|
||||||
#define GST_VAAPI_SUBPICTURE_GET_CLASS(obj) \
|
|
||||||
(G_TYPE_INSTANCE_GET_CLASS((obj), \
|
|
||||||
GST_VAAPI_TYPE_SUBPICTURE, \
|
|
||||||
GstVaapiSubpictureClass))
|
|
||||||
|
|
||||||
typedef struct _GstVaapiSubpicture GstVaapiSubpicture;
|
typedef struct _GstVaapiSubpicture GstVaapiSubpicture;
|
||||||
typedef struct _GstVaapiSubpicturePrivate GstVaapiSubpicturePrivate;
|
|
||||||
typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstVaapiSubpictureFlags:
|
* GstVaapiSubpictureFlags:
|
||||||
|
@ -73,31 +53,6 @@ typedef enum {
|
||||||
GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA = (1 << 1),
|
GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA = (1 << 1),
|
||||||
} GstVaapiSubpictureFlags;
|
} GstVaapiSubpictureFlags;
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVaapiSubpicture:
|
|
||||||
*
|
|
||||||
* A VA subpicture wrapper
|
|
||||||
*/
|
|
||||||
struct _GstVaapiSubpicture {
|
|
||||||
/*< private >*/
|
|
||||||
GstVaapiObject parent_instance;
|
|
||||||
|
|
||||||
GstVaapiSubpicturePrivate *priv;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVaapiSubpictureClass:
|
|
||||||
*
|
|
||||||
* A VA subpicture wrapper class
|
|
||||||
*/
|
|
||||||
struct _GstVaapiSubpictureClass {
|
|
||||||
/*< private >*/
|
|
||||||
GstVaapiObjectClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
GType
|
|
||||||
gst_vaapi_subpicture_get_type(void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
GstVaapiSubpicture *
|
GstVaapiSubpicture *
|
||||||
gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags);
|
gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags);
|
||||||
|
|
||||||
|
@ -116,11 +71,9 @@ gst_vaapi_subpicture_get_flags(GstVaapiSubpicture *subpicture);
|
||||||
GstVaapiImage *
|
GstVaapiImage *
|
||||||
gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture);
|
gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture);
|
||||||
|
|
||||||
void
|
gboolean
|
||||||
gst_vaapi_subpicture_set_image(
|
gst_vaapi_subpicture_set_image(GstVaapiSubpicture *subpicture,
|
||||||
GstVaapiSubpicture *subpicture,
|
GstVaapiImage *image);
|
||||||
GstVaapiImage *image
|
|
||||||
);
|
|
||||||
|
|
||||||
gfloat
|
gfloat
|
||||||
gst_vaapi_subpicture_get_global_alpha(GstVaapiSubpicture *subpicture);
|
gst_vaapi_subpicture_get_global_alpha(GstVaapiSubpicture *subpicture);
|
||||||
|
|
|
@ -30,21 +30,24 @@
|
||||||
#include "gstvaapiutils.h"
|
#include "gstvaapiutils.h"
|
||||||
#include "gstvaapisurface.h"
|
#include "gstvaapisurface.h"
|
||||||
#include "gstvaapisurface_priv.h"
|
#include "gstvaapisurface_priv.h"
|
||||||
|
#include "gstvaapiobject_priv.h"
|
||||||
#include "gstvaapicontext.h"
|
#include "gstvaapicontext.h"
|
||||||
#include "gstvaapiimage.h"
|
#include "gstvaapiimage.h"
|
||||||
#include "gstvaapi_priv.h"
|
|
||||||
|
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
#include "gstvaapidebug.h"
|
#include "gstvaapidebug.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE(GstVaapiSurface, gst_vaapi_surface, GST_VAAPI_TYPE_OBJECT)
|
typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass;
|
||||||
|
|
||||||
#define GST_VAAPI_SURFACE_GET_PRIVATE(obj) \
|
/**
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
|
* GstVaapiSurface:
|
||||||
GST_VAAPI_TYPE_SURFACE, \
|
*
|
||||||
GstVaapiSurfacePrivate))
|
* A VA surface wrapper.
|
||||||
|
*/
|
||||||
|
struct _GstVaapiSurface {
|
||||||
|
/*< private >*/
|
||||||
|
GstVaapiObject parent_instance;
|
||||||
|
|
||||||
struct _GstVaapiSurfacePrivate {
|
|
||||||
guint width;
|
guint width;
|
||||||
guint height;
|
guint height;
|
||||||
GstVaapiChromaType chroma_type;
|
GstVaapiChromaType chroma_type;
|
||||||
|
@ -52,13 +55,14 @@ struct _GstVaapiSurfacePrivate {
|
||||||
GstVaapiContext *parent_context;
|
GstVaapiContext *parent_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
/**
|
||||||
PROP_0,
|
* GstVaapiSurfaceClass:
|
||||||
|
*
|
||||||
PROP_WIDTH,
|
* A VA surface wrapper class.
|
||||||
PROP_HEIGHT,
|
*/
|
||||||
PROP_CHROMA_TYPE,
|
struct _GstVaapiSurfaceClass {
|
||||||
PROP_PARENT_CONTEXT
|
/*< private >*/
|
||||||
|
GstVaapiObjectClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -79,18 +83,17 @@ static void
|
||||||
destroy_subpicture_cb(gpointer subpicture, gpointer surface)
|
destroy_subpicture_cb(gpointer subpicture, gpointer surface)
|
||||||
{
|
{
|
||||||
_gst_vaapi_surface_deassociate_subpicture(surface, subpicture);
|
_gst_vaapi_surface_deassociate_subpicture(surface, subpicture);
|
||||||
g_object_unref(subpicture);
|
gst_vaapi_object_unref(subpicture);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vaapi_surface_destroy_subpictures(GstVaapiSurface *surface)
|
gst_vaapi_surface_destroy_subpictures(GstVaapiSurface *surface)
|
||||||
{
|
{
|
||||||
GstVaapiSurfacePrivate * const priv = surface->priv;
|
if (surface->subpictures) {
|
||||||
|
g_ptr_array_foreach(surface->subpictures, destroy_subpicture_cb,
|
||||||
if (priv->subpictures) {
|
surface);
|
||||||
g_ptr_array_foreach(priv->subpictures, destroy_subpicture_cb, surface);
|
g_ptr_array_free(surface->subpictures, TRUE);
|
||||||
g_ptr_array_free(priv->subpictures, TRUE);
|
surface->subpictures = NULL;
|
||||||
priv->subpictures = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,15 +125,15 @@ gst_vaapi_surface_destroy(GstVaapiSurface *surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vaapi_surface_create(GstVaapiSurface *surface)
|
gst_vaapi_surface_create(GstVaapiSurface *surface,
|
||||||
|
GstVaapiChromaType chroma_type, guint width, guint height)
|
||||||
{
|
{
|
||||||
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface);
|
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface);
|
||||||
GstVaapiSurfacePrivate * const priv = surface->priv;
|
|
||||||
VASurfaceID surface_id;
|
VASurfaceID surface_id;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
guint format;
|
guint format;
|
||||||
|
|
||||||
switch (priv->chroma_type) {
|
switch (chroma_type) {
|
||||||
case GST_VAAPI_CHROMA_TYPE_YUV420:
|
case GST_VAAPI_CHROMA_TYPE_YUV420:
|
||||||
format = VA_RT_FORMAT_YUV420;
|
format = VA_RT_FORMAT_YUV420;
|
||||||
break;
|
break;
|
||||||
|
@ -141,168 +144,31 @@ gst_vaapi_surface_create(GstVaapiSurface *surface)
|
||||||
format = VA_RT_FORMAT_YUV444;
|
format = VA_RT_FORMAT_YUV444;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GST_DEBUG("unsupported chroma-type %u\n", priv->chroma_type);
|
GST_DEBUG("unsupported chroma-type %u\n", chroma_type);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_VAAPI_DISPLAY_LOCK(display);
|
GST_VAAPI_DISPLAY_LOCK(display);
|
||||||
status = vaCreateSurfaces(
|
status = vaCreateSurfaces(
|
||||||
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
GST_VAAPI_DISPLAY_VADISPLAY(display),
|
||||||
priv->width,
|
width, height, format,
|
||||||
priv->height,
|
|
||||||
format,
|
|
||||||
1, &surface_id
|
1, &surface_id
|
||||||
);
|
);
|
||||||
GST_VAAPI_DISPLAY_UNLOCK(display);
|
GST_VAAPI_DISPLAY_UNLOCK(display);
|
||||||
if (!vaapi_check_status(status, "vaCreateSurfaces()"))
|
if (!vaapi_check_status(status, "vaCreateSurfaces()"))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
surface->chroma_type = chroma_type;
|
||||||
|
surface->width = width;
|
||||||
|
surface->height = height;
|
||||||
|
|
||||||
GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id));
|
GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id));
|
||||||
GST_VAAPI_OBJECT_ID(surface) = surface_id;
|
GST_VAAPI_OBJECT_ID(surface) = surface_id;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
#define gst_vaapi_surface_finalize gst_vaapi_surface_destroy
|
||||||
gst_vaapi_surface_finalize(GObject *object)
|
GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiSurface, gst_vaapi_surface)
|
||||||
{
|
|
||||||
gst_vaapi_surface_destroy(GST_VAAPI_SURFACE(object));
|
|
||||||
|
|
||||||
G_OBJECT_CLASS(gst_vaapi_surface_parent_class)->finalize(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vaapi_surface_set_property(
|
|
||||||
GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
const GValue *value,
|
|
||||||
GParamSpec *pspec
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object);
|
|
||||||
GstVaapiSurfacePrivate * const priv = surface->priv;
|
|
||||||
|
|
||||||
switch (prop_id) {
|
|
||||||
case PROP_WIDTH:
|
|
||||||
priv->width = g_value_get_uint(value);
|
|
||||||
break;
|
|
||||||
case PROP_HEIGHT:
|
|
||||||
priv->height = g_value_get_uint(value);
|
|
||||||
break;
|
|
||||||
case PROP_CHROMA_TYPE:
|
|
||||||
priv->chroma_type = g_value_get_uint(value);
|
|
||||||
break;
|
|
||||||
case PROP_PARENT_CONTEXT:
|
|
||||||
gst_vaapi_surface_set_parent_context(surface, g_value_get_object(value));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vaapi_surface_get_property(
|
|
||||||
GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object);
|
|
||||||
|
|
||||||
switch (prop_id) {
|
|
||||||
case PROP_WIDTH:
|
|
||||||
g_value_set_uint(value, gst_vaapi_surface_get_width(surface));
|
|
||||||
break;
|
|
||||||
case PROP_HEIGHT:
|
|
||||||
g_value_set_uint(value, gst_vaapi_surface_get_height(surface));
|
|
||||||
break;
|
|
||||||
case PROP_CHROMA_TYPE:
|
|
||||||
g_value_set_uint(value, gst_vaapi_surface_get_chroma_type(surface));
|
|
||||||
break;
|
|
||||||
case PROP_PARENT_CONTEXT:
|
|
||||||
g_value_set_object(value, gst_vaapi_surface_get_parent_context(surface));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vaapi_surface_constructed(GObject *object)
|
|
||||||
{
|
|
||||||
GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object);
|
|
||||||
GObjectClass *parent_class;
|
|
||||||
|
|
||||||
gst_vaapi_surface_create(surface);
|
|
||||||
|
|
||||||
parent_class = G_OBJECT_CLASS(gst_vaapi_surface_parent_class);
|
|
||||||
if (parent_class->constructed)
|
|
||||||
parent_class->constructed(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vaapi_surface_class_init(GstVaapiSurfaceClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
|
|
||||||
|
|
||||||
g_type_class_add_private(klass, sizeof(GstVaapiSurfacePrivate));
|
|
||||||
|
|
||||||
object_class->finalize = gst_vaapi_surface_finalize;
|
|
||||||
object_class->set_property = gst_vaapi_surface_set_property;
|
|
||||||
object_class->get_property = gst_vaapi_surface_get_property;
|
|
||||||
object_class->constructed = gst_vaapi_surface_constructed;
|
|
||||||
|
|
||||||
g_object_class_install_property
|
|
||||||
(object_class,
|
|
||||||
PROP_WIDTH,
|
|
||||||
g_param_spec_uint("width",
|
|
||||||
"Width",
|
|
||||||
"The width of the surface",
|
|
||||||
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 surface",
|
|
||||||
0, G_MAXINT32, 0,
|
|
||||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
|
||||||
|
|
||||||
g_object_class_install_property
|
|
||||||
(object_class,
|
|
||||||
PROP_CHROMA_TYPE,
|
|
||||||
g_param_spec_uint("chroma-type",
|
|
||||||
"Chroma type",
|
|
||||||
"The chroma type of the surface",
|
|
||||||
0, G_MAXUINT32, 0,
|
|
||||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
|
||||||
|
|
||||||
g_object_class_install_property
|
|
||||||
(object_class,
|
|
||||||
PROP_PARENT_CONTEXT,
|
|
||||||
g_param_spec_object("parent-context",
|
|
||||||
"Parent Context",
|
|
||||||
"The parent context, if any",
|
|
||||||
GST_VAAPI_TYPE_CONTEXT,
|
|
||||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vaapi_surface_init(GstVaapiSurface *surface)
|
|
||||||
{
|
|
||||||
GstVaapiSurfacePrivate *priv = GST_VAAPI_SURFACE_GET_PRIVATE(surface);
|
|
||||||
|
|
||||||
surface->priv = priv;
|
|
||||||
priv->width = 0;
|
|
||||||
priv->height = 0;
|
|
||||||
priv->chroma_type = 0;
|
|
||||||
priv->subpictures = NULL;
|
|
||||||
priv->parent_context = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_vaapi_surface_new:
|
* gst_vaapi_surface_new:
|
||||||
|
@ -324,15 +190,21 @@ gst_vaapi_surface_new(
|
||||||
guint height
|
guint height
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
GstVaapiSurface *surface;
|
||||||
|
|
||||||
GST_DEBUG("size %ux%u, chroma type 0x%x", width, height, chroma_type);
|
GST_DEBUG("size %ux%u, chroma type 0x%x", width, height, chroma_type);
|
||||||
|
|
||||||
return g_object_new(GST_VAAPI_TYPE_SURFACE,
|
surface = gst_vaapi_object_new(gst_vaapi_surface_class(), display);
|
||||||
"display", display,
|
if (!surface)
|
||||||
"id", GST_VAAPI_ID(VA_INVALID_ID),
|
return NULL;
|
||||||
"width", width,
|
|
||||||
"height", height,
|
if (!gst_vaapi_surface_create(surface, chroma_type, width, height))
|
||||||
"chroma-type", chroma_type,
|
goto error;
|
||||||
NULL);
|
return surface;
|
||||||
|
|
||||||
|
error:
|
||||||
|
gst_vaapi_object_unref(surface);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -364,7 +236,7 @@ gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0);
|
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0);
|
||||||
|
|
||||||
return surface->priv->chroma_type;
|
return surface->chroma_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -380,7 +252,7 @@ gst_vaapi_surface_get_width(GstVaapiSurface *surface)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0);
|
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0);
|
||||||
|
|
||||||
return surface->priv->width;
|
return surface->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -396,7 +268,7 @@ gst_vaapi_surface_get_height(GstVaapiSurface *surface)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0);
|
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0);
|
||||||
|
|
||||||
return surface->priv->height;
|
return surface->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -438,16 +310,9 @@ gst_vaapi_surface_set_parent_context(
|
||||||
GstVaapiContext *context
|
GstVaapiContext *context
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
GstVaapiSurfacePrivate *priv;
|
|
||||||
|
|
||||||
g_return_if_fail(GST_VAAPI_IS_SURFACE(surface));
|
g_return_if_fail(GST_VAAPI_IS_SURFACE(surface));
|
||||||
|
|
||||||
priv = surface->priv;
|
gst_vaapi_object_replace(&surface->parent_context, context);
|
||||||
|
|
||||||
g_clear_object(&priv->parent_context);
|
|
||||||
|
|
||||||
if (context)
|
|
||||||
priv->parent_context = g_object_ref(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -465,7 +330,7 @@ gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL);
|
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL);
|
||||||
|
|
||||||
return surface->priv->parent_context;
|
return surface->parent_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -487,7 +352,7 @@ gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface)
|
||||||
* unreferenced when it's no longer needed. The image and image buffer
|
* unreferenced when it's no longer needed. The image and image buffer
|
||||||
* data structures will be destroyed. However, the surface contents
|
* data structures will be destroyed. However, the surface contents
|
||||||
* will remain unchanged until destroyed through the last call to
|
* will remain unchanged until destroyed through the last call to
|
||||||
* g_object_unref().
|
* gst_vaapi_object_unref().
|
||||||
*
|
*
|
||||||
* Return value: the newly allocated #GstVaapiImage object, or %NULL
|
* Return value: the newly allocated #GstVaapiImage object, or %NULL
|
||||||
* on failure
|
* on failure
|
||||||
|
@ -546,7 +411,7 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
gst_vaapi_image_get_size(image, &width, &height);
|
gst_vaapi_image_get_size(image, &width, &height);
|
||||||
if (width != surface->priv->width || height != surface->priv->height)
|
if (width != surface->width || height != surface->height)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
image_id = GST_VAAPI_OBJECT_ID(image);
|
image_id = GST_VAAPI_OBJECT_ID(image);
|
||||||
|
@ -593,7 +458,7 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
gst_vaapi_image_get_size(image, &width, &height);
|
gst_vaapi_image_get_size(image, &width, &height);
|
||||||
if (width != surface->priv->width || height != surface->priv->height)
|
if (width != surface->width || height != surface->height)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
image_id = GST_VAAPI_OBJECT_ID(image);
|
image_id = GST_VAAPI_OBJECT_ID(image);
|
||||||
|
@ -646,15 +511,16 @@ gst_vaapi_surface_associate_subpicture(
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE);
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE);
|
||||||
|
|
||||||
if (!surface->priv->subpictures) {
|
if (!surface->subpictures) {
|
||||||
surface->priv->subpictures = g_ptr_array_new();
|
surface->subpictures = g_ptr_array_new();
|
||||||
if (!surface->priv->subpictures)
|
if (!surface->subpictures)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_ptr_array_remove_fast(surface->priv->subpictures, subpicture)) {
|
if (g_ptr_array_remove_fast(surface->subpictures, subpicture)) {
|
||||||
success = _gst_vaapi_surface_deassociate_subpicture(surface, subpicture);
|
success = _gst_vaapi_surface_deassociate_subpicture(surface,
|
||||||
g_object_unref(subpicture);
|
subpicture);
|
||||||
|
gst_vaapi_object_unref(subpicture);
|
||||||
if (!success)
|
if (!success)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -668,7 +534,7 @@ gst_vaapi_surface_associate_subpicture(
|
||||||
if (!success)
|
if (!success)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
g_ptr_array_add(surface->priv->subpictures, g_object_ref(subpicture));
|
g_ptr_array_add(surface->subpictures, gst_vaapi_object_ref(subpicture));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,8 +578,8 @@ _gst_vaapi_surface_associate_subpicture(
|
||||||
dst_rect = &dst_rect_default;
|
dst_rect = &dst_rect_default;
|
||||||
dst_rect_default.x = 0;
|
dst_rect_default.x = 0;
|
||||||
dst_rect_default.y = 0;
|
dst_rect_default.y = 0;
|
||||||
dst_rect_default.width = surface->priv->width;
|
dst_rect_default.width = surface->width;
|
||||||
dst_rect_default.height = surface->priv->height;
|
dst_rect_default.height = surface->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_VAAPI_DISPLAY_LOCK(display);
|
GST_VAAPI_DISPLAY_LOCK(display);
|
||||||
|
@ -752,11 +618,11 @@ gst_vaapi_surface_deassociate_subpicture(
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE);
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE);
|
||||||
|
|
||||||
if (!surface->priv->subpictures)
|
if (!surface->subpictures)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* First, check subpicture was really associated with this surface */
|
/* First, check subpicture was really associated with this surface */
|
||||||
if (!g_ptr_array_remove_fast(surface->priv->subpictures, subpicture)) {
|
if (!g_ptr_array_remove_fast(surface->subpictures, subpicture)) {
|
||||||
GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT " was not bound to "
|
GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT " was not bound to "
|
||||||
"surface %" GST_VAAPI_ID_FORMAT,
|
"surface %" GST_VAAPI_ID_FORMAT,
|
||||||
GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(subpicture)),
|
GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(subpicture)),
|
||||||
|
@ -765,7 +631,7 @@ gst_vaapi_surface_deassociate_subpicture(
|
||||||
}
|
}
|
||||||
|
|
||||||
success = _gst_vaapi_surface_deassociate_subpicture(surface, subpicture);
|
success = _gst_vaapi_surface_deassociate_subpicture(surface, subpicture);
|
||||||
g_object_unref(subpicture);
|
gst_vaapi_object_unref(subpicture);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -894,11 +760,9 @@ gst_vaapi_surface_set_subpictures_from_composition(
|
||||||
|
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE);
|
||||||
|
|
||||||
if (propagate_context) {
|
if (propagate_context && surface->parent_context)
|
||||||
GstVaapiContext * const context = surface->priv->parent_context;
|
return gst_vaapi_context_apply_composition(surface->parent_context,
|
||||||
if (context)
|
composition);
|
||||||
return gst_vaapi_context_apply_composition(context, composition);
|
|
||||||
}
|
|
||||||
|
|
||||||
display = GST_VAAPI_OBJECT_DISPLAY(surface);
|
display = GST_VAAPI_OBJECT_DISPLAY(surface);
|
||||||
if (!display)
|
if (!display)
|
||||||
|
@ -929,10 +793,10 @@ gst_vaapi_surface_set_subpictures_from_composition(
|
||||||
if (!gst_vaapi_surface_associate_subpicture (surface, subpicture,
|
if (!gst_vaapi_surface_associate_subpicture (surface, subpicture,
|
||||||
NULL, &sub_rect)) {
|
NULL, &sub_rect)) {
|
||||||
GST_WARNING ("could not render overlay rectangle %p", rect);
|
GST_WARNING ("could not render overlay rectangle %p", rect);
|
||||||
g_object_unref (subpicture);
|
gst_vaapi_object_unref (subpicture);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
g_object_unref (subpicture);
|
gst_vaapi_object_unref (subpicture);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,60 +112,15 @@ typedef enum {
|
||||||
GST_VAAPI_COLOR_STANDARD_ITUR_BT_709 = 1 << 3,
|
GST_VAAPI_COLOR_STANDARD_ITUR_BT_709 = 1 << 3,
|
||||||
} GstVaapiSurfaceRenderFlags;
|
} GstVaapiSurfaceRenderFlags;
|
||||||
|
|
||||||
#define GST_VAAPI_TYPE_SURFACE \
|
|
||||||
(gst_vaapi_surface_get_type())
|
|
||||||
|
|
||||||
#define GST_VAAPI_SURFACE(obj) \
|
#define GST_VAAPI_SURFACE(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
((GstVaapiSurface *)(obj))
|
||||||
GST_VAAPI_TYPE_SURFACE, \
|
|
||||||
GstVaapiSurface))
|
|
||||||
|
|
||||||
#define GST_VAAPI_SURFACE_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_CAST((klass), \
|
|
||||||
GST_VAAPI_TYPE_SURFACE, \
|
|
||||||
GstVaapiSurfaceClass))
|
|
||||||
|
|
||||||
#define GST_VAAPI_IS_SURFACE(obj) \
|
#define GST_VAAPI_IS_SURFACE(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SURFACE))
|
((obj) != NULL)
|
||||||
|
|
||||||
#define GST_VAAPI_IS_SURFACE_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SURFACE))
|
|
||||||
|
|
||||||
#define GST_VAAPI_SURFACE_GET_CLASS(obj) \
|
|
||||||
(G_TYPE_INSTANCE_GET_CLASS((obj), \
|
|
||||||
GST_VAAPI_TYPE_SURFACE, \
|
|
||||||
GstVaapiSurfaceClass))
|
|
||||||
|
|
||||||
typedef struct _GstVaapiSurface GstVaapiSurface;
|
typedef struct _GstVaapiSurface GstVaapiSurface;
|
||||||
typedef struct _GstVaapiSurfacePrivate GstVaapiSurfacePrivate;
|
|
||||||
typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass;
|
|
||||||
typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy;
|
typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy;
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVaapiSurface:
|
|
||||||
*
|
|
||||||
* A VA surface wrapper.
|
|
||||||
*/
|
|
||||||
struct _GstVaapiSurface {
|
|
||||||
/*< private >*/
|
|
||||||
GstVaapiObject parent_instance;
|
|
||||||
|
|
||||||
GstVaapiSurfacePrivate *priv;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVaapiSurfaceClass:
|
|
||||||
*
|
|
||||||
* A VA surface wrapper class.
|
|
||||||
*/
|
|
||||||
struct _GstVaapiSurfaceClass {
|
|
||||||
/*< private >*/
|
|
||||||
GstVaapiObjectClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
GType
|
|
||||||
gst_vaapi_surface_get_type(void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
GstVaapiSurface *
|
GstVaapiSurface *
|
||||||
gst_vaapi_surface_new(
|
gst_vaapi_surface_new(
|
||||||
GstVaapiDisplay *display,
|
GstVaapiDisplay *display,
|
||||||
|
|
|
@ -41,7 +41,7 @@ gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy)
|
||||||
if (proxy->surface) {
|
if (proxy->surface) {
|
||||||
if (proxy->pool)
|
if (proxy->pool)
|
||||||
gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface);
|
gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface);
|
||||||
g_object_unref(proxy->surface);
|
gst_vaapi_object_unref(proxy->surface);
|
||||||
proxy->surface = NULL;
|
proxy->surface = NULL;
|
||||||
}
|
}
|
||||||
g_clear_object(&proxy->pool);
|
g_clear_object(&proxy->pool);
|
||||||
|
@ -76,7 +76,7 @@ gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool)
|
||||||
proxy->timestamp = GST_CLOCK_TIME_NONE;
|
proxy->timestamp = GST_CLOCK_TIME_NONE;
|
||||||
proxy->duration = GST_CLOCK_TIME_NONE;
|
proxy->duration = GST_CLOCK_TIME_NONE;
|
||||||
proxy->destroy_func = NULL;
|
proxy->destroy_func = NULL;
|
||||||
g_object_ref(proxy->surface);
|
gst_vaapi_object_ref(proxy->surface);
|
||||||
return proxy;
|
return proxy;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include "sysdeps.h"
|
#include "sysdeps.h"
|
||||||
#include "gstvaapivideopool.h"
|
#include "gstvaapivideopool.h"
|
||||||
|
#include "gstvaapiobject.h"
|
||||||
|
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
#include "gstvaapidebug.h"
|
#include "gstvaapidebug.h"
|
||||||
|
@ -75,13 +76,13 @@ gst_vaapi_video_pool_clear(GstVaapiVideoPool *pool)
|
||||||
|
|
||||||
for (list = priv->used_objects; list; list = next) {
|
for (list = priv->used_objects; list; list = next) {
|
||||||
next = list->next;
|
next = list->next;
|
||||||
g_object_unref(list->data);
|
gst_vaapi_object_unref(list->data);
|
||||||
g_list_free_1(list);
|
g_list_free_1(list);
|
||||||
}
|
}
|
||||||
priv->used_objects = NULL;
|
priv->used_objects = NULL;
|
||||||
|
|
||||||
while ((object = g_queue_pop_head(&priv->free_objects)))
|
while ((object = g_queue_pop_head(&priv->free_objects)))
|
||||||
g_object_unref(object);
|
gst_vaapi_object_unref(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -313,7 +314,7 @@ gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool)
|
||||||
|
|
||||||
++priv->used_count;
|
++priv->used_count;
|
||||||
priv->used_objects = g_list_prepend(priv->used_objects, object);
|
priv->used_objects = g_list_prepend(priv->used_objects, object);
|
||||||
return g_object_ref(object);
|
return gst_vaapi_object_ref(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -333,14 +334,14 @@ gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object)
|
||||||
GList *elem;
|
GList *elem;
|
||||||
|
|
||||||
g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool));
|
g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool));
|
||||||
g_return_if_fail(G_IS_OBJECT(object));
|
g_return_if_fail(GST_VAAPI_IS_OBJECT(object));
|
||||||
|
|
||||||
priv = pool->priv;
|
priv = pool->priv;
|
||||||
elem = g_list_find(priv->used_objects, object);
|
elem = g_list_find(priv->used_objects, object);
|
||||||
if (!elem)
|
if (!elem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_object_unref(object);
|
gst_vaapi_object_unref(object);
|
||||||
--priv->used_count;
|
--priv->used_count;
|
||||||
priv->used_objects = g_list_delete_link(priv->used_objects, elem);
|
priv->used_objects = g_list_delete_link(priv->used_objects, elem);
|
||||||
g_queue_push_tail(&priv->free_objects, object);
|
g_queue_push_tail(&priv->free_objects, object);
|
||||||
|
@ -361,9 +362,9 @@ gboolean
|
||||||
gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object)
|
gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), FALSE);
|
||||||
g_return_val_if_fail(G_IS_OBJECT(object), FALSE);
|
g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), FALSE);
|
||||||
|
|
||||||
g_queue_push_tail(&pool->priv->free_objects, g_object_ref(object));
|
g_queue_push_tail(&pool->priv->free_objects, gst_vaapi_object_ref(object));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue