encoder: filter out the supported set of rate-control properties.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Sun, 12 Jan 2014 17:52:14 +0000 (18:52 +0100)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Mon, 13 Jan 2014 16:31:55 +0000 (17:31 +0100)
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
gst-libs/gst/vaapi/gstvaapiencoder_priv.h
gst-libs/gst/vaapi/gstvaapivalue.c
gst-libs/gst/vaapi/gstvaapivalue.h

index f222361..1a99147 100644 (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));
 
   /**
index d473a05..81549d5 100644 (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,                        \
   }
index 2f4c239..07d9923 100644 (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;
+}
index 4c4d798..2f6f431 100644 (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 */