From a6cf75e8c65542409841a1a45661556c78dcba79 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 30 Dec 2019 14:09:17 +0800 Subject: [PATCH] libs: encoder: get surfaces resolution the same time with formats. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 112 +++++++++++++++++---------- gst-libs/gst/vaapi/gstvaapiencoder.h | 5 +- gst/vaapi/gstvaapiencode.c | 45 ++++------- 3 files changed, 92 insertions(+), 70 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index a63cb8d18f..1befb562bf 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; } /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 84ca4aa6dd..1d81baf177 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -181,8 +181,9 @@ GstVaapiEncoderStatus gst_vaapi_encoder_flush (GstVaapiEncoder * encoder); 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); GstVaapiProfile gst_vaapi_encoder_get_profile (GstVaapiEncoder * encoder); diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index b573e188be..f19f221388 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -366,19 +366,6 @@ get_profile (GstVaapiEncode * encode) return GST_VAAPI_PROFILE_UNKNOWN; } -static GstVaapiEntrypoint -get_entrypoint (GstVaapiEncode * encode, GstVaapiProfile profile) -{ - GstVaapiEncoderTune tune = GST_VAAPI_ENCODER_TUNE_NONE; - - g_object_get (encode, "tune", &tune, NULL); - if (tune == GST_VAAPI_ENCODER_TUNE_LOW_POWER) - return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; - if (profile == GST_VAAPI_PROFILE_JPEG_BASELINE) - return GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; - return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; -} - static gboolean ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) { @@ -390,6 +377,7 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) GstVaapiProfile profile; guint i, size; GstStructure *structure; + gint min_width, min_height, max_width, max_height; if (encode->allowed_sinkpad_caps) return TRUE; @@ -397,19 +385,28 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) return TRUE; profile = get_profile (encode); - if (profile == GST_VAAPI_PROFILE_UNKNOWN) - return TRUE; /* First get all supported formats, all these formats should be recognized in video-format map. */ - formats = gst_vaapi_encoder_get_surface_formats (encode->encoder, profile); + formats = gst_vaapi_encoder_get_surface_attributes (encode->encoder, profile, + &min_width, &min_height, &max_width, &max_height); if (!formats) - goto failed_get_formats; + goto failed_get_attributes; raw_caps = gst_vaapi_video_format_new_template_caps_from_list (formats); if (!raw_caps) goto failed_create_raw_caps; + /* Set the width/height info to caps */ + size = gst_caps_get_size (raw_caps); + for (i = 0; i < size; i++) { + structure = gst_caps_get_structure (raw_caps, i); + if (!structure) + continue; + gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, min_width, + max_width, "height", GST_TYPE_INT_RANGE, min_height, max_height, NULL); + } + va_caps = gst_caps_copy (raw_caps); gst_caps_set_features_simple (va_caps, gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE)); @@ -424,16 +421,6 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) gst_caps_append (out_caps, va_caps); gst_caps_append (out_caps, dma_caps); - /* Last, set the width/height info to caps */ - size = gst_caps_get_size (out_caps); - for (i = 0; i < size; i++) { - structure = gst_caps_get_structure (out_caps, i); - if (!structure) - continue; - gst_vaapi_profile_caps_append_encoder (GST_VAAPI_PLUGIN_BASE_DISPLAY - (encode), profile, get_entrypoint (encode, profile), structure); - } - gst_caps_replace (&encode->allowed_sinkpad_caps, out_caps); GST_INFO_OBJECT (encode, "Allowed sink caps %" GST_PTR_FORMAT, encode->allowed_sinkpad_caps); @@ -452,9 +439,9 @@ bail: g_array_unref (formats); return ret; -failed_get_formats: +failed_get_attributes: { - GST_WARNING_OBJECT (encode, "failed to get allowed surface formats"); + GST_WARNING_OBJECT (encode, "failed to get surface attributes"); goto bail; } failed_create_raw_caps: