plugins/elements/gstfilesink.*: Check if we can seek in the file instead of assuming we always can. Post an error whe...
Original commit message from CVS:
* plugins/elements/gstfilesink.c: (gst_file_sink_open_file),
(gst_file_sink_close_file), (gst_file_sink_do_seek),
(gst_file_sink_event), (gst_file_sink_render):
* plugins/elements/gstfilesink.h:
Check if we can seek in the file instead of assuming
we always can. Post an error when we are asked to seek in a
non-seekable file (like a fifo). Fixes #343312.
Some cleanups.
diff --git a/ChangeLog b/ChangeLog
index d3af572..2f25b64 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-06-16 Wim Taymans <wim@fluendo.com>
+
+ * plugins/elements/gstfilesink.c: (gst_file_sink_open_file),
+ (gst_file_sink_close_file), (gst_file_sink_do_seek),
+ (gst_file_sink_event), (gst_file_sink_render):
+ * plugins/elements/gstfilesink.h:
+ Check if we can seek in the file instead of assuming
+ we always can. Post an error when we are asked to seek in a
+ non-seekable file (like a fifo). Fixes #343312.
+ Some cleanups.
+
2006-06-16 Tim-Philipp Müller <tim at centricular dot net>
* tools/gst-launch.1.in:
diff --git a/plugins/elements/gstfilesink.c b/plugins/elements/gstfilesink.c
index fd9f484..ec00670 100644
--- a/plugins/elements/gstfilesink.c
+++ b/plugins/elements/gstfilesink.c
@@ -1,6 +1,7 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wtay@chello.be>
+ * 2006 Wim Taymans <wim@fluendo.com>
*
* gstfilesink.c:
*
@@ -80,6 +81,9 @@
static GstFlowReturn gst_file_sink_render (GstBaseSink * sink,
GstBuffer * buffer);
+static gboolean gst_file_sink_do_seek (GstFileSink * filesink,
+ guint64 new_offset);
+
static gboolean gst_file_sink_query (GstPad * pad, GstQuery * query);
static void gst_file_sink_uri_handler_init (gpointer g_iface,
@@ -225,33 +229,55 @@
gst_file_sink_open_file (GstFileSink * sink)
{
/* open the file */
- if (sink->filename == NULL || sink->filename[0] == '\0') {
+ if (sink->filename == NULL || sink->filename[0] == '\0')
+ goto no_filename;
+
+ sink->file = fopen (sink->filename, "wb");
+ if (sink->file == NULL)
+ goto open_failed;
+
+ sink->data_written = 0;
+ /* try to seek in the file to figure out if it is seekable */
+ sink->seekable = gst_file_sink_do_seek (sink, 0);
+
+ GST_DEBUG_OBJECT (sink, "opened file %s, seekable %d",
+ sink->filename, sink->seekable);
+
+ return TRUE;
+
+ /* ERRORS */
+no_filename:
+ {
GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
(_("No file name specified for writing.")), (NULL));
return FALSE;
}
-
- sink->file = fopen (sink->filename, "wb");
- if (sink->file == NULL) {
+open_failed:
+ {
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
(_("Could not open file \"%s\" for writing."), sink->filename),
GST_ERROR_SYSTEM);
return FALSE;
}
-
- sink->data_written = 0;
-
- return TRUE;
}
static void
gst_file_sink_close_file (GstFileSink * sink)
{
if (sink->file) {
- if (fclose (sink->file) != 0) {
- GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE,
- (_("Error closing file \"%s\"."), sink->filename), GST_ERROR_SYSTEM);
- }
+ if (fclose (sink->file) != 0)
+ goto close_failed;
+
+ GST_DEBUG_OBJECT (sink, "closed file");
+ }
+ return;
+
+ /* ERRORS */
+close_failed:
+ {
+ GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE,
+ (_("Error closing file \"%s\"."), sink->filename), GST_ERROR_SYSTEM);
+ return;
}
}
@@ -292,7 +318,7 @@
# define __GST_STDIO_SEEK_FUNCTION "fseek"
#endif
-static void
+static gboolean
gst_file_sink_do_seek (GstFileSink * filesink, guint64 new_offset)
{
GST_DEBUG_OBJECT (filesink, "Seeking to offset %" G_GUINT64_FORMAT
@@ -313,18 +339,18 @@
goto seek_failed;
#endif
- return;
+ return TRUE;
/* ERRORS */
flush_failed:
{
GST_DEBUG_OBJECT (filesink, "Flush failed: %s", g_strerror (errno));
- return;
+ return FALSE;
}
seek_failed:
{
GST_DEBUG_OBJECT (filesink, "Seeking failed: %s", g_strerror (errno));
- return;
+ return FALSE;
}
}
@@ -349,24 +375,39 @@
&eoffset, NULL);
if (format == GST_FORMAT_BYTES) {
- gst_file_sink_do_seek (filesink, (guint64) soffset);
+ if (!gst_file_sink_do_seek (filesink, (guint64) soffset))
+ goto seek_failed;
} else {
- GST_DEBUG ("Ignored NEWSEGMENT event of format %u", (guint) format);
+ GST_DEBUG ("Ignored NEWSEGMENT event of format %u (%s)",
+ (guint) format, gst_format_get_name (format));
}
break;
}
case GST_EVENT_EOS:
- if (fflush (filesink->file)) {
- GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE,
- (_("Error while writing to file \"%s\"."), filesink->filename),
- GST_ERROR_SYSTEM);
- }
+ if (fflush (filesink->file))
+ goto flush_failed;
break;
default:
break;
}
return TRUE;
+
+ /* ERRORS */
+seek_failed:
+ {
+ GST_ELEMENT_ERROR (filesink, RESOURCE, SEEK,
+ (_("Error while seeking in file \"%s\"."), filesink->filename),
+ GST_ERROR_SYSTEM);
+ return FALSE;
+ }
+flush_failed:
+ {
+ GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE,
+ (_("Error while writing to file \"%s\"."), filesink->filename),
+ GST_ERROR_SYSTEM);
+ return FALSE;
+ }
}
static gboolean
@@ -403,8 +444,12 @@
filesink = GST_FILE_SINK (sink);
- if (!gst_file_sink_get_current_offset (filesink, &cur_pos))
- goto handle_error;
+ if (filesink->seekable) {
+ if (!gst_file_sink_get_current_offset (filesink, &cur_pos))
+ goto handle_error;
+ } else {
+ cur_pos = filesink->data_written;
+ }
if (cur_pos < filesink->data_written)
back_pending = filesink->data_written - cur_pos;
diff --git a/plugins/elements/gstfilesink.h b/plugins/elements/gstfilesink.h
index 9a462ae..052afa5 100644
--- a/plugins/elements/gstfilesink.h
+++ b/plugins/elements/gstfilesink.h
@@ -56,6 +56,7 @@
gchar *uri;
FILE *file;
+ gboolean seekable;
guint64 data_written;
};