From ade4a83e633cd88d06f986662294985010837eab Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 16 Apr 2015 10:32:02 +1000 Subject: [PATCH] Add GST_BUFFER_FLAG_SYNC_AFTER flag, and implement in filesink. Makes it possible to get filesink to fsync() after rendering a buffer. --- gst/gstbuffer.h | 4 ++++ plugins/elements/gstfilesink.c | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/gst/gstbuffer.h b/gst/gstbuffer.h index dd7f237402..3e4fab9910 100644 --- a/gst/gstbuffer.h +++ b/gst/gstbuffer.h @@ -194,6 +194,9 @@ typedef struct _GstBufferPool GstBufferPool; * @GST_BUFFER_FLAG_DELTA_UNIT: this unit cannot be decoded independently. * @GST_BUFFER_FLAG_TAG_MEMORY: this flag is set when memory of the buffer * is added/removed + * @GST_BUFFER_FLAG_SYNC_AFTER: Elements which write to disk or permanent + * storage should ensure the data is synced after + * writing the contents of this buffer. (Since: 1.6) * @GST_BUFFER_FLAG_LAST: additional media specific flags can be added starting from * this flag. * @@ -211,6 +214,7 @@ typedef enum { GST_BUFFER_FLAG_DROPPABLE = (GST_MINI_OBJECT_FLAG_LAST << 8), GST_BUFFER_FLAG_DELTA_UNIT = (GST_MINI_OBJECT_FLAG_LAST << 9), GST_BUFFER_FLAG_TAG_MEMORY = (GST_MINI_OBJECT_FLAG_LAST << 10), + GST_BUFFER_FLAG_SYNC_AFTER = (GST_MINI_OBJECT_FLAG_LAST << 11), GST_BUFFER_FLAG_LAST = (GST_MINI_OBJECT_FLAG_LAST << 16) } GstBufferFlags; diff --git a/plugins/elements/gstfilesink.c b/plugins/elements/gstfilesink.c index 0c2706c65e..3751150bf4 100644 --- a/plugins/elements/gstfilesink.c +++ b/plugins/elements/gstfilesink.c @@ -673,6 +673,7 @@ gst_file_sink_render_list (GstBaseSink * bsink, GstBufferList * buffer_list) guint8 *mem_nums; guint total_mems; guint i, num_buffers; + gboolean sync_after = FALSE; sink = GST_FILE_SINK_CAST (bsink); @@ -687,12 +688,23 @@ gst_file_sink_render_list (GstBaseSink * bsink, GstBufferList * buffer_list) buffers[i] = gst_buffer_list_get (buffer_list, i); mem_nums[i] = gst_buffer_n_memory (buffers[i]); total_mems += mem_nums[i]; + if (GST_BUFFER_FLAG_IS_SET (buffers[i], GST_BUFFER_FLAG_SYNC_AFTER)) + sync_after = TRUE; } flow = gst_file_sink_render_buffers (sink, buffers, num_buffers, mem_nums, total_mems); + if (flow == GST_FLOW_OK && sync_after) { + if (fflush (sink->file) || fsync (fileno (sink->file))) { + GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, + (_("Error while writing to file \"%s\"."), sink->filename), + ("%s", g_strerror (errno))); + flow = GST_FLOW_ERROR; + } + } + return flow; no_data: @@ -718,6 +730,16 @@ gst_file_sink_render (GstBaseSink * sink, GstBuffer * buffer) else flow = GST_FLOW_OK; + if (flow == GST_FLOW_OK && + GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_SYNC_AFTER)) { + if (fflush (filesink->file) || fsync (fileno (filesink->file))) { + GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE, + (_("Error while writing to file \"%s\"."), filesink->filename), + ("%s", g_strerror (errno))); + flow = GST_FLOW_ERROR; + } + } + return flow; }