diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index ec2dcdcd70..6cdc9edb38 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -347,28 +347,39 @@ append_h263_config (GArray * configs) } } +/* Sort profiles. Group per codec */ +static gint +compare_profiles (gconstpointer a, gconstpointer b) +{ + const GstVaapiConfig *const config1 = (GstVaapiConfig *) a; + const GstVaapiConfig *const config2 = (GstVaapiConfig *) b; + + if (config1->profile == config2->profile) + return config1->entrypoint - config2->entrypoint; + + return config1->profile - config2->profile; +} + /* Convert configs array to profiles as GstCaps */ -static GstCaps * -get_profile_caps (GArray * configs) +static GArray * +get_profiles (GArray * configs) { GstVaapiConfig *config; - GstCaps *out_caps, *caps; + GArray *out_profiles; guint i; if (!configs) return NULL; - out_caps = gst_caps_new_empty (); - if (!out_caps) + out_profiles = g_array_new (FALSE, FALSE, sizeof (GstVaapiProfile)); + if (!out_profiles) return NULL; for (i = 0; i < configs->len; i++) { config = &g_array_index (configs, GstVaapiConfig, i); - caps = gst_vaapi_profile_get_caps (config->profile); - if (caps) - out_caps = gst_caps_merge (out_caps, caps); + g_array_append_val (out_profiles, config->profile); } - return out_caps; + return out_profiles; } /* Find format info */ @@ -554,6 +565,9 @@ ensure_profiles (GstVaapiDisplay * display) } append_h263_config (priv->decoders); + g_array_sort (priv->decoders, compare_profiles); + g_array_sort (priv->encoders, compare_profiles); + /* Video processing API */ #if USE_VA_VPP status = vaQueryConfigEntrypoints (priv->display, VAProfileNone, @@ -1364,21 +1378,24 @@ gst_vaapi_display_has_video_processing (GstVaapiDisplay * display) } /** - * gst_vaapi_display_get_decode_caps: + * gst_vaapi_display_get_decode_profiles: * @display: a #GstVaapiDisplay * - * Gets the supported profiles for decoding as #GstCaps capabilities. + * Gets the supported profiles for decoding. The caller owns an extra + * reference to the resulting array of #GstVaapiProfile elements, so + * it shall be released with g_array_unref() after usage. * - * Return value: a newly allocated #GstCaps object, possibly empty + * Return value: a newly allocated #GArray, or %NULL or error or if + * decoding is not supported at all */ -GstCaps * -gst_vaapi_display_get_decode_caps (GstVaapiDisplay * display) +GArray * +gst_vaapi_display_get_decode_profiles (GstVaapiDisplay * display) { g_return_val_if_fail (display != NULL, NULL); if (!ensure_profiles (display)) return NULL; - return get_profile_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders); + return get_profiles (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders); } /** @@ -1405,21 +1422,24 @@ gst_vaapi_display_has_decoder (GstVaapiDisplay * display, } /** - * gst_vaapi_display_get_encode_caps: + * gst_vaapi_display_get_encode_profiles: * @display: a #GstVaapiDisplay * - * Gets the supported profiles for decoding as #GstCaps capabilities. + * Gets the supported profiles for encoding. The caller owns an extra + * reference to the resulting array of #GstVaapiProfile elements, so + * it shall be released with g_array_unref() after usage. * - * Return value: a newly allocated #GstCaps object, possibly empty + * Return value: a newly allocated #GArray, or %NULL or error or if + * encoding is not supported at all */ -GstCaps * -gst_vaapi_display_get_encode_caps (GstVaapiDisplay * display) +GArray * +gst_vaapi_display_get_encode_profiles (GstVaapiDisplay * display) { g_return_val_if_fail (display != NULL, NULL); if (!ensure_profiles (display)) return NULL; - return get_profile_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders); + return get_profiles (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 75518a0369..e925a185b7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -144,15 +144,15 @@ gst_vaapi_display_get_pixel_aspect_ratio (GstVaapiDisplay * display, gboolean gst_vaapi_display_has_video_processing (GstVaapiDisplay * display); -GstCaps * -gst_vaapi_display_get_decode_caps (GstVaapiDisplay * display); +GArray * +gst_vaapi_display_get_decode_profiles (GstVaapiDisplay * display); gboolean gst_vaapi_display_has_decoder (GstVaapiDisplay * display, GstVaapiProfile profile, GstVaapiEntrypoint entrypoint); -GstCaps * -gst_vaapi_display_get_encode_caps (GstVaapiDisplay * display); +GArray * +gst_vaapi_display_get_encode_profiles (GstVaapiDisplay * display); gboolean gst_vaapi_display_has_encoder (GstVaapiDisplay * display, diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 8a6b31d212..f31ad78dc5 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -815,8 +815,9 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) static gboolean gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) { - GstCaps *decode_caps; - guint i, n_decode_caps; + GstCaps *caps, *allowed_caps; + GArray *profiles; + guint i; if (decode->allowed_caps) return TRUE; @@ -824,30 +825,32 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) if (!gst_vaapidecode_ensure_display(decode)) goto error_no_display; - decode_caps = gst_vaapi_display_get_decode_caps( + profiles = gst_vaapi_display_get_decode_profiles( GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); - if (!decode_caps) - goto error_no_decode_caps; - n_decode_caps = gst_caps_get_size(decode_caps); + if (!profiles) + goto error_no_profiles; - decode->allowed_caps = gst_caps_new_empty(); - if (!decode->allowed_caps) + allowed_caps = gst_caps_new_empty(); + if (!allowed_caps) goto error_no_memory; - for (i = 0; i < n_decode_caps; i++) { - GstStructure *structure; - structure = gst_caps_get_structure(decode_caps, i); - if (!structure) - continue; - structure = gst_structure_copy(structure); - if (!structure) - continue; - gst_structure_remove_field(structure, "profile"); - decode->allowed_caps = - gst_caps_merge_structure(decode->allowed_caps, structure); - } + for (i = 0; i < profiles->len; i++) { + const GstVaapiProfile profile = + g_array_index(profiles, GstVaapiProfile, i); + const gchar *media_type_name; - gst_caps_unref(decode_caps); + media_type_name = gst_vaapi_profile_get_media_type_name(profile); + if (!media_type_name) + continue; + + caps = gst_caps_from_string(media_type_name); + if (!caps) + continue; + allowed_caps = gst_caps_merge(allowed_caps, caps); + } + decode->allowed_caps = allowed_caps; + + g_array_unref(profiles); return TRUE; /* ERRORS */ @@ -856,15 +859,15 @@ error_no_display: GST_ERROR("failed to retrieve VA display"); return FALSE; } -error_no_decode_caps: +error_no_profiles: { - GST_ERROR("failed to retrieve VA decode caps"); + GST_ERROR("failed to retrieve VA decode profiles"); return FALSE; } error_no_memory: { GST_ERROR("failed to allocate allowed-caps set"); - gst_caps_unref(decode_caps); + g_array_unref(profiles); return FALSE; } } diff --git a/tests/test-display.c b/tests/test-display.c index 163ab503ea..22f5859a47 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -63,33 +63,31 @@ print_value(const GValue *value, const gchar *name) } static void -print_profile_caps(GstCaps *caps, const gchar *name) +print_profiles(GArray *profiles, const gchar *name) { - guint i, n_caps = gst_caps_get_size(caps); - gint version; - const gchar *profile; - gboolean has_version; + GstVaapiCodec codec; + const gchar *codec_name, *profile_name; + guint i; - g_print("%u %s caps\n", n_caps, name); + g_print("%u %s caps\n", profiles->len, name); - for (i = 0; i < gst_caps_get_size(caps); i++) { - GstStructure * const structure = gst_caps_get_structure(caps, i); - if (!structure) - g_error("could not get caps structure %d", i); + for (i = 0; i < profiles->len; i++) { + const GstVaapiProfile profile = + g_array_index(profiles, GstVaapiProfile, i); - has_version = ( - gst_structure_get_int(structure, "version", &version) || - gst_structure_get_int(structure, "mpegversion", &version) - ); + codec = gst_vaapi_profile_get_codec(profile); + if (!codec) + continue; - g_print(" %s", gst_structure_get_name(structure)); - if (has_version) - g_print("%d", version); + codec_name = gst_vaapi_codec_get_name(codec); + if (!codec_name) + continue; - profile = gst_structure_get_string(structure, "profile"); - if (!profile) - g_error("could not get structure profile"); - g_print(": %s profile\n", profile); + profile_name = gst_vaapi_profile_get_name(profile); + if (!profile_name) + continue; + + g_print(" %s: %s profile\n", codec_name, profile_name); } } @@ -232,22 +230,21 @@ end: static void dump_info(GstVaapiDisplay *display) { - GArray *formats; - GstCaps *caps; + GArray *profiles, *formats; - caps = gst_vaapi_display_get_decode_caps(display); - if (!caps) - g_error("could not get VA decode caps"); + profiles = gst_vaapi_display_get_decode_profiles(display); + if (!profiles) + g_error("could not get VA decode profiles"); - print_profile_caps(caps, "decoders"); - gst_caps_unref(caps); + print_profiles(profiles, "decoders"); + g_array_unref(profiles); - caps = gst_vaapi_display_get_encode_caps(display); - if (!caps) - g_error("could not get VA encode caps"); + profiles = gst_vaapi_display_get_encode_profiles(display); + if (!profiles) + g_error("could not get VA encode profiles"); - print_profile_caps(caps, "encoders"); - gst_caps_unref(caps); + print_profiles(profiles, "encoders"); + g_array_unref(profiles); formats = gst_vaapi_display_get_image_formats(display); if (!formats)