mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
context: allow number of reference frames to be set.
Make it possible to specify the maximum number of references to use within a single VA context. This helps reducing GPU memory allocations to the useful number of references to be used.
This commit is contained in:
parent
d895e17db8
commit
4ca1f3f47c
2 changed files with 124 additions and 25 deletions
|
@ -65,6 +65,7 @@ struct _GstVaapiContextPrivate {
|
||||||
GstVaapiEntrypoint entrypoint;
|
GstVaapiEntrypoint entrypoint;
|
||||||
guint width;
|
guint width;
|
||||||
guint height;
|
guint height;
|
||||||
|
guint ref_frames;
|
||||||
guint is_constructed : 1;
|
guint is_constructed : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,9 +75,22 @@ enum {
|
||||||
PROP_PROFILE,
|
PROP_PROFILE,
|
||||||
PROP_ENTRYPOINT,
|
PROP_ENTRYPOINT,
|
||||||
PROP_WIDTH,
|
PROP_WIDTH,
|
||||||
PROP_HEIGHT
|
PROP_HEIGHT,
|
||||||
|
PROP_REF_FRAMES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static guint
|
||||||
|
get_max_ref_frames(GstVaapiProfile profile)
|
||||||
|
{
|
||||||
|
guint ref_frames;
|
||||||
|
|
||||||
|
switch (gst_vaapi_profile_get_codec(profile)) {
|
||||||
|
case GST_VAAPI_CODEC_H264: ref_frames = 16; break;
|
||||||
|
default: ref_frames = 2; break;
|
||||||
|
}
|
||||||
|
return ref_frames;
|
||||||
|
}
|
||||||
|
|
||||||
static GstVaapiOverlayRectangle *
|
static GstVaapiOverlayRectangle *
|
||||||
overlay_rectangle_new(GstVaapiContext *context)
|
overlay_rectangle_new(GstVaapiContext *context)
|
||||||
{
|
{
|
||||||
|
@ -218,7 +232,7 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context)
|
||||||
GstVaapiContextPrivate * const priv = context->priv;
|
GstVaapiContextPrivate * const priv = context->priv;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstVaapiSurface *surface;
|
GstVaapiSurface *surface;
|
||||||
guint i, num_ref_frames, num_surfaces;
|
guint i, num_surfaces;
|
||||||
|
|
||||||
/* Number of scratch surfaces beyond those used as reference */
|
/* Number of scratch surfaces beyond those used as reference */
|
||||||
const guint SCRATCH_SURFACES_COUNT = 4;
|
const guint SCRATCH_SURFACES_COUNT = 4;
|
||||||
|
@ -251,11 +265,7 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_ref_frames = 2;
|
num_surfaces = priv->ref_frames + SCRATCH_SURFACES_COUNT;
|
||||||
if (gst_vaapi_profile_get_codec(priv->profile) == GST_VAAPI_CODEC_H264)
|
|
||||||
num_ref_frames = 16;
|
|
||||||
num_surfaces = num_ref_frames + SCRATCH_SURFACES_COUNT;
|
|
||||||
|
|
||||||
gst_vaapi_video_pool_set_capacity(priv->surfaces_pool, num_surfaces);
|
gst_vaapi_video_pool_set_capacity(priv->surfaces_pool, num_surfaces);
|
||||||
|
|
||||||
for (i = priv->surfaces->len; i < num_surfaces; i++) {
|
for (i = priv->surfaces->len; i < num_surfaces; i++) {
|
||||||
|
@ -397,6 +407,9 @@ gst_vaapi_context_set_property(
|
||||||
case PROP_HEIGHT:
|
case PROP_HEIGHT:
|
||||||
priv->height = g_value_get_uint(value);
|
priv->height = g_value_get_uint(value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_REF_FRAMES:
|
||||||
|
priv->ref_frames = g_value_get_uint(value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -427,6 +440,9 @@ gst_vaapi_context_get_property(
|
||||||
case PROP_HEIGHT:
|
case PROP_HEIGHT:
|
||||||
g_value_set_uint(value, priv->height);
|
g_value_set_uint(value, priv->height);
|
||||||
break;
|
break;
|
||||||
|
case PROP_REF_FRAMES:
|
||||||
|
g_value_set_uint(value, priv->ref_frames);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -479,6 +495,15 @@ gst_vaapi_context_class_init(GstVaapiContextClass *klass)
|
||||||
"The height of the decoded surfaces",
|
"The height of the decoded surfaces",
|
||||||
0, G_MAXINT32, 0,
|
0, G_MAXINT32, 0,
|
||||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
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
|
static void
|
||||||
|
@ -495,6 +520,7 @@ gst_vaapi_context_init(GstVaapiContext *context)
|
||||||
priv->entrypoint = 0;
|
priv->entrypoint = 0;
|
||||||
priv->width = 0;
|
priv->width = 0;
|
||||||
priv->height = 0;
|
priv->height = 0;
|
||||||
|
priv->ref_frames = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -515,26 +541,51 @@ gst_vaapi_context_new(
|
||||||
GstVaapiDisplay *display,
|
GstVaapiDisplay *display,
|
||||||
GstVaapiProfile profile,
|
GstVaapiProfile profile,
|
||||||
GstVaapiEntrypoint entrypoint,
|
GstVaapiEntrypoint entrypoint,
|
||||||
unsigned int width,
|
guint width,
|
||||||
unsigned int height
|
guint height
|
||||||
)
|
)
|
||||||
|
{
|
||||||
|
GstVaapiContextInfo info;
|
||||||
|
|
||||||
|
info.profile = profile;
|
||||||
|
info.entrypoint = entrypoint;
|
||||||
|
info.width = width;
|
||||||
|
info.height = height;
|
||||||
|
info.ref_frames = get_max_ref_frames(profile);
|
||||||
|
return gst_vaapi_context_new_full(display, &info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vaapi_context_new_full:
|
||||||
|
* @display: a #GstVaapiDisplay
|
||||||
|
* @cip: a pointer to the #GstVaapiContextInfo
|
||||||
|
*
|
||||||
|
* Creates a new #GstVaapiContext with the configuration specified by
|
||||||
|
* @cip, thus including profile, entry-point, encoded size and maximum
|
||||||
|
* number of reference frames reported by the bitstream.
|
||||||
|
*
|
||||||
|
* Return value: the newly allocated #GstVaapiContext object
|
||||||
|
*/
|
||||||
|
GstVaapiContext *
|
||||||
|
gst_vaapi_context_new_full(GstVaapiDisplay *display, GstVaapiContextInfo *cip)
|
||||||
{
|
{
|
||||||
GstVaapiContext *context;
|
GstVaapiContext *context;
|
||||||
|
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
|
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
|
||||||
g_return_val_if_fail(profile, NULL);
|
g_return_val_if_fail(cip->profile, NULL);
|
||||||
g_return_val_if_fail(entrypoint, NULL);
|
g_return_val_if_fail(cip->entrypoint, NULL);
|
||||||
g_return_val_if_fail(width > 0, NULL);
|
g_return_val_if_fail(cip->width > 0, NULL);
|
||||||
g_return_val_if_fail(height > 0, NULL);
|
g_return_val_if_fail(cip->height > 0, NULL);
|
||||||
|
|
||||||
context = g_object_new(
|
context = g_object_new(
|
||||||
GST_VAAPI_TYPE_CONTEXT,
|
GST_VAAPI_TYPE_CONTEXT,
|
||||||
"display", display,
|
"display", display,
|
||||||
"id", GST_VAAPI_ID(VA_INVALID_ID),
|
"id", GST_VAAPI_ID(VA_INVALID_ID),
|
||||||
"profile", profile,
|
"profile", cip->profile,
|
||||||
"entrypoint", entrypoint,
|
"entrypoint", cip->entrypoint,
|
||||||
"width", width,
|
"width", cip->width,
|
||||||
"height", height,
|
"height", cip->height,
|
||||||
|
"ref-frames", cip->ref_frames,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (!context->priv->is_constructed) {
|
if (!context->priv->is_constructed) {
|
||||||
|
@ -565,22 +616,48 @@ gst_vaapi_context_reset(
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height
|
unsigned int height
|
||||||
)
|
)
|
||||||
|
{
|
||||||
|
GstVaapiContextPrivate * const priv = context->priv;
|
||||||
|
GstVaapiContextInfo info;
|
||||||
|
|
||||||
|
info.profile = profile;
|
||||||
|
info.entrypoint = entrypoint;
|
||||||
|
info.width = width;
|
||||||
|
info.height = height;
|
||||||
|
info.ref_frames = priv->ref_frames;
|
||||||
|
|
||||||
|
return gst_vaapi_context_reset_full(context, &info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vaapi_context_reset_full:
|
||||||
|
* @context: a #GstVaapiContext
|
||||||
|
* @cip: a pointer to the new #GstVaapiContextInfo details
|
||||||
|
*
|
||||||
|
* Resets @context to the configuration specified by @cip, thus
|
||||||
|
* including profile, entry-point, encoded size and maximum number of
|
||||||
|
* reference frames reported by the bitstream.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE on success
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_context_reset_full(GstVaapiContext *context, GstVaapiContextInfo *cip)
|
||||||
{
|
{
|
||||||
GstVaapiContextPrivate * const priv = context->priv;
|
GstVaapiContextPrivate * const priv = context->priv;
|
||||||
gboolean size_changed, codec_changed;
|
gboolean size_changed, codec_changed;
|
||||||
|
|
||||||
size_changed = priv->width != width || priv->height != height;
|
size_changed = priv->width != cip->width || priv->height != cip->height;
|
||||||
if (size_changed) {
|
if (size_changed) {
|
||||||
gst_vaapi_context_destroy_surfaces(context);
|
gst_vaapi_context_destroy_surfaces(context);
|
||||||
priv->width = width;
|
priv->width = cip->width;
|
||||||
priv->height = height;
|
priv->height = cip->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
codec_changed = priv->profile != profile || priv->entrypoint != entrypoint;
|
codec_changed = priv->profile != cip->profile || priv->entrypoint != cip->entrypoint;
|
||||||
if (codec_changed) {
|
if (codec_changed) {
|
||||||
gst_vaapi_context_destroy(context);
|
gst_vaapi_context_destroy(context);
|
||||||
priv->profile = profile;
|
priv->profile = cip->profile;
|
||||||
priv->entrypoint = entrypoint;
|
priv->entrypoint = cip->entrypoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size_changed && !gst_vaapi_context_create_surfaces(context))
|
if (size_changed && !gst_vaapi_context_create_surfaces(context))
|
||||||
|
|
|
@ -56,9 +56,25 @@ G_BEGIN_DECLS
|
||||||
GstVaapiContextClass))
|
GstVaapiContextClass))
|
||||||
|
|
||||||
typedef struct _GstVaapiContext GstVaapiContext;
|
typedef struct _GstVaapiContext GstVaapiContext;
|
||||||
|
typedef struct _GstVaapiContextInfo GstVaapiContextInfo;
|
||||||
typedef struct _GstVaapiContextPrivate GstVaapiContextPrivate;
|
typedef struct _GstVaapiContextPrivate GstVaapiContextPrivate;
|
||||||
typedef struct _GstVaapiContextClass GstVaapiContextClass;
|
typedef struct _GstVaapiContextClass GstVaapiContextClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstVaapiContextInfo:
|
||||||
|
*
|
||||||
|
* Structure holding VA context info like encoded size, decoder
|
||||||
|
* profile and entry-point to use, and maximum number of reference
|
||||||
|
* frames reported by the bitstream.
|
||||||
|
*/
|
||||||
|
struct _GstVaapiContextInfo {
|
||||||
|
GstVaapiProfile profile;
|
||||||
|
GstVaapiEntrypoint entrypoint;
|
||||||
|
guint width;
|
||||||
|
guint height;
|
||||||
|
guint ref_frames;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstVaapiContext:
|
* GstVaapiContext:
|
||||||
*
|
*
|
||||||
|
@ -93,15 +109,21 @@ gst_vaapi_context_new(
|
||||||
guint height
|
guint height
|
||||||
);
|
);
|
||||||
|
|
||||||
|
GstVaapiContext *
|
||||||
|
gst_vaapi_context_new_full(GstVaapiDisplay *display, GstVaapiContextInfo *cip);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_vaapi_context_reset(
|
gst_vaapi_context_reset(
|
||||||
GstVaapiContext *context,
|
GstVaapiContext *context,
|
||||||
GstVaapiProfile profile,
|
GstVaapiProfile profile,
|
||||||
GstVaapiEntrypoint entrypoint,
|
GstVaapiEntrypoint entrypoint,
|
||||||
unsigned int width,
|
guint width,
|
||||||
unsigned int height
|
guint height
|
||||||
);
|
);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_context_reset_full(GstVaapiContext *context, GstVaapiContextInfo *cip);
|
||||||
|
|
||||||
GstVaapiID
|
GstVaapiID
|
||||||
gst_vaapi_context_get_id(GstVaapiContext *context);
|
gst_vaapi_context_get_id(GstVaapiContext *context);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue