diff --git a/ext/gio/gstgiobasesrc.c b/ext/gio/gstgiobasesrc.c
index 3955629fef..8488fc2ede 100644
--- a/ext/gio/gstgiobasesrc.c
+++ b/ext/gio/gstgiobasesrc.c
@@ -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);
-
- if (!G_IS_INPUT_STREAM (src->stream)) {
- GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
- ("No stream given yet"));
- return FALSE;
- }
+ GstGioBaseSrcClass *gbsrc_class = GST_GIO_BASE_SRC_GET_CLASS (src);
src->position = 0;
- GST_DEBUG_OBJECT (src, "started stream");
+ /* 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 input stream provided by subclass"));
+ return FALSE;
+ }
+
+ 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 c09b9cf82b..63e6fd4c14 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 244398b8ac..5b61fcfb5b 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 81f0596d25..219f2696bc 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 2608923bca..b43c0e5de4 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