query: register queries like events

Also register queries with a QueryType that allows us to check if the event is
sent in the right direction. Add a serialized query type because we will need
this for the allocation query.
Remove the QueryTypeDefinition stuff, it is not used anymore and we now use
custom queries and separate API for them.
Update defs.
This commit is contained in:
Wim Taymans 2012-03-14 14:51:16 +01:00
parent d8578d5c09
commit 5a21eb36c7
4 changed files with 147 additions and 244 deletions

View file

@ -704,6 +704,7 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
g_type_class_ref (gst_plugin_flags_get_type ());
g_type_class_ref (gst_plugin_dependency_flags_get_type ());
g_type_class_ref (gst_rank_get_type ());
g_type_class_ref (gst_query_type_flags_get_type ());
g_type_class_ref (gst_query_type_get_type ());
g_type_class_ref (gst_buffering_mode_get_type ());
g_type_class_ref (gst_stream_status_type_get_type ());
@ -1069,6 +1070,7 @@ gst_deinit (void)
g_type_class_unref (g_type_class_peek (gst_plugin_error_get_type ()));
g_type_class_unref (g_type_class_peek (gst_plugin_flags_get_type ()));
g_type_class_unref (g_type_class_peek (gst_rank_get_type ()));
g_type_class_unref (g_type_class_peek (gst_query_type_flags_get_type ()));
g_type_class_unref (g_type_class_peek (gst_query_type_get_type ()));
g_type_class_unref (g_type_class_peek (gst_buffering_mode_get_type ()));
g_type_class_unref (g_type_class_peek (gst_tag_merge_mode_get_type ()));

View file

