summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2020-07-21 20:14:57 +0200
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2020-07-23 19:29:19 +0200
commite962069dbe15fb7cfedced1b325de6dc758bf190 (patch)
treee1d652c7e3e660a5cb00b777ddffa433cf939990
parent2da3314534ae9c279c0a647fe4e935104b0882bc (diff)
downloadgstreamer-vaapi-e962069dbe15fb7cfedced1b325de6dc758bf190.tar.gz
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>
-rw-r--r--gst/vaapi/gstvaapidecode.c146
-rw-r--r--gst/vaapi/gstvaapipluginutil.c31
-rw-r--r--gst/vaapi/gstvaapipluginutil.h4
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 */