Add GST_BUFFER_FLAG_SYNC_AFTER flag, and implement in filesink.
authorJan Schmidt <jan@centricular.com>
Thu, 16 Apr 2015 00:32:02 +0000 (10:32 +1000)
committerJan Schmidt <jan@centricular.com>
Mon, 8 Jun 2015 09:13:18 +0000 (19:13 +1000)
Makes it possible to get filesink to fsync() after rendering
a buffer.

gst/gstbuffer.h
plugins/elements/gstfilesink.c

index dd7f237..3e4fab9 100644 (file)
@@ -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;
index 0c2706c..3751150 100644 (file)
@@ -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;
 }