summaryrefslogtreecommitdiff
path: root/gst-libs/gst/vaapi/gstvaapiencoder.c
diff options
context:
space:
mode:
authorHe Junyan <junyan.he@hotmail.com>2019-12-30 14:09:17 +0800
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2020-01-02 18:01:45 +0100
commita6cf75e8c65542409841a1a45661556c78dcba79 (patch)
tree8f5dff2ff3067d0035f08f2b58096ddd05b76660 /gst-libs/gst/vaapi/gstvaapiencoder.c
parentb4d73433c39e2fadea4a4a43e5d8ce7278832f19 (diff)
libs: encoder: get surfaces resolution the same time with formats.
We can get all the information about the video format at one shot when we create the test context for getting the supported formats. The current way to get the width and height ranges are inefficient, since it calls the function gst_vaapi_profile_caps_append_encoder() and it creates another temporal context to detect the resolution information. Signed-off-by: Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
Diffstat (limited to 'gst-libs/gst/vaapi/gstvaapiencoder.c')
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder.c112
1 files changed, 73 insertions, 39 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c
index a63cb8d1..1befb562 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder.c
@@ -1476,12 +1476,7 @@ create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile)
GstVaapiContextInfo cip = { 0, };
GstVaapiContext *ctxt;
- if (encoder->context)
- return gst_vaapi_context_ref (encoder->context);
-
- /* if there is no profile, let's figure out one */
- if (profile == GST_VAAPI_PROFILE_UNKNOWN)
- profile = get_profile (encoder);
+ g_assert (profile != GST_VAAPI_PROFILE_UNKNOWN);
cip.profile = profile;
cip.entrypoint = gst_vaapi_encoder_get_entrypoint (encoder, profile);
@@ -1499,69 +1494,96 @@ create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile)
return ctxt;
}
-static GArray *
-get_profile_surface_formats (GstVaapiEncoder * encoder, GstVaapiProfile profile)
+static gboolean
+get_profile_surface_attributes (GstVaapiEncoder * encoder,
+ GstVaapiProfile profile, GstVaapiConfigSurfaceAttributes * attribs)
{
- GstVaapiContext *ctxt;
- GArray *formats;
+ GstVaapiContext *ctxt = NULL;
+ gboolean ret;
+
+ g_return_val_if_fail (attribs != NULL, FALSE);
+ g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE);
ctxt = create_test_context_config (encoder, profile);
if (!ctxt)
- return NULL;
- formats = gst_vaapi_context_get_surface_formats (ctxt);
+ return FALSE;
+
+ ret = gst_vaapi_context_get_surface_attributes (ctxt, attribs);
+ if (ret)
+ attribs->formats = gst_vaapi_context_get_surface_formats (ctxt);
+
gst_vaapi_context_unref (ctxt);
- return formats;
+ return ret;
}
static gboolean
-merge_profile_surface_formats (GstVaapiEncoder * encoder,
- GstVaapiProfile profile, GArray * formats)
+merge_profile_surface_attributes (GstVaapiEncoder * encoder,
+ GstVaapiProfile profile, GstVaapiConfigSurfaceAttributes * attribs)
{
- GArray *surface_fmts;
+ GstVaapiConfigSurfaceAttributes attr = { 0, };
guint i, j;
GstVideoFormat fmt, sfmt;
if (profile == GST_VAAPI_PROFILE_UNKNOWN)
return FALSE;
- surface_fmts = get_profile_surface_formats (encoder, profile);
- if (!surface_fmts)
+ if (!get_profile_surface_attributes (encoder, profile, &attr))
return FALSE;
- for (i = 0; i < surface_fmts->len; i++) {
- sfmt = g_array_index (surface_fmts, GstVideoFormat, i);
- for (j = 0; j < formats->len; j++) {
- fmt = g_array_index (formats, GstVideoFormat, j);
+ for (i = 0; i < attr.formats->len; i++) {
+ sfmt = g_array_index (attr.formats, GstVideoFormat, i);
+ for (j = 0; j < attribs->formats->len; j++) {
+ fmt = g_array_index (attribs->formats, GstVideoFormat, j);
if (fmt == sfmt)
break;
}
- if (j >= formats->len)
- g_array_append_val (formats, sfmt);
+ if (j >= attribs->formats->len)
+ g_array_append_val (attribs->formats, sfmt);
}
- g_array_unref (surface_fmts);
+ g_array_unref (attr.formats);
+
+ attribs->min_width = MIN (attribs->min_width, attr.min_width);
+ attribs->min_height = MIN (attribs->min_height, attr.min_height);
+ attribs->max_width = MAX (attribs->max_width, attr.max_width);
+ attribs->max_height = MAX (attribs->max_height, attr.max_height);
+
return TRUE;
}
/**
- * gst_vaapi_encoder_get_surface_formats:
+ * gst_vaapi_encoder_get_surface_attributres:
* @encoder: a #GstVaapiEncoder instances
+ * @profile: a #GstVaapiProfile to test
+ * @min_width (out): the minimal surface width
+ * @min_height (out): the minimal surface height
+ * @max_width (out): the maximal surface width
+ * @max_height (out): the maximal surface height
*
- * Fetches the valid surface formats for the current VAConfig
+ * Fetches the valid surface's attributes for @profile if it is valid,
+ * Otherwise, it collects surface's attributes for all profiles which
+ * belong to the current encoder's codec.
*
- * Returns: a #GArray of valid formats for the current VAConfig
+ * Returns: a #GArray of valid formats we get or %NULL if failed.
**/
GArray *
-gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder,
- GstVaapiProfile profile)
+gst_vaapi_encoder_get_surface_attributes (GstVaapiEncoder * encoder,
+ GstVaapiProfile profile, gint * min_width, gint * min_height,
+ gint * max_width, gint * max_height)
{
const GstVaapiEncoderClassData *const cdata =
GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data;
- GArray *profiles, *formats;
+ GstVaapiConfigSurfaceAttributes attribs = {
+ G_MAXINT, G_MAXINT, 1, 1, 0, NULL
+ };
+ GArray *profiles;
guint i;
- if (profile || encoder->context)
- return get_profile_surface_formats (encoder, profile);
+ if (profile != GST_VAAPI_PROFILE_UNKNOWN) {
+ if (get_profile_surface_attributes (encoder, profile, &attribs))
+ goto success;
+ return NULL;
+ }
/* no specific context neither specific profile, let's iterate among
* the codec's profiles */
@@ -1569,21 +1591,33 @@ gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder,
if (!profiles)
return NULL;
- formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat));
+ attribs.formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat));
for (i = 0; i < profiles->len; i++) {
profile = g_array_index (profiles, GstVaapiProfile, i);
if (gst_vaapi_profile_get_codec (profile) == cdata->codec) {
- if (!merge_profile_surface_formats (encoder, profile, formats)) {
- g_array_unref (formats);
- formats = NULL;
- break;
+ if (!merge_profile_surface_attributes (encoder, profile, &attribs)) {
+ GST_INFO ("Can not get surface formats for profile %s",
+ gst_vaapi_profile_get_va_name (profile));
+ continue;
}
}
}
g_array_unref (profiles);
- return formats;
+ if (!attribs.formats)
+ return NULL;
+
+success:
+ if (min_width)
+ *min_width = attribs.min_width;
+ if (min_height)
+ *min_height = attribs.min_height;
+ if (max_width)
+ *max_width = attribs.max_width;
+ if (max_height)
+ *max_height = attribs.max_height;
+ return attribs.formats;
}
/**