summaryrefslogtreecommitdiff
path: root/ext/gnomevfs/gstgnomevfssink.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/gnomevfs/gstgnomevfssink.c')
-rw-r--r--ext/gnomevfs/gstgnomevfssink.c632
1 files changed, 0 insertions, 632 deletions
diff --git a/ext/gnomevfs/gstgnomevfssink.c b/ext/gnomevfs/gstgnomevfssink.c
deleted file mode 100644
index 431c9fda..00000000
--- a/ext/gnomevfs/gstgnomevfssink.c
+++ /dev/null
@@ -1,632 +0,0 @@
-/* GStreamer
- * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
- * 2000 Wim Taymans <wtay@chello.be>
- * 2001 Bastien Nocera <hadess@hadess.net>
- * 2003 Colin Walters <walters@verbum.org>
- * 2005 Tim-Philipp Müller <tim centricular net>
- *
- * gstgnomevfssink.c:
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-gnomevfssink
- * @see_also: #GstFileSink, #GstGnomeVFSSrc
- *
- * This plugin writes incoming data to a local or remote location specified
- * by an URI. This location can be specified using any protocol supported by
- * the GnomeVFS library. Common protocols are 'file', 'ftp', or 'smb'.
- *
- * Applications can connect to the #GstGnomeVFSSink::allow-overwrite signal to
- * receive a callback when an existing file will be overwritten. The return
- * value of the signal will determine if gnomevfssink will overwrite the
- * resource or abort with an error.
- *
- * <refsect2>
- * <title>Example launch lines</title>
- * |[
- * gst-launch -v filesrc location=input.xyz ! gnomevfssink location=file:///home/joe/out.xyz
- * ]| The above pipeline will simply copy a local file. Instead of gnomevfssink,
- * we could just as well have used the filesink element here.
- * |[
- * gst-launch -v filesrc location=foo.mp3 ! mad ! flacenc ! gnomevfssink location=smb://othercomputer/foo.flac
- * ]| The above pipeline will re-encode an mp3 file into FLAC format and store
- * it on a remote host using the Samba protocol.
- * </refsect2>
- *
- * Last reviewed on 2006-02-28 (0.10.4)
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gstgnomevfssink.h"
-
-#include "gst/gst-i18n-plugin.h"
-
-#include <gst/gst.h>
-#include <libgnomevfs/gnome-vfs.h>
-#include <string.h>
-#include <errno.h>
-
-static const GstElementDetails gst_gnome_vfs_sink_details =
-GST_ELEMENT_DETAILS ("GnomeVFS Sink",
- "Sink/File",
- "Write a stream to a GnomeVFS URI",
- "Bastien Nocera <hadess@hadess.net>");
-
-enum
-{
- SIGNAL_ERASE_ASK,
- LAST_SIGNAL
-};
-
-enum
-{
- ARG_0,
- ARG_LOCATION,
- ARG_URI,
- ARG_HANDLE
-};
-
-static void gst_gnome_vfs_sink_finalize (GObject * obj);
-
-static void gst_gnome_vfs_sink_uri_handler_init (gpointer g_iface,
- gpointer iface_data);
-
-static void gst_gnome_vfs_sink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_gnome_vfs_sink_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static gboolean gst_gnome_vfs_sink_open_file (GstGnomeVFSSink * sink);
-static void gst_gnome_vfs_sink_close_file (GstGnomeVFSSink * sink);
-static gboolean gst_gnome_vfs_sink_start (GstBaseSink * basesink);
-static gboolean gst_gnome_vfs_sink_stop (GstBaseSink * basesink);
-static GstFlowReturn gst_gnome_vfs_sink_render (GstBaseSink * basesink,
- GstBuffer * buffer);
-static gboolean gst_gnome_vfs_sink_handle_event (GstBaseSink * basesink,
- GstEvent * event);
-static gboolean gst_gnome_vfs_sink_query (GstPad * pad, GstQuery * query);
-
-static guint gst_gnome_vfs_sink_signals[LAST_SIGNAL]; /* all 0 */
-
-static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS_ANY);
-
-GST_DEBUG_CATEGORY_STATIC (gst_gnome_vfs_sink_debug);
-#define GST_CAT_DEFAULT gst_gnome_vfs_sink_debug
-
-static void
-gst_gnome_vfs_sink_do_init (GType type)
-{
- static const GInterfaceInfo urihandler_info = {
- gst_gnome_vfs_sink_uri_handler_init,
- NULL,
- NULL
- };
-
- g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info);
-
- GST_DEBUG_CATEGORY_INIT (gst_gnome_vfs_sink_debug, "gnomevfssink", 0,
- "Gnome VFS sink element");
-}
-
-GST_BOILERPLATE_FULL (GstGnomeVFSSink, gst_gnome_vfs_sink, GstBaseSink,
- GST_TYPE_BASE_SINK, gst_gnome_vfs_sink_do_init);
-
-static void
-gst_gnome_vfs_sink_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sinktemplate));
-
- gst_element_class_set_details (element_class, &gst_gnome_vfs_sink_details);
-}
-
-static gboolean
-_gst_boolean_allow_overwrite_accumulator (GSignalInvocationHint * ihint,
- GValue * return_accu, const GValue * handler_return, gpointer dummy)
-{
- gboolean allow_overwrite;
-
- allow_overwrite = g_value_get_boolean (handler_return);
- if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
- g_value_set_boolean (return_accu, allow_overwrite);
-
- /* stop emission if signal doesn't allow overwriting */
- return allow_overwrite;
-}
-
-static void
-gst_gnome_vfs_sink_class_init (GstGnomeVFSSinkClass * klass)
-{
- GstBaseSinkClass *basesink_class;
- GObjectClass *gobject_class;
-
- gobject_class = (GObjectClass *) klass;
- basesink_class = (GstBaseSinkClass *) klass;
-
- gobject_class->set_property = gst_gnome_vfs_sink_set_property;
- gobject_class->get_property = gst_gnome_vfs_sink_get_property;
- gobject_class->finalize = gst_gnome_vfs_sink_finalize;
-
- g_object_class_install_property (gobject_class, ARG_LOCATION,
- g_param_spec_string ("location", "File Location",
- "Location of the file to write", NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, ARG_URI,
- g_param_spec_boxed ("uri", "GnomeVFSURI", "URI for GnomeVFS",
- GST_TYPE_GNOME_VFS_URI, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, ARG_HANDLE,
- g_param_spec_boxed ("handle", "GnomeVFSHandle", "Handle for GnomeVFS",
- GST_TYPE_GNOME_VFS_HANDLE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * GstGnomeVFSSink::allow-overwrite
- * @sink: the object which received the signal
- * @uri: the URI to be overwritten
- *
- * This signal is fired when gnomevfssink is about to overwrite an
- * existing resource. The application can connect to this signal and ask
- * the user if the resource may be overwritten.
- *
- * Returns: A boolean indicating that the resource may be overwritten.
- */
- gst_gnome_vfs_sink_signals[SIGNAL_ERASE_ASK] =
- g_signal_new ("allow-overwrite", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_CLEANUP, G_STRUCT_OFFSET (GstGnomeVFSSinkClass, erase_ask),
- _gst_boolean_allow_overwrite_accumulator, NULL,
- gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, GST_TYPE_GNOME_VFS_URI);
-
- basesink_class->stop = GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_stop);
- basesink_class->start = GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_start);
- basesink_class->event = GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_handle_event);
- basesink_class->render = GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_render);
- basesink_class->get_times = NULL;
-}
-
-static void
-gst_gnome_vfs_sink_finalize (GObject * obj)
-{
- GstGnomeVFSSink *sink = GST_GNOME_VFS_SINK (obj);
-
- if (sink->uri) {
- gnome_vfs_uri_unref (sink->uri);
- sink->uri = NULL;
- }
-
- if (sink->uri_name) {
- g_free (sink->uri_name);
- sink->uri_name = NULL;
- }
-
- G_OBJECT_CLASS (parent_class)->finalize (obj);
-}
-
-static void
-gst_gnome_vfs_sink_init (GstGnomeVFSSink * sink, GstGnomeVFSSinkClass * klass)
-{
- gst_pad_set_query_function (GST_BASE_SINK_PAD (sink),
- GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_query));
-
- sink->uri = NULL;
- sink->uri_name = NULL;
- sink->handle = NULL;
- sink->own_handle = FALSE;
- sink->current_pos = 0;
-
- GST_BASE_SINK (sink)->sync = FALSE;
-}
-
-static void
-gst_gnome_vfs_sink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstGnomeVFSSink *sink;
- GstState cur_state;
-
- sink = GST_GNOME_VFS_SINK (object);
-
- gst_element_get_state (GST_ELEMENT (sink), &cur_state, NULL, 0);
-
- if (cur_state == GST_STATE_PLAYING || cur_state == GST_STATE_PAUSED) {
- GST_WARNING_OBJECT (sink, "cannot set property when PAUSED or PLAYING");
- return;
- }
-
- GST_OBJECT_LOCK (sink);
-
- switch (prop_id) {
- case ARG_LOCATION:{
- const gchar *new_location;
-
- if (sink->uri) {
- gnome_vfs_uri_unref (sink->uri);
- sink->uri = NULL;
- }
- if (sink->uri_name) {
- g_free (sink->uri_name);
- sink->uri_name = NULL;
- }
-
- new_location = g_value_get_string (value);
- if (new_location) {
- sink->uri_name = gst_gnome_vfs_location_to_uri_string (new_location);
- sink->uri = gnome_vfs_uri_new (sink->uri_name);
- }
- break;
- }
- case ARG_URI:{
- if (sink->uri) {
- gnome_vfs_uri_unref (sink->uri);
- sink->uri = NULL;
- }
- if (sink->uri_name) {
- g_free (sink->uri_name);
- sink->uri_name = NULL;
- }
- if (g_value_get_boxed (value)) {
- sink->uri = (GnomeVFSURI *) g_value_dup_boxed (value);
- sink->uri_name = gnome_vfs_uri_to_string (sink->uri, 0);
- }
- break;
- }
- case ARG_HANDLE:{
- if (sink->uri) {
- gnome_vfs_uri_unref (sink->uri);
- sink->uri = NULL;
- }
- if (sink->uri_name) {
- g_free (sink->uri_name);
- sink->uri_name = NULL;
- }
- sink->handle = g_value_get_boxed (value);
- break;
- }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-
- GST_OBJECT_UNLOCK (sink);
-}
-
-static void
-gst_gnome_vfs_sink_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstGnomeVFSSink *sink;
-
- sink = GST_GNOME_VFS_SINK (object);
-
- GST_OBJECT_LOCK (sink);
-
- switch (prop_id) {
- case ARG_LOCATION:
- g_value_set_string (value, sink->uri_name);
- break;
- case ARG_URI:
- g_value_set_boxed (value, sink->uri);
- break;
- case ARG_HANDLE:
- g_value_set_boxed (value, sink->handle);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-
- GST_OBJECT_UNLOCK (sink);
-}
-
-static gboolean
-gst_gnome_vfs_sink_open_file (GstGnomeVFSSink * sink)
-{
- GnomeVFSResult result;
-
- if (sink->uri) {
- /* open the file, all permissions, umask will apply */
- result = gnome_vfs_create_uri (&(sink->handle), sink->uri,
- GNOME_VFS_OPEN_WRITE, TRUE,
- GNOME_VFS_PERM_USER_READ | GNOME_VFS_PERM_USER_WRITE |
- GNOME_VFS_PERM_GROUP_READ | GNOME_VFS_PERM_GROUP_WRITE |
- GNOME_VFS_PERM_OTHER_READ | GNOME_VFS_PERM_OTHER_WRITE);
-
- /* if the file existed and the property says to ask, then ask! */
- if (result == GNOME_VFS_ERROR_FILE_EXISTS) {
- gboolean erase_anyway = FALSE;
-
- g_signal_emit (G_OBJECT (sink),
- gst_gnome_vfs_sink_signals[SIGNAL_ERASE_ASK], 0, sink->uri,
- &erase_anyway);
- if (erase_anyway) {
- result = gnome_vfs_create_uri (&(sink->handle), sink->uri,
- GNOME_VFS_OPEN_WRITE, FALSE,
- GNOME_VFS_PERM_USER_READ | GNOME_VFS_PERM_USER_WRITE |
- GNOME_VFS_PERM_GROUP_READ | GNOME_VFS_PERM_GROUP_WRITE |
- GNOME_VFS_PERM_OTHER_READ | GNOME_VFS_PERM_OTHER_WRITE);
- }
- }
-
- GST_DEBUG_OBJECT (sink, "open: %s", gnome_vfs_result_to_string (result));
-
- if (result != GNOME_VFS_OK) {
- gchar *filename = gnome_vfs_uri_to_string (sink->uri,
- GNOME_VFS_URI_HIDE_PASSWORD);
-
- GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
- (_("Could not open vfs file \"%s\" for writing: %s."),
- filename, gnome_vfs_result_to_string (result)), GST_ERROR_SYSTEM);
- g_free (filename);
- return FALSE;
- }
- sink->own_handle = TRUE;
- } else if (!sink->handle) {
- GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, (_("No filename given")),
- (NULL));
- return FALSE;
- } else {
- sink->own_handle = FALSE;
- }
-
- sink->current_pos = 0;
-
- return TRUE;
-}
-
-static void
-gst_gnome_vfs_sink_close_file (GstGnomeVFSSink * sink)
-{
- GnomeVFSResult result;
-
- if (sink->own_handle) {
- /* close the file */
- result = gnome_vfs_close (sink->handle);
-
- if (result != GNOME_VFS_OK) {
- gchar *filename = gnome_vfs_uri_to_string (sink->uri,
- GNOME_VFS_URI_HIDE_PASSWORD);
-
- GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE,
- (_("Could not close vfs file \"%s\"."), filename), GST_ERROR_SYSTEM);
- g_free (filename);
- }
-
- sink->own_handle = FALSE;
- sink->handle = NULL;
- }
-}
-
-static gboolean
-gst_gnome_vfs_sink_start (GstBaseSink * basesink)
-{
- gboolean ret;
-
- ret = gst_gnome_vfs_sink_open_file (GST_GNOME_VFS_SINK (basesink));
-
- return ret;
-}
-
-static gboolean
-gst_gnome_vfs_sink_stop (GstBaseSink * basesink)
-{
- GST_DEBUG_OBJECT (basesink, "closing ...");
- gst_gnome_vfs_sink_close_file (GST_GNOME_VFS_SINK (basesink));
- return TRUE;
-}
-
-static gboolean
-gst_gnome_vfs_sink_handle_event (GstBaseSink * basesink, GstEvent * event)
-{
- GstGnomeVFSSink *sink;
- gboolean ret = TRUE;
-
- sink = GST_GNOME_VFS_SINK (basesink);
-
- GST_DEBUG_OBJECT (sink, "processing %s event", GST_EVENT_TYPE_NAME (event));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:{
- GnomeVFSResult res;
- 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;
- }
-
- GST_LOG_OBJECT (sink, "seeking to offset %" G_GINT64_FORMAT, offset);
- res = gnome_vfs_seek (sink->handle, GNOME_VFS_SEEK_START, offset);
-
- if (res != GNOME_VFS_OK) {
- GST_ERROR_OBJECT (sink, "Failed to seek to offset %"
- G_GINT64_FORMAT ": %s", offset, gnome_vfs_result_to_string (res));
- ret = FALSE;
- } else {
- sink->current_pos = offset;
- }
-
- break;
- }
-
- case GST_EVENT_FLUSH_START:
- case GST_EVENT_EOS:{
- /* No need to flush with GnomeVfs */
- break;
- }
- default:
- break;
- }
-
- return ret;
-}
-
-static gboolean
-gst_gnome_vfs_sink_query (GstPad * pad, GstQuery * query)
-{
- GstGnomeVFSSink *sink;
- GstFormat format;
-
- sink = GST_GNOME_VFS_SINK (GST_PAD_PARENT (pad));
-
- switch (GST_QUERY_TYPE (query)) {
- case GST_QUERY_POSITION:
- gst_query_parse_position (query, &format, NULL);
- switch (format) {
- case GST_FORMAT_DEFAULT:
- case GST_FORMAT_BYTES:
- gst_query_set_position (query, GST_FORMAT_BYTES, sink->current_pos);
- return TRUE;
- default:
- return FALSE;
- }
-
- case GST_QUERY_FORMATS:
- gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES);
- return TRUE;
-
- case GST_QUERY_URI:
- gst_query_set_uri (query, sink->uri_name);
- return TRUE;
-
- default:
- return gst_pad_query_default (pad, query);
- }
-}
-
-static GstFlowReturn
-gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
-{
- GnomeVFSFileSize written, cur_pos;
- GstGnomeVFSSink *sink;
- GnomeVFSResult result;
- GstFlowReturn ret;
-
- sink = GST_GNOME_VFS_SINK (basesink);
-
- if (gnome_vfs_tell (sink->handle, &cur_pos) == GNOME_VFS_OK) {
- /* bring up to date with current position for proper reporting */
- sink->current_pos = cur_pos;
- }
-
- result = gnome_vfs_write (sink->handle, GST_BUFFER_DATA (buf),
- GST_BUFFER_SIZE (buf), &written);
-
- switch (result) {
- case GNOME_VFS_OK:{
- GST_DEBUG_OBJECT (sink, "wrote %" G_GINT64_FORMAT " bytes at %"
- G_GINT64_FORMAT, (gint64) written, (gint64) cur_pos);
-
- if (written < GST_BUFFER_SIZE (buf)) {
- /* FIXME: what to do here? (tpm) */
- g_warning ("%s: %d bytes should be written, only %"
- G_GUINT64_FORMAT " bytes written", G_STRLOC,
- GST_BUFFER_SIZE (buf), written);
- }
-
- sink->current_pos += GST_BUFFER_SIZE (buf);
- ret = GST_FLOW_OK;
- break;
- }
- case GNOME_VFS_ERROR_NO_SPACE:{
- /* TODO: emit signal/send msg on out-of-diskspace and
- * handle this gracefully (see open bug) (tpm) */
- GST_ELEMENT_ERROR (sink, RESOURCE, NO_SPACE_LEFT, (NULL),
- ("bufsize=%u, written=%u", GST_BUFFER_SIZE (buf), (guint) written));
- ret = GST_FLOW_ERROR;
- break;
- }
- default:{
- gchar *filename = gnome_vfs_uri_to_string (sink->uri,
- GNOME_VFS_URI_HIDE_PASSWORD);
-
- GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
- (_("Error while writing to file \"%s\"."), filename),
- ("%s, bufsize=%u, written=%u", gnome_vfs_result_to_string (result),
- GST_BUFFER_SIZE (buf), (guint) written));
-
- g_free (filename);
- ret = GST_FLOW_ERROR;
- break;
- }
- }
-
- return GST_FLOW_OK;
-}
-
-/*** GSTURIHANDLER INTERFACE *************************************************/
-
-static GstURIType
-gst_gnome_vfs_sink_uri_get_type (void)
-{
- return GST_URI_SINK;
-}
-
-static gchar **
-gst_gnome_vfs_sink_uri_get_protocols (void)
-{
- return gst_gnomevfs_get_supported_uris ();
-}
-
-static const gchar *
-gst_gnome_vfs_sink_uri_get_uri (GstURIHandler * handler)
-{
- GstGnomeVFSSink *sink = GST_GNOME_VFS_SINK (handler);
-
- return sink->uri_name;
-}
-
-static gboolean
-gst_gnome_vfs_sink_uri_set_uri (GstURIHandler * handler, const gchar * uri)
-{
- GstGnomeVFSSink *sink = GST_GNOME_VFS_SINK (handler);
- GstState cur_state;
-
- gst_element_get_state (GST_ELEMENT (sink), &cur_state, NULL, 0);
-
- if (cur_state == GST_STATE_PLAYING || cur_state == GST_STATE_PAUSED) {
- GST_WARNING_OBJECT (sink, "cannot set uri when PAUSED or PLAYING");
- return FALSE;
- }
-
- g_object_set (sink, "location", uri, NULL);
-
- return TRUE;
-}
-
-static void
-gst_gnome_vfs_sink_uri_handler_init (gpointer g_iface, gpointer iface_data)
-{
- GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
-
- iface->get_type = gst_gnome_vfs_sink_uri_get_type;
- iface->get_protocols = gst_gnome_vfs_sink_uri_get_protocols;
- iface->get_uri = gst_gnome_vfs_sink_uri_get_uri;
- iface->set_uri = gst_gnome_vfs_sink_uri_set_uri;
-}