libs: display: refine the profile/entrypoint map.

The old way make the one config for each profile/entrypoint pair,
which is not very convenient for description the relationship
between them. One profile may contain more than one entrypoints
to within it, so a set like data structure should be more suitable.
This commit is contained in:
He Junyan 2019-12-12 21:34:21 +08:00 committed by Víctor Manuel Jáquez Leal
parent 608ce681e5
commit b2cabe2f5b
3 changed files with 65 additions and 50 deletions

View file

@ -51,11 +51,11 @@ GST_DEBUG_CATEGORY (gst_debug_vaapi_display);
G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplay, gst_vaapi_display, GST_TYPE_OBJECT, G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplay, gst_vaapi_display, GST_TYPE_OBJECT,
_do_init); _do_init);
typedef struct _GstVaapiConfig GstVaapiConfig; typedef struct _GstVaapiProfileConfig GstVaapiProfileConfig;
struct _GstVaapiConfig struct _GstVaapiProfileConfig
{ {
GstVaapiProfile profile; GstVaapiProfile profile;
GstVaapiEntrypoint entrypoint; guint32 entrypoints; /* bits map of GstVaapiEntrypoint */
}; };
typedef struct _GstVaapiProperty GstVaapiProperty; typedef struct _GstVaapiProperty GstVaapiProperty;
@ -260,18 +260,18 @@ compare_rgb_formats (gconstpointer a, gconstpointer b)
/* Check if configs array contains profile at entrypoint */ /* Check if configs array contains profile at entrypoint */
static inline gboolean static inline gboolean
find_config (GArray * configs, find_config (GPtrArray * configs,
GstVaapiProfile profile, GstVaapiEntrypoint entrypoint) GstVaapiProfile profile, GstVaapiEntrypoint entrypoint)
{ {
GstVaapiConfig *config; GstVaapiProfileConfig *config;
guint i; guint i;
if (!configs) if (!configs)
return FALSE; return FALSE;
for (i = 0; i < configs->len; i++) { for (i = 0; i < configs->len; i++) {
config = &g_array_index (configs, GstVaapiConfig, i); config = g_ptr_array_index (configs, i);
if (config->profile == profile && config->entrypoint == entrypoint) if (config->profile == profile && (config->entrypoints & (1 << entrypoint)))
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
@ -279,21 +279,21 @@ find_config (GArray * configs,
/* HACK: append H.263 Baseline profile if MPEG-4:2 Simple profile is supported */ /* HACK: append H.263 Baseline profile if MPEG-4:2 Simple profile is supported */
static void static void
append_h263_config (GArray * configs) append_h263_config (GArray * configs, GPtrArray * decoders)
{ {
GstVaapiConfig *config, tmp_config; GstVaapiProfileConfig *config, tmp_config;
GstVaapiConfig *mpeg4_simple_config = NULL; GstVaapiProfileConfig *mpeg4_simple_config = NULL;
GstVaapiConfig *h263_baseline_config = NULL; GstVaapiProfileConfig *h263_baseline_config = NULL;
guint i; guint i;
if (!WORKAROUND_H263_BASELINE_DECODE_PROFILE) if (!WORKAROUND_H263_BASELINE_DECODE_PROFILE)
return; return;
if (!configs) if (!decoders)
return; return;
for (i = 0; i < configs->len; i++) { for (i = 0; i < decoders->len; i++) {
config = &g_array_index (configs, GstVaapiConfig, i); config = g_ptr_array_index (decoders, i);
if (config->profile == GST_VAAPI_PROFILE_MPEG4_SIMPLE) if (config->profile == GST_VAAPI_PROFILE_MPEG4_SIMPLE)
mpeg4_simple_config = config; mpeg4_simple_config = config;
else if (config->profile == GST_VAAPI_PROFILE_H263_BASELINE) else if (config->profile == GST_VAAPI_PROFILE_H263_BASELINE)
@ -304,6 +304,8 @@ append_h263_config (GArray * configs)
tmp_config = *mpeg4_simple_config; tmp_config = *mpeg4_simple_config;
tmp_config.profile = GST_VAAPI_PROFILE_H263_BASELINE; tmp_config.profile = GST_VAAPI_PROFILE_H263_BASELINE;
g_array_append_val (configs, tmp_config); g_array_append_val (configs, tmp_config);
g_ptr_array_add (decoders, &g_array_index (configs,
GstVaapiProfileConfig, configs->len - 1));
} }
} }
@ -311,20 +313,18 @@ append_h263_config (GArray * configs)
static gint static gint
compare_profiles (gconstpointer a, gconstpointer b) compare_profiles (gconstpointer a, gconstpointer b)
{ {
const GstVaapiConfig *const config1 = (GstVaapiConfig *) a; const GstVaapiProfileConfig *const config1 = (GstVaapiProfileConfig *) a;
const GstVaapiConfig *const config2 = (GstVaapiConfig *) b; const GstVaapiProfileConfig *const config2 = (GstVaapiProfileConfig *) b;
if (config1->profile == config2->profile)
return config1->entrypoint - config2->entrypoint;
g_assert (config1->profile != config2->profile);
return config1->profile - config2->profile; return config1->profile - config2->profile;
} }
/* Convert configs array to profiles as GstCaps */ /* Convert configs array to profiles as GstCaps */
static GArray * static GArray *
get_profiles (GArray * configs) get_profiles (GPtrArray * configs)
{ {
GstVaapiConfig *config; GstVaapiProfileConfig *config;
GArray *out_profiles; GArray *out_profiles;
guint i; guint i;
@ -336,7 +336,7 @@ get_profiles (GArray * configs)
return NULL; return NULL;
for (i = 0; i < configs->len; i++) { for (i = 0; i < configs->len; i++) {
config = &g_array_index (configs, GstVaapiConfig, i); config = g_ptr_array_index (configs, i);
g_array_append_val (out_profiles, config->profile); g_array_append_val (out_profiles, config->profile);
} }
return out_profiles; return out_profiles;
@ -470,10 +470,14 @@ ensure_profiles (GstVaapiDisplay * display)
return TRUE; return TRUE;
} }
priv->decoders = g_array_new (FALSE, FALSE, sizeof (GstVaapiConfig)); priv->codecs = g_array_new (FALSE, FALSE, sizeof (GstVaapiProfileConfig));
if (!priv->codecs)
goto cleanup;
priv->decoders = g_ptr_array_new ();
if (!priv->decoders) if (!priv->decoders)
goto cleanup; goto cleanup;
priv->encoders = g_array_new (FALSE, FALSE, sizeof (GstVaapiConfig)); priv->encoders = g_ptr_array_new ();
if (!priv->encoders) if (!priv->encoders)
goto cleanup; goto cleanup;
priv->has_profiles = TRUE; priv->has_profiles = TRUE;
@ -502,7 +506,8 @@ ensure_profiles (GstVaapiDisplay * display)
} }
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
GstVaapiConfig config; GstVaapiProfileConfig config;
memset (&config, 0, sizeof (GstVaapiProfileConfig));
config.profile = gst_vaapi_profile (profiles[i]); config.profile = gst_vaapi_profile (profiles[i]);
if (!config.profile) if (!config.profile)
@ -513,27 +518,30 @@ ensure_profiles (GstVaapiDisplay * display)
if (!vaapi_check_status (status, "vaQueryConfigEntrypoints()")) if (!vaapi_check_status (status, "vaQueryConfigEntrypoints()"))
continue; continue;
for (j = 0; j < num_entrypoints; j++) { for (j = 0; j < num_entrypoints; j++)
config.entrypoint = gst_vaapi_entrypoint (entrypoints[j]); config.entrypoints |= (1 << gst_vaapi_entrypoint (entrypoints[j]));
switch (config.entrypoint) {
case GST_VAAPI_ENTRYPOINT_VLD:
case GST_VAAPI_ENTRYPOINT_IDCT:
case GST_VAAPI_ENTRYPOINT_MOCO:
g_array_append_val (priv->decoders, config);
break;
case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE:
case GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE:
case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP:
case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI:
g_array_append_val (priv->encoders, config);
break;
}
}
}
append_h263_config (priv->decoders);
g_array_sort (priv->decoders, compare_profiles); g_array_append_val (priv->codecs, config);
g_array_sort (priv->encoders, compare_profiles); }
for (i = 0; i < priv->codecs->len; i++) {
GstVaapiProfileConfig *codec =
&g_array_index (priv->codecs, GstVaapiProfileConfig, i);
if ((codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_VLD)
|| (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_IDCT)
|| (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_MOCO))
g_ptr_array_add (priv->decoders, codec);
if ((codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_SLICE_ENCODE)
|| (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE)
|| (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP)
|| (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI))
g_ptr_array_add (priv->encoders, codec);
}
append_h263_config (priv->codecs, priv->decoders);
g_ptr_array_sort (priv->decoders, compare_profiles);
g_ptr_array_sort (priv->encoders, compare_profiles);
/* Video processing API */ /* Video processing API */
status = vaQueryConfigEntrypoints (priv->display, VAProfileNone, status = vaQueryConfigEntrypoints (priv->display, VAProfileNone,
@ -817,15 +825,20 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display)
GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
if (priv->decoders) { if (priv->decoders) {
g_array_free (priv->decoders, TRUE); g_ptr_array_free (priv->decoders, TRUE);
priv->decoders = NULL; priv->decoders = NULL;
} }
if (priv->encoders) { if (priv->encoders) {
g_array_free (priv->encoders, TRUE); g_ptr_array_free (priv->encoders, TRUE);
priv->encoders = NULL; priv->encoders = NULL;
} }
if (priv->codecs) {
g_array_free (priv->codecs, TRUE);
priv->codecs = NULL;
}
if (priv->image_formats) { if (priv->image_formats) {
g_array_free (priv->image_formats, TRUE); g_array_free (priv->image_formats, TRUE);
priv->image_formats = NULL; priv->image_formats = NULL;

View file

@ -120,8 +120,9 @@ struct _GstVaapiDisplayPrivate
guint height_mm; guint height_mm;
guint par_n; guint par_n;
guint par_d; guint par_d;
GArray *decoders; GPtrArray *decoders; /* ref element in codecs */
GArray *encoders; GPtrArray *encoders; /* ref element in codecs */
GArray *codecs;
GArray *image_formats; GArray *image_formats;
GArray *subpicture_formats; GArray *subpicture_formats;
GArray *properties; GArray *properties;

View file

@ -206,7 +206,8 @@ typedef enum {
GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE,
GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE, GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE,
GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP,
GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI,
GST_VAAPI_MAX_ENTRYPOINTS
} GstVaapiEntrypoint; } GstVaapiEntrypoint;
const gchar * const gchar *