diff options
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 */ |