gio: General clean up and simplification
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 7 Jul 2009 18:18:00 +0000 (20:18 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 7 Jul 2009 18:18:00 +0000 (20:18 +0200)
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
ext/gio/gstgiobasesrc.h
ext/gio/gstgiosrc.c
ext/gio/gstgiostreamsrc.c
ext/gio/gstgiostreamsrc.h

index 3955629..8488fc2 100644 (file)
@@ -25,6 +25,8 @@
 
 #include "gstgiobasesrc.h"
 
+#include <gst/base/gsttypefindhelper.h>
+
 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;
-}
index c09b9cf..63e6fd4 100644 (file)
@@ -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__ */
index 244398b..5b61fcf 100644 (file)
@@ -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;
 }
index 81f0596..219f269 100644 (file)
@@ -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;
+}
index 2608923..b43c0e5 100644 (file)
@@ -51,6 +51,9 @@ typedef struct _GstGioStreamSrcClass GstGioStreamSrcClass;
 struct _GstGioStreamSrc
 {
   GstGioBaseSrc src;
+
+  /* < private > */
+  GInputStream *stream;
 };
 
 struct _GstGioStreamSrcClass