+2005-05-06 Andy Wingo <wingo@pobox.com>
+
+ * gst/gstquery.h
+ * gst/gstquery.c (_gst_query_initialize): Extend GstQuery from
+ GstData, init a memchunk.
+ (standard_definitions): Add a few query types, deprecate a few.
+ (gst_query_get_type): New proc.
+ (_gst_query_copy, _gst_query_free, gst_query_new): GstData
+ implementation.
+ (gst_query_new_application, gst_query_get_structure): New public
+ procs.
+
+ * docs/design/draft-query.txt: Removed LINKS from the query types,
+ because all the rest can be dispatched to other pads -- seemed
+ ugly to have a query that couldn't be dispatched. internal_links
+ is fine as a pad method.
+
+ * gst/gstpad.h: Add query2 as a pad method, add the new functions
+ in gstpad.c, but maintain binary compatibility for the moment.
+ Will fix before 0.9 is out.
+
+ * gst/gstqueryutils.c:
+ * gst/gstqueryutils.h: New files, implement 3 methods for each
+ query type: parse_query, parse_response, and set. Probably need an
+ allocator as well.
+
+ * gst/gst.h: Add gstquery.h and gstqueryutils.h to the list.
+
+ * gst/elements/gstfilesink.c (gst_filesink_query2):
+ * gst/base/gstbasesrc.c (gst_basesrc_query2): Replace old query,
+ query_types, and formats methods.
+
+ * gst/gstpad.c (gst_pad_query2, gst_pad_query2_default)
+ (gst_pad_set_query2_function): New functions.
+ (gst_real_pad_init): Set query2_default as the default query2
+ function. Basically just dispatches to internally linked pads.
+
+ Needs review!
+
+ * gst/gstdata_private.h (_GST_DATA_INIT): Set data->refcount to 1
+ without using the atomic operations. Only one thread can possibly
+ be accessing the data at this point. Changed so as to avoid
+ gst_atomic operations.
+
2005-05-06 Wim Taymans <wim@fluendo.com>
* gst/gstpad.c: (gst_pad_alloc_buffer), (gst_pad_push):
- return list of supported formats.
- - GST_QUERY_LINKS:
-
- - return list of internal link pads.
-
Also????
- GST_QUERY_CAPS:
@GST_QUERY_START: start of configured segment
@GST_QUERY_SEGMENT_END: end of configured segment
@GST_QUERY_RATE: current rate of the stream
+@GST_QUERY_SEEKING:
+@GST_QUERY_CONVERT:
+@GST_QUERY_FORMATS:
<!-- ##### MACRO GST_QUERY_TYPE_RATE_DEN ##### -->
<para>
static void gst_basesrc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_basesrc_event_handler (GstPad * pad, GstEvent * event);
+
+static gboolean gst_basesrc_query2 (GstPad * pad, GstQuery * query);
+
static const GstEventMask *gst_basesrc_get_event_mask (GstPad * pad);
-static const GstQueryType *gst_basesrc_get_query_types (GstPad * pad);
-static gboolean gst_basesrc_query (GstPad * pad, GstQueryType type,
- GstFormat * format, gint64 * value);
-static const GstFormat *gst_basesrc_get_formats (GstPad * pad);
static gboolean gst_basesrc_unlock (GstBaseSrc * basesrc);
static gboolean gst_basesrc_get_size (GstBaseSrc * basesrc, guint64 * size);
gst_pad_set_activate_function (pad, gst_basesrc_activate);
gst_pad_set_event_function (pad, gst_basesrc_event_handler);
gst_pad_set_event_mask_function (pad, gst_basesrc_get_event_mask);
- gst_pad_set_query_function (pad, gst_basesrc_query);
- gst_pad_set_query_type_function (pad, gst_basesrc_get_query_types);
- gst_pad_set_formats_function (pad, gst_basesrc_get_formats);
+
+ gst_pad_set_query2_function (pad, gst_basesrc_query2);
+
gst_pad_set_checkgetrange_function (pad, gst_basesrc_check_get_range);
+
/* hold ref to pad */
basesrc->srcpad = pad;
gst_element_add_pad (GST_ELEMENT (basesrc), pad);
gst_pad_set_getrange_function (this->srcpad, NULL);
}
-static const GstFormat *
-gst_basesrc_get_formats (GstPad * pad)
-{
- static const GstFormat formats[] = {
- GST_FORMAT_DEFAULT,
- GST_FORMAT_BYTES,
- 0,
- };
-
- return formats;
-}
-
-static const GstQueryType *
-gst_basesrc_get_query_types (GstPad * pad)
-{
- static const GstQueryType types[] = {
- GST_QUERY_TOTAL,
- GST_QUERY_POSITION,
- GST_QUERY_START,
- GST_QUERY_SEGMENT_END,
- 0,
- };
-
- return types;
-}
-
static gboolean
-gst_basesrc_query (GstPad * pad, GstQueryType type,
- GstFormat * format, gint64 * value)
+gst_basesrc_query2 (GstPad * pad, GstQuery * query)
{
- GstBaseSrc *src = GST_BASESRC (GST_PAD_PARENT (pad));
-
- if (*format == GST_FORMAT_DEFAULT)
- *format = GST_FORMAT_BYTES;
+ gboolean b;
+ guint64 ui64;
+ gint64 i64;
+ GstBaseSrc *src;
- switch (type) {
- case GST_QUERY_TOTAL:
- switch (*format) {
- case GST_FORMAT_BYTES:
- {
- gboolean ret;
+ src = GST_BASESRC (GST_PAD_PARENT (pad));
- ret = gst_basesrc_get_size (src, (guint64 *) value);
- GST_DEBUG ("getting length %d %lld", ret, *value);
- return ret;
- }
- case GST_FORMAT_PERCENT:
- *value = GST_FORMAT_PERCENT_MAX;
- return TRUE;
- default:
- return FALSE;
- }
- break;
+ switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_POSITION:
- switch (*format) {
+ {
+ GstFormat format;
+
+ gst_query_parse_position_query (query, &format);
+ switch (format) {
+ case GST_FORMAT_DEFAULT:
case GST_FORMAT_BYTES:
- *value = src->offset;
- break;
+ b = gst_basesrc_get_size (src, &ui64);
+ /* better to make get_size take an int64 */
+ i64 = b ? (gint64) ui64 : -1;
+ gst_query_set_position (query, GST_FORMAT_BYTES, src->offset, i64);
+ return TRUE;
case GST_FORMAT_PERCENT:
- /* fixme */
- if (!gst_basesrc_get_size (src, (guint64 *) value))
- return FALSE;
- *value = src->offset * GST_FORMAT_PERCENT_MAX / *value;
+ b = gst_basesrc_get_size (src, &ui64);
+ i64 = GST_FORMAT_PERCENT_MAX;
+ i64 *= b ? (src->offset / (gdouble) ui64) : 1.0;
+ gst_query_set_position (query, GST_FORMAT_PERCENT,
+ i64, GST_FORMAT_PERCENT_MAX);
return TRUE;
default:
return FALSE;
}
- break;
- case GST_QUERY_START:
- *value = src->segment_start;
+ }
+
+ case GST_QUERY_SEEKING:
+ gst_query_set_seeking (query, GST_FORMAT_BYTES,
+ src->seekable, src->segment_start, src->segment_end);
return TRUE;
- case GST_QUERY_SEGMENT_END:
- *value = src->segment_end;
+
+ case GST_QUERY_FORMATS:
+ gst_query_set_formats (query, 3, GST_FORMAT_DEFAULT,
+ GST_FORMAT_BYTES, GST_FORMAT_PERCENT);
return TRUE;
+
+ case GST_QUERY_LATENCY:
+ case GST_QUERY_JITTER:
+ case GST_QUERY_RATE:
+ case GST_QUERY_CONVERT:
default:
- return FALSE;
+ return gst_pad_query2_default (pad, query);
}
- return FALSE;
}
static const GstEventMask *
ARG_LOCATION
};
-static const GstFormat *
-gst_filesink_get_formats (GstPad * pad)
-{
- static const GstFormat formats[] = {
- GST_FORMAT_BYTES,
- 0,
- };
-
- return formats;
-}
-
-static const GstQueryType *
-gst_filesink_get_query_types (GstPad * pad)
-{
- static const GstQueryType types[] = {
- GST_QUERY_TOTAL,
- GST_QUERY_POSITION,
- 0
- };
-
- return types;
-}
-
static void gst_filesink_dispose (GObject * object);
static void gst_filesink_set_property (GObject * object, guint prop_id,
static GstFlowReturn gst_filesink_render (GstBaseSink * sink,
GstBuffer * buffer);
-static gboolean gst_filesink_pad_query (GstPad * pad, GstQueryType type,
- GstFormat * format, gint64 * value);
+static gboolean gst_filesink_query2 (GstPad * pad, GstQuery * query);
static void gst_filesink_uri_handler_init (gpointer g_iface,
gpointer iface_data);
gst_static_pad_template_get (&sinktemplate));
gst_element_class_set_details (gstelement_class, &gst_filesink_details);
}
+
static void
gst_filesink_class_init (GstFileSinkClass * klass)
{
gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_filesink_render);
gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_filesink_event);
}
+
static void
gst_filesink_init (GstFileSink * filesink)
{
pad = GST_BASESINK_PAD (filesink);
- gst_pad_set_query_function (pad, gst_filesink_pad_query);
- gst_pad_set_query_type_function (pad, gst_filesink_get_query_types);
- gst_pad_set_formats_function (pad, gst_filesink_get_formats);
+ gst_pad_set_query2_function (pad, gst_filesink_query2);
filesink->filename = NULL;
filesink->file = NULL;
}
+
static void
gst_filesink_dispose (GObject * object)
{
}
static gboolean
-gst_filesink_pad_query (GstPad * pad, GstQueryType type,
- GstFormat * format, gint64 * value)
+gst_filesink_query2 (GstPad * pad, GstQuery * query)
{
- GstFileSink *sink = GST_FILESINK (GST_PAD_PARENT (pad));
+ GstFileSink *self;
+ GstFormat format;
- switch (type) {
- case GST_QUERY_TOTAL:
- switch (*format) {
- case GST_FORMAT_BYTES:
- *value = sink->data_written; /* FIXME - doesn't the kernel provide
- such a function? */
- break;
- default:
- return FALSE;
- }
- break;
+ self = GST_FILESINK (GST_PAD_PARENT (pad));
+
+ switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_POSITION:
- switch (*format) {
+ gst_query_parse_position_query (query, &format);
+ switch (format) {
+ case GST_FORMAT_DEFAULT:
case GST_FORMAT_BYTES:
- *value = ftell (sink->file);
- break;
+ gst_query_set_position (query, GST_FORMAT_BYTES,
+ self->data_written, self->data_written);
+ return TRUE;
default:
return FALSE;
}
- break;
+
+ case GST_QUERY_FORMATS:
+ gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES);
+ return TRUE;
+
default:
- return FALSE;
+ return gst_pad_query2_default (pad, query);
}
-
- return TRUE;
}
/* handle events (search) */
g_log_set_handler (g_log_domain_gstreamer, llf, debug_log_handler, NULL);
_gst_format_initialize ();
- _gst_query_type_initialize ();
+ _gst_query_initialize ();
gst_object_get_type ();
gst_probe_get_type ();
gst_pad_get_type ();
#include <gst/gstpad.h>
#include <gst/gstpipeline.h>
#include <gst/gstplugin.h>
+#include <gst/gstquery.h>
+#include <gst/gstqueryutils.h>
#include <gst/gstscheduler.h>
#include <gst/gststructure.h>
#include <gst/gstsystemclock.h>
#define _GST_DATA_INIT(data, ptype, pflags, pfree, pcopy) \
G_STMT_START { \
- gst_atomic_int_set (&(data)->refcount, 1); \
+ (data)->refcount = 1; \
(data)->type = ptype; \
(data)->flags = pflags; \
(data)->free = pfree; \
pad->queryfunc = gst_pad_query_default;
pad->intlinkfunc = gst_pad_get_internal_links_default;
+ pad->query2func = gst_pad_query2_default;
+
pad->eventmaskfunc = gst_pad_get_event_masks_default;
pad->formatsfunc = gst_pad_get_formats_default;
pad->querytypefunc = gst_pad_get_query_types_default;
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (query));
}
+/**
+ * gst_pad_set_query2_function:
+ * @pad: a real #GstPad of either direction.
+ * @query: the #GstPadQueryFunction to set.
+ *
+ * Set the given query function for the pad.
+ */
+void
+gst_pad_set_query2_function (GstPad * pad, GstPadQuery2Function query)
+{
+ g_return_if_fail (GST_IS_REAL_PAD (pad));
+
+ GST_RPAD_QUERY2FUNC (pad) = query;
+
+ GST_CAT_DEBUG (GST_CAT_PADS, "query2func for %s:%s set to %s",
+ GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (query));
+}
+
/**
* gst_pad_set_query_type_function:
* @pad: a real #GstPad of either direction.
return FALSE;
}
+/**
+ * gst_pad_query2:
+ * @pad: a #GstPad to invoke the default query on.
+ * @query: the #GstQuery to perform.
+ *
+ * Dispatches a query to a pad. The query should have been allocated by the
+ * caller via one of the type-specific allocation functions in gstquery.h. The
+ * element is responsible for filling the query with an appropriate response,
+ * which should then be parsed with a type-specific query parsing function.
+ *
+ * Again, the caller is responsible for both the allocation and deallocation of
+ * the query structure.
+ *
+ * Returns: TRUE if the query could be performed.
+ */
+gboolean
+gst_pad_query2 (GstPad * pad, GstQuery * query)
+{
+ GstRealPad *rpad;
+
+ g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
+ g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
+
+ rpad = GST_PAD_REALIZE (pad);
+
+ g_return_val_if_fail (rpad, FALSE);
+
+ if (GST_RPAD_QUERY2FUNC (rpad))
+ return GST_RPAD_QUERY2FUNC (rpad) (GST_PAD_CAST (rpad), query);
+
+ return FALSE;
+}
+
+gboolean
+gst_pad_query2_default (GstPad * pad, GstQuery * query)
+{
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_POSITION:
+ case GST_QUERY_SEEKING:
+ case GST_QUERY_FORMATS:
+ case GST_QUERY_LATENCY:
+ case GST_QUERY_JITTER:
+ case GST_QUERY_RATE:
+ case GST_QUERY_CONVERT:
+ default:
+ return gst_pad_dispatcher
+ (pad, (GstPadDispatcherFunction) gst_pad_query2, query);
+ }
+}
+
static gboolean
gst_pad_get_formats_dispatcher (GstPad * pad, const GstFormat ** data)
{
typedef gboolean (*GstPadCheckGetRangeFunction) (GstPad *pad);
typedef gboolean (*GstPadEventFunction) (GstPad *pad, GstEvent *event);
-/* convert/query/format functions */
+/* old, deprecated convert/query/format functions */
typedef gboolean (*GstPadConvertFunction) (GstPad *pad,
GstFormat src_format, gint64 src_value,
GstFormat *dest_format, gint64 *dest_value);
typedef const GstEventMask* (*GstPadEventMaskFunction) (GstPad *pad);
typedef const GstQueryType* (*GstPadQueryTypeFunction) (GstPad *pad);
+/* generic query function */
+typedef gboolean (*GstPadQuery2Function) (GstPad *pad, GstQuery *query);
+
/* linking */
typedef GstPadLinkReturn (*GstPadLinkFunction) (GstPad *pad, GstPad *peer);
typedef void (*GstPadUnlinkFunction) (GstPad *pad);
GList *ghostpads;
guint32 ghostpads_cookie;
- /* query/convert/formats functions */
+ /* old, deprecated query/convert/formats functions */
GstPadConvertFunction convertfunc;
GstPadQueryFunction queryfunc;
GstPadFormatsFunction formatsfunc;
GstProbeDispatcher probedisp;
+ /* generic query method */
+ GstPadQuery2Function query2func;
+
/*< private >*/
- gpointer _gst_reserved[GST_PADDING];
+ /* fixme: bring back to gst_padding when old query functions go away */
+ gpointer _gst_reserved[GST_PADDING - 1];
};
struct _GstRealPadClass {
#define GST_RPAD_FORMATSFUNC(pad) (GST_REAL_PAD_CAST(pad)->formatsfunc)
#define GST_RPAD_QUERYTYPEFUNC(pad) (GST_REAL_PAD_CAST(pad)->querytypefunc)
#define GST_RPAD_EVENTMASKFUNC(pad) (GST_REAL_PAD_CAST(pad)->eventmaskfunc)
+#define GST_RPAD_QUERY2FUNC(pad) (GST_REAL_PAD_CAST(pad)->query2func)
#define GST_RPAD_PEER(pad) (GST_REAL_PAD_CAST(pad)->peer)
#define GST_RPAD_LINKFUNC(pad) (GST_REAL_PAD_CAST(pad)->linkfunc)
GList* gst_pad_get_internal_links (GstPad *pad);
GList* gst_pad_get_internal_links_default (GstPad *pad);
+gboolean gst_pad_query2 (GstPad *pad, GstQuery *query);
+void gst_pad_set_query2_function (GstPad *pad, GstPadQuery2Function query);
+gboolean gst_pad_query2_default (GstPad *pad, GstQuery *query);
+
/* misc helper functions */
gboolean gst_pad_dispatcher (GstPad *pad, GstPadDispatcherFunction dispatch,
gpointer data);
#include "gst_private.h"
#include "gstquery.h"
+#include "gstmemchunk.h"
+#include "gstdata_private.h"
+
+
+GType _gst_query_type;
+
static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
static GList *_gst_queries = NULL;
static GHashTable *_query_type_to_nick = NULL;
static guint32 _n_values = 1; /* we start from 1 because 0 reserved for NONE */
+static GstMemChunk *chunk;
+
static GstQueryTypeDefinition standard_definitions[] = {
- {GST_QUERY_TOTAL, "total", "Total length"},
+ {GST_QUERY_TOTAL, "total", "Total length"}, /* deprecated */
{GST_QUERY_POSITION, "position", "Current Position"},
{GST_QUERY_LATENCY, "latency", "Latency"},
{GST_QUERY_JITTER, "jitter", "Jitter"},
- {GST_QUERY_START, "start", "Start position of stream"},
- {GST_QUERY_SEGMENT_END, "segment_end", "End position of the stream"},
+ {GST_QUERY_START, "start", "Start position of stream"}, /* deprecated */
+ {GST_QUERY_SEGMENT_END, "segment_end", "End position of the stream"}, /* dep */
{GST_QUERY_RATE, "rate", "Configured rate 1000000 = 1"},
+ {GST_QUERY_SEEKING, "seeking", "Seeking capabilities and parameters"},
+ {GST_QUERY_CONVERT, "convert", "Converting between formats"},
{0, NULL, NULL}
};
+
void
-_gst_query_type_initialize (void)
+_gst_query_initialize (void)
{
GstQueryTypeDefinition *standards = standard_definitions;
+ GST_CAT_INFO (GST_CAT_GST_INIT, "init queries");
+
g_static_mutex_lock (&mutex);
if (_nick_to_query == NULL) {
_nick_to_query = g_hash_table_new (g_str_hash, g_str_equal);
_n_values++;
}
g_static_mutex_unlock (&mutex);
+
+ /* register the type */
+ _gst_query_type = g_boxed_type_register_static ("GstQuery",
+ (GBoxedCopyFunc) gst_data_copy, (GBoxedFreeFunc) gst_data_unref);
+
+ chunk = gst_mem_chunk_new ("GstQueryChunk", sizeof (GstQuery),
+ sizeof (GstQuery) * 20, 0);
}
/**
return result;
}
+
+GType
+gst_query_get_type (void)
+{
+ return _gst_query_type;
+}
+
+static GstQuery *
+_gst_query_copy (GstQuery * query)
+{
+ GstQuery *copy;
+
+ GST_LOG ("copy query %p", query);
+
+ copy = gst_mem_chunk_alloc (chunk);
+
+ memcpy (copy, query, sizeof (GstQuery));
+
+ if (query->structure) {
+ copy->structure = gst_structure_copy (query->structure);
+ gst_structure_set_parent_refcount (copy->structure,
+ &GST_DATA_REFCOUNT (query));
+ }
+
+ return copy;
+}
+
+static void
+_gst_query_free (GstQuery * query)
+{
+ GST_LOG ("freeing query %p", query);
+
+ if (query->structure) {
+ gst_structure_set_parent_refcount (query->structure, NULL);
+ gst_structure_free (query->structure);
+ }
+
+ _GST_DATA_DISPOSE (GST_DATA (query));
+ gst_mem_chunk_free (chunk, query);
+}
+
+static GstQuery *
+gst_query_new (GstQueryType type, GstStructure * structure)
+{
+ GstQuery *query;
+
+ query = gst_mem_chunk_alloc0 (chunk);
+
+ GST_DEBUG ("creating new query %p %d", query, type);
+
+ _GST_DATA_INIT (GST_DATA (query),
+ _gst_query_type,
+ 0,
+ (GstDataFreeFunction) _gst_query_free,
+ (GstDataCopyFunction) _gst_query_copy);
+
+ GST_QUERY_TYPE (query) = type;
+
+ if (structure) {
+ query->structure = structure;
+ gst_structure_set_parent_refcount (query->structure,
+ &GST_DATA_REFCOUNT (query));
+ }
+
+ return query;
+}
+
+GstQuery *
+gst_query_new_application (GstQueryType type, GstStructure * structure)
+{
+ g_return_val_if_fail (gst_query_type_get_details (type) != NULL, NULL);
+ g_return_val_if_fail (structure != NULL, NULL);
+
+ return gst_query_new (type, structure);
+}
+
+GstStructure *
+gst_query_get_structure (GstQuery * query)
+{
+ g_return_val_if_fail (GST_IS_QUERY (query), NULL);
+
+ return query->structure;
+}
#include <glib.h>
#include <gst/gstiterator.h>
+#include <gst/gstdata.h>
+#include <gst/gststructure.h>
G_BEGIN_DECLS
typedef enum {
GST_QUERY_NONE = 0,
- GST_QUERY_TOTAL,
+ GST_QUERY_TOTAL, /* deprecated, use POSITION */
GST_QUERY_POSITION,
GST_QUERY_LATENCY,
- GST_QUERY_JITTER,
- GST_QUERY_START,
- GST_QUERY_SEGMENT_END,
- GST_QUERY_RATE
+ GST_QUERY_JITTER, /* not in draft-query, necessary? */
+ GST_QUERY_START, /* deprecated, use SEEKING */
+ GST_QUERY_SEGMENT_END, /* deprecated, use SEEKING */
+ GST_QUERY_RATE, /* not in draft-query, necessary? */
+ GST_QUERY_SEEKING,
+ GST_QUERY_CONVERT,
+ GST_QUERY_FORMATS
} GstQueryType;
/* rate is relative to 1000000 */
#define GST_QUERY_TYPE_RATE_DEN G_GINT64_CONSTANT (1000000)
typedef struct _GstQueryTypeDefinition GstQueryTypeDefinition;
+typedef struct _GstQuery GstQuery;
struct _GstQueryTypeDefinition
{
}
#endif
-void _gst_query_type_initialize (void);
+GST_EXPORT GType _gst_query_type;
+
+#define GST_TYPE_QUERY (_gst_query_type)
+#define GST_QUERY(query) ((GstQuery*)(query))
+#define GST_IS_QUERY(query) (GST_DATA_TYPE(query) == GST_TYPE_QUERY)
+#define GST_QUERY_TYPE(query) (((GstQuery*)(query))->type)
+
+struct _GstQuery
+{
+ GstData data;
+
+ /*< public > */
+ GstQueryType type;
+
+ GstStructure *structure;
+
+ /*< private > */
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+void _gst_query_initialize (void);
+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);
+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);
+gboolean gst_query_types_contains (const GstQueryType *types,
+ GstQueryType type);
/* query for query details */
G_CONST_RETURN GstQueryTypeDefinition*
- gst_query_type_get_details (GstQueryType type);
-GstIterator* gst_query_type_iterate_definitions (void);
+ gst_query_type_get_details (GstQueryType type);
+GstIterator* gst_query_type_iterate_definitions (void);
+
+/* refcounting */
+#define gst_query_ref(msg) GST_QUERY (gst_data_ref (GST_DATA (msg)))
+#define gst_query_ref_by_count(msg,c) GST_QUERY (gst_data_ref_by_count (GST_DATA (msg), (c)))
+#define gst_query_unref(msg) gst_data_unref (GST_DATA (msg))
+/* copy query */
+#define gst_query_copy(msg) GST_QUERY (gst_data_copy (GST_DATA (msg)))
+#define gst_query_copy_on_write(msg) GST_QUERY (gst_data_copy_on_write (GST_DATA (msg)))
+
+GstQuery * gst_query_new_application (GstQueryType type,
+ GstStructure *structure);
+
+GstStructure * gst_query_get_structure (GstQuery *query);
+
+/* hmm */
+#define GST_QUERY_POSITION_GET_FORMAT(q) \
+ (gst_structure_get_int ((q)->structure, "format"))
G_END_DECLS
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
+ *
+ * gstqueryutils.c: Utility functions for creating and parsing GstQueries.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#include <stdarg.h>
+
+#include "gstqueryutils.h"
+
+/* some macros are just waiting to be defined here */
+
+
+void
+gst_query_set_position (GstQuery * query, GstFormat format, gint64 cur,
+ gint64 end)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
+
+ structure = gst_query_get_structure (query);
+ gst_structure_set (structure,
+ "format", GST_TYPE_FORMAT, format,
+ "cur", G_TYPE_INT64, cur, "end", G_TYPE_INT64, end, NULL);
+}
+
+void
+gst_query_parse_position_query (GstQuery * query, GstFormat * format)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
+
+ structure = gst_query_get_structure (query);
+ *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
+}
+
+void
+gst_query_parse_position_response (GstQuery * query, GstFormat * format,
+ gint64 * cur, gint64 * end)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
+
+ structure = gst_query_get_structure (query);
+ *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
+ *cur = g_value_get_int64 (gst_structure_get_value (structure, "cur"));
+ *end = g_value_get_int64 (gst_structure_get_value (structure, "end"));
+}
+
+void
+gst_query_parse_seeking_query (GstQuery * query, GstFormat * format)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
+
+ structure = gst_query_get_structure (query);
+ *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
+}
+
+void
+gst_query_set_seeking (GstQuery * query, GstFormat format,
+ gboolean seekable, gint64 segment_start, gint64 segment_end)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
+
+ structure = gst_query_get_structure (query);
+ gst_structure_set (structure,
+ "format", GST_TYPE_FORMAT, format,
+ "seekable", G_TYPE_BOOLEAN, seekable,
+ "segment-start", G_TYPE_INT64, segment_start,
+ "segment-end", G_TYPE_INT64, segment_end, NULL);
+}
+
+void
+gst_query_parse_seeking_response (GstQuery * query, GstFormat * format,
+ gboolean * seekable, gint64 * segment_start, gint64 * segment_end)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
+
+ structure = gst_query_get_structure (query);
+ *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
+ *seekable = g_value_get_boolean (gst_structure_get_value
+ (structure, "seekable"));
+ *segment_start = g_value_get_int64 (gst_structure_get_value
+ (structure, "segment-start"));
+ *segment_end = g_value_get_int64 (gst_structure_get_value
+ (structure, "segment-end"));
+}
+
+void
+gst_query_set_formats (GstQuery * query, gint n_formats, ...)
+{
+ va_list ap;
+ GValue list = { 0, };
+ GValue item = { 0, };
+ GstStructure *structure;
+ gint i;
+
+ g_value_init (&list, GST_TYPE_LIST);
+
+ va_start (ap, n_formats);
+
+ for (i = 0; i < n_formats; i++) {
+ g_value_init (&item, GST_TYPE_FORMAT);
+ g_value_set_enum (&item, va_arg (ap, GstFormat));
+ gst_value_list_append_value (&list, &item);
+ g_value_unset (&item);
+ }
+
+ va_end (ap);
+
+ structure = gst_query_get_structure (query);
+ gst_structure_set_value (structure, "formats", &list);
+}
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
+ *
+ * gstqueryutils.c: Utility functions for creating and parsing GstQueries.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#include <gst/gstquery.h>
+
+
+void gst_query_set_position (GstQuery *query, GstFormat format,
+ gint64 cur, gint64 end);
+void gst_query_parse_position_query (GstQuery *query, GstFormat *format);
+void gst_query_parse_position_response (GstQuery *query, GstFormat *format,
+ gint64 *cur, gint64 *end);
+void gst_query_parse_seeking_query (GstQuery *query, GstFormat *format);
+void gst_query_set_seeking (GstQuery *query, GstFormat format,
+ gboolean seekable, gint64 segment_start,
+ gint64 segment_end);
+void gst_query_parse_seeking_response (GstQuery *query, GstFormat *format,
+ gboolean *seekable,
+ gint64 *segment_start,
+ gint64 *segment_end);
+void gst_query_set_formats (GstQuery *query, gint n_formats, ...);
static void gst_basesrc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_basesrc_event_handler (GstPad * pad, GstEvent * event);
+
+static gboolean gst_basesrc_query2 (GstPad * pad, GstQuery * query);
+
static const GstEventMask *gst_basesrc_get_event_mask (GstPad * pad);
-static const GstQueryType *gst_basesrc_get_query_types (GstPad * pad);
-static gboolean gst_basesrc_query (GstPad * pad, GstQueryType type,
- GstFormat * format, gint64 * value);
-static const GstFormat *gst_basesrc_get_formats (GstPad * pad);
static gboolean gst_basesrc_unlock (GstBaseSrc * basesrc);
static gboolean gst_basesrc_get_size (GstBaseSrc * basesrc, guint64 * size);
gst_pad_set_activate_function (pad, gst_basesrc_activate);
gst_pad_set_event_function (pad, gst_basesrc_event_handler);
gst_pad_set_event_mask_function (pad, gst_basesrc_get_event_mask);
- gst_pad_set_query_function (pad, gst_basesrc_query);
- gst_pad_set_query_type_function (pad, gst_basesrc_get_query_types);
- gst_pad_set_formats_function (pad, gst_basesrc_get_formats);
+
+ gst_pad_set_query2_function (pad, gst_basesrc_query2);
+
gst_pad_set_checkgetrange_function (pad, gst_basesrc_check_get_range);
+
/* hold ref to pad */
basesrc->srcpad = pad;
gst_element_add_pad (GST_ELEMENT (basesrc), pad);
gst_pad_set_getrange_function (this->srcpad, NULL);
}
-static const GstFormat *
-gst_basesrc_get_formats (GstPad * pad)
-{
- static const GstFormat formats[] = {
- GST_FORMAT_DEFAULT,
- GST_FORMAT_BYTES,
- 0,
- };
-
- return formats;
-}
-
-static const GstQueryType *
-gst_basesrc_get_query_types (GstPad * pad)
-{
- static const GstQueryType types[] = {
- GST_QUERY_TOTAL,
- GST_QUERY_POSITION,
- GST_QUERY_START,
- GST_QUERY_SEGMENT_END,
- 0,
- };
-
- return types;
-}
-
static gboolean
-gst_basesrc_query (GstPad * pad, GstQueryType type,
- GstFormat * format, gint64 * value)
+gst_basesrc_query2 (GstPad * pad, GstQuery * query)
{
- GstBaseSrc *src = GST_BASESRC (GST_PAD_PARENT (pad));
-
- if (*format == GST_FORMAT_DEFAULT)
- *format = GST_FORMAT_BYTES;
+ gboolean b;
+ guint64 ui64;
+ gint64 i64;
+ GstBaseSrc *src;
- switch (type) {
- case GST_QUERY_TOTAL:
- switch (*format) {
- case GST_FORMAT_BYTES:
- {
- gboolean ret;
+ src = GST_BASESRC (GST_PAD_PARENT (pad));
- ret = gst_basesrc_get_size (src, (guint64 *) value);
- GST_DEBUG ("getting length %d %lld", ret, *value);
- return ret;
- }
- case GST_FORMAT_PERCENT:
- *value = GST_FORMAT_PERCENT_MAX;
- return TRUE;
- default:
- return FALSE;
- }
- break;
+ switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_POSITION:
- switch (*format) {
+ {
+ GstFormat format;
+
+ gst_query_parse_position_query (query, &format);
+ switch (format) {
+ case GST_FORMAT_DEFAULT:
case GST_FORMAT_BYTES:
- *value = src->offset;
- break;
+ b = gst_basesrc_get_size (src, &ui64);
+ /* better to make get_size take an int64 */
+ i64 = b ? (gint64) ui64 : -1;
+ gst_query_set_position (query, GST_FORMAT_BYTES, src->offset, i64);
+ return TRUE;
case GST_FORMAT_PERCENT:
- /* fixme */
- if (!gst_basesrc_get_size (src, (guint64 *) value))
- return FALSE;
- *value = src->offset * GST_FORMAT_PERCENT_MAX / *value;
+ b = gst_basesrc_get_size (src, &ui64);
+ i64 = GST_FORMAT_PERCENT_MAX;
+ i64 *= b ? (src->offset / (gdouble) ui64) : 1.0;
+ gst_query_set_position (query, GST_FORMAT_PERCENT,
+ i64, GST_FORMAT_PERCENT_MAX);
return TRUE;
default:
return FALSE;
}
- break;
- case GST_QUERY_START:
- *value = src->segment_start;
+ }
+
+ case GST_QUERY_SEEKING:
+ gst_query_set_seeking (query, GST_FORMAT_BYTES,
+ src->seekable, src->segment_start, src->segment_end);
return TRUE;
- case GST_QUERY_SEGMENT_END:
- *value = src->segment_end;
+
+ case GST_QUERY_FORMATS:
+ gst_query_set_formats (query, 3, GST_FORMAT_DEFAULT,
+ GST_FORMAT_BYTES, GST_FORMAT_PERCENT);
return TRUE;
+
+ case GST_QUERY_LATENCY:
+ case GST_QUERY_JITTER:
+ case GST_QUERY_RATE:
+ case GST_QUERY_CONVERT:
default:
- return FALSE;
+ return gst_pad_query2_default (pad, query);
}
- return FALSE;
}
static const GstEventMask *
ARG_LOCATION
};
-static const GstFormat *
-gst_filesink_get_formats (GstPad * pad)
-{
- static const GstFormat formats[] = {
- GST_FORMAT_BYTES,
- 0,
- };
-
- return formats;
-}
-
-static const GstQueryType *
-gst_filesink_get_query_types (GstPad * pad)
-{
- static const GstQueryType types[] = {
- GST_QUERY_TOTAL,
- GST_QUERY_POSITION,
- 0
- };
-
- return types;
-}
-
static void gst_filesink_dispose (GObject * object);
static void gst_filesink_set_property (GObject * object, guint prop_id,
static GstFlowReturn gst_filesink_render (GstBaseSink * sink,
GstBuffer * buffer);
-static gboolean gst_filesink_pad_query (GstPad * pad, GstQueryType type,
- GstFormat * format, gint64 * value);
+static gboolean gst_filesink_query2 (GstPad * pad, GstQuery * query);
static void gst_filesink_uri_handler_init (gpointer g_iface,
gpointer iface_data);
gst_static_pad_template_get (&sinktemplate));
gst_element_class_set_details (gstelement_class, &gst_filesink_details);
}
+
static void
gst_filesink_class_init (GstFileSinkClass * klass)
{
gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_filesink_render);
gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_filesink_event);
}
+
static void
gst_filesink_init (GstFileSink * filesink)
{
pad = GST_BASESINK_PAD (filesink);
- gst_pad_set_query_function (pad, gst_filesink_pad_query);
- gst_pad_set_query_type_function (pad, gst_filesink_get_query_types);
- gst_pad_set_formats_function (pad, gst_filesink_get_formats);
+ gst_pad_set_query2_function (pad, gst_filesink_query2);
filesink->filename = NULL;
filesink->file = NULL;
}
+
static void
gst_filesink_dispose (GObject * object)
{
}
static gboolean
-gst_filesink_pad_query (GstPad * pad, GstQueryType type,
- GstFormat * format, gint64 * value)
+gst_filesink_query2 (GstPad * pad, GstQuery * query)
{
- GstFileSink *sink = GST_FILESINK (GST_PAD_PARENT (pad));
+ GstFileSink *self;
+ GstFormat format;
- switch (type) {
- case GST_QUERY_TOTAL:
- switch (*format) {
- case GST_FORMAT_BYTES:
- *value = sink->data_written; /* FIXME - doesn't the kernel provide
- such a function? */
- break;
- default:
- return FALSE;
- }
- break;
+ self = GST_FILESINK (GST_PAD_PARENT (pad));
+
+ switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_POSITION:
- switch (*format) {
+ gst_query_parse_position_query (query, &format);
+ switch (format) {
+ case GST_FORMAT_DEFAULT:
case GST_FORMAT_BYTES:
- *value = ftell (sink->file);
- break;
+ gst_query_set_position (query, GST_FORMAT_BYTES,
+ self->data_written, self->data_written);
+ return TRUE;
default:
return FALSE;
}
- break;
+
+ case GST_QUERY_FORMATS:
+ gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES);
+ return TRUE;
+
default:
- return FALSE;
+ return gst_pad_query2_default (pad, query);
}
-
- return TRUE;
}
/* handle events (search) */