utils: expose GstPluginAPIFlags

These can be passed to gst_type_mark_as_plugin_api, to inform
plugin cache generation.

For now a single flag is specified, "IGNORE_ENUM_MEMBERS", it
can be used for dynamically generated enums to avoid documenting
environment-specific enumeration members. An example is
GstX265EncTune.
This commit is contained in:
Mathieu Duponchelle 2020-06-05 21:10:29 +02:00
parent d46e902273
commit 0c1ce6e8c4
15 changed files with 98 additions and 42 deletions

View file

@ -183,7 +183,7 @@ _serialize_enum_default (GString * json, GType gtype, GValue * value)
}
static void
_serialize_enum (GString * json, GType gtype)
_serialize_enum (GString * json, GType gtype, GstPluginAPIFlags api_flags)
{
GEnumValue *values;
guint j = 0;
@ -191,25 +191,30 @@ _serialize_enum (GString * json, GType gtype)
values = G_ENUM_CLASS (g_type_class_ref (gtype))->values;
g_string_append_printf (json, "%s\"%s\": { "
"\"kind\": \"enum\"," "\"values\": [", json->len ? "," : "",
g_type_name (gtype));
"\"kind\": \"enum\"", json->len ? "," : "", g_type_name (gtype));
while (values[j].value_name) {
gchar *value_name = json_strescape (values[j].value_name);
gchar *value_nick = json_strescape (values[j].value_nick);
if (api_flags & GST_PLUGIN_API_FLAG_IGNORE_ENUM_MEMBERS) {
g_string_append (json, ",\"ignore-enum-members\": true}");
} else {
g_string_append (json, ",\"values\": [");
g_string_append_printf (json, "{\"name\": \"%s\","
"\"value\": \"%d\","
"\"desc\": \"%s\"}", value_nick, values[j].value, value_name);
j++;
if (values[j].value_name)
g_string_append_c (json, ',');
while (values[j].value_name) {
gchar *value_name = json_strescape (values[j].value_name);
gchar *value_nick = json_strescape (values[j].value_nick);
g_free (value_name);
g_free (value_nick);
g_string_append_printf (json, "{\"name\": \"%s\","
"\"value\": \"%d\","
"\"desc\": \"%s\"}", value_nick, values[j].value, value_name);
j++;
if (values[j].value_name)
g_string_append_c (json, ',');
g_free (value_name);
g_free (value_nick);
}
g_string_append (json, "]}");
}
g_string_append (json, "]}");
}
static void
@ -250,6 +255,7 @@ _add_signals (GString * json, GString * other_types,
gint i = 0, j, k;
GSignalQuery *query = NULL;
GType type;
GstPluginAPIFlags api_flags;
GSList *found_signals, *l;
for (k = 0; k < 2; k++) {
@ -323,12 +329,12 @@ _add_signals (GString * json, GString * other_types,
if (!g_hash_table_contains (seen_other_types,
g_type_name (query->param_types[j]))
&& gst_type_is_plugin_api (query->param_types[j])) {
&& gst_type_is_plugin_api (query->param_types[j], &api_flags)) {
g_hash_table_insert (seen_other_types,
(gpointer) g_type_name (query->param_types[j]), NULL);
if (g_type_is_a (query->param_types[j], G_TYPE_ENUM)) {
_serialize_enum (other_types, query->param_types[j]);
_serialize_enum (other_types, query->param_types[j], api_flags);
} else if (g_type_is_a (query->param_types[j], G_TYPE_FLAGS)) {
_serialize_flags (other_types, query->param_types[j]);
} else if (g_type_is_a (query->param_types[j], G_TYPE_OBJECT)) {
@ -341,11 +347,11 @@ _add_signals (GString * json, GString * other_types,
if (!g_hash_table_contains (seen_other_types,
g_type_name (query->return_type))
&& gst_type_is_plugin_api (query->return_type)) {
&& gst_type_is_plugin_api (query->return_type, &api_flags)) {
g_hash_table_insert (seen_other_types,
(gpointer) g_type_name (query->return_type), NULL);
if (g_type_is_a (query->return_type, G_TYPE_ENUM)) {
_serialize_enum (other_types, query->return_type);
_serialize_enum (other_types, query->return_type, api_flags);
} else if (g_type_is_a (query->return_type, G_TYPE_FLAGS)) {
_serialize_flags (other_types, query->return_type);
} else if (g_type_is_a (query->return_type, G_TYPE_OBJECT)) {
@ -395,6 +401,7 @@ _add_properties (GString * json, GString * other_types,
guint i, n_props;
gboolean opened = FALSE;
GParamSpec **specs, *spec;
GstPluginAPIFlags api_flags;
specs = g_object_class_list_properties (klass, &n_props);
@ -440,11 +447,11 @@ _add_properties (GString * json, GString * other_types,
if (!g_hash_table_contains (seen_other_types,
g_type_name (spec->value_type))
&& gst_type_is_plugin_api (spec->value_type)) {
&& gst_type_is_plugin_api (spec->value_type, &api_flags)) {
g_hash_table_insert (seen_other_types,
(gpointer) g_type_name (spec->value_type), NULL);
if (G_IS_PARAM_SPEC_ENUM (spec)) {
_serialize_enum (other_types, spec->value_type);
_serialize_enum (other_types, spec->value_type, api_flags);
} else if (G_IS_PARAM_SPEC_FLAGS (spec)) {
_serialize_flags (other_types, spec->value_type);
} else if (G_IS_PARAM_SPEC_OBJECT (spec)) {
@ -698,6 +705,7 @@ _add_element_pad_templates (GString * json, GString * other_types,
const GList *pads;
GstStaticPadTemplate *padtemplate;
GRegex *re = g_regex_new ("%", 0, 0, NULL);
GstPluginAPIFlags api_flags;
pads = gst_element_factory_get_static_pad_templates (factory);
while (pads) {
@ -735,7 +743,7 @@ _add_element_pad_templates (GString * json, GString * other_types,
g_type_name (pad_type));
if (!g_hash_table_contains (seen_other_types, g_type_name (pad_type))
&& gst_type_is_plugin_api (pad_type)) {
&& gst_type_is_plugin_api (pad_type, &api_flags)) {
g_hash_table_insert (seen_other_types,
(gpointer) g_type_name (pad_type), NULL);
_serialize_object (other_types, seen_other_types, pad_type);

View file

@ -79,7 +79,7 @@ static const gchar *_quark_strings[] = {
"GstMessageDeviceChanged", "device-changed", "trickmode-interval",
"GstEventInstantRateChange",
"GstEventInstantRateSyncTime", "GstMessageInstantRateRequest",
"upstream-running-time", "base", "offset", "plugin-api"
"upstream-running-time", "base", "offset", "plugin-api", "plugin-api-flags",
};
GQuark _priv_gst_quark_table[GST_QUARK_MAX];

View file

@ -229,7 +229,8 @@ typedef enum _GstQuarkId
GST_QUARK_BASE = 198,
GST_QUARK_OFFSET = 199,
GST_QUARK_PLUGIN_API = 200,
GST_QUARK_MAX = 201
GST_QUARK_PLUGIN_API_FLAGS = 201,
GST_QUARK_MAX = 202
} GstQuarkId;
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];

View file

@ -4521,6 +4521,7 @@ invalid:
/**
* gst_type_mark_as_plugin_api:
* @type: a GType
* @flags: a set of #GstPluginApiFlags to further inform cache generation.
*
* Marks @type as plugin API. This should be called in `class_init` of
* elements that expose new types (i.e. enums, flags or internal GObjects) via
@ -4536,14 +4537,17 @@ invalid:
* Since: 1.18
*/
void
gst_type_mark_as_plugin_api (GType type)
gst_type_mark_as_plugin_api (GType type, GstPluginAPIFlags flags)
{
g_type_set_qdata (type, GST_QUARK (PLUGIN_API), GINT_TO_POINTER (TRUE));
g_type_set_qdata (type, GST_QUARK (PLUGIN_API_FLAGS),
GINT_TO_POINTER (flags));
}
/**
* gst_type_is_plugin_api:
* @type: a GType
* @flags: (out) (nullable): What #GstPluginApiFlags the plugin was marked with
*
* Checks if @type is plugin API. See gst_type_mark_as_plugin_api() for
* details.
@ -4553,7 +4557,15 @@ gst_type_mark_as_plugin_api (GType type)
* Since: 1.18
*/
gboolean
gst_type_is_plugin_api (GType type)
gst_type_is_plugin_api (GType type, GstPluginAPIFlags * flags)
{
return ! !GPOINTER_TO_INT (g_type_get_qdata (type, GST_QUARK (PLUGIN_API)));
gboolean ret =
! !GPOINTER_TO_INT (g_type_get_qdata (type, GST_QUARK (PLUGIN_API)));
if (ret && flags) {
*flags =
GPOINTER_TO_INT (g_type_get_qdata (type, GST_QUARK (PLUGIN_API_FLAGS)));
}
return ret;
}

View file

@ -1168,6 +1168,18 @@ typedef enum {
GST_SEARCH_MODE_AFTER
} GstSearchMode;
/**
* GstPluginAPIFlags:
* @GST_PLUGIN_API_FLAG_IGNORE_ENUM_MEMBERS: Ignore enum members when generating
* the plugins cache. This is useful if the members of the enum are generated
* dynamically, in order not to expose incorrect documentation to the end user.
*
* Since: 1.18
*/
typedef enum {
GST_PLUGIN_API_FLAG_IGNORE_ENUM_MEMBERS = (1 << 0),
} GstPluginAPIFlags;
GST_API
gpointer gst_util_array_binary_search (gpointer array, guint num_elements,
gsize element_size, GCompareDataFunc search_func,
@ -1205,10 +1217,10 @@ gboolean gst_calculate_linear_regression (const GstClockTime * xy,
gdouble * r_squared);
GST_API
void gst_type_mark_as_plugin_api (GType type);
void gst_type_mark_as_plugin_api (GType type, GstPluginAPIFlags flags);
GST_API
gboolean gst_type_is_plugin_api (GType type);
gboolean gst_type_is_plugin_api (GType type, GstPluginAPIFlags *flags);
G_END_DECLS

View file

@ -158,7 +158,7 @@ gst_capsfilter_class_init (GstCapsFilterClass * klass)
trans_class->sink_event = GST_DEBUG_FUNCPTR (gst_capsfilter_sink_event);
trans_class->stop = GST_DEBUG_FUNCPTR (gst_capsfilter_stop);
gst_type_mark_as_plugin_api (GST_TYPE_CAPS_FILTER_CAPS_CHANGE_MODE);
gst_type_mark_as_plugin_api (GST_TYPE_CAPS_FILTER_CAPS_CHANGE_MODE, 0);
}
static void

View file

@ -242,7 +242,7 @@ gst_fake_sink_class_init (GstFakeSinkClass * klass)
gstbase_sink_class->render = GST_DEBUG_FUNCPTR (gst_fake_sink_render);
gstbase_sink_class->query = GST_DEBUG_FUNCPTR (gst_fake_sink_query);
gst_type_mark_as_plugin_api (GST_TYPE_FAKE_SINK_STATE_ERROR);
gst_type_mark_as_plugin_api (GST_TYPE_FAKE_SINK_STATE_ERROR, 0);
}
static void

View file

@ -349,9 +349,9 @@ gst_fake_src_class_init (GstFakeSrcClass * klass)
gstbase_src_class->get_times = GST_DEBUG_FUNCPTR (gst_fake_src_get_times);
gstbase_src_class->create = GST_DEBUG_FUNCPTR (gst_fake_src_create);
gst_type_mark_as_plugin_api (GST_TYPE_FAKE_SRC_DATA);
gst_type_mark_as_plugin_api (GST_TYPE_FAKE_SRC_SIZETYPE);
gst_type_mark_as_plugin_api (GST_TYPE_FAKE_SRC_FILLTYPE);
gst_type_mark_as_plugin_api (GST_TYPE_FAKE_SRC_DATA, 0);
gst_type_mark_as_plugin_api (GST_TYPE_FAKE_SRC_SIZETYPE, 0);
gst_type_mark_as_plugin_api (GST_TYPE_FAKE_SRC_FILLTYPE, 0);
}
static void

View file

@ -288,7 +288,7 @@ gst_file_sink_class_init (GstFileSinkClass * klass)
sizeof (off_t));
}
gst_type_mark_as_plugin_api (GST_TYPE_FILE_SINK_BUFFER_MODE);
gst_type_mark_as_plugin_api (GST_TYPE_FILE_SINK_BUFFER_MODE, 0);
}
static void

View file

@ -1305,8 +1305,8 @@ gst_input_selector_class_init (GstInputSelectorClass * klass)
gstelement_class->release_pad = gst_input_selector_release_pad;
gstelement_class->change_state = gst_input_selector_change_state;
gst_type_mark_as_plugin_api (GST_TYPE_SELECTOR_PAD);
gst_type_mark_as_plugin_api (GST_TYPE_INPUT_SELECTOR_SYNC_MODE);
gst_type_mark_as_plugin_api (GST_TYPE_SELECTOR_PAD, 0);
gst_type_mark_as_plugin_api (GST_TYPE_INPUT_SELECTOR_SYNC_MODE, 0);
}
static void

View file

@ -841,7 +841,7 @@ gst_multi_queue_class_init (GstMultiQueueClass * klass)
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_multi_queue_change_state);
gst_type_mark_as_plugin_api (GST_TYPE_MULTIQUEUE_PAD);
gst_type_mark_as_plugin_api (GST_TYPE_MULTIQUEUE_PAD, 0);
}
static void

View file

@ -148,7 +148,8 @@ gst_output_selector_class_init (GstOutputSelectorClass * klass)
gstelement_class->change_state = gst_output_selector_change_state;
gst_type_mark_as_plugin_api (GST_TYPE_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE);
gst_type_mark_as_plugin_api (GST_TYPE_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE,
0);
}
static void

View file

@ -420,7 +420,7 @@ gst_queue_class_init (GstQueueClass * klass)
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_chain);
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_chain_list);
gst_type_mark_as_plugin_api (GST_TYPE_QUEUE_LEAKY);
gst_type_mark_as_plugin_api (GST_TYPE_QUEUE_LEAKY, 0);
}
static void

View file

@ -298,7 +298,7 @@ gst_tee_class_init (GstTeeClass * klass)
GST_DEBUG_FUNCPTR (gst_tee_request_new_pad);
gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_tee_release_pad);
gst_type_mark_as_plugin_api (GST_TYPE_TEE_PULL_MODE);
gst_type_mark_as_plugin_api (GST_TYPE_TEE_PULL_MODE, 0);
}
static void

