diff options
Diffstat (limited to 'ext/gio/gstgiosrc.c')
-rw-r--r-- | ext/gio/gstgiosrc.c | 217 |
1 files changed, 13 insertions, 204 deletions
diff --git a/ext/gio/gstgiosrc.c b/ext/gio/gstgiosrc.c index e984e143..ee336f03 100644 --- a/ext/gio/gstgiosrc.c +++ b/ext/gio/gstgiosrc.c @@ -1,6 +1,7 @@ /* GStreamer * * Copyright (C) 2007 Rene Stadler <mail@renestadler.de> + * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -46,13 +47,8 @@ enum ARG_LOCATION }; -static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -GST_BOILERPLATE_FULL (GstGioSrc, gst_gio_src, GstBaseSrc, GST_TYPE_BASE_SRC, - gst_gio_uri_handler_do_init); +GST_BOILERPLATE_FULL (GstGioSrc, gst_gio_src, GstGioBaseSrc, + GST_TYPE_GIO_BASE_SRC, gst_gio_uri_handler_do_init); static void gst_gio_src_finalize (GObject * object); static void gst_gio_src_set_property (GObject * object, guint prop_id, @@ -60,14 +56,6 @@ 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 gboolean gst_gio_src_stop (GstBaseSrc * base_src); -static gboolean gst_gio_src_get_size (GstBaseSrc * base_src, guint64 * size); -static gboolean gst_gio_src_is_seekable (GstBaseSrc * base_src); -static gboolean gst_gio_src_unlock (GstBaseSrc * base_src); -static gboolean gst_gio_src_unlock_stop (GstBaseSrc * base_src); -static gboolean gst_gio_src_check_get_range (GstBaseSrc * base_src); -static GstFlowReturn gst_gio_src_create (GstBaseSrc * base_src, guint64 offset, - guint size, GstBuffer ** buf); static void gst_gio_src_base_init (gpointer gclass) @@ -76,14 +64,13 @@ gst_gio_src_base_init (gpointer gclass) "GIO source", "Source/File", "Read from any GIO-supported location", - "Ren\xc3\xa9 Stadler <mail@renestadler.de>" + "Ren\xc3\xa9 Stadler <mail@renestadler.de>, " + "Sebastian Dröge <slomo@circular-chaos.org>" }; GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - GST_DEBUG_CATEGORY_INIT (gst_gio_src_debug, "giosrc", 0, "GIO source"); + GST_DEBUG_CATEGORY_INIT (gst_gio_src_debug, "gio_src", 0, "GIO source"); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_factory)); gst_element_class_set_details (element_class, &element_details); } @@ -107,20 +94,11 @@ gst_gio_src_class_init (GstGioSrcClass * klass) NULL, G_PARAM_READWRITE)); gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_gio_src_start); - gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_gio_src_stop); - gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_gio_src_get_size); - gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_gio_src_is_seekable); - gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_gio_src_unlock); - gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_gio_src_unlock_stop); - gstbasesrc_class->check_get_range = - GST_DEBUG_FUNCPTR (gst_gio_src_check_get_range); - gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_gio_src_create); } static void gst_gio_src_init (GstGioSrc * src, GstGioSrcClass * gclass) { - src->cancel = g_cancellable_new (); } static void @@ -128,16 +106,6 @@ gst_gio_src_finalize (GObject * object) { GstGioSrc *src = GST_GIO_SRC (object); - if (src->cancel) { - g_object_unref (src->cancel); - src->cancel = NULL; - } - - if (src->stream) { - g_object_unref (src->stream); - src->stream = NULL; - } - if (src->location) { g_free (src->location); src->location = NULL; @@ -189,6 +157,8 @@ 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; if (src->location == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("No location given")); @@ -203,11 +173,11 @@ gst_gio_src_start (GstBaseSrc * base_src) return FALSE; } - src->stream = g_file_read (file, src->cancel, &err); + stream = G_INPUT_STREAM (g_file_read (file, cancel, &err)); g_object_unref (file); - if (src->stream == NULL && !gst_gio_error (src, "g_file_read", &err, NULL)) { + 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), @@ -222,174 +192,13 @@ gst_gio_src_start (GstBaseSrc * base_src) return FALSE; - } else if (src->stream == NULL) { + } else if (stream == NULL) { return FALSE; } - src->position = 0; + gst_gio_base_src_set_stream (GST_GIO_BASE_SRC (src), stream); GST_DEBUG_OBJECT (src, "opened location %s", src->location); - return TRUE; -} - -static gboolean -gst_gio_src_stop (GstBaseSrc * base_src) -{ - GstGioSrc *src = GST_GIO_SRC (base_src); - gboolean success = TRUE; - GError *err = NULL; - - if (src->stream != NULL) { - /* FIXME: In case that the call below would block, there is no one to - * trigger the cancellation! */ - - success = g_input_stream_close (G_INPUT_STREAM (src->stream), src->cancel, - &err); - - if (!success && !gst_gio_error (src, "g_input_stream_close", &err, NULL)) { - GST_ELEMENT_ERROR (src, RESOURCE, CLOSE, (NULL), - ("g_input_stream_close failed: %s", err->message)); - g_clear_error (&err); - } - - g_object_unref (src->stream); - src->stream = NULL; - } - - GST_DEBUG_OBJECT (src, "closed location %s", src->location); - - return success; -} - -static gboolean -gst_gio_src_get_size (GstBaseSrc * base_src, guint64 * size) -{ - GstGioSrc *src = GST_GIO_SRC (base_src); - GFileInfo *info; - GError *err = NULL; - - info = g_file_input_stream_query_info (src->stream, - G_FILE_ATTRIBUTE_STD_SIZE, src->cancel, &err); - - if (info != NULL) { - *size = g_file_info_get_size (info); - g_object_unref (info); - GST_DEBUG_OBJECT (src, "found size: %" G_GUINT64_FORMAT, *size); - return TRUE; - } - - if (!gst_gio_error (src, "g_file_input_stream_query_info", &err, NULL)) { - - if (GST_GIO_ERROR_MATCHES (err, NOT_SUPPORTED)) - GST_DEBUG_OBJECT (src, "size information not available"); - else - GST_WARNING_OBJECT (src, "size information retrieval failed: %s", - err->message); - - g_clear_error (&err); - } - - return FALSE; -} - -static gboolean -gst_gio_src_is_seekable (GstBaseSrc * base_src) -{ - GstGioSrc *src = GST_GIO_SRC (base_src); - gboolean seekable; - - seekable = g_seekable_can_seek (G_SEEKABLE (src->stream)); - - GST_DEBUG_OBJECT (src, "can seek: %d", seekable); - - return seekable; -} - -static gboolean -gst_gio_src_unlock (GstBaseSrc * base_src) -{ - GstGioSrc *src = GST_GIO_SRC (base_src); - - GST_LOG_OBJECT (src, "triggering cancellation"); - - g_cancellable_cancel (src->cancel); - - return TRUE; -} - -static gboolean -gst_gio_src_unlock_stop (GstBaseSrc * base_src) -{ - GstGioSrc *src = GST_GIO_SRC (base_src); - - GST_LOG_OBJECT (src, "resetting cancellable"); - - g_cancellable_reset (src->cancel); - - return TRUE; -} - -static gboolean -gst_gio_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); -} - -static GstFlowReturn -gst_gio_src_create (GstBaseSrc * base_src, guint64 offset, guint size, - GstBuffer ** buf_return) -{ - GstGioSrc *src = GST_GIO_SRC (base_src); - GstBuffer *buf; - gssize read; - gboolean success, eos; - GstFlowReturn ret = GST_FLOW_OK; - GError *err = NULL; - - if (G_UNLIKELY (offset != src->position)) { - - ret = gst_gio_seek (src, G_SEEKABLE (src->stream), offset, src->cancel); - - if (ret == GST_FLOW_OK) - src->position = offset; - else - return ret; - } - - buf = gst_buffer_new_and_alloc (size); - - GST_LOG_OBJECT (src, "reading %u bytes from offset %" G_GUINT64_FORMAT, - size, offset); - - read = - g_input_stream_read (G_INPUT_STREAM (src->stream), GST_BUFFER_DATA (buf), - size, src->cancel, &err); - - success = (read >= 0); - eos = (size > 0 && read == 0); - - if (!success && !gst_gio_error (src, "g_input_stream_read", &err, &ret)) { - GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), - ("Could not read from location %s: %s", src->location, err->message)); - g_clear_error (&err); - } - - if (success && !eos) { - src->position += read; - GST_BUFFER_OFFSET (buf) = offset; - GST_BUFFER_SIZE (buf) = read; - *buf_return = buf; - } else { - /* !success || eos */ - gst_buffer_unref (buf); - } - - if (eos) - ret = GST_FLOW_UNEXPECTED; - - return ret; + return GST_BASE_SRC_CLASS (parent_class)->start (base_src); } |