configure.ac: Check for stdio_ext.h for the filesink changes.

Original commit message from CVS:
Based on Patch by: Laurent Glayal <spglegle at yahoo dot fr>
* 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
This commit is contained in:
Laurent Glayal 2007-12-24 19:11:29 +00:00 committed by Wim Taymans
parent 20b951efc1
commit 2f22776f23
4 changed files with 122 additions and 6 deletions

View file

@ -1,3 +1,20 @@
2007-12-24 Wim Taymans <wim.taymans@collabora.co.uk>
Based on Patch by: Laurent Glayal <spglegle at yahoo dot fr>
* 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 <wim.taymans@collabora.co.uk>
* gst/gstsystemclock.c: (gst_system_clock_id_wait_jitter_unlocked):

View file

@ -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 ***

View file

@ -36,6 +36,9 @@
#include <gst/gst.h>
#include <stdio.h> /* for fseeko() */
#ifdef HAVE_STDIO_EXT_H
#include <stdio_ext.h> /* for __fbufsize, for debugging */
#endif
#include <errno.h>
#include "gstfilesink.h"
#include <string.h>
@ -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;

View file

@ -58,6 +58,10 @@ struct _GstFileSink {
gboolean seekable;
guint64 current_pos;
gint buffer_mode;
guint buffer_size;
gchar *buffer;
};
struct _GstFileSinkClass {