diff --git a/ChangeLog b/ChangeLog index a935a50a75..9e1ccf0f0f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2008-12-20 Sebastian Dröge + + * docs/gst/gstreamer-sections.txt: + * gst/gstquark.c: + * gst/gstquark.h: + * gst/gstquery.c: (gst_query_new_uri), (gst_query_set_uri), + (gst_query_parse_uri): + * gst/gstquery.h: + API: Add URI query type. This is useful to query the URI + of a sink/source element and can be used by demuxers that + need to get data from other files. + This query should go upstream by default. + Fixes bug #562949. + * plugins/elements/gstfdsink.c: (gst_fd_sink_query): + * plugins/elements/gstfdsrc.c: (gst_fd_src_class_init), + (gst_fd_src_query): + * plugins/elements/gstfilesink.c: (gst_file_sink_query): + * plugins/elements/gstfilesrc.c: (gst_file_src_class_init), + (gst_file_src_query): + Implement URI query. + 2008-12-19 Alessandro Decina * gst/gstghostpad.c: diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index b6eeec1d38..5dc1b4750c 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -1802,6 +1802,9 @@ gst_query_parse_buffering_stats gst_query_set_buffering_range gst_query_parse_buffering_range +gst_query_new_uri +gst_query_parse_uri +gst_query_set_uri GstQueryClass GST_QUERY diff --git a/gst/gstquark.c b/gst/gstquark.c index 0b40364805..9e2887d78d 100644 --- a/gst/gstquark.c +++ b/gst/gstquark.c @@ -37,7 +37,7 @@ static const gchar *_quark_strings[] = { "max-latency", "busy", "type", "owner", "update", "applied-rate", "start", "stop", "minsize", "maxsize", "async", "proportion", "diff", "timestamp", "flags", "cur-type", "cur", "stop-type", - "latency" + "latency", "uri" }; GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/gst/gstquark.h b/gst/gstquark.h index 10b0a443b4..b4e78e8289 100644 --- a/gst/gstquark.h +++ b/gst/gstquark.h @@ -77,8 +77,9 @@ typedef enum _GstQuarkId GST_QUARK_CUR = 48, GST_QUARK_STOP_TYPE = 49, GST_QUARK_LATENCY = 50, + GST_QUARK_URI = 51, - GST_QUARK_MAX = 51 + GST_QUARK_MAX = 52 } GstQuarkId; extern GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/gst/gstquery.c b/gst/gstquery.c index 3e6bad4e79..6539544969 100644 --- a/gst/gstquery.c +++ b/gst/gstquery.c @@ -65,6 +65,7 @@ #include "gstvalue.h" #include "gstenumtypes.h" #include "gstquark.h" +#include "gsturi.h" GST_DEBUG_CATEGORY_STATIC (gst_query_debug); #define GST_CAT_DEFAULT gst_query_debug @@ -93,6 +94,7 @@ static GstQueryTypeDefinition standard_definitions[] = { {GST_QUERY_FORMATS, "formats", "Supported formats for conversion", 0}, {GST_QUERY_BUFFERING, "buffering", "Buffering status", 0}, {GST_QUERY_CUSTOM, "custom", "Custom query", 0}, + {GST_QUERY_URI, "uri", "URI of the source or sink", 0}, {0, NULL, NULL, 0} }; @@ -1308,3 +1310,73 @@ gst_query_parse_buffering_range (GstQuery * query, GstFormat * format, g_value_get_int64 (gst_structure_id_get_value (structure, GST_QUARK (ESTIMATED_TOTAL))); } + +/** + * gst_query_new_uri: + * + * Constructs a new query URI query object. Use gst_query_unref() + * when done with it. An URI query is used to query the current URI + * that is used by the source or sink. + * + * Returns: A #GstQuery + * + * Since: 0.10.22 + */ +GstQuery * +gst_query_new_uri (void) +{ + GstQuery *query; + GstStructure *structure; + + structure = gst_structure_empty_new ("GstQueryURI"); + gst_structure_id_set (structure, GST_QUARK (URI), G_TYPE_STRING, NULL, NULL); + + query = gst_query_new (GST_QUERY_URI, structure); + + return query; +} + +/** + * gst_query_set_uri: + * @query: a #GstQuery with query type GST_QUERY_URI + * @uri: the URI to set + * + * Answer a URI query by setting the requested URI. + * + * Since: 0.10.22 + */ +void +gst_query_set_uri (GstQuery * query, const gchar * uri) +{ + GstStructure *structure; + + g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI); + g_return_if_fail (gst_uri_is_valid (uri)); + + structure = gst_query_get_structure (query); + gst_structure_id_set (structure, GST_QUARK (URI), G_TYPE_STRING, uri, NULL); +} + +/** + * gst_query_parse_uri: + * @query: a #GstQuery + * @uri: the storage for the current URI (may be NULL) + * + * Parse an URI query, writing the URI into @uri as a newly + * allocated string, if the respective parameters are non-NULL. + * Free the string with g_free() after usage. + * + * Since: 0.10.22 + */ +void +gst_query_parse_uri (GstQuery * query, gchar ** uri) +{ + GstStructure *structure; + + g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI); + + structure = gst_query_get_structure (query); + if (uri) + *uri = g_value_dup_string (gst_structure_id_get_value (structure, + GST_QUARK (URI))); +} diff --git a/gst/gstquery.h b/gst/gstquery.h index 77416330af..cd942342bf 100644 --- a/gst/gstquery.h +++ b/gst/gstquery.h @@ -50,6 +50,7 @@ G_BEGIN_DECLS * 0.10.20. * @GST_QUERY_CUSTOM: a custom application or element defined query. Since * 0.10.22. + * @GST_QUERY_URI: query the URI of the source or sink. Since 0.10.22. * * Standard predefined Query types */ @@ -67,7 +68,8 @@ typedef enum { GST_QUERY_CONVERT, GST_QUERY_FORMATS, GST_QUERY_BUFFERING, - GST_QUERY_CUSTOM + GST_QUERY_CUSTOM, + GST_QUERY_URI } GstQueryType; /** @@ -285,6 +287,10 @@ void gst_query_set_buffering_range (GstQuery *query, GstFormat fo void gst_query_parse_buffering_range (GstQuery *query, GstFormat *format, gint64 *start, gint64 *stop, gint64 *estimated_total); +/* URI query */ +GstQuery * gst_query_new_uri (void); +void gst_query_parse_uri (GstQuery *query, gchar **uri); +void gst_query_set_uri (GstQuery *query, const gchar *uri); G_END_DECLS diff --git a/plugins/elements/gstfdsink.c b/plugins/elements/gstfdsink.c index b11198fa95..203afa0176 100644 --- a/plugins/elements/gstfdsink.c +++ b/plugins/elements/gstfdsink.c @@ -202,6 +202,10 @@ gst_fd_sink_query (GstPad * pad, GstQuery * query) gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES); return TRUE; + case GST_QUERY_URI: + gst_query_set_uri (query, fdsink->uri); + return TRUE; + default: return gst_pad_query_default (pad, query); } @@ -495,6 +499,7 @@ gst_fd_sink_uri_get_type (void) { return GST_URI_SINK; } + static gchar ** gst_fd_sink_uri_get_protocols (void) { @@ -502,6 +507,7 @@ gst_fd_sink_uri_get_protocols (void) return protocols; } + static const gchar * gst_fd_sink_uri_get_uri (GstURIHandler * handler) { diff --git a/plugins/elements/gstfdsrc.c b/plugins/elements/gstfdsrc.c index 33fb5fdff2..9820cd7ef9 100644 --- a/plugins/elements/gstfdsrc.c +++ b/plugins/elements/gstfdsrc.c @@ -130,6 +130,7 @@ static gboolean gst_fd_src_unlock_stop (GstBaseSrc * bsrc); static gboolean gst_fd_src_is_seekable (GstBaseSrc * bsrc); static gboolean gst_fd_src_get_size (GstBaseSrc * src, guint64 * size); static gboolean gst_fd_src_do_seek (GstBaseSrc * src, GstSegment * segment); +static gboolean gst_fd_src_query (GstBaseSrc * src, GstQuery * query); static GstFlowReturn gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf); @@ -188,6 +189,7 @@ gst_fd_src_class_init (GstFdSrcClass * klass) gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_fd_src_is_seekable); gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_fd_src_get_size); gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_fd_src_do_seek); + gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_fd_src_query); gstpush_src_class->create = GST_DEBUG_FUNCPTR (gst_fd_src_create); } @@ -492,6 +494,28 @@ read_error: } } +static gboolean +gst_fd_src_query (GstBaseSrc * basesrc, GstQuery * query) +{ + gboolean ret = FALSE; + GstFdSrc *src = GST_FD_SRC (basesrc); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_URI: + gst_query_set_uri (query, src->uri); + ret = TRUE; + break; + default: + ret = FALSE; + break; + } + + if (!ret) + ret = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query); + + return ret; +} + static gboolean gst_fd_src_is_seekable (GstBaseSrc * bsrc) { diff --git a/plugins/elements/gstfilesink.c b/plugins/elements/gstfilesink.c index c32dcfa8d1..92abe6e7f2 100644 --- a/plugins/elements/gstfilesink.c +++ b/plugins/elements/gstfilesink.c @@ -247,6 +247,7 @@ was_open: return FALSE; } } + static void gst_file_sink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -409,6 +410,10 @@ gst_file_sink_query (GstPad * pad, GstQuery * query) gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES); return TRUE; + case GST_QUERY_URI: + gst_query_set_uri (query, self->uri); + return TRUE; + default: return gst_pad_query_default (pad, query); } @@ -613,6 +618,7 @@ gst_file_sink_uri_get_type (void) { return GST_URI_SINK; } + static gchar ** gst_file_sink_uri_get_protocols (void) { @@ -620,6 +626,7 @@ gst_file_sink_uri_get_protocols (void) return protocols; } + static const gchar * gst_file_sink_uri_get_uri (GstURIHandler * handler) { diff --git a/plugins/elements/gstfilesrc.c b/plugins/elements/gstfilesrc.c index 2d2ec410ac..964b60599a 100644 --- a/plugins/elements/gstfilesrc.c +++ b/plugins/elements/gstfilesrc.c @@ -193,6 +193,7 @@ static gboolean gst_file_src_is_seekable (GstBaseSrc * src); static gboolean gst_file_src_get_size (GstBaseSrc * src, guint64 * size); static GstFlowReturn gst_file_src_create (GstBaseSrc * src, guint64 offset, guint length, GstBuffer ** buffer); +static gboolean gst_file_src_query (GstBaseSrc * src, GstQuery * query); static void gst_file_src_uri_handler_init (gpointer g_iface, gpointer iface_data); @@ -293,6 +294,7 @@ gst_file_src_class_init (GstFileSrcClass * klass) gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_file_src_is_seekable); gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_file_src_get_size); gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_file_src_create); + gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_file_src_query); if (sizeof (off_t) < 8) { GST_LOG ("No large file support, sizeof (off_t) = %" G_GSIZE_FORMAT "!", @@ -902,6 +904,28 @@ gst_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint length, return ret; } +static gboolean +gst_file_src_query (GstBaseSrc * basesrc, GstQuery * query) +{ + gboolean ret = FALSE; + GstFileSrc *src = GST_FILE_SRC (basesrc); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_URI: + gst_query_set_uri (query, src->uri); + ret = TRUE; + break; + default: + ret = FALSE; + break; + } + + if (!ret) + ret = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query); + + return ret; +} + static gboolean gst_file_src_is_seekable (GstBaseSrc * basesrc) {