summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-09-10 18:15:02 +0200
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-09-10 18:15:02 +0200
commit4ca1f3f47c44db2347adf5606f058250179f38c7 (patch)
tree7293ce5321ec9a15fb19a246f06cb4ebf3883c12
parentd895e17db88d7d2e7886fe0eee51753fbfee2901 (diff)
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.
-rw-r--r--gst-libs/gst/vaapi/gstvaapicontext.c123
-rw-r--r--gst-libs/gst/vaapi/gstvaapicontext.h26
2 files changed, 124 insertions, 25 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c
index 5030a52..1862e38 100644
--- a/gst-libs/gst/vaapi/gstvaapicontext.c
+++ b/gst-libs/gst/vaapi/gstvaapicontext.c
@@ -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;
+ 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;
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) {
gst_vaapi_context_destroy_surfaces(context);
- priv->width = width;
- priv->height = height;
+ priv->width = cip->width;
+ 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) {
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))
diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h
index 1187c40..cffbd7e 100644
--- a/gst-libs/gst/vaapi/gstvaapicontext.h
+++ b/gst-libs/gst/vaapi/gstvaapicontext.h
@@ -56,10 +56,26 @@ 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:
*
* A VA context wrapper.
@@ -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);