From 9f83e90909dbe45ef5fc5839b08c09501d28177e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 20 Apr 2008 10:11:54 +0000 Subject: [PATCH] ext/gio/gstgio.c: Don't generate a new supported protocols list on each call but cache it. It's supposed to be static... Original commit message from CVS: * ext/gio/gstgio.c: (_internal_get_supported_protocols), (gst_gio_get_supported_protocols): Don't generate a new supported protocols list on each call but cache it. It's supposed to be static anyway, this way we only leak it once per process. * ext/gio/gstgiosink.c: (gst_gio_sink_base_init), (gst_gio_sink_class_init), (gst_gio_sink_finalize), (gst_gio_sink_set_property), (gst_gio_sink_get_property), (gst_gio_sink_start): * ext/gio/gstgiosink.h: * ext/gio/gstgiosrc.c: (gst_gio_src_base_init), (gst_gio_src_class_init), (gst_gio_src_finalize), (gst_gio_src_set_property), (gst_gio_src_get_property), (gst_gio_src_start): * ext/gio/gstgiosrc.h: API: Add "file" properties where one can set a GFile as source/destination. Add locking to the properties and use gst_element_class_set_details_simple() instead of a static GstElementDetails struct. --- ChangeLog | 23 +++++++++ ext/gio/gstgio.c | 13 +++++- ext/gio/gstgiosink.c | 129 +++++++++++++++++++++++++++++++++++++-------------- ext/gio/gstgiosink.h | 5 +- ext/gio/gstgiosrc.c | 128 ++++++++++++++++++++++++++++++++++++-------------- ext/gio/gstgiosrc.h | 5 +- 6 files changed, 221 insertions(+), 82 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9614a4c..830d129 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2008-04-20 Sebastian Dröge + + * ext/gio/gstgio.c: (_internal_get_supported_protocols), + (gst_gio_get_supported_protocols): + Don't generate a new supported protocols list on each call but cache + it. It's supposed to be static anyway, this way we only leak it once + per process. + + * ext/gio/gstgiosink.c: (gst_gio_sink_base_init), + (gst_gio_sink_class_init), (gst_gio_sink_finalize), + (gst_gio_sink_set_property), (gst_gio_sink_get_property), + (gst_gio_sink_start): + * ext/gio/gstgiosink.h: + * ext/gio/gstgiosrc.c: (gst_gio_src_base_init), + (gst_gio_src_class_init), (gst_gio_src_finalize), + (gst_gio_src_set_property), (gst_gio_src_get_property), + (gst_gio_src_start): + * ext/gio/gstgiosrc.h: + API: Add "file" properties where one can set a GFile as source/destination. + + Add locking to the properties and use gst_element_class_set_details_simple() + instead of a static GstElementDetails struct. + 2008-04-19 Sebastian Dröge * gst/typefind/gsttypefindfunctions.c: (musepack_type_find), diff --git a/ext/gio/gstgio.c b/ext/gio/gstgio.c index 9803d21..f71c263 100644 --- a/ext/gio/gstgio.c +++ b/ext/gio/gstgio.c @@ -93,8 +93,8 @@ gst_gio_seek (gpointer element, GSeekable * stream, guint64 offset, return ret; } -static gchar ** -gst_gio_get_supported_protocols (void) +static gpointer +_internal_get_supported_protocols (gpointer data) { const gchar *const *schemes; gchar **our_schemes; @@ -129,6 +129,15 @@ gst_gio_get_supported_protocols (void) return our_schemes; } +static gchar ** +gst_gio_get_supported_protocols (void) +{ + static GOnce once = G_ONCE_INIT; + + g_once (&once, _internal_get_supported_protocols, NULL); + return (gchar **) once.retval; +} + static GstURIType gst_gio_uri_handler_get_type_sink (void) { diff --git a/ext/gio/gstgiosink.c b/ext/gio/gstgiosink.c index 287756f..9852762 100644 --- a/ext/gio/gstgiosink.c +++ b/ext/gio/gstgiosink.c @@ -84,7 +84,8 @@ enum enum { ARG_0, - ARG_LOCATION + ARG_LOCATION, + ARG_FILE }; GST_BOILERPLATE_FULL (GstGioSink, gst_gio_sink, GstGioBaseSink, @@ -100,18 +101,15 @@ static gboolean gst_gio_sink_start (GstBaseSink * base_sink); static void gst_gio_sink_base_init (gpointer gclass) { - static GstElementDetails element_details = { - "GIO sink", - "Sink/File", - "Write to any GIO-supported location", - "Ren\xc3\xa9 Stadler , " - "Sebastian Dröge " - }; GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); GST_DEBUG_CATEGORY_INIT (gst_gio_sink_debug, "gio_sink", 0, "GIO sink"); - gst_element_class_set_details (element_class, &element_details); + gst_element_class_set_details_simple (element_class, "GIO sink", + "Sink/File", + "Write to any GIO-supported location", + "Ren\xc3\xa9 Stadler , " + "Sebastian Dröge "); } static void @@ -133,6 +131,17 @@ gst_gio_sink_class_init (GstGioSinkClass * klass) g_param_spec_string ("location", "Location", "URI location to write to", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstGioSink:file + * + * %GFile to write to. + * + * Since: 0.10.20 + **/ + g_object_class_install_property (gobject_class, ARG_FILE, + g_param_spec_object ("file", "File", "GFile to write to", + G_TYPE_FILE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_gio_sink_start); } @@ -146,9 +155,9 @@ gst_gio_sink_finalize (GObject * object) { GstGioSink *sink = GST_GIO_SINK (object); - if (sink->location) { - g_free (sink->location); - sink->location = NULL; + if (sink->file) { + g_object_unref (sink->file); + sink->file = NULL; } GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); @@ -161,13 +170,49 @@ gst_gio_sink_set_property (GObject * object, guint prop_id, GstGioSink *sink = GST_GIO_SINK (object); switch (prop_id) { - case ARG_LOCATION: + case ARG_LOCATION:{ + const gchar *uri = NULL; + + if (GST_STATE (sink) == GST_STATE_PLAYING || + GST_STATE (sink) == GST_STATE_PAUSED) { + GST_WARNING + ("Setting a new location or GFile not supported in PLAYING or PAUSED state"); + break; + } + + GST_OBJECT_LOCK (GST_OBJECT (sink)); + if (sink->file) + g_object_unref (sink->file); + + uri = g_value_get_string (value); + + if (uri) { + sink->file = g_file_new_for_uri (uri); + + if (!sink->file) { + GST_ERROR ("Could not create GFile for URI '%s'", uri); + } + } else { + sink->file = NULL; + } + GST_OBJECT_UNLOCK (GST_OBJECT (sink)); + break; + } + case ARG_FILE: if (GST_STATE (sink) == GST_STATE_PLAYING || - GST_STATE (sink) == GST_STATE_PAUSED) + GST_STATE (sink) == GST_STATE_PAUSED) { + GST_WARNING + ("Setting a new location or GFile not supported in PLAYING or PAUSED state"); break; + } - g_free (sink->location); - sink->location = g_strdup (g_value_get_string (value)); + GST_OBJECT_LOCK (GST_OBJECT (sink)); + if (sink->file) + g_object_unref (sink->file); + + sink->file = g_value_dup_object (value); + + GST_OBJECT_UNLOCK (GST_OBJECT (sink)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -182,8 +227,24 @@ gst_gio_sink_get_property (GObject * object, guint prop_id, GstGioSink *sink = GST_GIO_SINK (object); switch (prop_id) { - case ARG_LOCATION: - g_value_set_string (value, sink->location); + case ARG_LOCATION:{ + gchar *uri; + + GST_OBJECT_LOCK (GST_OBJECT (sink)); + if (sink->file) { + uri = g_file_get_uri (sink->file); + g_value_set_string (value, uri); + g_free (uri); + } else { + g_value_set_string (value, NULL); + } + GST_OBJECT_UNLOCK (GST_OBJECT (sink)); + break; + } + case ARG_FILE: + GST_OBJECT_LOCK (GST_OBJECT (sink)); + g_value_set_object (value, sink->file); + GST_OBJECT_UNLOCK (GST_OBJECT (sink)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -195,33 +256,28 @@ static gboolean gst_gio_sink_start (GstBaseSink * base_sink) { GstGioSink *sink = GST_GIO_SINK (base_sink); - GFile *file; GOutputStream *stream; GCancellable *cancel = GST_GIO_BASE_SINK (sink)->cancel; gboolean success; GError *err = NULL; + gchar *uri; - if (sink->location == NULL) { + if (sink->file == NULL) { GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL), - ("No location given")); + ("No location or GFile given")); return FALSE; } - file = g_file_new_for_uri (sink->location); - - if (file == NULL) { - GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL), - ("Malformed URI or protocol not supported (%s)", sink->location)); - return FALSE; - } + uri = g_file_get_uri (sink->file); + if (!uri) + uri = g_strdup ("(null)"); stream = - G_OUTPUT_STREAM (g_file_create (file, G_FILE_CREATE_NONE, cancel, &err)); + G_OUTPUT_STREAM (g_file_create (sink->file, G_FILE_CREATE_NONE, cancel, + &err)); success = (stream != NULL); - g_object_unref (file); - if (!success && !gst_gio_error (sink, "g_file_create", &err, NULL)) { /*if (GST_GIO_ERROR_MATCHES (err, EXISTS)) */ @@ -229,20 +285,21 @@ gst_gio_sink_start (GstBaseSink * base_sink) if (GST_GIO_ERROR_MATCHES (err, NOT_FOUND)) GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND, (NULL), - ("Could not open location %s for writing: %s", - sink->location, err->message)); + ("Could not open location %s for writing: %s", uri, err->message)); else GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_READ, (NULL), - ("Could not open location %s for writing: %s", - sink->location, err->message)); + ("Could not open location %s for writing: %s", uri, err->message)); + g_free (uri); g_clear_error (&err); } if (!success) return FALSE; - GST_DEBUG_OBJECT (sink, "opened location %s", sink->location); + GST_DEBUG_OBJECT (sink, "opened location %s", uri); + + g_free (uri); gst_gio_base_sink_set_stream (GST_GIO_BASE_SINK (sink), stream); diff --git a/ext/gio/gstgiosink.h b/ext/gio/gstgiosink.h index fc2478a..7f4f12f 100644 --- a/ext/gio/gstgiosink.h +++ b/ext/gio/gstgiosink.h @@ -53,10 +53,7 @@ struct _GstGioSink GstGioBaseSink sink; /*< private >*/ - gchar *location; - - GMainLoop *loop; - gboolean mount_successful; + GFile *file; }; struct _GstGioSinkClass diff --git a/ext/gio/gstgiosrc.c b/ext/gio/gstgiosrc.c index b9cd3f9..ed712d7 100644 --- a/ext/gio/gstgiosrc.c +++ b/ext/gio/gstgiosrc.c @@ -79,7 +79,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_gio_src_debug); enum { ARG_0, - ARG_LOCATION + ARG_LOCATION, + ARG_FILE }; GST_BOILERPLATE_FULL (GstGioSrc, gst_gio_src, GstGioBaseSrc, @@ -95,18 +96,15 @@ static gboolean gst_gio_src_start (GstBaseSrc * base_src); static void gst_gio_src_base_init (gpointer gclass) { - static GstElementDetails element_details = { - "GIO source", - "Source/File", - "Read from any GIO-supported location", - "Ren\xc3\xa9 Stadler , " - "Sebastian Dröge " - }; GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); GST_DEBUG_CATEGORY_INIT (gst_gio_src_debug, "gio_src", 0, "GIO source"); - gst_element_class_set_details (element_class, &element_details); + gst_element_class_set_details_simple (element_class, "GIO source", + "Source/File", + "Read from any GIO-supported location", + "Ren\xc3\xa9 Stadler , " + "Sebastian Dröge "); } static void @@ -128,6 +126,17 @@ gst_gio_src_class_init (GstGioSrcClass * klass) g_param_spec_string ("location", "Location", "URI location to read from", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstGioSrc:file + * + * %GFile to read from. + * + * Since: 0.10.20 + **/ + g_object_class_install_property (gobject_class, ARG_FILE, + g_param_spec_object ("file", "File", "GFile to read from", + G_TYPE_FILE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_gio_src_start); } @@ -141,9 +150,9 @@ gst_gio_src_finalize (GObject * object) { GstGioSrc *src = GST_GIO_SRC (object); - if (src->location) { - g_free (src->location); - src->location = NULL; + if (src->file) { + g_object_unref (src->file); + src->file = NULL; } GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); @@ -156,13 +165,49 @@ gst_gio_src_set_property (GObject * object, guint prop_id, GstGioSrc *src = GST_GIO_SRC (object); switch (prop_id) { - case ARG_LOCATION: + case ARG_LOCATION:{ + const gchar *uri = NULL; + if (GST_STATE (src) == GST_STATE_PLAYING || - GST_STATE (src) == GST_STATE_PAUSED) + GST_STATE (src) == GST_STATE_PAUSED) { + GST_WARNING + ("Setting a new location or GFile not supported in PLAYING or PAUSED state"); break; + } + + GST_OBJECT_LOCK (GST_OBJECT (src)); + if (src->file) + g_object_unref (src->file); + + uri = g_value_get_string (value); + + if (uri) { + src->file = g_file_new_for_uri (uri); - g_free (src->location); - src->location = g_strdup (g_value_get_string (value)); + if (!src->file) { + GST_ERROR ("Could not create GFile for URI '%s'", uri); + } + } else { + src->file = NULL; + } + GST_OBJECT_UNLOCK (GST_OBJECT (src)); + break; + } + case ARG_FILE: + if (GST_STATE (src) == GST_STATE_PLAYING || + GST_STATE (src) == GST_STATE_PAUSED) { + GST_WARNING + ("Setting a new location or GFile not supported in PLAYING or PAUSED state"); + break; + } + + GST_OBJECT_LOCK (GST_OBJECT (src)); + if (src->file) + g_object_unref (src->file); + + src->file = g_value_dup_object (value); + + GST_OBJECT_UNLOCK (GST_OBJECT (src)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -177,8 +222,24 @@ gst_gio_src_get_property (GObject * object, guint prop_id, GstGioSrc *src = GST_GIO_SRC (object); switch (prop_id) { - case ARG_LOCATION: - g_value_set_string (value, src->location); + case ARG_LOCATION:{ + gchar *uri; + + GST_OBJECT_LOCK (GST_OBJECT (src)); + if (src->file) { + uri = g_file_get_uri (src->file); + g_value_set_string (value, uri); + g_free (uri); + } else { + g_value_set_string (value, NULL); + } + GST_OBJECT_UNLOCK (GST_OBJECT (src)); + break; + } + case ARG_FILE: + GST_OBJECT_LOCK (GST_OBJECT (src)); + g_value_set_object (value, src->file); + GST_OBJECT_UNLOCK (GST_OBJECT (src)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -190,49 +251,44 @@ static gboolean gst_gio_src_start (GstBaseSrc * base_src) { GstGioSrc *src = GST_GIO_SRC (base_src); - GFile *file; GError *err = NULL; GInputStream *stream; GCancellable *cancel = GST_GIO_BASE_SRC (src)->cancel; + gchar *uri = NULL; - if (src->location == NULL) { - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("No location given")); - return FALSE; - } - - file = g_file_new_for_uri (src->location); - - if (file == NULL) { + if (src->file == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), - ("Malformed URI or protocol not supported (%s)", src->location)); + ("No location or GFile given")); return FALSE; } - stream = G_INPUT_STREAM (g_file_read (file, cancel, &err)); + uri = g_file_get_uri (src->file); + if (!uri) + uri = g_strdup ("(null)"); - g_object_unref (file); + stream = G_INPUT_STREAM (g_file_read (src->file, cancel, &err)); if (stream == NULL && !gst_gio_error (src, "g_file_read", &err, NULL)) { - if (GST_GIO_ERROR_MATCHES (err, NOT_FOUND)) { GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), - ("Could not open location %s for reading: %s", - src->location, err->message)); + ("Could not open location %s for reading: %s", uri, err->message)); } else { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), - ("Could not open location %s for reading: %s", - src->location, err->message)); + ("Could not open location %s for reading: %s", uri, err->message)); } + g_free (uri); g_clear_error (&err); return FALSE; } else if (stream == NULL) { + g_free (uri); return FALSE; } gst_gio_base_src_set_stream (GST_GIO_BASE_SRC (src), stream); - GST_DEBUG_OBJECT (src, "opened location %s", src->location); + GST_DEBUG_OBJECT (src, "opened location %s", uri); + g_free (uri); return GST_BASE_SRC_CLASS (parent_class)->start (base_src); } diff --git a/ext/gio/gstgiosrc.h b/ext/gio/gstgiosrc.h index 92d2b25..f83a99a 100644 --- a/ext/gio/gstgiosrc.h +++ b/ext/gio/gstgiosrc.h @@ -53,10 +53,7 @@ struct _GstGioSrc GstGioBaseSrc src; /*< private >*/ - gchar *location; - - GMainLoop *loop; - gboolean mount_successful; + GFile *file; }; struct _GstGioSrcClass -- 2.7.4