From 850a637d0f21b750a37fe836f0dc123c4a826dd9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sun, 12 Jan 2014 18:52:14 +0100 Subject: [PATCH] encoder: filter out the supported set of rate-control properties. Only expose the exact static set of supported rate-control properties to the upper layer. For instance, if the GstVaapiEncoderXXX class does only support CQP rate control, then only add it the the exposed enum type. Add helper macros and functions to build a GType for an enum subset. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 4 +- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 9 ++++ gst-libs/gst/vaapi/gstvaapivalue.c | 51 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapivalue.h | 65 +++++++++++++++++++++++ 4 files changed, 128 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index f222361211..1a99147185 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -115,6 +115,8 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) const GstVaapiEncoderClassData *const cdata = klass->class_data; GPtrArray *props = NULL; + g_assert (cdata->rate_control_get_type != NULL); + /** * GstVaapiEncoder:rate-control: * @@ -124,7 +126,7 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) GST_VAAPI_ENCODER_PROP_RATECONTROL, g_param_spec_enum ("rate-control", "Rate Control", "Rate control mode", - GST_VAAPI_TYPE_RATE_CONTROL, cdata->default_rate_control, + cdata->rate_control_get_type (), cdata->default_rate_control, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index d473a0508a..81549d58cf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -27,6 +27,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -197,13 +198,21 @@ struct _GstVaapiEncoderClassData /*< private >*/ GstVaapiCodec codec; + GType (*rate_control_get_type)(void); GstVaapiRateControl default_rate_control; guint32 rate_control_mask; }; #define GST_VAAPI_ENCODER_DEFINE_CLASS_DATA(CODEC) \ + GST_VAAPI_TYPE_DEFINE_ENUM_SUBSET_FROM_MASK( \ + G_PASTE (GstVaapiRateControl, CODEC), \ + G_PASTE (gst_vaapi_rate_control_, CODEC), \ + GST_VAAPI_TYPE_RATE_CONTROL, SUPPORTED_RATECONTROLS); \ + \ static const GstVaapiEncoderClassData g_class_data = { \ .codec = G_PASTE (GST_VAAPI_CODEC_, CODEC), \ + .rate_control_get_type = \ + G_PASTE (G_PASTE (gst_vaapi_rate_control_, CODEC), _get_type), \ .default_rate_control = DEFAULT_RATECONTROL, \ .rate_control_mask = SUPPORTED_RATECONTROLS, \ } diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 2f4c239b27..07d99233b4 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -150,3 +150,54 @@ gst_vaapi_rate_control_get_type(void) } return g_type; } + +static gboolean +build_enum_subset_values_from_mask (GstVaapiEnumSubset *subset, guint32 mask) +{ + GEnumClass *enum_class; + const GEnumValue *value; + guint i, n; + + enum_class = g_type_class_ref(subset->parent_type); + if (!enum_class) + return FALSE; + + for (i = 0, n = 0; i < 32 && n < subset->num_values; i++) { + if (!(mask & (1U << i))) + continue; + value = g_enum_get_value(enum_class, i); + if (!value) + continue; + subset->values[n++] = *value; + } + g_type_class_unref(enum_class); + if (n != subset->num_values - 1) + goto error_invalid_num_values; + return TRUE; + + /* ERRORS */ +error_invalid_num_values: + { + g_error("invalid number of static values for `%s'", subset->type_name); + return FALSE; + } +} + +GType +gst_vaapi_type_define_enum_subset_from_mask(GstVaapiEnumSubset *subset, + guint32 mask) +{ + if (g_once_init_enter(&subset->type)) { + GType type; + + build_enum_subset_values_from_mask(subset, mask); + memset(&subset->type_info, 0, sizeof(subset->type_info)); + g_enum_complete_type_info(subset->parent_type, &subset->type_info, + subset->values); + + type = g_type_register_static (G_TYPE_ENUM, subset->type_name, + &subset->type_info, 0); + g_once_init_leave(&subset->type, type); + } + return subset->type; +} diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index 4c4d7982d9..2f6f431b54 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -92,6 +92,71 @@ gst_vaapi_rotation_get_type(void) G_GNUC_CONST; GType gst_vaapi_rate_control_get_type(void) G_GNUC_CONST; +/** + * GST_VAAPI_POPCOUNT32: + * @x: the value from which to compute population count + * + * Computes the number of bits set in the supplied 32-bit value @x. + * + * Return value: the number of bits set in @x + */ +#define GST_VAAPI_POPCOUNT32(x) \ + GST_VAAPI_POPCOUNT32_0(x) +#define GST_VAAPI_POPCOUNT32_0(x) \ + GST_VAAPI_POPCOUNT32_1((x) - (((x) >> 1) & 0x55555555)) +#define GST_VAAPI_POPCOUNT32_1(x) \ + GST_VAAPI_POPCOUNT32_2(((x) & 0x33333333) + (((x) >> 2) & 0x33333333)) +#define GST_VAAPI_POPCOUNT32_2(x) \ + GST_VAAPI_POPCOUNT32_3((x) + ((x) >> 4)) +#define GST_VAAPI_POPCOUNT32_3(x) \ + GST_VAAPI_POPCOUNT32_4((x) & 0x0f0f0f0f) +#define GST_VAAPI_POPCOUNT32_4(x) \ + (((x) * 0x01010101) >> 24) + +/* --- GstVaapiEnumSubset --- */ + +/** + * GstVaapiEnumSubset: + * @name: name of the enum subset + * @parent_type: parent enum type + * @type: registered #GType + * @type_info: #GTypeInfo used to build the @type + * @values: pointer to a static array of #GEnumValue elements + * @num_values: number of elements in the @values array, including the + * terminator + * + * Structure that holds the required information to build a GEnum + * subset from the supplied @parent_type, i.e. a subset of its values. + */ +typedef struct { + GType parent_type; + GType type; + GTypeInfo type_info; + const gchar *type_name; + GEnumValue *values; + guint num_values; +} GstVaapiEnumSubset; + +G_GNUC_INTERNAL +GType +gst_vaapi_type_define_enum_subset_from_mask(GstVaapiEnumSubset *subset, + guint32 mask); + +#define GST_VAAPI_TYPE_DEFINE_ENUM_SUBSET_FROM_MASK(NAME, name, TYPE, MASK) \ +static GType \ +G_PASTE(name,_get_type)(void) \ +{ \ + static GEnumValue enum_values[GST_VAAPI_POPCOUNT32(MASK) + 1]; \ + static GstVaapiEnumSubset subset = { \ + .type_name = G_STRINGIFY(NAME), \ + .values = enum_values, \ + .num_values = G_N_ELEMENTS(enum_values), \ + }; \ + if (g_once_init_enter(&subset.parent_type)) \ + g_once_init_leave(&subset.parent_type, TYPE); \ + return gst_vaapi_type_define_enum_subset_from_mask(&subset, MASK); \ +} + G_END_DECLS #endif /* GST_VAAPI_VALUE_H */