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;
|
||||
guint width;
|
||||
guint height;
|
||||
guint ref_frames;
|
||||
guint is_constructed : 1;
|
||||
};
|
||||
|
||||
|
@ -74,9 +75,22 @@ enum {
|
|||
PROP_PROFILE,
|
||||
PROP_ENTRYPOINT,
|
||||
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 *
|
||||
overlay_rectangle_new(GstVaapiContext *context)
|
||||
{
|
||||
|
@ -218,7 +232,7 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context)
|
|||
GstVaapiContextPrivate * const priv = context->priv;
|
||||
GstCaps *caps;
|
||||
GstVaapiSurface *surface;
|
||||
guint i, num_ref_frames, num_surfaces;
|
||||
guint i, num_surfaces;
|
||||
|
||||
/* Number of scratch surfaces beyond those used as reference */
|
||||
const guint SCRATCH_SURFACES_COUNT = 4;
|
||||
|
@ -251,11 +265,7 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
num_ref_frames = 2;
|
||||
if (gst_vaapi_profile_get_codec(priv->profile) == GST_VAAPI_CODEC_H264)
|
||||
num_ref_frames = 16;
|
||||
num_surfaces = num_ref_frames + SCRATCH_SURFACES_COUNT;
|
||||
|
||||
num_surfaces = priv->ref_frames + SCRATCH_SURFACES_COUNT;
|
||||
gst_vaapi_video_pool_set_capacity(priv->surfaces_pool, num_surfaces);
|
||||
|
||||
for (i = priv->surfaces->len; i < num_surfaces; i++) {
|
||||
|
@ -397,6 +407,9 @@ gst_vaapi_context_set_property(
|
|||
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;
|
||||
|
@ -427,6 +440,9 @@ gst_vaapi_context_get_property(
|
|||
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;
|
||||
|
@ -479,6 +495,15 @@ gst_vaapi_context_class_init(GstVaapiContextClass *klass)
|
|||
"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
|
||||
|
@ -495,6 +520,7 @@ gst_vaapi_context_init(GstVaapiContext *context)
|
|||
priv->entrypoint = 0;
|
||||
priv->width = 0;
|
||||
priv->height = 0;
|
||||
priv->ref_frames = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -515,26 +541,51 @@ gst_vaapi_context_new(
|
|||
GstVaapiDisplay *display,
|
||||
GstVaapiProfile profile,
|
||||
GstVaapiEntrypoint entrypoint,
|
||||
unsigned int width,
|
||||
unsigned int height
|
||||
guint width,
|
||||
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;
|
||||
|
||||
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
|
||||
g_return_val_if_fail(profile, NULL);
|
||||
g_return_val_if_fail(entrypoint, NULL);
|
||||
g_return_val_if_fail(width > 0, NULL);
|
||||
g_return_val_if_fail(height > 0, NULL);
|
||||
g_return_val_if_fail(cip->profile, NULL);
|
||||
g_return_val_if_fail(cip->entrypoint, NULL);
|
||||
g_return_val_if_fail(cip->width > 0, NULL);
|
||||
g_return_val_if_fail(cip->height > 0, NULL);
|
||||
|
||||
context = g_object_new(
|
||||
GST_VAAPI_TYPE_CONTEXT,
|
||||
"display", display,
|
||||
"id", GST_VAAPI_ID(VA_INVALID_ID),
|
||||
"profile", profile,
|
||||
"entrypoint", entrypoint,
|
||||
"width", width,
|
||||
"height", height,
|
||||
"profile", cip->profile,
|
||||
"entrypoint", cip->entrypoint,
|
||||
"width", cip->width,
|
||||
"height", cip->height,
|
||||
"ref-frames", cip->ref_frames,
|
||||
NULL
|
||||
);
|
||||
if (!context->priv->is_constructed) {
|
||||
|
@ -567,20 +618,46 @@ gst_vaapi_context_reset(
|
|||
)
|
||||
{
|
||||
GstVaapiContextPrivate * const priv = context->priv;
|
||||
gboolean size_changed, codec_changed;
|
||||
GstVaapiContextInfo info;
|
||||
|
||||
size_changed = priv->width != width || priv->height != height;
|
||||
if (size_changed) {
|
||||
gst_vaapi_context_destroy_surfaces(context);
|
||||
priv->width = width;
|
||||
priv->height = height;
|
||||
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);
|
||||
}
|
||||
|
||||
codec_changed = priv->profile != profile || priv->entrypoint != entrypoint;
|
||||
/**
|
||||
* 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;
|
||||
gboolean size_changed, codec_changed;
|
||||
|
||||
size_changed = priv->width != cip->width || priv->height != cip->height;
|
||||
if (size_changed) {
|
||||
gst_vaapi_context_destroy_surfaces(context);
|
||||
priv->width = cip->width;
|
||||
priv->height = cip->height;
|
||||
}
|
||||
|
||||
codec_changed = priv->profile != cip->profile || priv->entrypoint != cip->entrypoint;
|
||||
if (codec_changed) {
|
||||
gst_vaapi_context_destroy(context);
|
||||
priv->profile = profile;
|
||||
priv->entrypoint = entrypoint;
|
||||
priv->profile = cip->profile;
|
||||
priv->entrypoint = cip->entrypoint;
|
||||
}
|
||||
|
||||
if (size_changed && !gst_vaapi_context_create_surfaces(context))
|
||||
|
|
|
@ -56,9 +56,25 @@ G_BEGIN_DECLS
|
|||
GstVaapiContextClass))
|
||||
|
||||
typedef struct _GstVaapiContext GstVaapiContext;
|
||||
typedef struct _GstVaapiContextInfo GstVaapiContextInfo;
|
||||
typedef struct _GstVaapiContextPrivate GstVaapiContextPrivate;
|
||||
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:
|
||||
*
|
||||
|
@ -93,15 +109,21 @@ gst_vaapi_context_new(
|
|||
guint height
|
||||
);
|
||||
|
||||
GstVaapiContext *
|
||||
gst_vaapi_context_new_full(GstVaapiDisplay *display, GstVaapiContextInfo *cip);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_context_reset(
|
||||
GstVaapiContext *context,
|
||||
GstVaapiProfile profile,
|
||||
GstVaapiEntrypoint entrypoint,
|
||||
unsigned int width,
|
||||
unsigned int height
|
||||
guint width,
|
||||
guint height
|
||||
);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_context_reset_full(GstVaapiContext *context, GstVaapiContextInfo *cip);
|
||||
|
||||
GstVaapiID
|
||||
gst_vaapi_context_get_id(GstVaapiContext *context);
|
||||
|
||||
|
|
Loading…
Reference in a new issue