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.
This commit is contained in:
Gwenole Beauchesne 2014-01-12 18:52:14 +01:00
parent 59229b20a5
commit 850a637d0f
4 changed files with 128 additions and 1 deletions

View file

@ -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));
/**

View file

@ -27,6 +27,7 @@
#include <gst/vaapi/gstvaapicontext.h>
#include <gst/vaapi/gstvaapivideopool.h>
#include <gst/video/gstvideoutils.h>
#include <gst/vaapi/gstvaapivalue.h>
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, \
}

View file

@ -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;
}

View file

@ -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 */