fdsink: implement ::render_list() using writev()
authorTim-Philipp Müller <tim@centricular.com>
Fri, 28 Nov 2014 14:39:33 +0000 (14:39 +0000)
committerTim-Philipp Müller <tim@centricular.com>
Sun, 30 Nov 2014 14:40:46 +0000 (14:40 +0000)
Write out multiple buffers possibly containing multiple
memories with one writev() call, without merging the
buffer memories first, like ::render() does currently.

plugins/elements/gstfdsink.c
plugins/elements/gstfdsink.h

index d7b9e88..012feaf 100644 (file)
@@ -58,6 +58,7 @@
 #include <string.h>
 
 #include "gstfdsink.h"
+#include "gstelements_private.h"
 
 #ifdef G_OS_WIN32
 #include <io.h>                 /* lseek, open, close, read */
@@ -107,6 +108,8 @@ static void gst_fd_sink_dispose (GObject * obj);
 static gboolean gst_fd_sink_query (GstBaseSink * bsink, GstQuery * query);
 static GstFlowReturn gst_fd_sink_render (GstBaseSink * sink,
     GstBuffer * buffer);
+static GstFlowReturn gst_fd_sink_render_list (GstBaseSink * bsink,
+    GstBufferList * buffer_list);
 static gboolean gst_fd_sink_start (GstBaseSink * basesink);
 static gboolean gst_fd_sink_stop (GstBaseSink * basesink);
 static gboolean gst_fd_sink_unlock (GstBaseSink * basesink);
@@ -138,6 +141,7 @@ gst_fd_sink_class_init (GstFdSinkClass * klass)
       gst_static_pad_template_get (&sinktemplate));
 
   gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_fd_sink_render);
+  gstbasesink_class->render_list = GST_DEBUG_FUNCPTR (gst_fd_sink_render_list);
   gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_fd_sink_start);
   gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_fd_sink_stop);
   gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_fd_sink_unlock);
@@ -228,6 +232,53 @@ gst_fd_sink_query (GstBaseSink * bsink, GstQuery * query)
 }
 
 static GstFlowReturn
+gst_fd_sink_render_buffers (GstFdSink * sink, GstBuffer ** buffers,
+    guint num_buffers, guint8 * mem_nums, guint total_mems)
+{
+  return gst_writev_buffers (GST_OBJECT_CAST (sink), sink->fd, sink->fdset,
+      buffers, num_buffers, mem_nums, total_mems, &sink->bytes_written,
+      &sink->current_pos);
+}
+
+static GstFlowReturn
+gst_fd_sink_render_list (GstBaseSink * bsink, GstBufferList * buffer_list)
+{
+  GstFlowReturn flow;
+  GstBuffer **buffers;
+  GstFdSink *sink;
+  guint8 *mem_nums;
+  guint total_mems;
+  guint i, num_buffers;
+
+  sink = GST_FD_SINK_CAST (bsink);
+
+  num_buffers = gst_buffer_list_length (buffer_list);
+  if (num_buffers == 0)
+    goto no_data;
+
+  /* extract buffers from list and count memories */
+  buffers = g_newa (GstBuffer *, num_buffers);
+  mem_nums = g_newa (guint8, num_buffers);
+  for (i = 0, total_mems = 0; i < num_buffers; ++i) {
+    buffers[i] = gst_buffer_list_get (buffer_list, i);
+    mem_nums[i] = gst_buffer_n_memory (buffers[i]);
+    total_mems += mem_nums[i];
+  }
+
+  flow =
+      gst_fd_sink_render_buffers (sink, buffers, num_buffers, mem_nums,
+      total_mems);
+
+  return flow;
+
+no_data:
+  {
+    GST_LOG_OBJECT (sink, "empty buffer list");
+    return GST_FLOW_OK;
+  }
+}
+
+static GstFlowReturn
 gst_fd_sink_render (GstBaseSink * sink, GstBuffer * buffer)
 {
   GstFdSink *fdsink;
index 3d7ee31..66a2340 100644 (file)
@@ -40,6 +40,7 @@ G_BEGIN_DECLS
   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FD_SINK))
 #define GST_IS_FD_SINK_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FD_SINK))
+#define GST_FD_SINK_CAST(obj) ((GstFdSink *)(obj))
 
 typedef struct _GstFdSink GstFdSink;
 typedef struct _GstFdSinkClass GstFdSinkClass;