diff options
author | Víctor Manuel Jáquez Leal <vjaquez@igalia.com> | 2020-07-21 20:14:57 +0200 |
---|---|---|
committer | Víctor Manuel Jáquez Leal <vjaquez@igalia.com> | 2020-07-23 19:29:19 +0200 |
commit | e962069dbe15fb7cfedced1b325de6dc758bf190 (patch) | |
tree | e1d652c7e3e660a5cb00b777ddffa433cf939990 /gst | |
parent | 2da3314534ae9c279c0a647fe4e935104b0882bc (diff) |
vaapidecode: merge common profiles before setting size range
The synthetic profiles, such as H264 baseline, H265 intra, etc. are
added at the end of processing all available VA profiles. This
generated an non-optimal caps for negotiation, since the synthetic
profiles don't have frame size ranges.
This patch adds those possible synthetic profiles when the associated
profile is processed, with its frame size ranges.
Now allowed sink caps are simpler.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/merge_requests/363>
Diffstat (limited to 'gst')
-rw-r--r-- | gst/vaapi/gstvaapidecode.c | 146 | ||||
-rw-r--r-- | gst/vaapi/gstvaapipluginutil.c | 31 | ||||
-rw-r--r-- | gst/vaapi/gstvaapipluginutil.h | 4 |
3 files changed, 102 insertions, 79 deletions
diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 2796ab14..0f631e70 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1170,14 +1170,18 @@ is_svc_profile (GstVaapiProfile profile) || profile == GST_VAAPI_PROFILE_H264_SCALABLE_HIGH; } - -static GstCaps * -add_h264_profile_in_caps (GstCaps * caps, const gchar * profile_name) +static void +find_mvc_and_svc (GArray * profiles, gboolean * have_mvc, gboolean * have_svc) { - GstCaps *caps_new = - gst_caps_new_simple ("video/x-h264", "profile", G_TYPE_STRING, - profile_name, NULL); - return gst_caps_merge (caps_new, caps); + guint i; + + for (i = 0; i < profiles->len; i++) { + const GstVaapiProfile profile = + g_array_index (profiles, GstVaapiProfile, i); + + *have_mvc |= is_mvc_profile (profile); + *have_svc |= is_svc_profile (profile); + } } static gboolean @@ -1189,7 +1193,6 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (decode); guint i; gboolean base_only = FALSE; - gboolean have_high = FALSE; gboolean have_mvc = FALSE; gboolean have_svc = FALSE; @@ -1205,6 +1208,8 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) g_object_get (decode, "base-only", &base_only, NULL); } + find_mvc_and_svc (profiles, &have_mvc, &have_svc); + for (i = 0; i < profiles->len; i++) { const GstVaapiProfile profile = g_array_index (profiles, GstVaapiProfile, i); @@ -1224,84 +1229,67 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) continue; profile_name = gst_vaapi_profile_get_name (profile); - if (profile_name) { - /* Add all according -intra profile for HEVC */ - if (profile == GST_VAAPI_PROFILE_H265_MAIN - || profile == GST_VAAPI_PROFILE_H265_MAIN10 - || profile == GST_VAAPI_PROFILE_H265_MAIN_422_10 - || profile == GST_VAAPI_PROFILE_H265_MAIN_444 - || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10 - || profile == GST_VAAPI_PROFILE_H265_MAIN12) { - GValue list_value = G_VALUE_INIT; - GValue value = G_VALUE_INIT; - gchar *intra_name; - - g_value_init (&list_value, GST_TYPE_LIST); - g_value_init (&value, G_TYPE_STRING); - g_value_set_string (&value, profile_name); - gst_value_list_append_value (&list_value, &value); - - intra_name = g_strdup_printf ("%s-intra", profile_name); - g_value_take_string (&value, intra_name); - gst_value_list_append_value (&list_value, &value); - - gst_structure_set_value (structure, "profile", &list_value); - g_value_unset (&list_value); - g_value_unset (&value); - } else { - gst_structure_set (structure, "profile", G_TYPE_STRING, - profile_name, NULL); - } - } + if (!profile_name) + continue; - gst_vaapi_profile_caps_append_decoder (display, profile, structure); + /* Add all according -intra profile for HEVC */ + if (profile == GST_VAAPI_PROFILE_H265_MAIN + || profile == GST_VAAPI_PROFILE_H265_MAIN10 + || profile == GST_VAAPI_PROFILE_H265_MAIN_422_10 + || profile == GST_VAAPI_PROFILE_H265_MAIN_444 + || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10 + || profile == GST_VAAPI_PROFILE_H265_MAIN12) { + gchar *profiles[3], *intra_name; + + intra_name = g_strdup_printf ("%s-intra", profile_name); + + profiles[0] = (gchar *) profile_name; + profiles[1] = intra_name; + profiles[2] = NULL; + + gst_vaapi_structure_set_profiles (structure, profiles); + g_free (intra_name); + + } else if (profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE) { + /* XXX: artificially adding baseline if constrained_baseline is + * available. */ + gchar *profiles[] = { (gchar *) profile_name, "baseline", NULL }; + + gst_vaapi_structure_set_profiles (structure, profiles); + } else if (profile == GST_VAAPI_PROFILE_H264_HIGH) { + gchar *profiles[11] = { (gchar *) profile_name, "progressive-high", + "constrained-high" + }; + gint i = 3; + + if (base_only && !have_mvc) { + GST_DEBUG ("base_only: force adding MVC profiles in caps"); + + profiles[i++] = "multiview-high"; + profiles[i++] = "stereo-high"; + } - allowed_sinkpad_caps = gst_caps_merge (allowed_sinkpad_caps, caps); - have_mvc |= is_mvc_profile (profile); - have_svc |= is_svc_profile (profile); - have_high |= profile == GST_VAAPI_PROFILE_H264_HIGH; - - /* XXX: artificially adding baseline if constrained_baseline is - * available. */ - if (profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE) - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "baseline"); - } + if (base_only && !have_svc) { + GST_DEBUG ("base_only: force adding SVC profiles in caps"); - if (have_high) { - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "progressive-high"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "constrained-high"); - } + profiles[i++] = "scalable-constrained-baseline"; + profiles[i++] = "scalable-baseline"; + profiles[i++] = "scalable-high-intra"; + profiles[i++] = "scalable-constrained-high"; + profiles[i++] = "scalable-high"; + } - if (base_only && (!have_mvc || !have_svc) && have_high) { - if (!have_mvc) { - GST_DEBUG ("base_only: force adding MVC profiles in caps"); + profiles[i++] = NULL; - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "multiview-high"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "stereo-high"); + gst_vaapi_structure_set_profiles (structure, profiles); + } else { + gst_structure_set (structure, "profile", G_TYPE_STRING, + profile_name, NULL); } - if (!have_svc) { - GST_DEBUG ("base_only: force adding SVC profiles in caps"); - - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, - "scalable-constrained-baseline"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "scalable-baseline"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, - "scalable-high-intra"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, - "scalable-constrained-high"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "scalable-high"); - } + gst_vaapi_profile_caps_append_decoder (display, profile, structure); + + allowed_sinkpad_caps = gst_caps_merge (allowed_sinkpad_caps, caps); } caps = gst_pad_get_pad_template_caps (sinkpad); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index c558138a..ece8a683 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -1244,3 +1244,34 @@ out: return out_caps; } + +/** + * gst_vaapi_structure_set_profiles: + * @st: a #GstStructure + * @list: a %NULL-terminated array of strings + * + * The @list of profiles are set in @st + **/ +void +gst_vaapi_structure_set_profiles (GstStructure * st, gchar ** list) +{ + guint i; + GValue vlist = G_VALUE_INIT; + GValue value = G_VALUE_INIT; + + g_value_init (&vlist, GST_TYPE_LIST); + g_value_init (&value, G_TYPE_STRING); + + for (i = 0; list[i]; i++) { + g_value_set_string (&value, list[i]); + gst_value_list_append_value (&vlist, &value); + } + + if (i == 1) + gst_structure_set_value (st, "profile", &value); + else if (i > 1) + gst_structure_set_value (st, "profile", &vlist); + + g_value_unset (&value); + g_value_unset (&vlist); +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index abdaf1e9..cad6b871 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -171,4 +171,8 @@ GstCaps * gst_vaapi_build_template_caps_by_codec (GstVaapiDisplay * display, GstVaapiContextUsage usage, GstVaapiCodec codec, GArray * extra_fmts); +G_GNUC_INTERNAL +void +gst_vaapi_structure_set_profiles (GstStructure * st, gchar ** list); + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ |