mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
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>
This commit is contained in:
parent
2da3314534
commit
e962069dbe
3 changed files with 100 additions and 77 deletions
|
@ -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;
|
||||
if (!profile_name)
|
||||
continue;
|
||||
|
||||
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);
|
||||
/* 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);
|
||||
g_value_take_string (&value, intra_name);
|
||||
gst_value_list_append_value (&list_value, &value);
|
||||
intra_name = g_strdup_printf ("%s-intra", profile_name);
|
||||
|
||||
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);
|
||||
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";
|
||||
}
|
||||
|
||||
if (base_only && !have_svc) {
|
||||
GST_DEBUG ("base_only: force adding SVC profiles in caps");
|
||||
|
||||
profiles[i++] = "scalable-constrained-baseline";
|
||||
profiles[i++] = "scalable-baseline";
|
||||
profiles[i++] = "scalable-high-intra";
|
||||
profiles[i++] = "scalable-constrained-high";
|
||||
profiles[i++] = "scalable-high";
|
||||
}
|
||||
|
||||
profiles[i++] = NULL;
|
||||
|
||||
gst_vaapi_structure_set_profiles (structure, profiles);
|
||||
} else {
|
||||
gst_structure_set (structure, "profile", G_TYPE_STRING,
|
||||
profile_name, NULL);
|
||||
}
|
||||
|
||||
gst_vaapi_profile_caps_append_decoder (display, profile, structure);
|
||||
|
||||
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 (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");
|
||||
}
|
||||
|
||||
if (base_only && (!have_mvc || !have_svc) && have_high) {
|
||||
if (!have_mvc) {
|
||||
GST_DEBUG ("base_only: force adding MVC profiles in caps");
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
caps = gst_pad_get_pad_template_caps (sinkpad);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue