gst/gstquery.h

Original commit message from CVS:
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.
This commit is contained in:
Andy Wingo 2005-05-06 21:41:22 +00:00
parent 1185aabed9
commit 8970bda4ba
16 changed files with 615 additions and 265 deletions

View file

@ -1,3 +1,47 @@
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):

View file

@ -83,10 +83,6 @@ Proposed types
- return list of supported formats.
- GST_QUERY_LINKS:
- return list of internal link pads.
Also????
- GST_QUERY_CAPS:

View file

@ -28,6 +28,9 @@ Standard predefined Query types
@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>

View file

@ -88,11 +88,10 @@ static void gst_basesrc_set_property (GObject * object, guint prop_id,
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);
@ -160,10 +159,11 @@ gst_basesrc_init (GstBaseSrc * basesrc, gpointer g_class)
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);
@ -192,84 +192,59 @@ gst_basesrc_set_dataflow_funcs (GstBaseSrc * this)
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));
gboolean b;
guint64 ui64;
gint64 i64;
GstBaseSrc *src;
if (*format == GST_FORMAT_DEFAULT)
*format = GST_FORMAT_BYTES;
src = GST_BASESRC (GST_PAD_PARENT (pad));
switch (type) {
case GST_QUERY_TOTAL:
switch (*format) {
case GST_FORMAT_BYTES:
{
gboolean ret;
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 *

View file

@ -66,29 +66,6 @@ enum
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,
@ -103,8 +80,7 @@ static gboolean gst_filesink_event (GstBaseSink * sink, GstEvent * event);
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);
@ -141,6 +117,7 @@ gst_filesink_base_init (gpointer g_class)
gst_static_pad_template_get (&sinktemplate));
gst_element_class_set_details (gstelement_class, &gst_filesink_details);
}
static void
gst_filesink_class_init (GstFileSinkClass * klass)
{
@ -159,6 +136,7 @@ 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)
{
@ -166,13 +144,12 @@ 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)
{
@ -278,36 +255,33 @@ gst_filesink_close_file (GstFileSink * sink)
}
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;
default:
return FALSE;
}
return TRUE;
case GST_QUERY_FORMATS:
gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES);
return TRUE;
default:
return gst_pad_query2_default (pad, query);
}
}
/* handle events (search) */

View file

@ -582,7 +582,7 @@ init_post (void)
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 ();

View file

@ -48,6 +48,8 @@
#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>

View file

@ -22,7 +22,7 @@
#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; \

View file

@ -251,6 +251,8 @@ gst_real_pad_init (GstRealPad * pad)
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;
@ -987,6 +989,24 @@ gst_pad_set_query_function (GstPad * pad, GstPadQueryFunction query)
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.
@ -3793,6 +3813,56 @@ gst_pad_query (GstPad * pad, GstQueryType type,
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)
{

View file

@ -141,7 +141,7 @@ typedef GstFlowReturn (*GstPadGetRangeFunction) (GstPad *pad, guint64 offset,
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);
@ -152,6 +152,9 @@ typedef const GstFormat* (*GstPadFormatsFunction) (GstPad *pad);
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);
@ -249,7 +252,7 @@ struct _GstRealPad {
GList *ghostpads;
guint32 ghostpads_cookie;
/* query/convert/formats functions */
/* old, deprecated query/convert/formats functions */
GstPadConvertFunction convertfunc;
GstPadQueryFunction queryfunc;
GstPadFormatsFunction formatsfunc;
@ -260,8 +263,12 @@ struct _GstRealPad {
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 {
@ -313,6 +320,7 @@ struct _GstGhostPadClass {
#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)
@ -566,6 +574,10 @@ void gst_pad_set_internal_link_function (GstPad *pad, GstPadIntLinkFunction in
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);

View file

@ -25,6 +25,12 @@
#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;
@ -32,22 +38,29 @@ 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 */
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);
@ -64,6 +77,13 @@ _gst_query_type_initialize (void)
_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);
}
/**
@ -197,3 +217,86 @@ gst_query_type_iterate_definitions (void)
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;
}

View file

@ -28,24 +28,30 @@
#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
{
@ -78,20 +84,59 @@ functionname (type object) \
}
#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

138
gst/gstqueryutils.c Normal file
View file

@ -0,0 +1,138 @@
/* 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);
}

39
gst/gstqueryutils.h Normal file
View file

@ -0,0 +1,39 @@
/* 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, ...);

View file

@ -88,11 +88,10 @@ static void gst_basesrc_set_property (GObject * object, guint prop_id,
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);
@ -160,10 +159,11 @@ gst_basesrc_init (GstBaseSrc * basesrc, gpointer g_class)
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);
@ -192,84 +192,59 @@ gst_basesrc_set_dataflow_funcs (GstBaseSrc * this)
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));
gboolean b;
guint64 ui64;
gint64 i64;
GstBaseSrc *src;
if (*format == GST_FORMAT_DEFAULT)
*format = GST_FORMAT_BYTES;
src = GST_BASESRC (GST_PAD_PARENT (pad));
switch (type) {
case GST_QUERY_TOTAL:
switch (*format) {
case GST_FORMAT_BYTES:
{
gboolean ret;
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 *

View file

@ -66,29 +66,6 @@ enum
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,
@ -103,8 +80,7 @@ static gboolean gst_filesink_event (GstBaseSink * sink, GstEvent * event);
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);
@ -141,6 +117,7 @@ gst_filesink_base_init (gpointer g_class)
gst_static_pad_template_get (&sinktemplate));
gst_element_class_set_details (gstelement_class, &gst_filesink_details);
}
static void
gst_filesink_class_init (GstFileSinkClass * klass)
{
@ -159,6 +136,7 @@ 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)
{
@ -166,13 +144,12 @@ 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)
{
@ -278,36 +255,33 @@ gst_filesink_close_file (GstFileSink * sink)
}
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;
default:
return FALSE;
}
return TRUE;
case GST_QUERY_FORMATS:
gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES);
return TRUE;
default:
return gst_pad_query2_default (pad, query);
}
}
/* handle events (search) */