From 160b70e8418b23730da94919e82ffd44dcab2cd7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 7 Jul 2009 20:18:00 +0200 Subject: [PATCH] gio: General clean up and simplification The GInputStreams are now requested by a vfunc from the subclasses instead of relying that the subclass sets it until it's needed. This might also fix bug #587896. --- ext/gio/gstgiobasesrc.c | 69 +++++++---------------------------------------- ext/gio/gstgiobasesrc.h | 6 +++-- ext/gio/gstgiosrc.c | 33 +++++++++-------------- ext/gio/gstgiostreamsrc.c | 49 ++++++++++++++++++++++----------- ext/gio/gstgiostreamsrc.h | 3 +++ 5 files changed, 64 insertions(+), 96 deletions(-) diff --git a/ext/gio/gstgiobasesrc.c b/ext/gio/gstgiobasesrc.c index 3955629..8488fc2 100644 --- a/ext/gio/gstgiobasesrc.c +++ b/ext/gio/gstgiobasesrc.c @@ -25,6 +25,8 @@ #include "gstgiobasesrc.h" +#include + GST_DEBUG_CATEGORY_STATIC (gst_gio_base_src_debug); #define GST_CAT_DEFAULT gst_gio_base_src_debug @@ -67,9 +69,7 @@ static void gst_gio_base_src_class_init (GstGioBaseSrcClass * klass) { GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseSrcClass *gstbasesrc_class; gobject_class = (GObjectClass *) klass; @@ -125,16 +125,19 @@ static gboolean gst_gio_base_src_start (GstBaseSrc * base_src) { GstGioBaseSrc *src = GST_GIO_BASE_SRC (base_src); + GstGioBaseSrcClass *gbsrc_class = GST_GIO_BASE_SRC_GET_CLASS (src); - if (!G_IS_INPUT_STREAM (src->stream)) { + src->position = 0; + + /* FIXME: This will likely block */ + src->stream = gbsrc_class->get_stream (src); + if (G_UNLIKELY (!G_IS_INPUT_STREAM (src->stream))) { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), - ("No stream given yet")); + ("No input stream provided by subclass")); return FALSE; } - src->position = 0; - - GST_DEBUG_OBJECT (src, "started stream"); + GST_DEBUG_OBJECT (src, "started source"); return TRUE; } @@ -143,9 +146,7 @@ static gboolean gst_gio_base_src_stop (GstBaseSrc * base_src) { GstGioBaseSrc *src = GST_GIO_BASE_SRC (base_src); - gboolean success; - GError *err = NULL; if (G_IS_INPUT_STREAM (src->stream)) { @@ -180,7 +181,6 @@ gst_gio_base_src_get_size (GstBaseSrc * base_src, guint64 * size) if (G_IS_FILE_INPUT_STREAM (src->stream)) { GFileInfo *info; - GError *err = NULL; info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (src->stream), @@ -207,13 +207,9 @@ gst_gio_base_src_get_size (GstBaseSrc * base_src, guint64 * size) if (GST_GIO_STREAM_IS_SEEKABLE (src->stream)) { goffset old; - goffset stream_size; - gboolean ret; - GSeekable *seekable = G_SEEKABLE (src->stream); - GError *err = NULL; old = g_seekable_tell (seekable); @@ -231,7 +227,6 @@ gst_gio_base_src_get_size (GstBaseSrc * base_src, guint64 * size) } else { GST_WARNING_OBJECT (src, "Seeking to end of stream failed"); } - return FALSE; } @@ -249,7 +244,6 @@ gst_gio_base_src_get_size (GstBaseSrc * base_src, guint64 * size) } else { GST_ERROR_OBJECT (src, "Seeking to the old position faile"); } - return FALSE; } @@ -266,7 +260,6 @@ static gboolean gst_gio_base_src_is_seekable (GstBaseSrc * base_src) { GstGioBaseSrc *src = GST_GIO_BASE_SRC (base_src); - gboolean seekable; seekable = GST_GIO_STREAM_IS_SEEKABLE (src->stream); @@ -303,8 +296,6 @@ gst_gio_base_src_unlock_stop (GstBaseSrc * base_src) static gboolean gst_gio_base_src_check_get_range (GstBaseSrc * base_src) { - /* FIXME: Implement dry-run variant using guesswork like gnomevfssrc? */ - return GST_CALL_PARENT_WITH_DEFAULT (GST_BASE_SRC_CLASS, check_get_range, (base_src), FALSE); } @@ -327,7 +318,6 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size, * over DBus if our backend is GVfs and this is painfully slow. */ if (src->cache && offset >= GST_BUFFER_OFFSET (src->cache) && offset + size <= GST_BUFFER_OFFSET_END (src->cache)) { - GST_DEBUG_OBJECT (src, "Creating subbuffer from cached buffer: offset %" G_GUINT64_FORMAT " length %u", offset, size); @@ -339,11 +329,8 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size, GST_BUFFER_SIZE (buf) = size; } else { guint cachesize = MAX (4096, size); - gssize read, res; - gboolean success, eos; - GError *err = NULL; if (src->cache) { @@ -452,39 +439,3 @@ gst_gio_base_src_query (GstBaseSrc * base_src, GstQuery * query) return ret; } - -void -gst_gio_base_src_set_stream (GstGioBaseSrc * src, GInputStream * stream) -{ - gboolean success; - - GError *err = NULL; - - g_return_if_fail (G_IS_INPUT_STREAM (stream)); - g_return_if_fail ((GST_STATE (src) != GST_STATE_PLAYING && - GST_STATE (src) != GST_STATE_PAUSED)); - - if (G_IS_INPUT_STREAM (src->stream)) { - GST_DEBUG_OBJECT (src, "closing old stream"); - - /* FIXME: can block but unfortunately we can't use async operations - * here because they require a running main loop */ - success = g_input_stream_close (src->stream, src->cancel, &err); - - if (!success && !gst_gio_error (src, "g_input_stream_close", &err, NULL)) { - GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL), - ("g_input_stream_close failed: %s", err->message)); - g_clear_error (&err); - } else if (!success) { - GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL), - ("g_input_stream_close failed")); - } else { - GST_DEBUG_OBJECT (src, "g_input_stream_close succeeded"); - } - - g_object_unref (src->stream); - src->stream = NULL; - } - - src->stream = stream; -} diff --git a/ext/gio/gstgiobasesrc.h b/ext/gio/gstgiobasesrc.h index c09b9cf..63e6fd4 100644 --- a/ext/gio/gstgiobasesrc.h +++ b/ext/gio/gstgiobasesrc.h @@ -32,6 +32,8 @@ G_BEGIN_DECLS (gst_gio_base_src_get_type()) #define GST_GIO_BASE_SRC(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GIO_BASE_SRC,GstGioBaseSrc)) +#define GST_GIO_BASE_SRC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_GIO_BASE_SRC, GstGioBaseSrcClass)) #define GST_GIO_BASE_SRC_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GIO_BASE_SRC,GstGioBaseSrcClass)) #define GST_IS_GIO_BASE_SRC(obj) \ @@ -56,12 +58,12 @@ struct _GstGioBaseSrc struct _GstGioBaseSrcClass { GstBaseSrcClass parent_class; + + GInputStream * (*get_stream) (GstGioBaseSrc *bsrc); }; GType gst_gio_base_src_get_type (void); -void gst_gio_base_src_set_stream (GstGioBaseSrc *src, GInputStream *stream); - G_END_DECLS #endif /* __GST_GIO_BASE_SRC_H__ */ diff --git a/ext/gio/gstgiosrc.c b/ext/gio/gstgiosrc.c index 244398b..5b61fcf 100644 --- a/ext/gio/gstgiosrc.c +++ b/ext/gio/gstgiosrc.c @@ -81,7 +81,7 @@ static void gst_gio_src_set_property (GObject * object, guint prop_id, static void gst_gio_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static gboolean gst_gio_src_start (GstBaseSrc * base_src); +static GInputStream *gst_gio_src_get_stream (GstGioBaseSrc * bsrc); static gboolean gst_gio_src_check_get_range (GstBaseSrc * base_src); @@ -103,14 +103,12 @@ static void gst_gio_src_class_init (GstGioSrcClass * klass) { GObjectClass *gobject_class; - - GstElementClass *gstelement_class; - GstBaseSrcClass *gstbasesrc_class; + GstGioBaseSrcClass *gstgiobasesrc_class; gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; gstbasesrc_class = (GstBaseSrcClass *) klass; + gstgiobasesrc_class = (GstGioBaseSrcClass *) klass; gobject_class->finalize = gst_gio_src_finalize; gobject_class->set_property = gst_gio_src_set_property; @@ -131,9 +129,10 @@ gst_gio_src_class_init (GstGioSrcClass * klass) 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); gstbasesrc_class->check_get_range = GST_DEBUG_FUNCPTR (gst_gio_src_check_get_range); + + gstgiobasesrc_class->get_stream = GST_DEBUG_FUNCPTR (gst_gio_src_get_stream); } static void @@ -279,23 +278,19 @@ done: } -static gboolean -gst_gio_src_start (GstBaseSrc * base_src) +static GInputStream * +gst_gio_src_get_stream (GstGioBaseSrc * bsrc) { - GstGioSrc *src = GST_GIO_SRC (base_src); - + GstGioSrc *src = GST_GIO_SRC (bsrc); GError *err = NULL; - GInputStream *stream; - - GCancellable *cancel = GST_GIO_BASE_SRC (src)->cancel; - + GCancellable *cancel = bsrc->cancel; gchar *uri = NULL; if (src->file == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("No location or GFile given")); - return FALSE; + return NULL; } uri = g_file_get_uri (src->file); @@ -315,16 +310,14 @@ gst_gio_src_start (GstBaseSrc * base_src) g_free (uri); g_clear_error (&err); - return FALSE; + return NULL; } else if (stream == NULL) { g_free (uri); - return FALSE; + return NULL; } - gst_gio_base_src_set_stream (GST_GIO_BASE_SRC (src), stream); - GST_DEBUG_OBJECT (src, "opened location %s", uri); g_free (uri); - return GST_BASE_SRC_CLASS (parent_class)->start (base_src); + return stream; } diff --git a/ext/gio/gstgiostreamsrc.c b/ext/gio/gstgiostreamsrc.c index 81f0596..219f269 100644 --- a/ext/gio/gstgiostreamsrc.c +++ b/ext/gio/gstgiostreamsrc.c @@ -73,8 +73,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_gio_stream_src_debug); enum { - ARG_0, - ARG_STREAM + PROP_0, + PROP_STREAM }; GST_BOILERPLATE (GstGioStreamSrc, gst_gio_stream_src, GstGioBaseSrc, @@ -85,6 +85,7 @@ static void gst_gio_stream_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_gio_stream_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +static GInputStream *gst_gio_stream_src_get_stream (GstGioBaseSrc * bsrc); static void gst_gio_stream_src_base_init (gpointer gclass) @@ -107,20 +108,21 @@ static void gst_gio_stream_src_class_init (GstGioStreamSrcClass * klass) { GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseSrcClass *gstbasesrc_class; + GstGioBaseSrcClass *gstgiobasesrc_class; gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasesrc_class = (GstBaseSrcClass *) klass; + gstgiobasesrc_class = (GstGioBaseSrcClass *) klass; gobject_class->finalize = gst_gio_stream_src_finalize; gobject_class->set_property = gst_gio_stream_src_set_property; gobject_class->get_property = gst_gio_stream_src_get_property; - g_object_class_install_property (gobject_class, ARG_STREAM, + g_object_class_install_property (gobject_class, PROP_STREAM, g_param_spec_object ("stream", "Stream", "Stream to read from", G_TYPE_INPUT_STREAM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + gstgiobasesrc_class->get_stream = + GST_DEBUG_FUNCPTR (gst_gio_stream_src_get_stream); } static void @@ -131,6 +133,13 @@ gst_gio_stream_src_init (GstGioStreamSrc * src, GstGioStreamSrcClass * gclass) static void gst_gio_stream_src_finalize (GObject * object) { + GstGioStreamSrc *src = GST_GIO_STREAM_SRC (object); + + if (src->stream) { + g_object_unref (src->stream); + src->stream = NULL; + } + GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); } @@ -141,18 +150,20 @@ gst_gio_stream_src_set_property (GObject * object, guint prop_id, GstGioStreamSrc *src = GST_GIO_STREAM_SRC (object); switch (prop_id) { - case ARG_STREAM:{ + case PROP_STREAM:{ GObject *stream; if (GST_STATE (src) == GST_STATE_PLAYING || - GST_STATE (src) == GST_STATE_PAUSED) + GST_STATE (src) == GST_STATE_PAUSED) { + GST_WARNING + ("Setting a new stream not supported in PLAYING or PAUSED state"); break; + } stream = g_value_dup_object (value); - if (G_IS_INPUT_STREAM (stream)) - gst_gio_base_src_set_stream (GST_GIO_BASE_SRC (src), - G_INPUT_STREAM (stream)); - + if (src->stream) + g_object_unref (src->stream); + src->stream = G_INPUT_STREAM (stream); break; } default: @@ -168,11 +179,19 @@ gst_gio_stream_src_get_property (GObject * object, guint prop_id, GstGioStreamSrc *src = GST_GIO_STREAM_SRC (object); switch (prop_id) { - case ARG_STREAM: - g_value_set_object (value, GST_GIO_BASE_SRC (src)->stream); + case PROP_STREAM: + g_value_set_object (value, src->stream); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } + +static GInputStream * +gst_gio_stream_src_get_stream (GstGioBaseSrc * bsrc) +{ + GstGioStreamSrc *src = GST_GIO_STREAM_SRC (bsrc); + + return (src->stream) ? g_object_ref (src->stream) : NULL; +} diff --git a/ext/gio/gstgiostreamsrc.h b/ext/gio/gstgiostreamsrc.h index 2608923..b43c0e5 100644 --- a/ext/gio/gstgiostreamsrc.h +++ b/ext/gio/gstgiostreamsrc.h @@ -51,6 +51,9 @@ typedef struct _GstGioStreamSrcClass GstGioStreamSrcClass; struct _GstGioStreamSrc { GstGioBaseSrc src; + + /* < private > */ + GInputStream *stream; }; struct _GstGioStreamSrcClass -- 2.7.4