diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 027a288eec..86de800d36 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -1275,3 +1275,77 @@ gst_vaapi_structure_set_profiles (GstStructure * st, gchar ** list) g_value_unset (&value); g_value_unset (&vlist); } + +/** + * gst_vaapi_build_template_coded_caps_by_codec: + * @display: a #GstVaapiDisplay + * @usage: used for encode or decode + * @codec: a #GstVaapiCodec specify the codec to detect + * @caps_str: a string of basic caps + * + * Called by vaapi elements to detect the all possible profiles belong to the + * specified codec and build the caps based on the basic caps description. + * + * Returns: a built #GstCaps if succeeds, or %NULL if error. + **/ +GstCaps * +gst_vaapi_build_template_coded_caps_by_codec (GstVaapiDisplay * display, + GstVaapiContextUsage usage, GstVaapiCodec codec, const char *caps_str, + GstVaapiProfileToStrFunc func) +{ + GValue v_profiles = G_VALUE_INIT; + GValue v_profile = G_VALUE_INIT; + GstCaps *caps = NULL; + guint i, num; + GArray *profiles = NULL; + GstVaapiProfile profile; + const gchar *str; + + caps = gst_caps_from_string (caps_str); + if (!caps) + goto out; + + if (!func) + goto out; + + /* If no profiles, just ignore the profile field. */ + if (usage == GST_VAAPI_CONTEXT_USAGE_ENCODE) { + profiles = gst_vaapi_display_get_encode_profiles (display); + } else if (usage == GST_VAAPI_CONTEXT_USAGE_DECODE) { + profiles = gst_vaapi_display_get_decode_profiles (display); + } + if (!profiles || profiles->len == 0) + goto out; + + num = 0; + g_value_init (&v_profiles, GST_TYPE_LIST); + g_value_init (&v_profile, G_TYPE_STRING); + + for (i = 0; i < profiles->len; i++) { + profile = g_array_index (profiles, GstVaapiProfile, i); + if (gst_vaapi_profile_get_codec (profile) != codec) + continue; + + str = func (profile); + if (!str) + continue; + + g_value_set_string (&v_profile, str); + num++; + gst_value_list_append_value (&v_profiles, &v_profile); + } + + if (num == 1) { + gst_caps_set_value (caps, "profile", &v_profile); + } else if (num > 1) { + gst_caps_set_value (caps, "profile", &v_profiles); + } + +out: + g_value_unset (&v_profile); + g_value_unset (&v_profiles); + if (profiles) + g_array_unref (profiles); + + return caps; +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index f5814d3424..db069cb9c5 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -31,7 +31,7 @@ #include "gstvaapivideomemory.h" typedef GstVaapiProfile (*GstVaapiStrToProfileFunc) (const gchar * str); - +typedef const gchar * (*GstVaapiProfileToStrFunc) (GstVaapiProfile profile); G_GNUC_INTERNAL gboolean @@ -175,4 +175,10 @@ G_GNUC_INTERNAL void gst_vaapi_structure_set_profiles (GstStructure * st, gchar ** list); +G_GNUC_INTERNAL +GstCaps * +gst_vaapi_build_template_coded_caps_by_codec (GstVaapiDisplay * display, + GstVaapiContextUsage usage, GstVaapiCodec codec, const char *caps_str, + GstVaapiProfileToStrFunc func); + #endif /* GST_VAAPI_PLUGIN_UTIL_H */