summaryrefslogtreecommitdiffstats
path: root/ext/gio/gstgiosink.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/gio/gstgiosink.c')
-rw-r--r--ext/gio/gstgiosink.c236
1 files changed, 14 insertions, 222 deletions
diff --git a/ext/gio/gstgiosink.c b/ext/gio/gstgiosink.c
index 8929bd9d..ad0433b2 100644
--- a/ext/gio/gstgiosink.c
+++ b/ext/gio/gstgiosink.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
@@ -52,13 +53,8 @@ enum
ARG_LOCATION
};
-static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS_ANY);
-
-GST_BOILERPLATE_FULL (GstGioSink, gst_gio_sink, GstBaseSink, GST_TYPE_BASE_SINK,
- gst_gio_uri_handler_do_init);
+GST_BOILERPLATE_FULL (GstGioSink, gst_gio_sink, GstGioBaseSink,
+ GST_TYPE_GIO_BASE_SINK, gst_gio_uri_handler_do_init);
static void gst_gio_sink_finalize (GObject * object);
static void gst_gio_sink_set_property (GObject * object, guint prop_id,
@@ -66,13 +62,6 @@ static void gst_gio_sink_set_property (GObject * object, guint prop_id,
static void gst_gio_sink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_gio_sink_start (GstBaseSink * base_sink);
-static gboolean gst_gio_sink_stop (GstBaseSink * base_sink);
-static gboolean gst_gio_sink_unlock (GstBaseSink * base_sink);
-static gboolean gst_gio_sink_unlock_stop (GstBaseSink * base_sink);
-static gboolean gst_gio_sink_event (GstBaseSink * base_sink, GstEvent * event);
-static GstFlowReturn gst_gio_sink_render (GstBaseSink * base_sink,
- GstBuffer * buffer);
-static gboolean gst_gio_sink_query (GstPad * pad, GstQuery * query);
static void
gst_gio_sink_base_init (gpointer gclass)
@@ -81,14 +70,13 @@ gst_gio_sink_base_init (gpointer gclass)
"GIO sink",
"Sink/File",
"Write to 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_sink_debug, "giosink", 0, "GIO source");
+ GST_DEBUG_CATEGORY_INIT (gst_gio_sink_debug, "gio_sink", 0, "GIO sink");
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_factory));
gst_element_class_set_details (element_class, &element_details);
}
@@ -112,22 +100,11 @@ gst_gio_sink_class_init (GstGioSinkClass * klass)
NULL, G_PARAM_READWRITE));
gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_gio_sink_start);
- gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_gio_sink_stop);
- gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_gio_sink_unlock);
- gstbasesink_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_gio_sink_unlock_stop);
- gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_gio_sink_event);
- gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_gio_sink_render);
}
static void
gst_gio_sink_init (GstGioSink * sink, GstGioSinkClass * gclass)
{
- gst_pad_set_query_function (GST_BASE_SINK_PAD (sink),
- GST_DEBUG_FUNCPTR (gst_gio_sink_query));
-
- GST_BASE_SINK (sink)->sync = FALSE;
-
- sink->cancel = g_cancellable_new ();
}
static void
@@ -135,16 +112,6 @@ gst_gio_sink_finalize (GObject * object)
{
GstGioSink *sink = GST_GIO_SINK (object);
- if (sink->cancel) {
- g_object_unref (sink->cancel);
- sink->cancel = NULL;
- }
-
- if (sink->stream) {
- g_object_unref (sink->stream);
- sink->stream = NULL;
- }
-
if (sink->location) {
g_free (sink->location);
sink->location = NULL;
@@ -195,6 +162,8 @@ 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;
@@ -212,9 +181,10 @@ gst_gio_sink_start (GstBaseSink * base_sink)
return FALSE;
}
- sink->stream =
- g_file_create (file, G_FILE_CREATE_FLAGS_NONE, sink->cancel, &err);
- success = (sink->stream != NULL);
+ stream =
+ G_OUTPUT_STREAM (g_file_create (file, G_FILE_CREATE_FLAGS_NONE, cancel,
+ &err));
+ success = (stream != NULL);
g_object_unref (file);
@@ -238,187 +208,9 @@ gst_gio_sink_start (GstBaseSink * base_sink)
if (!success)
return FALSE;
- sink->position = 0;
-
GST_DEBUG_OBJECT (sink, "opened location %s", sink->location);
- return TRUE;
-}
-
-static gboolean
-gst_gio_sink_stop (GstBaseSink * base_sink)
-{
- GstGioSink *sink = GST_GIO_SINK (base_sink);
- gboolean success = TRUE;
- GError *err = NULL;
-
- if (sink->stream != NULL) {
- /* FIXME: In case that the call below would block, there is no one to
- * trigger the cancellation! */
+ gst_gio_base_sink_set_stream (GST_GIO_BASE_SINK (sink), stream);
- success = g_output_stream_close (G_OUTPUT_STREAM (sink->stream),
- sink->cancel, &err);
-
- if (success) {
- GST_DEBUG_OBJECT (sink, "closed location %s", sink->location);
- } else if (!gst_gio_error (sink, "g_output_stream_close", &err, NULL)) {
- GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE, (NULL),
- ("g_output_stream_close failed: %s", err->message));
- g_clear_error (&err);
- }
-
- g_object_unref (sink->stream);
- sink->stream = NULL;
- }
-
- return success;
-}
-
-static gboolean
-gst_gio_sink_unlock (GstBaseSink * base_sink)
-{
- GstGioSink *sink = GST_GIO_SINK (base_sink);
-
- GST_LOG_OBJECT (sink, "triggering cancellation");
-
- g_cancellable_cancel (sink->cancel);
-
- return TRUE;
-}
-
-static gboolean
-gst_gio_sink_unlock_stop (GstBaseSink * base_sink)
-{
- GstGioSink *sink = GST_GIO_SINK (base_sink);
-
- GST_LOG_OBJECT (sink, "resetting cancellable");
-
- g_cancellable_reset (sink->cancel);
-
- return TRUE;
-}
-
-static gboolean
-gst_gio_sink_event (GstBaseSink * base_sink, GstEvent * event)
-{
- GstGioSink *sink = GST_GIO_SINK (base_sink);
- GstFlowReturn ret = GST_FLOW_OK;
-
- if (sink->stream == NULL)
- return TRUE;
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
- {
- GstFormat format;
- gint64 offset;
-
- gst_event_parse_new_segment (event, NULL, NULL, &format, &offset, NULL,
- NULL);
-
- if (format != GST_FORMAT_BYTES) {
- GST_WARNING_OBJECT (sink, "ignored NEWSEGMENT event in %s format",
- gst_format_get_name (format));
- break;
- }
-
- ret = gst_gio_seek (sink, G_SEEKABLE (sink->stream), offset,
- sink->cancel);
-
- if (ret == GST_FLOW_OK)
- sink->position = offset;
- }
- break;
-
- case GST_EVENT_EOS:
- case GST_EVENT_FLUSH_START:
- {
- gboolean success;
- GError *err = NULL;
-
- success = g_output_stream_flush (G_OUTPUT_STREAM (sink->stream),
- sink->cancel, &err);
-
- if (!success && !gst_gio_error (sink, "g_output_stream_flush", &err,
- &ret)) {
- GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
- ("flush failed: %s", err->message));
- g_clear_error (&err);
- }
- }
- break;
-
- default:
- break;
- }
-
- return (ret == GST_FLOW_OK);
-}
-
-static GstFlowReturn
-gst_gio_sink_render (GstBaseSink * base_sink, GstBuffer * buffer)
-{
- GstGioSink *sink = GST_GIO_SINK (base_sink);
- gssize written;
- gboolean success;
- GError *err = NULL;
-
- GST_LOG_OBJECT (sink, "writing %u bytes to offset %" G_GUINT64_FORMAT,
- GST_BUFFER_SIZE (buffer), sink->position);
-
- written = g_output_stream_write (G_OUTPUT_STREAM (sink->stream),
- GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), sink->cancel, &err);
-
- success = (written >= 0);
-
- if (G_UNLIKELY (success && written < GST_BUFFER_SIZE (buffer))) {
- /* FIXME: Can this happen? Should we handle it gracefully? gnomevfssink
- * doesn't... */
- GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
- ("Could not write to location %s: (short write, only %"
- G_GUINT64_FORMAT " bytes of %d bytes written)",
- sink->location, written, GST_BUFFER_SIZE (buffer)));
- return GST_FLOW_ERROR;
- }
-
- if (success) {
- sink->position += written;
- return GST_FLOW_OK;
-
- } else {
- GstFlowReturn ret;
-
- if (!gst_gio_error (sink, "g_output_stream_write", &err, &ret)) {
- GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
- ("Could not write to location %s: %s", sink->location, err->message));
- g_clear_error (&err);
- }
-
- return ret;
- }
-}
-
-static gboolean
-gst_gio_sink_query (GstPad * pad, GstQuery * query)
-{
- GstGioSink *sink = GST_GIO_SINK (GST_PAD_PARENT (pad));
- GstFormat format;
-
- switch (GST_QUERY_TYPE (query)) {
- case GST_QUERY_POSITION:
- gst_query_parse_position (query, &format, NULL);
- switch (format) {
- case GST_FORMAT_BYTES:
- case GST_FORMAT_DEFAULT:
- gst_query_set_position (query, GST_FORMAT_BYTES, sink->position);
- return TRUE;
- default:
- return FALSE;
- }
- case GST_QUERY_FORMATS:
- gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES);
- return TRUE;
- default:
- return gst_pad_query_default (pad, query);
- }
+ return GST_BASE_SINK_CLASS (parent_class)->start (base_sink);
}