View file

@ -1953,6 +1953,26 @@ GST_START_TEST (test_regression)
GST_END_TEST;
GST_START_TEST (test_mark_as_plugin_api)
{
GstPluginAPIFlags api_flags;
fail_unless (!gst_type_is_plugin_api (GST_TYPE_ELEMENT, NULL));
gst_type_mark_as_plugin_api (GST_TYPE_ELEMENT, 0);
fail_unless (gst_type_is_plugin_api (GST_TYPE_ELEMENT, &api_flags));
fail_unless_equals_int (api_flags, 0);
gst_type_mark_as_plugin_api (GST_TYPE_ELEMENT,
GST_PLUGIN_API_FLAG_IGNORE_ENUM_MEMBERS);
fail_unless (gst_type_is_plugin_api (GST_TYPE_ELEMENT, &api_flags));
fail_unless_equals_int (api_flags, GST_PLUGIN_API_FLAG_IGNORE_ENUM_MEMBERS);
}
GST_END_TEST;
static Suite *
gst_utils_suite (void)
{
@ -1994,6 +2014,8 @@ gst_utils_suite (void)
tcase_add_test (tc_chain, test_write_macros);
tcase_add_test (tc_chain, test_regression);
tcase_add_test (tc_chain, test_mark_as_plugin_api);
return s;
}