From 2f22776f2381319a78f0dc7c0407c4617fe040ea Mon Sep 17 00:00:00 2001 From: Laurent Glayal Date: Mon, 24 Dec 2007 19:11:29 +0000 Subject: [PATCH] configure.ac: Check for stdio_ext.h for the filesink changes. Original commit message from CVS: Based on Patch by: Laurent Glayal * configure.ac: Check for stdio_ext.h for the filesink changes. * plugins/elements/gstfilesink.c: (buffer_mode_get_type), (gst_file_sink_class_init), (gst_file_sink_init), (gst_file_sink_dispose), (gst_file_sink_set_property), (gst_file_sink_get_property), (gst_file_sink_open_file), (gst_file_sink_close_file): * plugins/elements/gstfilesink.h: Add two properties to control the buffering mode and size. API: GstFileSink::buffer-mode API: GstFileSink::buffer-size --- ChangeLog | 17 +++++++ configure.ac | 3 ++ plugins/elements/gstfilesink.c | 104 ++++++++++++++++++++++++++++++++++++++--- plugins/elements/gstfilesink.h | 4 ++ 4 files changed, 122 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3f245dd..5be4824 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,22 @@ 2007-12-24 Wim Taymans + Based on Patch by: Laurent Glayal + + * configure.ac: + Check for stdio_ext.h for the filesink changes. + + * plugins/elements/gstfilesink.c: (buffer_mode_get_type), + (gst_file_sink_class_init), (gst_file_sink_init), + (gst_file_sink_dispose), (gst_file_sink_set_property), + (gst_file_sink_get_property), (gst_file_sink_open_file), + (gst_file_sink_close_file): + * plugins/elements/gstfilesink.h: + Add two properties to control the buffering mode and size. + API: GstFileSink::buffer-mode + API: GstFileSink::buffer-size + +2007-12-24 Wim Taymans + * gst/gstsystemclock.c: (gst_system_clock_id_wait_jitter_unlocked): Add some more docs to explain why a FIXME was wrongly added. diff --git a/configure.ac b/configure.ac index 97afd7e..c3ae7ce 100644 --- a/configure.ac +++ b/configure.ac @@ -315,6 +315,9 @@ AC_CHECK_HEADERS([process.h]) dnl Check for sys/utsname.h for uname AC_CHECK_HEADERS([sys/utsname.h]) +dnl Check for stdio_ext.f for __fbufsize +AC_CHECK_HEADERS([stdio_ext.h]) + dnl *** checks for types/defines *** dnl *** checks for structures *** diff --git a/plugins/elements/gstfilesink.c b/plugins/elements/gstfilesink.c index 9280657..38c8b40 100644 --- a/plugins/elements/gstfilesink.c +++ b/plugins/elements/gstfilesink.c @@ -36,6 +36,9 @@ #include #include /* for fseeko() */ +#ifdef HAVE_STDIO_EXT_H +#include /* for __fbufsize, for debugging */ +#endif #include #include "gstfilesink.h" #include @@ -50,13 +53,40 @@ static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); +#define GST_TYPE_BUFFER_MODE (buffer_mode_get_type ()) +static GType +buffer_mode_get_type (void) +{ + static GType buffer_mode_type = 0; + static const GEnumValue buffer_mode[] = { + {-1, "Default buffering", "default"}, + {_IOFBF, "Fully buffered", "full"}, + {_IOLBF, "Line buffered", "line"}, + {_IONBF, "Unbuffered", "unbuffered"}, + {0, NULL, NULL}, + }; + + if (!buffer_mode_type) { + buffer_mode_type = + g_enum_register_static ("GstFileSinkBufferMode", buffer_mode); + } + return buffer_mode_type; +} + GST_DEBUG_CATEGORY_STATIC (gst_file_sink_debug); #define GST_CAT_DEFAULT gst_file_sink_debug +#define DEFAULT_LOCATION NULL +#define DEFAULT_BUFFER_MODE -1 +#define DEFAULT_BUFFER_SIZE 64 * 1024 + enum { - ARG_0, - ARG_LOCATION + PROP_0, + PROP_LOCATION, + PROP_BUFFER_MODE, + PROP_BUFFER_SIZE, + PROP_LAST }; static void gst_file_sink_dispose (GObject * object); @@ -122,14 +152,24 @@ gst_file_sink_class_init (GstFileSinkClass * klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GstBaseSinkClass *gstbasesink_class = GST_BASE_SINK_CLASS (klass); + gobject_class->dispose = gst_file_sink_dispose; + gobject_class->set_property = gst_file_sink_set_property; gobject_class->get_property = gst_file_sink_get_property; - g_object_class_install_property (gobject_class, ARG_LOCATION, + g_object_class_install_property (gobject_class, PROP_LOCATION, g_param_spec_string ("location", "File Location", "Location of the file to write", NULL, G_PARAM_READWRITE)); - gobject_class->dispose = gst_file_sink_dispose; + g_object_class_install_property (gobject_class, PROP_BUFFER_MODE, + g_param_spec_enum ("buffer-mode", "Buffering mode", + "The buffering mode to use", GST_TYPE_BUFFER_MODE, + DEFAULT_BUFFER_MODE, G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_BUFFER_SIZE, + g_param_spec_uint ("buffer-size", "Buffering size", + "Size of buffer in number of bytes for line or full buffer-mode", 0, + G_MAXUINT, DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE)); gstbasesink_class->get_times = NULL; gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_file_sink_start); @@ -154,6 +194,9 @@ gst_file_sink_init (GstFileSink * filesink, GstFileSinkClass * g_class) filesink->filename = NULL; filesink->file = NULL; + filesink->buffer_mode = DEFAULT_BUFFER_MODE; + filesink->buffer_size = DEFAULT_BUFFER_SIZE; + filesink->buffer = NULL; gst_base_sink_set_sync (GST_BASE_SINK (filesink), FALSE); } @@ -169,6 +212,9 @@ gst_file_sink_dispose (GObject * object) sink->uri = NULL; g_free (sink->filename); sink->filename = NULL; + g_free (sink->buffer); + sink->buffer = NULL; + sink->buffer_size = 0; } static gboolean @@ -204,9 +250,15 @@ gst_file_sink_set_property (GObject * object, guint prop_id, GstFileSink *sink = GST_FILE_SINK (object); switch (prop_id) { - case ARG_LOCATION: + case PROP_LOCATION: gst_file_sink_set_location (sink, g_value_get_string (value)); break; + case PROP_BUFFER_MODE: + sink->buffer_mode = g_value_get_enum (value); + break; + case PROP_BUFFER_SIZE: + sink->buffer_size = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -220,9 +272,15 @@ gst_file_sink_get_property (GObject * object, guint prop_id, GValue * value, GstFileSink *sink = GST_FILE_SINK (object); switch (prop_id) { - case ARG_LOCATION: + case PROP_LOCATION: g_value_set_string (value, sink->filename); break; + case PROP_BUFFER_MODE: + g_value_set_enum (value, sink->buffer_mode); + break; + case PROP_BUFFER_SIZE: + g_value_set_uint (value, sink->buffer_size); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -232,6 +290,8 @@ gst_file_sink_get_property (GObject * object, guint prop_id, GValue * value, static gboolean gst_file_sink_open_file (GstFileSink * sink) { + gint mode; + /* open the file */ if (sink->filename == NULL || sink->filename[0] == '\0') goto no_filename; @@ -240,6 +300,35 @@ gst_file_sink_open_file (GstFileSink * sink) if (sink->file == NULL) goto open_failed; + /* see if we are asked to perform a specific kind of buffering */ + if ((mode = sink->buffer_mode) != -1) { + size_t buffer_size; + + /* free previous buffer if any */ + g_free (sink->buffer); + + if (mode == _IONBF) { + /* no buffering */ + sink->buffer = NULL; + buffer_size = 0; + } else { + /* allocate buffer */ + sink->buffer = g_malloc (sink->buffer_size); + buffer_size = sink->buffer_size; + } +#ifdef HAVE_STDIO_EXT_H + GST_DEBUG_OBJECT (sink, "change buffer size %d to %d, mode %d", + __fbufsize (sink->file), buffer_size, mode); +#else + GST_DEBUG_OBJECT (sink, "change buffer size to %d, mode %d", + sink->buffer_size, mode); +#endif + if (setvbuf (sink->file, sink->buffer, mode, buffer_size) != 0) { + GST_WARNING_OBJECT (sink, "warning: setvbuf failed: %s", + g_strerror (errno)); + } + } + sink->current_pos = 0; /* try to seek in the file to figure out if it is seekable */ sink->seekable = gst_file_sink_do_seek (sink, 0); @@ -274,6 +363,9 @@ gst_file_sink_close_file (GstFileSink * sink) GST_DEBUG_OBJECT (sink, "closed file"); sink->file = NULL; + + g_free (sink->buffer); + sink->buffer = NULL; } return; diff --git a/plugins/elements/gstfilesink.h b/plugins/elements/gstfilesink.h index 6e509d5..36b0e19 100644 --- a/plugins/elements/gstfilesink.h +++ b/plugins/elements/gstfilesink.h @@ -58,6 +58,10 @@ struct _GstFileSink { gboolean seekable; guint64 current_pos; + + gint buffer_mode; + guint buffer_size; + gchar *buffer; }; struct _GstFileSinkClass { -- 2.7.4