From 8df6cd7243a593bfae5f1d85f1283e815eabd176 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 9 May 2005 10:53:13 +0000 Subject: [PATCH] Remove old query functions. Ported old code. Original commit message from CVS: Remove old query functions. Ported old code. Added position/convert helper functions to gstutils. Reordered gstpad.c code, grouping relevant things. Remove gst_message_new(), always need to speficy a specific message. --- ChangeLog | 57 ++ docs/design/draft-push-pull.txt | 22 + gst/base/gstbasesrc.c | 16 +- gst/elements/gstfilesink.c | 10 +- gst/elements/gsttypefindelement.c | 78 +- gst/gstelement.c | 157 +--- gst/gstelement.h | 60 +- gst/gstmessage.c | 2 +- gst/gstmessage.h | 1 - gst/gstpad.c | 1122 +++++++++---------------- gst/gstpad.h | 88 +- gst/gstquery.c | 110 ++- gst/gstquery.h | 16 + gst/gstqueryutils.c | 53 -- gst/gstqueryutils.h | 6 - gst/gstqueue.c | 46 +- gst/gstutils.c | 120 +++ gst/gstutils.h | 15 +- libs/gst/base/gstbasesrc.c | 16 +- plugins/elements/gstfilesink.c | 10 +- plugins/elements/gstqueue.c | 46 +- plugins/elements/gsttypefindelement.c | 78 +- tools/gst-inspect.c | 15 +- tools/gst-xmlinspect.c | 19 +- 24 files changed, 966 insertions(+), 1197 deletions(-) diff --git a/ChangeLog b/ChangeLog index f661d61449..aa23ce13a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,60 @@ +2005-05-09 Wim Taymans + + * docs/design/draft-push-pull.txt: + * gst/base/gstbasesrc.c: (gst_basesrc_init), (gst_basesrc_query): + * gst/elements/gstfilesink.c: (gst_filesink_init), + (gst_filesink_query): + * gst/elements/gsttypefindelement.c: (gst_type_find_element_init), + (gst_type_find_handle_src_query), (find_element_get_length): + * gst/gstelement.c: (gst_element_seek), (gst_element_query): + * gst/gstelement.h: + * gst/gstmessage.c: + * gst/gstmessage.h: + * gst/gstpad.c: (gst_real_pad_init), (gst_pad_get_query_types), + (gst_real_pad_get_caps_unlocked), + (gst_pad_get_internal_links_default), (gst_pad_get_internal_links), + (gst_pad_event_default_dispatch), (gst_pad_event_default), + (gst_pad_dispatcher), (gst_pad_query), (gst_pad_query_default), + (gst_real_pad_dispose), (gst_real_pad_finalize), + (gst_pad_load_and_link), (gst_pad_save_thyself), + (gst_ghost_pad_save_thyself), (handle_pad_block), (gst_pad_push), + (gst_pad_check_pull_range), (gst_pad_pull_range), + (gst_pad_template_get_type), (gst_pad_template_class_init), + (gst_pad_template_init), (gst_pad_template_dispose), + (name_is_valid), (gst_static_pad_template_get), + (gst_pad_template_new), (gst_static_pad_template_get_caps), + (gst_pad_template_get_caps), (gst_pad_set_element_private), + (gst_pad_get_element_private), (gst_pad_start_task), + (gst_pad_pause_task), (gst_pad_stop_task), + (gst_ghost_pad_get_type), (gst_ghost_pad_class_init), + (gst_ghost_pad_init), (gst_ghost_pad_dispose), + (gst_ghost_pad_set_property), (gst_ghost_pad_get_property), + (gst_ghost_pad_new): + * gst/gstpad.h: + * gst/gstquery.c: (_gst_query_initialize), (gst_query_new), + (gst_query_new_position), (gst_query_set_position), + (gst_query_parse_position), (gst_query_new_convert), + (gst_query_set_convert), (gst_query_parse_convert): + * gst/gstquery.h: + * gst/gstqueryutils.c: + * gst/gstqueryutils.h: + * gst/gstqueue.c: (gst_queue_init), (gst_queue_getcaps), + (gst_queue_bufferalloc), (gst_queue_handle_sink_event), + (gst_queue_handle_src_query): + * gst/gstutils.c: (gst_element_get_compatible_pad_template), + (gst_element_query_position), (gst_element_query_convert), + (intersect_caps_func), (gst_pad_query_position), + (gst_pad_query_convert): + * gst/gstutils.h: + * tools/gst-inspect.c: (print_pad_info): + * tools/gst-xmlinspect.c: (print_element_info): + Remove old query functions. Ported old code. + Added position/convert helper functions to gstutils. + Reordered gstpad.c code, grouping relevant things. + Remove gst_message_new(), always need to speficy a specific + message. + + 2005-05-09 Andy Wingo * gst/gstiterator.h: Add some includes. diff --git a/docs/design/draft-push-pull.txt b/docs/design/draft-push-pull.txt index fbcbee75a1..e56ce5f6c1 100644 --- a/docs/design/draft-push-pull.txt +++ b/docs/design/draft-push-pull.txt @@ -80,9 +80,31 @@ Proposition: decision. +Things to query: + - pad can do real random access (downstream peer can ask for offset != -1) + - min offset + - suggest sequential access + - max offset + - align: all offsets should be aligned with this value. + - pad can give ranges from A to B length (peer can ask for A <= length <= B) + - min length + - suggested length + - max length +Use cases: + + - An audio source can provide random access to the samples queued in its + DMA buffer, it however suggests sequential access method. + An audio source can provide a random number of samples but prefers + reading from the hardware using a fixed segment size. + + - A caching network source would suggest sequential access but is seekable + in the cached region. Applications can query for the already downloaded + portion and update the GUI, a seek can be done in that area. + - a live video source can only provide buffers sequentialy. It exposes + offsets as -1. lengths are also -1. diff --git a/gst/base/gstbasesrc.c b/gst/base/gstbasesrc.c index 503156870e..2d7b966c15 100644 --- a/gst/base/gstbasesrc.c +++ b/gst/base/gstbasesrc.c @@ -89,9 +89,11 @@ 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 gboolean gst_basesrc_query (GstPad * pad, GstQuery * query); +#if 0 static const GstEventMask *gst_basesrc_get_event_mask (GstPad * pad); +#endif static gboolean gst_basesrc_unlock (GstBaseSrc * basesrc); static gboolean gst_basesrc_get_size (GstBaseSrc * basesrc, guint64 * size); @@ -158,9 +160,7 @@ 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_query2_function (pad, gst_basesrc_query2); + gst_pad_set_query_function (pad, gst_basesrc_query); gst_pad_set_checkgetrange_function (pad, gst_basesrc_check_get_range); @@ -193,7 +193,7 @@ gst_basesrc_set_dataflow_funcs (GstBaseSrc * this) } static gboolean -gst_basesrc_query2 (GstPad * pad, GstQuery * query) +gst_basesrc_query (GstPad * pad, GstQuery * query) { gboolean b; guint64 ui64; @@ -207,7 +207,7 @@ gst_basesrc_query2 (GstPad * pad, GstQuery * query) { GstFormat format; - gst_query_parse_position_query (query, &format); + gst_query_parse_position (query, &format, NULL, NULL); switch (format) { case GST_FORMAT_DEFAULT: case GST_FORMAT_BYTES: @@ -243,10 +243,11 @@ gst_basesrc_query2 (GstPad * pad, GstQuery * query) case GST_QUERY_RATE: case GST_QUERY_CONVERT: default: - return gst_pad_query2_default (pad, query); + return gst_pad_query_default (pad, query); } } +#if 0 static const GstEventMask * gst_basesrc_get_event_mask (GstPad * pad) { @@ -260,6 +261,7 @@ gst_basesrc_get_event_mask (GstPad * pad) }; return masks; } +#endif static gboolean gst_basesrc_do_seek (GstBaseSrc * src, GstEvent * event) diff --git a/gst/elements/gstfilesink.c b/gst/elements/gstfilesink.c index c0da0e3632..cc44e970fa 100644 --- a/gst/elements/gstfilesink.c +++ b/gst/elements/gstfilesink.c @@ -80,7 +80,7 @@ static gboolean gst_filesink_event (GstBaseSink * sink, GstEvent * event); static GstFlowReturn gst_filesink_render (GstBaseSink * sink, GstBuffer * buffer); -static gboolean gst_filesink_query2 (GstPad * pad, GstQuery * query); +static gboolean gst_filesink_query (GstPad * pad, GstQuery * query); static void gst_filesink_uri_handler_init (gpointer g_iface, gpointer iface_data); @@ -144,7 +144,7 @@ gst_filesink_init (GstFileSink * filesink) pad = GST_BASESINK_PAD (filesink); - gst_pad_set_query2_function (pad, gst_filesink_query2); + gst_pad_set_query_function (pad, gst_filesink_query); filesink->filename = NULL; filesink->file = NULL; @@ -255,7 +255,7 @@ gst_filesink_close_file (GstFileSink * sink) } static gboolean -gst_filesink_query2 (GstPad * pad, GstQuery * query) +gst_filesink_query (GstPad * pad, GstQuery * query) { GstFileSink *self; GstFormat format; @@ -264,7 +264,7 @@ gst_filesink_query2 (GstPad * pad, GstQuery * query) switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: - gst_query_parse_position_query (query, &format); + gst_query_parse_position (query, &format, NULL, NULL); switch (format) { case GST_FORMAT_DEFAULT: case GST_FORMAT_BYTES: @@ -280,7 +280,7 @@ gst_filesink_query2 (GstPad * pad, GstQuery * query) return TRUE; default: - return gst_pad_query2_default (pad, query); + return gst_pad_query_default (pad, query); } } diff --git a/gst/elements/gsttypefindelement.c b/gst/elements/gsttypefindelement.c index 994e04f951..5aeece8250 100644 --- a/gst/elements/gsttypefindelement.c +++ b/gst/elements/gsttypefindelement.c @@ -115,11 +115,13 @@ static void gst_type_find_element_set_property (GObject * object, static void gst_type_find_element_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +#if 0 static const GstEventMask *gst_type_find_element_src_event_mask (GstPad * pad); +#endif + static gboolean gst_type_find_element_src_event (GstPad * pad, GstEvent * event); -static gboolean gst_type_find_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * fmt, gint64 * value); +static gboolean gst_type_find_handle_src_query (GstPad * pad, GstQuery * query); static GstFlowReturn push_buffer_store (GstTypeFindElement * typefind); static gboolean gst_type_find_element_handle_event (GstPad * pad, @@ -219,8 +221,6 @@ gst_type_find_element_init (GstTypeFindElement * typefind) gst_type_find_element_checkgetrange); gst_pad_set_getrange_function (typefind->src, gst_type_find_element_getrange); gst_pad_set_event_function (typefind->src, gst_type_find_element_src_event); - gst_pad_set_event_mask_function (typefind->src, - gst_type_find_element_src_event_mask); gst_pad_set_query_function (typefind->src, GST_DEBUG_FUNCPTR (gst_type_find_handle_src_query)); gst_pad_use_fixed_caps (typefind->src); @@ -295,32 +295,48 @@ gst_type_find_element_get_property (GObject * object, guint prop_id, } static gboolean -gst_type_find_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * fmt, gint64 * value) +gst_type_find_handle_src_query (GstPad * pad, GstQuery * query) { - GstTypeFindElement *typefind = - GST_TYPE_FIND_ELEMENT (gst_pad_get_parent (pad)); + GstTypeFindElement *typefind; gboolean res; - res = gst_pad_query (GST_PAD_PEER (typefind->sink), type, fmt, value); + typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); + + res = gst_pad_query (GST_PAD_PEER (typefind->sink), query); if (!res) return FALSE; - if (type == GST_QUERY_POSITION && typefind->store != NULL) { - /* FIXME: this code assumes that there's no discont in the queue */ - switch (*fmt) { - case GST_FORMAT_BYTES: - *value -= gst_buffer_store_get_size (typefind->store, 0); - break; - default: - /* FIXME */ - break; + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_POSITION: + { + gint64 peer_pos, peer_total; + GstFormat format; + + if (typefind->store == NULL) + return TRUE; + + gst_query_parse_position (query, &format, &peer_pos, &peer_total); + + /* FIXME: this code assumes that there's no discont in the queue */ + switch (format) { + case GST_FORMAT_BYTES: + peer_pos -= gst_buffer_store_get_size (typefind->store, 0); + break; + default: + /* FIXME */ + break; + } + gst_query_set_position (query, format, peer_pos, peer_total); + break; } + default: + break; } return TRUE; } +#if 0 static const GstEventMask * gst_type_find_element_src_event_mask (GstPad * pad) { @@ -334,6 +350,7 @@ gst_type_find_element_src_event_mask (GstPad * pad) return mask; } +#endif static gboolean gst_type_find_element_src_event (GstPad * pad, GstEvent * event) @@ -462,24 +479,29 @@ find_element_get_length (gpointer data) return 0; } if (entry->self->stream_length == 0) { - typefind->stream_length_available = - gst_pad_query (GST_PAD_PEER (entry->self->sink), GST_QUERY_TOTAL, - &format, (gint64 *) & entry->self->stream_length); - if (format != GST_FORMAT_BYTES) + if (!gst_pad_query_position (GST_PAD_PEER (entry->self->sink), &format, + NULL, (gint64 *) & entry->self->stream_length)) + goto no_length; + + if (format != GST_FORMAT_BYTES) { typefind->stream_length_available = FALSE; - if (!typefind->stream_length_available) { - GST_DEBUG_OBJECT (entry->self, - "'%s' called get_length () but it's not available", - GST_PLUGIN_FEATURE_NAME (entry->factory)); - return 0; + entry->self->stream_length = 0; } else { GST_DEBUG_OBJECT (entry->self, "'%s' called get_length () and it's %" G_GUINT64_FORMAT " bytes", GST_PLUGIN_FEATURE_NAME (entry->factory), entry->self->stream_length); } } - return entry->self->stream_length; + +no_length: + { + typefind->stream_length_available = FALSE; + GST_DEBUG_OBJECT (entry->self, + "'%s' called get_length () but it's not available", + GST_PLUGIN_FEATURE_NAME (entry->factory)); + return 0; + } } static gboolean diff --git a/gst/gstelement.c b/gst/gstelement.c index 28ffe83fff..0523f4fcf7 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -1049,48 +1049,6 @@ wrong_direction: } } -/** - * gst_element_get_event_masks: - * @element: a #GstElement to query - * - * Get an array of event masks from the element. - * If the element doesn't implement an event masks function, - * the query will be forwarded to a random linked sink pad. - * - * Returns: An array of #GstEventMask elements. The array - * cannot be modified or freed. - * - * MT safe. - */ -const GstEventMask * -gst_element_get_event_masks (GstElement * element) -{ - GstElementClass *oclass; - const GstEventMask *result = NULL; - - g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); - - oclass = GST_ELEMENT_GET_CLASS (element); - - if (oclass->get_event_masks) { - result = oclass->get_event_masks (element); - } else { - GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK); - - if (pad) { - GstPad *peer = gst_pad_get_peer (pad); - - if (peer) { - result = gst_pad_get_event_masks (peer); - gst_object_unref (GST_OBJECT (peer)); - } - gst_object_unref (GST_OBJECT (pad)); - } - } - - return result; -} - /** * gst_element_send_event: * @element: a #GstElement to send the event to. @@ -1156,9 +1114,12 @@ gst_element_send_event (GstElement * element, GstEvent * event) gboolean gst_element_seek (GstElement * element, GstSeekType seek_type, guint64 offset) { - GstEvent *event = gst_event_new_seek (seek_type, offset); + GstEvent *event; gboolean result; + g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); + + event = gst_event_new_seek (seek_type, offset); result = gst_element_send_event (element, event); return result; @@ -1224,25 +1185,23 @@ gst_element_get_query_types (GstElement * element) * MT safe. */ gboolean -gst_element_query (GstElement * element, GstQueryType type, - GstFormat * format, gint64 * value) +gst_element_query (GstElement * element, GstQuery * query) { GstElementClass *oclass; gboolean result = FALSE; g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); - g_return_val_if_fail (format != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); + g_return_val_if_fail (query != NULL, FALSE); oclass = GST_ELEMENT_GET_CLASS (element); if (oclass->query) { - result = oclass->query (element, type, format, value); + result = oclass->query (element, query); } else { GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC); if (pad) { - result = gst_pad_query (pad, type, format, value); + result = gst_pad_query (pad, query); gst_object_unref (GST_OBJECT (pad)); } else { @@ -1251,7 +1210,7 @@ gst_element_query (GstElement * element, GstQueryType type, GstPad *peer = gst_pad_get_peer (pad); if (peer) { - result = gst_pad_query (peer, type, format, value); + result = gst_pad_query (peer, query); gst_object_unref (GST_OBJECT (peer)); } @@ -1262,104 +1221,6 @@ gst_element_query (GstElement * element, GstQueryType type, return result; } -/** - * gst_element_get_formats: - * @element: a #GstElement to query - * - * Get an array of formats from the element. - * If the element doesn't implement a formats function, - * the query will be forwarded to a random sink pad. - * - * Returns: An array of #GstFormat elements. - * - * MT safe. - */ -const GstFormat * -gst_element_get_formats (GstElement * element) -{ - GstElementClass *oclass; - const GstFormat *result = NULL; - - g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); - - oclass = GST_ELEMENT_GET_CLASS (element); - - if (oclass->get_formats) { - result = oclass->get_formats (element); - } else { - GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK); - - if (pad) { - GstPad *peer = gst_pad_get_peer (pad); - - if (peer) { - result = gst_pad_get_formats (peer); - - gst_object_unref (GST_OBJECT (peer)); - } - gst_object_unref (GST_OBJECT (pad)); - } - } - - return result; -} - -/** - * gst_element_convert: - * @element: a #GstElement to invoke the converter on. - * @src_format: the source #GstFormat. - * @src_value: the source value. - * @dest_format: a pointer to the destination #GstFormat. - * @dest_value: a pointer to the destination value. - * - * Invokes a conversion on the element. - * If the element doesn't implement a convert function, - * the query will be forwarded to a random sink pad. - * - * Returns: TRUE if the conversion could be performed. - * - * MT safe. - */ -gboolean -gst_element_convert (GstElement * element, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value) -{ - GstElementClass *oclass; - gboolean result = FALSE; - - g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); - g_return_val_if_fail (dest_format != NULL, FALSE); - g_return_val_if_fail (dest_value != NULL, FALSE); - - if (src_format == *dest_format) { - *dest_value = src_value; - return TRUE; - } - - oclass = GST_ELEMENT_GET_CLASS (element); - - if (oclass->convert) { - result = oclass->convert (element, - src_format, src_value, dest_format, dest_value); - } else { - GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK); - - if (pad) { - GstPad *peer = gst_pad_get_peer (pad); - - if (peer) { - result = gst_pad_convert (peer, - src_format, src_value, dest_format, dest_value); - - gst_object_unref (GST_OBJECT (peer)); - } - gst_object_unref (GST_OBJECT (pad)); - } - } - return result; -} - /** * gst_element_post_message: * @element: a #GstElement posting the message diff --git a/gst/gstelement.h b/gst/gstelement.h index 6e3c137fcb..be4e9f0a4f 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -249,13 +249,13 @@ struct _GstElementClass void (*release_pad) (GstElement *element, GstPad *pad); /* state changes */ - GstElementStateReturn (*get_state) (GstElement * element, GstElementState * state, - GstElementState * pending, GTimeVal * timeout); + GstElementStateReturn (*get_state) (GstElement * element, GstElementState * state, + GstElementState * pending, GTimeVal * timeout); GstElementStateReturn (*change_state) (GstElement *element); /* manager */ - void (*set_manager) (GstElement * element, GstPipeline * pipeline); - void (*set_bus) (GstElement * element, GstBus * bus); + void (*set_manager) (GstElement * element, GstPipeline * pipeline); + void (*set_bus) (GstElement * element, GstBus * bus); void (*set_scheduler) (GstElement *element, GstScheduler *scheduler); /* set/get clocks */ @@ -266,16 +266,11 @@ struct _GstElementClass GstIndex* (*get_index) (GstElement *element); void (*set_index) (GstElement *element, GstIndex *index); - /* query/convert/events functions */ - const GstEventMask* (*get_event_masks) (GstElement *element); + /* query functions */ gboolean (*send_event) (GstElement *element, GstEvent *event); - const GstFormat* (*get_formats) (GstElement *element); - gboolean (*convert) (GstElement *element, - GstFormat src_format, gint64 src_value, - GstFormat *dest_format, gint64 *dest_value); + const GstQueryType* (*get_query_types) (GstElement *element); - gboolean (*query) (GstElement *element, GstQueryType type, - GstFormat *format, gint64 *value); + gboolean (*query) (GstElement *element, GstQuery *query); /*< private >*/ gpointer _gst_reserved[GST_PADDING]; @@ -309,10 +304,10 @@ void gst_element_set_index (GstElement *element, GstIndex *index); GstIndex* gst_element_get_index (GstElement *element); /* manager and tasks */ -void gst_element_set_manager (GstElement * element, GstPipeline * pipeline); -GstPipeline *gst_element_get_manager (GstElement * element); -void gst_element_set_bus (GstElement * element, GstBus * bus); -GstBus *gst_element_get_bus (GstElement * element); +void gst_element_set_manager (GstElement * element, GstPipeline * pipeline); +GstPipeline * gst_element_get_manager (GstElement * element); +void gst_element_set_bus (GstElement * element, GstBus * bus); +GstBus * gst_element_get_bus (GstElement * element); void gst_element_set_scheduler (GstElement *element, GstScheduler *sched); GstScheduler* gst_element_get_scheduler (GstElement *element); @@ -330,44 +325,37 @@ void gst_element_release_request_pad (GstElement *element, GstPad *pad); GstIterator * gst_element_iterate_pads (GstElement * element); /* event/query/format stuff */ -G_CONST_RETURN GstEventMask* - gst_element_get_event_masks (GstElement *element); gboolean gst_element_send_event (GstElement *element, GstEvent *event); gboolean gst_element_seek (GstElement *element, GstSeekType seek_type, guint64 offset); G_CONST_RETURN GstQueryType* gst_element_get_query_types (GstElement *element); -gboolean gst_element_query (GstElement *element, GstQueryType type, - GstFormat *format, gint64 *value); -G_CONST_RETURN GstFormat* - gst_element_get_formats (GstElement *element); -gboolean gst_element_convert (GstElement *element, - GstFormat src_format, gint64 src_value, - GstFormat *dest_format, gint64 *dest_value); +gboolean gst_element_query (GstElement *element, GstQuery *query); /* messages */ -gboolean gst_element_post_message (GstElement * element, GstMessage * message); +gboolean gst_element_post_message (GstElement * element, GstMessage * message); /* error handling */ gchar * _gst_element_error_printf (const gchar *format, ...); -void gst_element_message_full (GstElement * element, GstMessageType type, - GQuark domain, gint code, gchar * text, gchar * debug, const gchar * file, - const gchar * function, gint line); +void gst_element_message_full (GstElement * element, GstMessageType type, + GQuark domain, gint code, gchar * text, + gchar * debug, const gchar * file, + const gchar * function, gint line); /* state management */ gboolean gst_element_is_locked_state (GstElement *element); gboolean gst_element_set_locked_state (GstElement *element, gboolean locked_state); gboolean gst_element_sync_state_with_parent (GstElement *element); -GstElementStateReturn gst_element_get_state (GstElement * element, - GstElementState * state, - GstElementState * pending, - GTimeVal * timeout); +GstElementStateReturn gst_element_get_state (GstElement * element, + GstElementState * state, + GstElementState * pending, + GTimeVal * timeout); GstElementStateReturn gst_element_set_state (GstElement *element, GstElementState state); -void gst_element_abort_state (GstElement * element); -void gst_element_commit_state (GstElement * element); -void gst_element_lost_state (GstElement * element); +void gst_element_abort_state (GstElement * element); +void gst_element_commit_state (GstElement * element); +void gst_element_lost_state (GstElement * element); /* factory management */ GstElementFactory* gst_element_get_factory (GstElement *element); diff --git a/gst/gstmessage.c b/gst/gstmessage.c index bc459ebd34..ab887a8a13 100644 --- a/gst/gstmessage.c +++ b/gst/gstmessage.c @@ -128,7 +128,7 @@ gst_message_get_type (void) * * MT safe. */ -GstMessage * +static GstMessage * gst_message_new (GstMessageType type, GstObject * src) { GstMessage *message; diff --git a/gst/gstmessage.h b/gst/gstmessage.h index 286682aa87..91a5743b1a 100644 --- a/gst/gstmessage.h +++ b/gst/gstmessage.h @@ -111,7 +111,6 @@ struct _GstMessage void _gst_message_initialize (void); GType gst_message_get_type (void); -GstMessage * gst_message_new (GstMessageType type, GstObject * src); /* refcounting */ #define gst_message_ref(msg) GST_MESSAGE (gst_data_ref (GST_DATA (msg))) diff --git a/gst/gstpad.c b/gst/gstpad.c index cc63fcaab2..8981c38810 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -247,16 +247,10 @@ gst_real_pad_init (GstRealPad * pad) pad->getcapsfunc = NULL; pad->eventfunc = gst_pad_event_default; - pad->convertfunc = gst_pad_convert_default; + pad->querytypefunc = gst_pad_get_query_types_default; 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_FLAG_UNSET (pad, GST_PAD_ACTIVE); pad->preroll_lock = g_mutex_new (); @@ -878,99 +872,6 @@ gst_pad_set_event_function (GstPad * pad, GstPadEventFunction event) GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (event)); } -/** - * gst_pad_set_event_mask_function: - * @pad: a real #GstPad of either direction. - * @mask_func: the #GstPadEventMaskFunction to set. - * - * Sets the given event mask function for the pad. - */ -void -gst_pad_set_event_mask_function (GstPad * pad, - GstPadEventMaskFunction mask_func) -{ - g_return_if_fail (GST_IS_REAL_PAD (pad)); - - GST_RPAD_EVENTMASKFUNC (pad) = mask_func; - - GST_CAT_DEBUG (GST_CAT_PADS, "eventmaskfunc for %s:%s set to %s", - GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (mask_func)); -} - -/** - * gst_pad_get_event_masks: - * @pad: a #GstPad. - * - * Gets the array of eventmasks from the given pad. - * - * Returns: a zero-terminated array of #GstEventMask, or NULL if the pad does - * not have an event mask function. - */ -const GstEventMask * -gst_pad_get_event_masks (GstPad * pad) -{ - GstRealPad *rpad; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - rpad = GST_PAD_REALIZE (pad); - - g_return_val_if_fail (rpad, NULL); - - if (GST_RPAD_EVENTMASKFUNC (rpad)) - return GST_RPAD_EVENTMASKFUNC (rpad) (GST_PAD (pad)); - - return NULL; -} - -static gboolean -gst_pad_get_event_masks_dispatcher (GstPad * pad, const GstEventMask ** data) -{ - *data = gst_pad_get_event_masks (pad); - - return TRUE; -} - -/** - * gst_pad_get_event_masks_default: - * @pad: a #GstPad. - * - * Invokes the default event masks dispatcher on the pad. - * - * Returns: a zero-terminated array of #GstEventMask, or NULL if none of the - * internally-linked pads have an event mask function. - */ -const GstEventMask * -gst_pad_get_event_masks_default (GstPad * pad) -{ - GstEventMask *result = NULL; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - gst_pad_dispatcher (pad, (GstPadDispatcherFunction) - gst_pad_get_event_masks_dispatcher, &result); - - return result; -} - -/** - * gst_pad_set_convert_function: - * @pad: a real #GstPad of either direction. - * @convert: the #GstPadConvertFunction to set. - * - * Sets the given convert function for the pad. - */ -void -gst_pad_set_convert_function (GstPad * pad, GstPadConvertFunction convert) -{ - g_return_if_fail (GST_IS_REAL_PAD (pad)); - - GST_RPAD_CONVERTFUNC (pad) = convert; - - GST_CAT_DEBUG (GST_CAT_PADS, "convertfunc for %s:%s set to %s", - GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (convert)); -} - /** * gst_pad_set_query_function: * @pad: a real #GstPad of either direction. @@ -989,24 +890,6 @@ 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. @@ -1039,6 +922,7 @@ const GstQueryType * gst_pad_get_query_types (GstPad * pad) { GstRealPad *rpad; + GstPadQueryTypeFunction func; g_return_val_if_fail (GST_IS_PAD (pad), NULL); @@ -1046,10 +930,15 @@ gst_pad_get_query_types (GstPad * pad) g_return_val_if_fail (rpad, NULL); - if (GST_RPAD_QUERYTYPEFUNC (rpad)) - return GST_RPAD_QUERYTYPEFUNC (rpad) (GST_PAD (pad)); + if (G_UNLIKELY ((func = GST_RPAD_QUERYTYPEFUNC (rpad)) == NULL)) + goto no_func; - return NULL; + return func (GST_PAD (rpad)); + +no_func: + { + return NULL; + } } static gboolean @@ -1100,23 +989,6 @@ gst_pad_set_internal_link_function (GstPad * pad, GstPadIntLinkFunction intlink) GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (intlink)); } -/** - * gst_pad_set_formats_function: - * @pad: a real #GstPad of either direction. - * @formats: the #GstPadFormatsFunction to set. - * - * Sets the given formats function for the pad. - */ -void -gst_pad_set_formats_function (GstPad * pad, GstPadFormatsFunction formats) -{ - g_return_if_fail (GST_IS_REAL_PAD (pad)); - - GST_RPAD_FORMATSFUNC (pad) = formats; - GST_CAT_DEBUG (GST_CAT_PADS, "formats function for %s:%s set to %s", - GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (formats)); -} - /** * gst_pad_set_link_function: * @pad: a real #GstPad. @@ -1622,6 +1494,8 @@ gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ) * * Returns: the #GstPadTemplate from which this pad was instantiated, or %NULL * if this pad has no template. + * + * FIXME: currently returns an unrefcounted padtemplate. */ GstPadTemplate * gst_pad_get_pad_template (GstPad * pad) @@ -1641,7 +1515,7 @@ gst_pad_get_pad_template (GstPad * pad) * returned, as opposed to #gst_pad_get_parent(). * Unref the object after use. * - * Returns: the parent #GstElement. + * Returns: the parent #GstElement. unref after usage. * * MT safe. */ @@ -1717,7 +1591,7 @@ gst_real_pad_get_caps_unlocked (GstRealPad * realpad) GST_FLAG_UNSET (realpad, GST_PAD_IN_GETCAPS); if (result == NULL) { - g_critical ("pad %s:%s returned NULL caps from getcaps function\n", + g_critical ("pad %s:%s returned NULL caps from getcaps function", GST_DEBUG_PAD_NAME (realpad)); } else { #ifndef G_DISABLE_ASSERT @@ -2408,6 +2282,263 @@ not_negotiated: } } +/** + * gst_pad_get_internal_links_default: + * @pad: the #GstPad to get the internal links of. + * + * Gets a list of pads to which the given pad is linked to + * inside of the parent element. + * This is the default handler, and thus returns a list of all of the + * pads inside the parent element with opposite direction. + * The caller must free this list after use. + * + * Returns: a newly allocated #GList of pads. + * + * Not MT safe. + */ +GList * +gst_pad_get_internal_links_default (GstPad * pad) +{ + GList *res = NULL; + GstElement *parent; + GList *parent_pads; + GstPadDirection direction; + GstRealPad *rpad; + + g_return_val_if_fail (GST_IS_PAD (pad), NULL); + + rpad = GST_PAD_REALIZE (pad); + direction = rpad->direction; + + parent = GST_PAD_PARENT (rpad); + parent_pads = parent->pads; + + while (parent_pads) { + GstRealPad *parent_pad = GST_PAD_REALIZE (parent_pads->data); + + if (parent_pad->direction != direction) { + res = g_list_prepend (res, parent_pad); + } + + parent_pads = g_list_next (parent_pads); + } + + return res; +} + +/** + * gst_pad_get_internal_links: + * @pad: the #GstPad to get the internal links of. + * + * Gets a list of pads to which the given pad is linked to + * inside of the parent element. + * The caller must free this list after use. + * + * Returns: a newly allocated #GList of pads. + * + * Not MT safe. + */ +GList * +gst_pad_get_internal_links (GstPad * pad) +{ + GList *res = NULL; + GstRealPad *rpad; + + g_return_val_if_fail (GST_IS_PAD (pad), NULL); + + rpad = GST_PAD_REALIZE (pad); + + if (GST_RPAD_INTLINKFUNC (rpad)) + res = GST_RPAD_INTLINKFUNC (rpad) (GST_PAD_CAST (rpad)); + + return res; +} + + +static gboolean +gst_pad_event_default_dispatch (GstPad * pad, GstEvent * event) +{ + GList *orig, *pads; + gboolean result; + + GST_INFO_OBJECT (pad, "Sending event %p to all internally linked pads", + event); + + result = (GST_PAD_DIRECTION (pad) == GST_PAD_SINK); + + orig = pads = gst_pad_get_internal_links (pad); + + while (pads) { + GstPad *eventpad = GST_PAD (pads->data); + + pads = g_list_next (pads); + + /* for all of the internally-linked pads that are actually linked */ + if (GST_PAD_IS_LINKED (eventpad)) { + if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) { + /* for each pad we send to, we should ref the event; it's up + * to downstream to unref again when handled. */ + GST_LOG_OBJECT (pad, "Reffing and sending event %p to %s:%s", event, + GST_DEBUG_PAD_NAME (eventpad)); + gst_event_ref (event); + gst_pad_push_event (eventpad, event); + } else { + /* we only send the event on one pad, multi-sinkpad elements + * should implement a handler */ + GST_LOG_OBJECT (pad, "sending event %p to one sink pad %s:%s", event, + GST_DEBUG_PAD_NAME (eventpad)); + result = gst_pad_push_event (eventpad, event); + goto done; + } + } + } + /* we handled the incoming event so we unref once */ + GST_LOG_OBJECT (pad, "handled event %p, unreffing", event); + gst_event_unref (event); + +done: + g_list_free (orig); + + return result; +} + +/** + * gst_pad_event_default: + * @pad: a #GstPad to call the default event handler on. + * @event: the #GstEvent to handle. + * + * Invokes the default event handler for the given pad. End-of-stream and + * discontinuity events are handled specially, and then the event is sent to all + * pads internally linked to @pad. Note that if there are many possible sink + * pads that are internally linked to @pad, only one will be sent an event. + * Multi-sinkpad elements should implement custom event handlers. + * + * Returns: TRUE if the event was sent succesfully. + */ +gboolean +gst_pad_event_default (GstPad * pad, GstEvent * event) +{ + g_return_val_if_fail (GST_IS_PAD (pad), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_EOS: + { + GstRealPad *rpad = GST_PAD_REALIZE (pad); + + if (GST_RPAD_TASK (rpad)) { + GST_DEBUG_OBJECT (rpad, "pausing task because of eos"); + gst_task_pause (GST_RPAD_TASK (rpad)); + } + } + default: + break; + } + + return gst_pad_event_default_dispatch (pad, event); +} + +/** + * gst_pad_dispatcher: + * @pad: a #GstPad to dispatch. + * @dispatch: the #GstDispatcherFunction to call. + * @data: gpointer user data passed to the dispatcher function. + * + * Invokes the given dispatcher function on all pads that are + * internally linked to the given pad. + * The GstPadDispatcherFunction should return TRUE when no further pads + * need to be processed. + * + * Returns: TRUE if one of the dispatcher functions returned TRUE. + */ +gboolean +gst_pad_dispatcher (GstPad * pad, GstPadDispatcherFunction dispatch, + gpointer data) +{ + gboolean res = FALSE; + GList *int_pads, *orig; + + g_return_val_if_fail (GST_IS_PAD (pad), FALSE); + g_return_val_if_fail (dispatch != NULL, FALSE); + + orig = int_pads = gst_pad_get_internal_links (pad); + + while (int_pads) { + GstRealPad *int_rpad = GST_PAD_REALIZE (int_pads->data); + GstRealPad *int_peer = GST_RPAD_PEER (int_rpad); + + if (int_peer) { + res = dispatch (GST_PAD (int_peer), data); + if (res) + break; + } + int_pads = g_list_next (int_pads); + } + + g_list_free (orig); + + return res; +} + +/** + * gst_pad_query: + * @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_query (GstPad * pad, GstQuery * query) +{ + GstRealPad *rpad; + GstPadQueryFunction func; + + 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); + + GST_DEBUG ("sending query %p to pad %s:%s", query, GST_DEBUG_PAD_NAME (pad)); + + if ((func = GST_RPAD_QUERYFUNC (rpad)) == NULL) + goto no_func; + + return func (GST_PAD_CAST (rpad), query); + +no_func: + { + GST_DEBUG ("pad had no query function"); + return FALSE; + } +} + +gboolean +gst_pad_query_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_query, query); + } +} + static void gst_real_pad_dispose (GObject * object) { @@ -2676,6 +2807,11 @@ handle_pad_block (GstRealPad * pad) gst_object_unref (GST_OBJECT (pad)); } +/********************************************************************** + * Data passing functions + */ + + /** * gst_pad_push: * @pad: a source #GstPad. @@ -2722,7 +2858,7 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer) /* FIXME, move capnego this into a base class? */ caps = GST_BUFFER_CAPS (buffer); caps_changed = caps && caps != GST_RPAD_CAPS (peer); - GST_DEBUG ("caps changed %d %" GST_PTR_FORMAT "\n", caps_changed, caps); + GST_DEBUG ("caps changed %d %" GST_PTR_FORMAT, caps_changed, caps); /* we got a new datatype on the peer pad, see if it can handle it */ if (G_UNLIKELY (caps_changed)) { if (G_UNLIKELY (!gst_pad_configure_sink (GST_PAD_CAST (peer), caps))) @@ -2943,6 +3079,108 @@ no_function: } } +/** + * gst_pad_push_event: + * @pad: a #GstPad to push the event to. + * @event: the #GstEvent to send to the pad. + * + * Sends the event to the peer of the given pad. + * + * Returns: TRUE if the event was handled. + * + * MT safe. + */ +gboolean +gst_pad_push_event (GstPad * pad, GstEvent * event) +{ + GstRealPad *peerpad; + gboolean result; + + g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + GST_LOCK (pad); + peerpad = GST_RPAD_PEER (pad); + if (peerpad == NULL) + goto not_linked; + + gst_object_ref (GST_OBJECT_CAST (peerpad)); + GST_UNLOCK (pad); + + result = gst_pad_send_event (GST_PAD_CAST (peerpad), event); + + gst_object_unref (GST_OBJECT_CAST (peerpad)); + + return result; + + /* ERROR handling */ +not_linked: + { + GST_UNLOCK (pad); + return FALSE; + } +} + +/** + * gst_pad_send_event: + * @pad: a #GstPad to send the event to. + * @event: the #GstEvent to send to the pad. + * + * Sends the event to the pad. This function can be used + * by applications to send events in the pipeline. + * + * Returns: TRUE if the event was handled. + */ +gboolean +gst_pad_send_event (GstPad * pad, GstEvent * event) +{ + gboolean result = FALSE; + GstRealPad *rpad; + GstPadEventFunction eventfunc; + + g_return_val_if_fail (GST_IS_PAD (pad), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + rpad = GST_PAD_REALIZE (pad); + + if (GST_EVENT_SRC (event) == NULL) + GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (rpad)); + + GST_CAT_DEBUG (GST_CAT_EVENT, "have event type %d on pad %s:%s", + GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (rpad)); + + if (GST_PAD_IS_SINK (pad)) { + if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH) { + GST_CAT_DEBUG (GST_CAT_EVENT, "have flush event"); + GST_LOCK (pad); + if (GST_EVENT_FLUSH_DONE (event)) { + GST_CAT_DEBUG (GST_CAT_EVENT, "clear flush flag"); + GST_FLAG_UNSET (pad, GST_PAD_FLUSHING); + } else { + GST_CAT_DEBUG (GST_CAT_EVENT, "set flush flag"); + GST_FLAG_SET (pad, GST_PAD_FLUSHING); + } + GST_UNLOCK (pad); + } + } + + if ((eventfunc = GST_RPAD_EVENTFUNC (rpad)) == NULL) + goto no_function; + + result = eventfunc (GST_PAD_CAST (rpad), event); + + return result; + + /* ERROR handling */ +no_function: + { + g_warning ("pad %s:%s has no event handler, file a bug.", + GST_DEBUG_PAD_NAME (rpad)); + gst_event_unref (event); + return FALSE; + } +} + /************************************************************************ * * templates @@ -3345,605 +3583,3 @@ gst_ghost_pad_new (const gchar * name, GstPad * pad) return gpad; } - -/** - * gst_pad_get_internal_links_default: - * @pad: the #GstPad to get the internal links of. - * - * Gets a list of pads to which the given pad is linked to - * inside of the parent element. - * This is the default handler, and thus returns a list of all of the - * pads inside the parent element with opposite direction. - * The caller must free this list after use. - * - * Returns: a newly allocated #GList of pads. - * - * Not MT safe. - */ -GList * -gst_pad_get_internal_links_default (GstPad * pad) -{ - GList *res = NULL; - GstElement *parent; - GList *parent_pads; - GstPadDirection direction; - GstRealPad *rpad; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - rpad = GST_PAD_REALIZE (pad); - direction = rpad->direction; - - parent = GST_PAD_PARENT (rpad); - parent_pads = parent->pads; - - while (parent_pads) { - GstRealPad *parent_pad = GST_PAD_REALIZE (parent_pads->data); - - if (parent_pad->direction != direction) { - res = g_list_prepend (res, parent_pad); - } - - parent_pads = g_list_next (parent_pads); - } - - return res; -} - -/** - * gst_pad_get_internal_links: - * @pad: the #GstPad to get the internal links of. - * - * Gets a list of pads to which the given pad is linked to - * inside of the parent element. - * The caller must free this list after use. - * - * Returns: a newly allocated #GList of pads. - * - * Not MT safe. - */ -GList * -gst_pad_get_internal_links (GstPad * pad) -{ - GList *res = NULL; - GstRealPad *rpad; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - rpad = GST_PAD_REALIZE (pad); - - if (GST_RPAD_INTLINKFUNC (rpad)) - res = GST_RPAD_INTLINKFUNC (rpad) (GST_PAD_CAST (rpad)); - - return res; -} - - -static gboolean -gst_pad_event_default_dispatch (GstPad * pad, GstEvent * event) -{ - GList *orig, *pads; - gboolean result; - - GST_INFO_OBJECT (pad, "Sending event %p to all internally linked pads", - event); - - result = (GST_PAD_DIRECTION (pad) == GST_PAD_SINK); - - orig = pads = gst_pad_get_internal_links (pad); - - while (pads) { - GstPad *eventpad = GST_PAD (pads->data); - - pads = g_list_next (pads); - - /* for all of the internally-linked pads that are actually linked */ - if (GST_PAD_IS_LINKED (eventpad)) { - if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) { - /* for each pad we send to, we should ref the event; it's up - * to downstream to unref again when handled. */ - GST_LOG_OBJECT (pad, "Reffing and sending event %p to %s:%s", event, - GST_DEBUG_PAD_NAME (eventpad)); - gst_event_ref (event); - gst_pad_push_event (eventpad, event); - } else { - /* we only send the event on one pad, multi-sinkpad elements - * should implement a handler */ - GST_LOG_OBJECT (pad, "sending event %p to one sink pad %s:%s", event, - GST_DEBUG_PAD_NAME (eventpad)); - result = gst_pad_push_event (eventpad, event); - goto done; - } - } - } - /* we handled the incoming event so we unref once */ - GST_LOG_OBJECT (pad, "handled event %p, unreffing", event); - gst_event_unref (event); - -done: - g_list_free (orig); - - return result; -} - -/** - * gst_pad_event_default: - * @pad: a #GstPad to call the default event handler on. - * @event: the #GstEvent to handle. - * - * Invokes the default event handler for the given pad. End-of-stream and - * discontinuity events are handled specially, and then the event is sent to all - * pads internally linked to @pad. Note that if there are many possible sink - * pads that are internally linked to @pad, only one will be sent an event. - * Multi-sinkpad elements should implement custom event handlers. - * - * Returns: TRUE if the event was sent succesfully. - */ -gboolean -gst_pad_event_default (GstPad * pad, GstEvent * event) -{ - g_return_val_if_fail (GST_IS_PAD (pad), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - { - GstRealPad *rpad = GST_PAD_REALIZE (pad); - - if (GST_RPAD_TASK (rpad)) { - GST_DEBUG_OBJECT (rpad, "pausing task because of eos"); - gst_task_pause (GST_RPAD_TASK (rpad)); - } - } - default: - break; - } - - return gst_pad_event_default_dispatch (pad, event); -} - -/** - * gst_pad_dispatcher: - * @pad: a #GstPad to dispatch. - * @dispatch: the #GstDispatcherFunction to call. - * @data: gpointer user data passed to the dispatcher function. - * - * Invokes the given dispatcher function on all pads that are - * internally linked to the given pad. - * The GstPadDispatcherFunction should return TRUE when no further pads - * need to be processed. - * - * Returns: TRUE if one of the dispatcher functions returned TRUE. - */ -gboolean -gst_pad_dispatcher (GstPad * pad, GstPadDispatcherFunction dispatch, - gpointer data) -{ - gboolean res = FALSE; - GList *int_pads, *orig; - - g_return_val_if_fail (GST_IS_PAD (pad), FALSE); - g_return_val_if_fail (dispatch != NULL, FALSE); - - orig = int_pads = gst_pad_get_internal_links (pad); - - while (int_pads) { - GstRealPad *int_rpad = GST_PAD_REALIZE (int_pads->data); - GstRealPad *int_peer = GST_RPAD_PEER (int_rpad); - - if (int_peer) { - res = dispatch (GST_PAD (int_peer), data); - if (res) - break; - } - int_pads = g_list_next (int_pads); - } - - g_list_free (orig); - - return res; -} - -/** - * gst_pad_push_event: - * @pad: a #GstPad to push the event to. - * @event: the #GstEvent to send to the pad. - * - * Sends the event to the peer of the given pad. - * - * Returns: TRUE if the event was handled. - * - * MT safe. - */ -gboolean -gst_pad_push_event (GstPad * pad, GstEvent * event) -{ - GstRealPad *peerpad; - gboolean result; - - g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - GST_LOCK (pad); - peerpad = GST_RPAD_PEER (pad); - if (peerpad == NULL) - goto not_linked; - - gst_object_ref (GST_OBJECT_CAST (peerpad)); - GST_UNLOCK (pad); - - result = gst_pad_send_event (GST_PAD_CAST (peerpad), event); - - gst_object_unref (GST_OBJECT_CAST (peerpad)); - - return result; - - /* ERROR handling */ -not_linked: - { - GST_UNLOCK (pad); - return FALSE; - } -} - -/** - * gst_pad_send_event: - * @pad: a #GstPad to send the event to. - * @event: the #GstEvent to send to the pad. - * - * Sends the event to the pad. This function can be used - * by applications to send events in the pipeline. - * - * Returns: TRUE if the event was handled. - */ -gboolean -gst_pad_send_event (GstPad * pad, GstEvent * event) -{ - gboolean result = FALSE; - GstRealPad *rpad; - GstPadEventFunction eventfunc; - - g_return_val_if_fail (GST_IS_PAD (pad), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - rpad = GST_PAD_REALIZE (pad); - - if (GST_EVENT_SRC (event) == NULL) - GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (rpad)); - - GST_CAT_DEBUG (GST_CAT_EVENT, "have event type %d on pad %s:%s", - GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (rpad)); - - if (GST_PAD_IS_SINK (pad)) { - if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH) { - GST_CAT_DEBUG (GST_CAT_EVENT, "have flush event"); - GST_LOCK (pad); - if (GST_EVENT_FLUSH_DONE (event)) { - GST_CAT_DEBUG (GST_CAT_EVENT, "clear flush flag"); - GST_FLAG_UNSET (pad, GST_PAD_FLUSHING); - } else { - GST_CAT_DEBUG (GST_CAT_EVENT, "set flush flag"); - GST_FLAG_SET (pad, GST_PAD_FLUSHING); - } - GST_UNLOCK (pad); - } - } - - if ((eventfunc = GST_RPAD_EVENTFUNC (rpad)) == NULL) - goto no_function; - - result = eventfunc (GST_PAD_CAST (rpad), event); - - return result; - - /* ERROR handling */ -no_function: - { - g_warning ("pad %s:%s has no event handler, file a bug.", - GST_DEBUG_PAD_NAME (rpad)); - gst_event_unref (event); - return FALSE; - } -} - -typedef struct -{ - GstFormat src_format; - gint64 src_value; - GstFormat *dest_format; - gint64 *dest_value; -} -GstPadConvertData; - -static gboolean -gst_pad_convert_dispatcher (GstPad * pad, GstPadConvertData * data) -{ - return gst_pad_convert (pad, data->src_format, data->src_value, - data->dest_format, data->dest_value); -} - -/** - * gst_pad_convert_default: - * @pad: a #GstPad to invoke the default converter on. - * @src_format: the source #GstFormat. - * @src_value: the source value. - * @dest_format: a pointer to the destination #GstFormat. - * @dest_value: a pointer to the destination value. - * - * Invokes the default converter on a pad. - * This will forward the call to the pad obtained - * using the internal link of - * the element. - * - * Returns: TRUE if the conversion could be performed. - */ -gboolean -gst_pad_convert_default (GstPad * pad, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value) -{ - GstPadConvertData data; - - g_return_val_if_fail (GST_IS_PAD (pad), FALSE); - g_return_val_if_fail (dest_format != NULL, FALSE); - g_return_val_if_fail (dest_value != NULL, FALSE); - - data.src_format = src_format; - data.src_value = src_value; - data.dest_format = dest_format; - data.dest_value = dest_value; - - return gst_pad_dispatcher (pad, (GstPadDispatcherFunction) - gst_pad_convert_dispatcher, &data); -} - -/** - * gst_pad_convert: - * @pad: a #GstPad to invoke the default converter on. - * @src_format: the source #GstFormat. - * @src_value: the source value. - * @dest_format: a pointer to the destination #GstFormat. - * @dest_value: a pointer to the destination value. - * - * Invokes a conversion on the pad. - * - * Returns: TRUE if the conversion could be performed. - */ -gboolean -gst_pad_convert (GstPad * pad, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value) -{ - GstRealPad *rpad; - - g_return_val_if_fail (GST_IS_PAD (pad), FALSE); - g_return_val_if_fail (dest_format != NULL, FALSE); - g_return_val_if_fail (dest_value != NULL, FALSE); - - if (src_format == *dest_format) { - *dest_value = src_value; - return TRUE; - } - - rpad = GST_PAD_REALIZE (pad); - - if (GST_RPAD_CONVERTFUNC (rpad)) { - return GST_RPAD_CONVERTFUNC (rpad) (GST_PAD (rpad), src_format, - src_value, dest_format, dest_value); - } - - return FALSE; -} - -typedef struct -{ - GstQueryType type; - GstFormat *format; - gint64 *value; -} -GstPadQueryData; - -static gboolean -gst_pad_query_dispatcher (GstPad * pad, GstPadQueryData * data) -{ - return gst_pad_query (pad, data->type, data->format, data->value); -} - -/** - * gst_pad_query_default: - * @pad: a #GstPad to invoke the default query on. - * @type: the #GstQueryType of the query to perform. - * @format: a pointer to the #GstFormat of the result. - * @value: a pointer to the result. - * - * Invokes the default query function on a pad. - * - * Returns: TRUE if the query could be performed. - */ -gboolean -gst_pad_query_default (GstPad * pad, GstQueryType type, - GstFormat * format, gint64 * value) -{ - GstPadQueryData data; - - g_return_val_if_fail (GST_IS_PAD (pad), FALSE); - g_return_val_if_fail (format != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); - - data.type = type; - data.format = format; - data.value = value; - - return gst_pad_dispatcher (pad, (GstPadDispatcherFunction) - gst_pad_query_dispatcher, &data); -} - -/** - * gst_pad_query: - * @pad: a #GstPad to invoke the default query on. - * @type: the #GstQueryType of the query to perform. - * @format: a pointer to the #GstFormat asked for. - * On return contains the #GstFormat used. - * @value: a pointer to the result. - * - * Queries a pad for one of the available properties. The format will be - * adjusted to the actual format used when specifying formats such as - * GST_FORMAT_DEFAULT. - * FIXME: Tell if the format can be adjusted when specifying a definite format. - * - * Returns: TRUE if the query could be performed. - */ -gboolean -gst_pad_query (GstPad * pad, GstQueryType type, - GstFormat * format, gint64 * value) -{ - GstRealPad *rpad; - - g_return_val_if_fail (GST_IS_PAD (pad), FALSE); - g_return_val_if_fail (format != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); - - rpad = GST_PAD_REALIZE (pad); - - g_return_val_if_fail (rpad, FALSE); - - if (GST_RPAD_QUERYFUNC (rpad)) - return GST_RPAD_QUERYFUNC (rpad) (GST_PAD_CAST (rpad), type, format, value); - - 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); - } -} - -/** - * gst_pad_query_position: - * @pad: a #GstPad to invoke the default query on. - * @format: a pointer to the #GstFormat asked for. - * On return contains the #GstFormat used. - * @cur: A location in which to store the current position, or NULL. - * @end: A location in which to store the end position (length), or NULL. - * - * Queries a pad for the stream position and length. - * - * Returns: TRUE if the query could be performed. - */ -gboolean -gst_pad_query_position (GstPad * pad, GstFormat * format, gint64 * cur, - gint64 * end) -{ - GstQuery *query; - gboolean ret; - - g_return_val_if_fail (GST_IS_PAD (pad), FALSE); - g_return_val_if_fail (format != NULL, FALSE); - - query = gst_query_new_position (*format); - ret = gst_pad_query2 (pad, query); - - if (ret) - gst_query_parse_position_response (query, format, cur, end); - - gst_query_unref (query); - - return ret; -} - -static gboolean -gst_pad_get_formats_dispatcher (GstPad * pad, const GstFormat ** data) -{ - *data = gst_pad_get_formats (pad); - - return TRUE; -} - -/** - * gst_pad_get_formats_default: - * @pad: a #GstPad to query - * - * Invoke the default format dispatcher for the pad. - * - * Returns: An array of GstFormats ended with a 0 value. - */ -const GstFormat * -gst_pad_get_formats_default (GstPad * pad) -{ - GstFormat *result = NULL; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - gst_pad_dispatcher (pad, (GstPadDispatcherFunction) - gst_pad_get_formats_dispatcher, &result); - - return result; -} - -/** - * gst_pad_get_formats: - * @pad: a #GstPad to query - * - * Gets the list of supported formats from the pad. - * - * Returns: An array of GstFormats ended with a 0 value. - */ -const GstFormat * -gst_pad_get_formats (GstPad * pad) -{ - GstRealPad *rpad; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - rpad = GST_PAD_REALIZE (pad); - - if (GST_RPAD_FORMATSFUNC (rpad)) - return GST_RPAD_FORMATSFUNC (rpad) (GST_PAD (pad)); - - return NULL; -} diff --git a/gst/gstpad.h b/gst/gstpad.h index b560b80766..d8fcd9f0d4 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -135,26 +135,21 @@ typedef enum { typedef gboolean (*GstPadActivateFunction) (GstPad *pad, GstActivateMode mode); /* data passing */ -typedef void (*GstPadLoopFunction) (GstPad *pad); typedef GstFlowReturn (*GstPadChainFunction) (GstPad *pad, GstBuffer *buffer); typedef GstFlowReturn (*GstPadGetRangeFunction) (GstPad *pad, guint64 offset, guint length, GstBuffer **buffer); -typedef gboolean (*GstPadCheckGetRangeFunction) (GstPad *pad); typedef gboolean (*GstPadEventFunction) (GstPad *pad, GstEvent *event); -/* old, deprecated convert/query/format functions */ -typedef gboolean (*GstPadConvertFunction) (GstPad *pad, - GstFormat src_format, gint64 src_value, - GstFormat *dest_format, gint64 *dest_value); -typedef gboolean (*GstPadQueryFunction) (GstPad *pad, GstQueryType type, - GstFormat *format, gint64 *value); +/* deprecate me, check range should use seeking query, loop function is internal */ +typedef gboolean (*GstPadCheckGetRangeFunction) (GstPad *pad); +typedef void (*GstPadLoopFunction) (GstPad *pad); + +/* internal links */ typedef GList* (*GstPadIntLinkFunction) (GstPad *pad); -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); +typedef const GstQueryType* (*GstPadQueryTypeFunction) (GstPad *pad); +typedef gboolean (*GstPadQueryFunction) (GstPad *pad, GstQuery *query); /* linking */ typedef GstPadLinkReturn (*GstPadLinkFunction) (GstPad *pad, GstPad *peer); @@ -247,29 +242,23 @@ struct _GstRealPad { GstPadGetRangeFunction getrangefunc; GstPadEventFunction eventfunc; - GstPadEventMaskFunction eventmaskfunc; - /* ghostpads */ GList *ghostpads; guint32 ghostpads_cookie; - /* old, deprecated query/convert/formats functions */ - GstPadConvertFunction convertfunc; - GstPadQueryFunction queryfunc; - GstPadFormatsFunction formatsfunc; + /* generic query method */ GstPadQueryTypeFunction querytypefunc; + GstPadQueryFunction queryfunc; + + /* internal links */ GstPadIntLinkFunction intlinkfunc; GstPadBufferAllocFunction bufferallocfunc; GstProbeDispatcher probedisp; - /* generic query method */ - GstPadQuery2Function query2func; - /*< private >*/ - /* fixme: bring back to gst_padding when old query functions go away */ - gpointer _gst_reserved[GST_PADDING - 1]; + gpointer _gst_reserved[GST_PADDING]; }; struct _GstRealPadClass { @@ -315,13 +304,9 @@ struct _GstGhostPadClass { #define GST_RPAD_CHECKGETRANGEFUNC(pad) (GST_REAL_PAD_CAST(pad)->checkgetrangefunc) #define GST_RPAD_GETRANGEFUNC(pad) (GST_REAL_PAD_CAST(pad)->getrangefunc) #define GST_RPAD_EVENTFUNC(pad) (GST_REAL_PAD_CAST(pad)->eventfunc) -#define GST_RPAD_CONVERTFUNC(pad) (GST_REAL_PAD_CAST(pad)->convertfunc) +#define GST_RPAD_QUERYTYPEFUNC(pad) (GST_REAL_PAD_CAST(pad)->querytypefunc) #define GST_RPAD_QUERYFUNC(pad) (GST_REAL_PAD_CAST(pad)->queryfunc) #define GST_RPAD_INTLINKFUNC(pad) (GST_REAL_PAD_CAST(pad)->intlinkfunc) -#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) @@ -379,11 +364,10 @@ struct _GstGhostPadClass { #define GST_PAD_IS_LINKED(pad) (GST_RPAD_IS_LINKED(GST_PAD_REALIZE(pad))) #define GST_PAD_IS_ACTIVE(pad) (GST_RPAD_IS_ACTIVE(GST_PAD_REALIZE(pad))) #define GST_PAD_IS_BLOCKED(pad) (GST_RPAD_IS_BLOCKED(GST_PAD_REALIZE(pad))) -#define GST_PAD_IS_NEGOTIATING(pad) (GST_RPAD_IS_NEGOTIATING(GST_PAD_REALIZE(pad))) +#define GST_PAD_IS_FLUSHING(pad) (GST_RPAD_IS_FLUSHING(GST_PAD_REALIZE(pad))) #define GST_PAD_IS_IN_GETCAPS(pad) (GST_RPAD_IS_IN_GETCAPS(GST_PAD_REALIZE(pad))) #define GST_PAD_IS_IN_SETCAPS(pad) (GST_RPAD_IS_IN_SETCAPS(GST_PAD_REALIZE(pad))) #define GST_PAD_IS_USABLE(pad) (GST_RPAD_IS_USABLE(GST_PAD_REALIZE(pad))) -#define GST_PAD_CAN_PULL(pad) (GST_RPAD_CAN_PULL(GST_PAD_REALIZE(pad))) #define GST_PAD_IS_SRC(pad) (GST_RPAD_IS_SRC(GST_PAD_REALIZE(pad))) #define GST_PAD_IS_SINK(pad) (GST_RPAD_IS_SINK(GST_PAD_REALIZE(pad))) @@ -492,11 +476,6 @@ void gst_pad_set_chain_function (GstPad *pad, GstPadChainFunction chain); void gst_pad_set_getrange_function (GstPad *pad, GstPadGetRangeFunction get); void gst_pad_set_checkgetrange_function (GstPad *pad, GstPadCheckGetRangeFunction check); void gst_pad_set_event_function (GstPad *pad, GstPadEventFunction event); -void gst_pad_set_event_mask_function (GstPad *pad, GstPadEventMaskFunction mask_func); -G_CONST_RETURN GstEventMask* - gst_pad_get_event_masks (GstPad *pad); -G_CONST_RETURN GstEventMask* - gst_pad_get_event_masks_default (GstPad *pad); /* pad links */ void gst_pad_set_link_function (GstPad *pad, GstPadLinkFunction link); @@ -544,44 +523,21 @@ gboolean gst_pad_start_task (GstPad *pad); gboolean gst_pad_pause_task (GstPad *pad); gboolean gst_pad_stop_task (GstPad *pad); -/* convert/query/format functions */ -void gst_pad_set_formats_function (GstPad *pad, - GstPadFormatsFunction formats); -G_CONST_RETURN GstFormat* - gst_pad_get_formats (GstPad *pad); -G_CONST_RETURN GstFormat* - gst_pad_get_formats_default (GstPad *pad); +/* internal links */ +void gst_pad_set_internal_link_function (GstPad *pad, GstPadIntLinkFunction intlink); +GList* gst_pad_get_internal_links (GstPad *pad); +GList* gst_pad_get_internal_links_default (GstPad *pad); -void gst_pad_set_convert_function (GstPad *pad, GstPadConvertFunction convert); -gboolean gst_pad_convert (GstPad *pad, - GstFormat src_format, gint64 src_value, - GstFormat *dest_format, gint64 *dest_value); -gboolean gst_pad_convert_default (GstPad *pad, - GstFormat src_format, gint64 src_value, - GstFormat *dest_format, gint64 *dest_value); - -void gst_pad_set_query_function (GstPad *pad, GstPadQueryFunction query); +/* generic query function */ void gst_pad_set_query_type_function (GstPad *pad, GstPadQueryTypeFunction type_func); G_CONST_RETURN GstQueryType* gst_pad_get_query_types (GstPad *pad); G_CONST_RETURN GstQueryType* gst_pad_get_query_types_default (GstPad *pad); -gboolean gst_pad_query (GstPad *pad, GstQueryType type, - GstFormat *format, gint64 *value); -gboolean gst_pad_query_default (GstPad *pad, GstQueryType type, - GstFormat *format, gint64 *value); -void gst_pad_set_internal_link_function (GstPad *pad, GstPadIntLinkFunction intlink); -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); - -/* util query functions */ -gboolean gst_pad_query_position (GstPad *pad, GstFormat *format, - gint64 *cur, gint64 *end); +gboolean gst_pad_query (GstPad *pad, GstQuery *query); +void gst_pad_set_query_function (GstPad *pad, GstPadQueryFunction query); +gboolean gst_pad_query_default (GstPad *pad, GstQuery *query); /* misc helper functions */ gboolean gst_pad_dispatcher (GstPad *pad, GstPadDispatcherFunction dispatch, diff --git a/gst/gstquery.c b/gst/gstquery.c index 5f02fe4f9a..9b57fb370e 100644 --- a/gst/gstquery.c +++ b/gst/gstquery.c @@ -26,12 +26,14 @@ #include "gst_private.h" #include "gstquery.h" #include "gstmemchunk.h" +#include "gstenumtypes.h" #include "gstdata_private.h" +GST_DEBUG_CATEGORY_STATIC (gst_query_debug); +#define GST_CAT_DEFAULT gst_query_debug GType _gst_query_type; - static GStaticMutex mutex = G_STATIC_MUTEX_INIT; static GList *_gst_queries = NULL; static GHashTable *_nick_to_query = NULL; @@ -61,6 +63,8 @@ _gst_query_initialize (void) GST_CAT_INFO (GST_CAT_GST_INIT, "init queries"); + GST_DEBUG_CATEGORY_INIT (gst_query_debug, "query", 0, "query system"); + g_static_mutex_lock (&mutex); if (_nick_to_query == NULL) { _nick_to_query = g_hash_table_new (g_str_hash, g_str_equal); @@ -279,11 +283,115 @@ gst_query_new (GstQueryType type, GstStructure * structure) query->structure = structure; gst_structure_set_parent_refcount (query->structure, &GST_DATA_REFCOUNT (query)); + } else { + query->structure = NULL; } return query; } +GstQuery * +gst_query_new_position (GstFormat format) +{ + GstQuery *query; + GstStructure *structure; + + structure = gst_structure_new ("GstQueryPosition", + "format", GST_TYPE_FORMAT, format, + "cur", G_TYPE_INT64, (gint64) - 1, + "end", G_TYPE_INT64, (gint64) - 1, NULL); + query = gst_query_new (GST_QUERY_POSITION, structure); + + return query; +} + +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 (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); + if (format) + *format = g_value_get_enum (gst_structure_get_value (structure, "format")); + if (cur) + *cur = g_value_get_int64 (gst_structure_get_value (structure, "cur")); + if (end) + *end = g_value_get_int64 (gst_structure_get_value (structure, "end")); +} + +GstQuery * +gst_query_new_convert (GstFormat src_fmt, gint64 value, GstFormat dest_fmt) +{ + GstQuery *query; + GstStructure *structure; + + structure = gst_structure_new ("GstQueryConvert", + "src_format", GST_TYPE_FORMAT, src_fmt, + "src_value", G_TYPE_INT64, value, + "dest_format", GST_TYPE_FORMAT, dest_fmt, + "dest_value", G_TYPE_INT64, (gint64) - 1, NULL); + query = gst_query_new (GST_QUERY_CONVERT, structure); + + return query; +} + +void +gst_query_set_convert (GstQuery * query, GstFormat src_format, gint64 src_value, + GstFormat dest_format, gint64 dest_value) +{ + GstStructure *structure; + + g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT); + + structure = gst_query_get_structure (query); + gst_structure_set (structure, + "src_format", GST_TYPE_FORMAT, src_format, + "src_value", G_TYPE_INT64, src_value, + "dest_format", GST_TYPE_FORMAT, dest_format, + "dest_value", G_TYPE_INT64, dest_value, NULL); +} + +void +gst_query_parse_convert (GstQuery * query, GstFormat * src_format, + gint64 * src_value, GstFormat * dest_format, gint64 * dest_value) +{ + GstStructure *structure; + + g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT); + + structure = gst_query_get_structure (query); + if (src_format) + *src_format = + g_value_get_enum (gst_structure_get_value (structure, "src_format")); + if (src_value) + *src_value = + g_value_get_int64 (gst_structure_get_value (structure, "src_value")); + if (dest_format) + *dest_format = + g_value_get_enum (gst_structure_get_value (structure, "dest_format")); + if (dest_value) + *dest_value = + g_value_get_int64 (gst_structure_get_value (structure, "dest_value")); +} + + GstQuery * gst_query_new_application (GstQueryType type, GstStructure * structure) { diff --git a/gst/gstquery.h b/gst/gstquery.h index 70d49e86a7..3501c47006 100644 --- a/gst/gstquery.h +++ b/gst/gstquery.h @@ -30,6 +30,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -129,9 +130,24 @@ GstIterator* gst_query_type_iterate_definitions (void); #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))) +/* position query */ +GstQuery* gst_query_new_position (GstFormat format); +void gst_query_set_position (GstQuery *query, GstFormat format, + gint64 cur, gint64 end); +void gst_query_parse_position (GstQuery *query, GstFormat *format, + gint64 *cur, gint64 *end); +/* convert query */ +GstQuery* gst_query_new_convert (GstFormat src_fmt, gint64 value, GstFormat dest_fmt); +void gst_query_set_convert (GstQuery *query, GstFormat src_format, gint64 src_value, + GstFormat dest_format, gint64 dest_value); +void gst_query_parse_convert (GstQuery *query, GstFormat *src_format, gint64 *src_value, + GstFormat *dest_format, gint64 *dest_value); + +/* application specific query */ GstQuery * gst_query_new_application (GstQueryType type, GstStructure *structure); + GstStructure * gst_query_get_structure (GstQuery *query); /* hmm */ diff --git a/gst/gstqueryutils.c b/gst/gstqueryutils.c index 25a39f5eb2..b2ad6633cd 100644 --- a/gst/gstqueryutils.c +++ b/gst/gstqueryutils.c @@ -29,59 +29,6 @@ /* some macros are just waiting to be defined here */ - -GstQuery * -gst_query_new_position (GstFormat format) -{ - GstStructure *structure = gst_structure_new ("query", - "format", GST_TYPE_FORMAT, format, NULL); - - return gst_query_new_application (GST_QUERY_POSITION, structure); -} - -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); - if (format) - *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); - if (format) - *format = g_value_get_enum (gst_structure_get_value (structure, "format")); - if (cur) - *cur = g_value_get_int64 (gst_structure_get_value (structure, "cur")); - if (end) - *end = g_value_get_int64 (gst_structure_get_value (structure, "end")); -} - void gst_query_parse_seeking_query (GstQuery * query, GstFormat * format) { diff --git a/gst/gstqueryutils.h b/gst/gstqueryutils.h index d59a8044e4..d72c165624 100644 --- a/gst/gstqueryutils.h +++ b/gst/gstqueryutils.h @@ -26,12 +26,6 @@ #include -GstQuery* gst_query_new_position (GstFormat format); -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, diff --git a/gst/gstqueue.c b/gst/gstqueue.c index 0596538c09..aa2b905d99 100644 --- a/gst/gstqueue.c +++ b/gst/gstqueue.c @@ -133,8 +133,7 @@ static void gst_queue_loop (GstPad * pad); static gboolean gst_queue_handle_sink_event (GstPad * pad, GstEvent * event); static gboolean gst_queue_handle_src_event (GstPad * pad, GstEvent * event); -static gboolean gst_queue_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * fmt, gint64 * value); +static gboolean gst_queue_handle_src_query (GstPad * pad, GstQuery * query); static GstCaps *gst_queue_getcaps (GstPad * pad); static GstPadLinkReturn gst_queue_link_sink (GstPad * pad, GstPad * peer); @@ -811,29 +810,42 @@ gst_queue_handle_src_event (GstPad * pad, GstEvent * event) } static gboolean -gst_queue_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * fmt, gint64 * value) +gst_queue_handle_src_query (GstPad * pad, GstQuery * query) { GstQueue *queue = GST_QUEUE (GST_PAD_PARENT (pad)); if (!GST_PAD_PEER (queue->sinkpad)) return FALSE; - if (!gst_pad_query (GST_PAD_PEER (queue->sinkpad), type, fmt, value)) + if (!gst_pad_query (GST_PAD_PEER (queue->sinkpad), query)) return FALSE; - if (type == GST_QUERY_POSITION) { - /* FIXME: this code assumes that there's no discont in the queue */ - switch (*fmt) { - case GST_FORMAT_BYTES: - *value -= queue->cur_level.bytes; - break; - case GST_FORMAT_TIME: - *value -= queue->cur_level.time; - break; - default: - /* FIXME */ - break; + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_POSITION: + { + gint64 peer_pos, peer_total; + GstFormat format; + + /* get peer position */ + gst_query_parse_position (query, &format, &peer_pos, &peer_total); + + /* FIXME: this code assumes that there's no discont in the queue */ + switch (format) { + case GST_FORMAT_BYTES: + peer_pos -= queue->cur_level.bytes; + break; + case GST_FORMAT_TIME: + peer_pos -= queue->cur_level.time; + break; + default: + /* FIXME */ + break; + } + /* set updated positions */ + gst_query_set_position (query, format, peer_pos, peer_total); + break; } + default: + break; } return TRUE; diff --git a/gst/gstutils.c b/gst/gstutils.c index 0345bf4295..e02ac8edf2 100644 --- a/gst/gstutils.c +++ b/gst/gstutils.c @@ -1155,6 +1155,55 @@ gst_element_unlink (GstElement * src, GstElement * dest) } } +gboolean +gst_element_query_position (GstElement * element, GstFormat * format, + gint64 * cur, gint64 * end) +{ + GstQuery *query; + gboolean ret; + + g_return_val_if_fail (GST_IS_PAD (element), FALSE); + g_return_val_if_fail (format != NULL, FALSE); + + query = gst_query_new_position (*format); + ret = gst_element_query (element, query); + + if (ret) + gst_query_parse_position (query, format, cur, end); + + gst_query_unref (query); + + return ret; +} + +gboolean +gst_element_query_convert (GstElement * element, GstFormat src_format, + gint64 src_val, GstFormat * dest_fmt, gint64 * dest_val) +{ + GstQuery *query; + gboolean ret; + + g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); + g_return_val_if_fail (dest_fmt != NULL, FALSE); + g_return_val_if_fail (dest_val != NULL, FALSE); + + if (*dest_fmt == src_format) { + *dest_val = src_val; + return TRUE; + } + + query = gst_query_new_convert (src_format, src_val, *dest_fmt); + ret = gst_element_query (element, query); + + if (ret) + gst_query_parse_convert (query, NULL, NULL, dest_fmt, dest_val); + + gst_query_unref (query); + + return ret; +} + + /** * gst_pad_can_link: * @srcpad: the source #GstPad to link. @@ -1675,6 +1724,77 @@ gst_pad_proxy_setcaps (GstPad * pad, GstCaps * caps) return g_value_get_boolean (&ret); } +/** + * gst_pad_query_position: + * @pad: a #GstPad to invoke the position query on. + * @format: a pointer to the #GstFormat asked for. + * On return contains the #GstFormat used. + * @cur: A location in which to store the current position, or NULL. + * @end: A location in which to store the end position (length), or NULL. + * + * Queries a pad for the stream position and length. + * + * Returns: TRUE if the query could be performed. + */ +gboolean +gst_pad_query_position (GstPad * pad, GstFormat * format, gint64 * cur, + gint64 * end) +{ + GstQuery *query; + gboolean ret; + + g_return_val_if_fail (GST_IS_PAD (pad), FALSE); + g_return_val_if_fail (format != NULL, FALSE); + + query = gst_query_new_position (*format); + ret = gst_pad_query (pad, query); + + if (ret) + gst_query_parse_position (query, format, cur, end); + + gst_query_unref (query); + + return ret; +} + +/** + * gst_pad_query_convert: + * @pad: a #GstPad to invoke the convert query on. + * @src_format: a #GstFormat to convert from. + * @src_val: a value to convert. + * @dest_format: a pointer to the #GstFormat to convert to. + * @dest_val: a pointer to the result. + * + * Queries a pad to convert @src_val in @src_format to @dest_format. + * + * Returns: TRUE if the query could be performed. + */ +gboolean +gst_pad_query_convert (GstPad * pad, GstFormat src_format, gint64 src_val, + GstFormat * dest_fmt, gint64 * dest_val) +{ + GstQuery *query; + gboolean ret; + + g_return_val_if_fail (GST_IS_PAD (pad), FALSE); + g_return_val_if_fail (dest_fmt != NULL, FALSE); + g_return_val_if_fail (dest_val != NULL, FALSE); + + if (*dest_fmt == src_format) { + *dest_val = src_val; + return TRUE; + } + + query = gst_query_new_convert (src_format, src_val, *dest_fmt); + ret = gst_pad_query (pad, query); + + if (ret) + gst_query_parse_convert (query, NULL, NULL, dest_fmt, dest_val); + + gst_query_unref (query); + + return ret; +} /** * gst_atomic_int_set: diff --git a/gst/gstutils.h b/gst/gstutils.h index d5b17cac72..a27851767d 100644 --- a/gst/gstutils.h +++ b/gst/gstutils.h @@ -251,10 +251,15 @@ gboolean gst_element_link_pads (GstElement *src, const gchar *srcpadn GstElement *dest, const gchar *destpadname); void gst_element_unlink_pads (GstElement *src, const gchar *srcpadname, GstElement *dest, const gchar *destpadname); +/* util query functions */ +gboolean gst_element_query_position (GstElement *element, GstFormat *format, + gint64 *cur, gint64 *end); +gboolean gst_element_query_convert (GstElement *element, GstFormat src_format, gint64 src_val, + GstFormat *dest_fmt, gint64 *dest_val); /* element class functions */ -void gst_element_class_install_std_props (GstElementClass * klass, - const gchar * first_name, ...); +void gst_element_class_install_std_props (GstElementClass * klass, + const gchar * first_name, ...); /* pad functions */ gboolean gst_pad_can_link (GstPad *srcpad, GstPad *sinkpad); @@ -264,6 +269,12 @@ GstCaps* gst_pad_get_fixed_caps_func (GstPad *pad); GstCaps* gst_pad_proxy_getcaps (GstPad * pad); gboolean gst_pad_proxy_setcaps (GstPad * pad, GstCaps * caps); +/* util query functions */ +gboolean gst_pad_query_position (GstPad *pad, GstFormat *format, + gint64 *cur, gint64 *end); +gboolean gst_pad_query_convert (GstPad *pad, GstFormat src_format, gint64 src_val, + GstFormat *dest_fmt, gint64 *dest_val); + /* bin functions */ void gst_bin_add_many (GstBin *bin, GstElement *element_1, ...); void gst_bin_remove_many (GstBin *bin, GstElement *element_1, ...); diff --git a/libs/gst/base/gstbasesrc.c b/libs/gst/base/gstbasesrc.c index 503156870e..2d7b966c15 100644 --- a/libs/gst/base/gstbasesrc.c +++ b/libs/gst/base/gstbasesrc.c @@ -89,9 +89,11 @@ 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 gboolean gst_basesrc_query (GstPad * pad, GstQuery * query); +#if 0 static const GstEventMask *gst_basesrc_get_event_mask (GstPad * pad); +#endif static gboolean gst_basesrc_unlock (GstBaseSrc * basesrc); static gboolean gst_basesrc_get_size (GstBaseSrc * basesrc, guint64 * size); @@ -158,9 +160,7 @@ 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_query2_function (pad, gst_basesrc_query2); + gst_pad_set_query_function (pad, gst_basesrc_query); gst_pad_set_checkgetrange_function (pad, gst_basesrc_check_get_range); @@ -193,7 +193,7 @@ gst_basesrc_set_dataflow_funcs (GstBaseSrc * this) } static gboolean -gst_basesrc_query2 (GstPad * pad, GstQuery * query) +gst_basesrc_query (GstPad * pad, GstQuery * query) { gboolean b; guint64 ui64; @@ -207,7 +207,7 @@ gst_basesrc_query2 (GstPad * pad, GstQuery * query) { GstFormat format; - gst_query_parse_position_query (query, &format); + gst_query_parse_position (query, &format, NULL, NULL); switch (format) { case GST_FORMAT_DEFAULT: case GST_FORMAT_BYTES: @@ -243,10 +243,11 @@ gst_basesrc_query2 (GstPad * pad, GstQuery * query) case GST_QUERY_RATE: case GST_QUERY_CONVERT: default: - return gst_pad_query2_default (pad, query); + return gst_pad_query_default (pad, query); } } +#if 0 static const GstEventMask * gst_basesrc_get_event_mask (GstPad * pad) { @@ -260,6 +261,7 @@ gst_basesrc_get_event_mask (GstPad * pad) }; return masks; } +#endif static gboolean gst_basesrc_do_seek (GstBaseSrc * src, GstEvent * event) diff --git a/plugins/elements/gstfilesink.c b/plugins/elements/gstfilesink.c index c0da0e3632..cc44e970fa 100644 --- a/plugins/elements/gstfilesink.c +++ b/plugins/elements/gstfilesink.c @@ -80,7 +80,7 @@ static gboolean gst_filesink_event (GstBaseSink * sink, GstEvent * event); static GstFlowReturn gst_filesink_render (GstBaseSink * sink, GstBuffer * buffer); -static gboolean gst_filesink_query2 (GstPad * pad, GstQuery * query); +static gboolean gst_filesink_query (GstPad * pad, GstQuery * query); static void gst_filesink_uri_handler_init (gpointer g_iface, gpointer iface_data); @@ -144,7 +144,7 @@ gst_filesink_init (GstFileSink * filesink) pad = GST_BASESINK_PAD (filesink); - gst_pad_set_query2_function (pad, gst_filesink_query2); + gst_pad_set_query_function (pad, gst_filesink_query); filesink->filename = NULL; filesink->file = NULL; @@ -255,7 +255,7 @@ gst_filesink_close_file (GstFileSink * sink) } static gboolean -gst_filesink_query2 (GstPad * pad, GstQuery * query) +gst_filesink_query (GstPad * pad, GstQuery * query) { GstFileSink *self; GstFormat format; @@ -264,7 +264,7 @@ gst_filesink_query2 (GstPad * pad, GstQuery * query) switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: - gst_query_parse_position_query (query, &format); + gst_query_parse_position (query, &format, NULL, NULL); switch (format) { case GST_FORMAT_DEFAULT: case GST_FORMAT_BYTES: @@ -280,7 +280,7 @@ gst_filesink_query2 (GstPad * pad, GstQuery * query) return TRUE; default: - return gst_pad_query2_default (pad, query); + return gst_pad_query_default (pad, query); } } diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index 0596538c09..aa2b905d99 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -133,8 +133,7 @@ static void gst_queue_loop (GstPad * pad); static gboolean gst_queue_handle_sink_event (GstPad * pad, GstEvent * event); static gboolean gst_queue_handle_src_event (GstPad * pad, GstEvent * event); -static gboolean gst_queue_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * fmt, gint64 * value); +static gboolean gst_queue_handle_src_query (GstPad * pad, GstQuery * query); static GstCaps *gst_queue_getcaps (GstPad * pad); static GstPadLinkReturn gst_queue_link_sink (GstPad * pad, GstPad * peer); @@ -811,29 +810,42 @@ gst_queue_handle_src_event (GstPad * pad, GstEvent * event) } static gboolean -gst_queue_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * fmt, gint64 * value) +gst_queue_handle_src_query (GstPad * pad, GstQuery * query) { GstQueue *queue = GST_QUEUE (GST_PAD_PARENT (pad)); if (!GST_PAD_PEER (queue->sinkpad)) return FALSE; - if (!gst_pad_query (GST_PAD_PEER (queue->sinkpad), type, fmt, value)) + if (!gst_pad_query (GST_PAD_PEER (queue->sinkpad), query)) return FALSE; - if (type == GST_QUERY_POSITION) { - /* FIXME: this code assumes that there's no discont in the queue */ - switch (*fmt) { - case GST_FORMAT_BYTES: - *value -= queue->cur_level.bytes; - break; - case GST_FORMAT_TIME: - *value -= queue->cur_level.time; - break; - default: - /* FIXME */ - break; + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_POSITION: + { + gint64 peer_pos, peer_total; + GstFormat format; + + /* get peer position */ + gst_query_parse_position (query, &format, &peer_pos, &peer_total); + + /* FIXME: this code assumes that there's no discont in the queue */ + switch (format) { + case GST_FORMAT_BYTES: + peer_pos -= queue->cur_level.bytes; + break; + case GST_FORMAT_TIME: + peer_pos -= queue->cur_level.time; + break; + default: + /* FIXME */ + break; + } + /* set updated positions */ + gst_query_set_position (query, format, peer_pos, peer_total); + break; } + default: + break; } return TRUE; diff --git a/plugins/elements/gsttypefindelement.c b/plugins/elements/gsttypefindelement.c index 994e04f951..5aeece8250 100644 --- a/plugins/elements/gsttypefindelement.c +++ b/plugins/elements/gsttypefindelement.c @@ -115,11 +115,13 @@ static void gst_type_find_element_set_property (GObject * object, static void gst_type_find_element_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +#if 0 static const GstEventMask *gst_type_find_element_src_event_mask (GstPad * pad); +#endif + static gboolean gst_type_find_element_src_event (GstPad * pad, GstEvent * event); -static gboolean gst_type_find_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * fmt, gint64 * value); +static gboolean gst_type_find_handle_src_query (GstPad * pad, GstQuery * query); static GstFlowReturn push_buffer_store (GstTypeFindElement * typefind); static gboolean gst_type_find_element_handle_event (GstPad * pad, @@ -219,8 +221,6 @@ gst_type_find_element_init (GstTypeFindElement * typefind) gst_type_find_element_checkgetrange); gst_pad_set_getrange_function (typefind->src, gst_type_find_element_getrange); gst_pad_set_event_function (typefind->src, gst_type_find_element_src_event); - gst_pad_set_event_mask_function (typefind->src, - gst_type_find_element_src_event_mask); gst_pad_set_query_function (typefind->src, GST_DEBUG_FUNCPTR (gst_type_find_handle_src_query)); gst_pad_use_fixed_caps (typefind->src); @@ -295,32 +295,48 @@ gst_type_find_element_get_property (GObject * object, guint prop_id, } static gboolean -gst_type_find_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * fmt, gint64 * value) +gst_type_find_handle_src_query (GstPad * pad, GstQuery * query) { - GstTypeFindElement *typefind = - GST_TYPE_FIND_ELEMENT (gst_pad_get_parent (pad)); + GstTypeFindElement *typefind; gboolean res; - res = gst_pad_query (GST_PAD_PEER (typefind->sink), type, fmt, value); + typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); + + res = gst_pad_query (GST_PAD_PEER (typefind->sink), query); if (!res) return FALSE; - if (type == GST_QUERY_POSITION && typefind->store != NULL) { - /* FIXME: this code assumes that there's no discont in the queue */ - switch (*fmt) { - case GST_FORMAT_BYTES: - *value -= gst_buffer_store_get_size (typefind->store, 0); - break; - default: - /* FIXME */ - break; + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_POSITION: + { + gint64 peer_pos, peer_total; + GstFormat format; + + if (typefind->store == NULL) + return TRUE; + + gst_query_parse_position (query, &format, &peer_pos, &peer_total); + + /* FIXME: this code assumes that there's no discont in the queue */ + switch (format) { + case GST_FORMAT_BYTES: + peer_pos -= gst_buffer_store_get_size (typefind->store, 0); + break; + default: + /* FIXME */ + break; + } + gst_query_set_position (query, format, peer_pos, peer_total); + break; } + default: + break; } return TRUE; } +#if 0 static const GstEventMask * gst_type_find_element_src_event_mask (GstPad * pad) { @@ -334,6 +350,7 @@ gst_type_find_element_src_event_mask (GstPad * pad) return mask; } +#endif static gboolean gst_type_find_element_src_event (GstPad * pad, GstEvent * event) @@ -462,24 +479,29 @@ find_element_get_length (gpointer data) return 0; } if (entry->self->stream_length == 0) { - typefind->stream_length_available = - gst_pad_query (GST_PAD_PEER (entry->self->sink), GST_QUERY_TOTAL, - &format, (gint64 *) & entry->self->stream_length); - if (format != GST_FORMAT_BYTES) + if (!gst_pad_query_position (GST_PAD_PEER (entry->self->sink), &format, + NULL, (gint64 *) & entry->self->stream_length)) + goto no_length; + + if (format != GST_FORMAT_BYTES) { typefind->stream_length_available = FALSE; - if (!typefind->stream_length_available) { - GST_DEBUG_OBJECT (entry->self, - "'%s' called get_length () but it's not available", - GST_PLUGIN_FEATURE_NAME (entry->factory)); - return 0; + entry->self->stream_length = 0; } else { GST_DEBUG_OBJECT (entry->self, "'%s' called get_length () and it's %" G_GUINT64_FORMAT " bytes", GST_PLUGIN_FEATURE_NAME (entry->factory), entry->self->stream_length); } } - return entry->self->stream_length; + +no_length: + { + typefind->stream_length_available = FALSE; + GST_DEBUG_OBJECT (entry->self, + "'%s' called get_length () but it's not available", + GST_PLUGIN_FEATURE_NAME (entry->factory)); + return 0; + } } static gboolean diff --git a/tools/gst-inspect.c b/tools/gst-inspect.c index 67b25d6069..e0aca2efd9 100644 --- a/tools/gst-inspect.c +++ b/tools/gst-inspect.c @@ -87,6 +87,7 @@ print_caps (const GstCaps * caps, const gchar * pfx) } } +#if 0 static void print_formats (const GstFormat * formats) { @@ -103,6 +104,7 @@ print_formats (const GstFormat * formats) formats++; } } +#endif static void print_query_types (const GstQueryType * types) @@ -122,6 +124,7 @@ print_query_types (const GstQueryType * types) } #ifndef GST_DISABLE_ENUMTYPES +#if 0 static void print_event_masks (const GstEventMask * masks) { @@ -169,6 +172,7 @@ print_event_masks (const GstEventMask * masks) masks++; } } +#endif #else static void print_event_masks (const GstEventMask * masks) @@ -631,20 +635,9 @@ print_pad_info (GstElement * element) if (realpad->getrangefunc) n_print (" Has getrangefunc(): %s\n", GST_DEBUG_FUNCPTR_NAME (realpad->getrangefunc)); - if (realpad->formatsfunc != gst_pad_get_formats_default) { - n_print (" Supports seeking/conversion/query formats:\n"); - print_formats (gst_pad_get_formats (GST_PAD (realpad))); - } - if (realpad->convertfunc != gst_pad_convert_default) - n_print (" Has custom convertfunc(): %s\n", - GST_DEBUG_FUNCPTR_NAME (realpad->convertfunc)); if (realpad->eventfunc != gst_pad_event_default) n_print (" Has custom eventfunc(): %s\n", GST_DEBUG_FUNCPTR_NAME (realpad->eventfunc)); - if (realpad->eventmaskfunc != gst_pad_get_event_masks_default) { - n_print (" Provides event masks:\n"); - print_event_masks (gst_pad_get_event_masks (GST_PAD (realpad))); - } if (realpad->queryfunc != gst_pad_query_default) n_print (" Has custom queryfunc(): %s\n", GST_DEBUG_FUNCPTR_NAME (realpad->queryfunc)); diff --git a/tools/gst-xmlinspect.c b/tools/gst-xmlinspect.c index fd478a6dad..2548437f47 100644 --- a/tools/gst-xmlinspect.c +++ b/tools/gst-xmlinspect.c @@ -73,6 +73,7 @@ print_caps (const GstCaps * caps, gint pfx) g_free (s); } +#if 0 static void print_formats (const GstFormat * formats, gint pfx) { @@ -89,6 +90,7 @@ print_formats (const GstFormat * formats, gint pfx) formats++; } } +#endif static void print_query_types (const GstQueryType * types, gint pfx) @@ -107,6 +109,7 @@ print_query_types (const GstQueryType * types, gint pfx) } } +#if 0 static void print_event_masks (const GstEventMask * masks, gint pfx) { @@ -156,6 +159,7 @@ print_event_masks (const GstEventMask * masks, gint pfx) } #endif } +#endif static void output_hierarchy (GType type, gint level, gint * maxlevel) @@ -606,24 +610,9 @@ print_element_info (GstElementFactory * factory) if (realpad->getrangefunc) PUT_STRING (4, "", GST_DEBUG_FUNCPTR_NAME (realpad->getrangefunc)); - if (realpad->formatsfunc != gst_pad_get_formats_default) { - PUT_STRING (4, "", - GST_DEBUG_FUNCPTR_NAME (realpad->formatsfunc)); - print_formats (gst_pad_get_formats (GST_PAD (realpad)), 5); - PUT_END_TAG (4, "formats-function"); - } - if (realpad->convertfunc != gst_pad_convert_default) - PUT_STRING (4, "", - GST_DEBUG_FUNCPTR_NAME (realpad->convertfunc)); if (realpad->eventfunc != gst_pad_event_default) PUT_STRING (4, "", GST_DEBUG_FUNCPTR_NAME (realpad->eventfunc)); - if (realpad->eventmaskfunc != gst_pad_get_event_masks_default) { - PUT_STRING (4, "", - GST_DEBUG_FUNCPTR_NAME (realpad->eventmaskfunc)); - print_event_masks (gst_pad_get_event_masks (GST_PAD (realpad)), 5); - PUT_END_TAG (4, "event-mask-func"); - } if (realpad->queryfunc != gst_pad_query_default) PUT_STRING (4, "", GST_DEBUG_FUNCPTR_NAME (realpad->queryfunc));