@ -96,30 +96,33 @@ typedef struct
gint64 stop;
} GstQueryBufferingRange;
static GMutex mutex;
static GList *_gst_queries = NULL;
static GHashTable *_nick_to_query = NULL;
static GHashTable *_query_type_to_nick = NULL;
static guint32 _n_values = 1; /* we start from 1 because 0 reserved for NONE */
typedef struct
{
const gint type;
const gchar *name;
GQuark quark;
} GstQueryQuarks;
static GstQueryTypeDefinition standard_definitions[] = {
{GST_QUERY_POSITION, "position", "Current position", 0},
{GST_QUERY_DURATION, "duration", "Total duration", 0},
{GST_QUERY_LATENCY, "latency", "Latency", 0},
{GST_QUERY_JITTER, "jitter", "Jitter", 0},
{GST_QUERY_RATE, "rate", "Configured rate 1000000 = 1", 0},
{GST_QUERY_SEEKING, "seeking", "Seeking capabilities and parameters", 0},
{GST_QUERY_SEGMENT, "segment", "currently configured segment", 0},
{GST_QUERY_CONVERT, "convert", "Converting between formats", 0},
{GST_QUERY_FORMATS, "formats", "Supported formats for conversion", 0},
{GST_QUERY_BUFFERING, "buffering", "Buffering status", 0},
{GST_QUERY_CUSTOM, "custom", "Custom query", 0},
{GST_QUERY_URI, "uri", "URI of the source or sink", 0},
{GST_QUERY_ALLOCATION, "allocation", "Allocation properties", 0},
{GST_QUERY_SCHEDULING, "scheduling", "Scheduling properties", 0},
{GST_QUERY_ACCEPT_CAPS, "accept-caps", "Accept caps", 0},
{GST_QUERY_CAPS, "caps", "Caps", 0},
{GST_QUERY_NONE, NULL, NULL, 0}
static GstQueryQuarks query_quarks[] = {
{GST_QUERY_UNKNOWN, "unknown", 0},
{GST_QUERY_POSITION, "position", 0},
{GST_QUERY_DURATION, "duration", 0},
{GST_QUERY_LATENCY, "latency", 0},
{GST_QUERY_JITTER, "jitter", 0},
{GST_QUERY_RATE, "rate", 0},
{GST_QUERY_SEEKING, "seeking", 0},
{GST_QUERY_SEGMENT, "segment", 0},
{GST_QUERY_CONVERT, "convert", 0},
{GST_QUERY_FORMATS, "formats", 0},
{GST_QUERY_BUFFERING, "buffering", 0},
{GST_QUERY_CUSTOM, "custom", 0},
{GST_QUERY_URI, "uri", 0},
{GST_QUERY_ALLOCATION, "allocation", 0},
{GST_QUERY_SCHEDULING, "scheduling", 0},
{GST_QUERY_ACCEPT_CAPS, "accept-caps", 0},
{GST_QUERY_CAPS, "caps", 0},
{0, NULL, 0}
};
GST_DEFINE_MINI_OBJECT_TYPE (GstQuery, gst_query);
@ -127,205 +130,73 @@ GST_DEFINE_MINI_OBJECT_TYPE (GstQuery, gst_query);
void
_priv_gst_query_initialize (void)
{
GstQueryTypeDefinition *standards = standard_definitions;
gint i;
GST_CAT_INFO (GST_CAT_GST_INIT, "init queries");
_gst_query_type = gst_query_get_type ();
GST_DEBUG_CATEGORY_INIT (gst_query_debug, "query", 0, "query system");
g_mutex_lock (&mutex);
if (_nick_to_query == NULL) {
_nick_to_query = g_hash_table_new (g_str_hash, g_str_equal);
_query_type_to_nick = g_hash_table_new (NULL, NULL);
for (i = 0; query_quarks[i].name; i++) {
query_quarks[i].quark = g_quark_from_static_string (query_quarks[i].name);
}
while (standards->nick) {
standards->quark = g_quark_from_static_string (standards->nick);
g_hash_table_insert (_nick_to_query, (gpointer) standards->nick, standards);
g_hash_table_insert (_query_type_to_nick,
GINT_TO_POINTER (standards->value), standards);
_gst_queries = g_list_append (_gst_queries, standards);
standards++;
_n_values++;
}
g_mutex_unlock (&mutex);
_gst_query_type = gst_query_get_type ();
}
/**
* gst_query_type_get_name:
* @query: the query type
* @type: the query type
*
* Get a printable name for the given query type. Do not modify or free.
*
* Returns: a reference to the static name of the query.
*/
const gchar *
gst_query_type_get_name (GstQueryType query)
gst_query_type_get_name (GstQueryType type)
{
const GstQueryTypeDefinition *def;
gint i;
def = gst_query_type_get_details (query);
g_return_val_if_fail (def != NULL, NULL);
return def->nick;
for (i = 0; query_quarks[i].name; i++) {
if (type == query_quarks[i].type)
return query_quarks[i].name;
}
return "unknown";
}
/**
* gst_query_type_to_quark:
* @query: the query type
* @type: the query type
*
* Get the unique quark for the given query type.
*
* Returns: the quark associated with the query type
*/
GQuark
gst_query_type_to_quark (GstQueryType query)
gst_query_type_to_quark (GstQueryType type)
{
const GstQueryTypeDefinition *def;
gint i;
def = gst_query_type_get_details (query);
g_return_val_if_fail (def != NULL, 0);
return def->quark;
}
/**
* gst_query_type_register:
* @nick: The nick of the new query
* @description: The description of the new query
*
* Create a new GstQueryType based on the nick or return an
* already registered query with that nick
*
* Returns: A new GstQueryType or an already registered query
* with the same nick.
*/
GstQueryType
gst_query_type_register (const gchar * nick, const gchar * description)
{
GstQueryTypeDefinition *query;
GstQueryType lookup;
g_return_val_if_fail (nick != NULL, GST_QUERY_NONE);
g_return_val_if_fail (description != NULL, GST_QUERY_NONE);
lookup = gst_query_type_get_by_nick (nick);
if (lookup != GST_QUERY_NONE)
return lookup;
query = g_slice_new (GstQueryTypeDefinition);
query->value = (GstQueryType) _n_values;
query->nick = g_strdup (nick);
query->description = g_strdup (description);
query->quark = g_quark_from_static_string (query->nick);
g_mutex_lock (&mutex);
g_hash_table_insert (_nick_to_query, (gpointer) query->nick, query);
g_hash_table_insert (_query_type_to_nick, GINT_TO_POINTER (query->value),
query);
_gst_queries = g_list_append (_gst_queries, query);
_n_values++;
g_mutex_unlock (&mutex);
return query->value;
}
/**
* gst_query_type_get_by_nick:
* @nick: The nick of the query
*
* Get the query type registered with @nick.
*
* Returns: The query registered with @nick or #GST_QUERY_NONE
* if the query was not registered.
*/
GstQueryType
gst_query_type_get_by_nick (const gchar * nick)
{
GstQueryTypeDefinition *query;
g_return_val_if_fail (nick != NULL, GST_QUERY_NONE);
g_mutex_lock (&mutex);
query = g_hash_table_lookup (_nick_to_query, nick);
g_mutex_unlock (&mutex);
if (query != NULL)
return query->value;
else
return GST_QUERY_NONE;
}
/**
* gst_query_types_contains:
* @types: The query array to search
* @type: the #GstQueryType to find
*
* See if the given #GstQueryType is inside the @types query types array.
*
* Returns: TRUE if the type is found inside the array
*/
gboolean
gst_query_types_contains (const GstQueryType * types, GstQueryType type)
{
if (!types)
return FALSE;
while (*types) {
if (*types == type)
return TRUE;
types++;
for (i = 0; query_quarks[i].name; i++) {
if (type == query_quarks[i].type)
return query_quarks[i].quark;
}
return FALSE;
return 0;
}
/**
* gst_query_type_get_details:
* gst_query_type_get_flags:
* @type: a #GstQueryType
*
* Get details about the given #GstQueryType.
* Gets the #GstQueryTypeFlags associated with @type.
*
* Returns: The #GstQueryTypeDefinition for @type or NULL on failure.
* Returns: a #GstQueryTypeFlags.
*/
const GstQueryTypeDefinition *
gst_query_type_get_details (GstQueryType type)
GstQueryTypeFlags
gst_query_type_get_flags (GstQueryType type)
{
const GstQueryTypeDefinition *result;
GstQueryTypeFlags ret;
g_mutex_lock (&mutex);
result = g_hash_table_lookup (_query_type_to_nick, GINT_TO_POINTER (type));
g_mutex_unlock (&mutex);
ret = type & ((1 << GST_EVENT_NUM_SHIFT) - 1);
return result;
}
/**
* gst_query_type_iterate_definitions:
*
* Get a #GstIterator of all the registered query types. The definitions
* iterated over are read only.
*
* Free-function: gst_iterator_free
*
* Returns: (transfer full): a #GstIterator of #GstQueryTypeDefinition.
*/
GstIterator *
gst_query_type_iterate_definitions (void)
{
GstIterator *result;
g_mutex_lock (&mutex);
/* FIXME: register a boxed type for GstQueryTypeDefinition */
result = gst_iterator_new_list (G_TYPE_POINTER,
&mutex, &_n_values, &_gst_queries, NULL, NULL);
g_mutex_unlock (&mutex);
return result;
return ret;
}
static void

View file

@ -36,9 +36,53 @@
G_BEGIN_DECLS
typedef struct _GstQuery GstQuery;
/**
* GstQueryTypeFlags:
* @GST_QUERY_TYPE_UPSTREAM: Set if the query can travel upstream.
* @GST_QUERY_TYPE_DOWNSTREAM: Set if the query can travel downstream.
* @GST_QUERY_TYPE_SERIALIZED: Set if the query should be serialized with data
* flow.
*
* #GstQueryTypeFlags indicate the aspects of the different #GstQueryType
* values. You can get the type flags of a #GstQueryType with the
* gst_query_type_get_flags() function.
*/
typedef enum {
GST_QUERY_TYPE_UPSTREAM = 1 << 0,
GST_QUERY_TYPE_DOWNSTREAM = 1 << 1,
GST_QUERY_TYPE_SERIALIZED = 1 << 2
} GstQueryTypeFlags;
/**
* GST_QUERY_TYPE_BOTH:
*
* The same thing as #GST_QUERY_TYPE_UPSTREAM | #GST_QUERY_TYPE_DOWNSTREAM.
*/
#define GST_QUERY_TYPE_BOTH \
(GST_QUERY_TYPE_UPSTREAM | GST_QUERY_TYPE_DOWNSTREAM)
#define GST_QUERY_NUM_SHIFT (8)
/**
* GST_QUERY_MAKE_TYPE:
* @num: the query number to create
* @idx: the index in the sticky array
* @flags: the query flags
*
* when making custom query types, use this macro with the num and
* the given flags
*/
#define GST_QUERY_MAKE_TYPE(num,flags) \
(((num) << GST_QUERY_NUM_SHIFT) | (flags))
#define FLAG(name) GST_QUERY_TYPE_##name
/**
* GstQueryType:
* @GST_QUERY_NONE: invalid query type
* @GST_QUERY_UNKNOWN: unknown query type
* @GST_QUERY_POSITION: current position in stream
* @GST_QUERY_DURATION: total duration of the stream
* @GST_QUERY_LATENCY: latency of stream
@ -63,51 +107,31 @@ G_BEGIN_DECLS
/* NOTE: don't forget to update the table in gstquery.c when changing
* this enum */
typedef enum {
GST_QUERY_NONE = 0,
GST_QUERY_POSITION,
GST_QUERY_DURATION,
GST_QUERY_LATENCY,
GST_QUERY_JITTER, /* not in draft-query, necessary? */
GST_QUERY_RATE,
GST_QUERY_SEEKING,
GST_QUERY_SEGMENT,
GST_QUERY_CONVERT,
GST_QUERY_FORMATS,
GST_QUERY_BUFFERING,
GST_QUERY_CUSTOM,
GST_QUERY_URI,
GST_QUERY_ALLOCATION,
GST_QUERY_SCHEDULING,
GST_QUERY_ACCEPT_CAPS,
GST_QUERY_CAPS
GST_QUERY_UNKNOWN = GST_QUERY_MAKE_TYPE (0, 0),
GST_QUERY_POSITION = GST_QUERY_MAKE_TYPE (10, FLAG(BOTH)),
GST_QUERY_DURATION = GST_QUERY_MAKE_TYPE (20, FLAG(BOTH)),
GST_QUERY_LATENCY = GST_QUERY_MAKE_TYPE (30, FLAG(BOTH)),
GST_QUERY_JITTER = GST_QUERY_MAKE_TYPE (40, FLAG(BOTH)),
GST_QUERY_RATE = GST_QUERY_MAKE_TYPE (50, FLAG(BOTH)),
GST_QUERY_SEEKING = GST_QUERY_MAKE_TYPE (60, FLAG(BOTH)),
GST_QUERY_SEGMENT = GST_QUERY_MAKE_TYPE (70, FLAG(BOTH)),
GST_QUERY_CONVERT = GST_QUERY_MAKE_TYPE (80, FLAG(BOTH)),
GST_QUERY_FORMATS = GST_QUERY_MAKE_TYPE (90, FLAG(BOTH)),
GST_QUERY_BUFFERING = GST_QUERY_MAKE_TYPE (110, FLAG(BOTH)),
GST_QUERY_CUSTOM = GST_QUERY_MAKE_TYPE (120, FLAG(BOTH)),
GST_QUERY_URI = GST_QUERY_MAKE_TYPE (130, FLAG(BOTH)),
GST_QUERY_ALLOCATION = GST_QUERY_MAKE_TYPE (140, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
GST_QUERY_SCHEDULING = GST_QUERY_MAKE_TYPE (150, FLAG(UPSTREAM)),
GST_QUERY_ACCEPT_CAPS = GST_QUERY_MAKE_TYPE (160, FLAG(BOTH)),
GST_QUERY_CAPS = GST_QUERY_MAKE_TYPE (170, FLAG(BOTH))
} GstQueryType;
typedef struct _GstQueryTypeDefinition GstQueryTypeDefinition;
typedef struct _GstQuery GstQuery;
/**
* GstQueryTypeDefinition:
* @value: the unique id of the Query type
* @nick: a short nick
* @description: a longer description of the query type
* @quark: the quark for the nick
*
* A Query Type definition
*/
struct _GstQueryTypeDefinition
{
GstQueryType value;
const gchar *nick;
const gchar *description;
GQuark quark;
};
#undef FLAG
#define GST_TYPE_QUERY (gst_query_get_type())
#define GST_IS_QUERY(obj) (GST_IS_MINI_OBJECT_TYPE (obj, GST_TYPE_QUERY))
#define GST_QUERY_CAST(obj) ((GstQuery*)(obj))
#define GST_QUERY(obj) (GST_QUERY_CAST(obj))
/**
* GST_QUERY_TYPE:
* @query: the query to query
@ -126,6 +150,28 @@ struct _GstQueryTypeDefinition
*/
#define GST_QUERY_TYPE_NAME(query) (gst_query_type_get_name(GST_QUERY_TYPE(query)))
/**
* GST_QUERY_IS_UPSTREAM:
* @ev: the query to query
*
* Check if an query can travel upstream.
*/
#define GST_QUERY_IS_UPSTREAM(ev) !!(GST_QUERY_TYPE (ev) & GST_QUERY_TYPE_UPSTREAM)
/**
* GST_QUERY_IS_DOWNSTREAM:
* @ev: the query to query
*
* Check if an query can travel downstream.
*/
#define GST_QUERY_IS_DOWNSTREAM(ev) !!(GST_QUERY_TYPE (ev) & GST_QUERY_TYPE_DOWNSTREAM)
/**
* GST_QUERY_IS_SERIALIZED:
* @ev: the query to query
*
* Check if an query is serialized with the data stream.
*/
#define GST_QUERY_IS_SERIALIZED(ev) !!(GST_QUERY_TYPE (ev) & GST_QUERY_TYPE_SERIALIZED)
/**
* GstQuery:
@ -142,26 +188,14 @@ struct _GstQuery
GstQueryType type;
};
const gchar* gst_query_type_get_name (GstQueryType query);
GQuark gst_query_type_to_quark (GstQueryType query);
const gchar* gst_query_type_get_name (GstQueryType type);
GQuark gst_query_type_to_quark (GstQueryType type);
GstQueryTypeFlags
gst_query_type_get_flags (GstQueryType type);
GType gst_query_get_type (void);
/* register a new query */
GstQueryType gst_query_type_register (const gchar *nick,
const gchar *description);
GstQueryType gst_query_type_get_by_nick (const gchar *nick);
/* check if a query is in an array of querys */
gboolean gst_query_types_contains (const GstQueryType *types,
GstQueryType type);
/* query for query details */
const GstQueryTypeDefinition*
gst_query_type_get_details (GstQueryType type);
GstIterator* gst_query_type_iterate_definitions (void) G_GNUC_MALLOC;
/* refcounting */
/**
* gst_query_ref:

View file

@ -206,7 +206,6 @@ EXPORTS
gst_caps_subtract
gst_caps_to_string
gst_caps_truncate
gst_caps_union
gst_child_proxy_child_added
gst_child_proxy_child_removed
gst_child_proxy_get
@ -874,14 +873,11 @@ EXPORTS
gst_query_set_seeking
gst_query_set_segment
gst_query_set_uri
gst_query_type_get_by_nick
gst_query_type_get_details
gst_query_type_flags_get_type
gst_query_type_get_flags
gst_query_type_get_name
gst_query_type_get_type
gst_query_type_iterate_definitions
gst_query_type_register
gst_query_type_to_quark
gst_query_types_contains
gst_query_writable_structure
gst_rank_get_type
gst_registry_add_feature