Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / gst / multifile / gstmultifilesink.c
index 2be3b56..af19290 100644 (file)
@@ -192,28 +192,14 @@ gst_multi_file_sink_next_get_type (void)
   return multi_file_sync_next_type;
 }
 
-GST_BOILERPLATE (GstMultiFileSink, gst_multi_file_sink, GstBaseSink,
-    GST_TYPE_BASE_SINK);
-
-static void
-gst_multi_file_sink_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  GST_DEBUG_CATEGORY_INIT (gst_multi_file_sink_debug, "multifilesink", 0,
-      "multifilesink element");
-
-  gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);
-  gst_element_class_set_details_simple (gstelement_class, "Multi-File Sink",
-      "Sink/File",
-      "Write buffers to a sequentially named set of files",
-      "David Schleef <ds@schleef.org>");
-}
+#define gst_multi_file_sink_parent_class parent_class
+G_DEFINE_TYPE (GstMultiFileSink, gst_multi_file_sink, GST_TYPE_BASE_SINK);
 
 static void
 gst_multi_file_sink_class_init (GstMultiFileSinkClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
   GstBaseSinkClass *gstbasesink_class = GST_BASE_SINK_CLASS (klass);
 
   gobject_class->set_property = gst_multi_file_sink_set_property;
@@ -293,11 +279,20 @@ gst_multi_file_sink_class_init (GstMultiFileSinkClass * klass)
   gstbasesink_class->set_caps =
       GST_DEBUG_FUNCPTR (gst_multi_file_sink_set_caps);
   gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_multi_file_sink_event);
+
+  GST_DEBUG_CATEGORY_INIT (gst_multi_file_sink_debug, "multifilesink", 0,
+      "multifilesink element");
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+  gst_element_class_set_details_simple (gstelement_class, "Multi-File Sink",
+      "Sink/File",
+      "Write buffers to a sequentially named set of files",
+      "David Schleef <ds@schleef.org>");
 }
 
 static void
-gst_multi_file_sink_init (GstMultiFileSink * multifilesink,
-    GstMultiFileSinkClass * g_class)
+gst_multi_file_sink_init (GstMultiFileSink * multifilesink)
 {
   multifilesink->filename = g_strdup (DEFAULT_LOCATION);
   multifilesink->index = DEFAULT_INDEX;
@@ -492,16 +487,19 @@ gst_multi_file_sink_write_stream_headers (GstMultiFileSink * sink)
 
   for (i = 0; i < sink->n_streamheaders; i++) {
     GstBuffer *hdr;
+    guint8 *sdata;
+    gsize ssize;
     int ret;
 
     hdr = sink->streamheaders[i];
-
-    ret = fwrite (GST_BUFFER_DATA (hdr), GST_BUFFER_SIZE (hdr), 1, sink->file);
+    sdata = gst_buffer_map (hdr, &ssize, NULL, GST_MAP_READ);
+    ret = fwrite (sdata, ssize, 1, sink->file);
+    gst_buffer_unmap (hdr, sdata, ssize);
 
     if (ret != 1)
       return FALSE;
 
-    sink->cur_file_size += GST_BUFFER_SIZE (hdr);
+    sink->cur_file_size += ssize;
   }
 
   return TRUE;
@@ -511,14 +509,13 @@ static GstFlowReturn
 gst_multi_file_sink_render (GstBaseSink * sink, GstBuffer * buffer)
 {
   GstMultiFileSink *multifilesink;
-  guint size;
+  gsize size;
   guint8 *data;
   gchar *filename;
   gboolean ret;
   GError *error = NULL;
 
-  size = GST_BUFFER_SIZE (buffer);
-  data = GST_BUFFER_DATA (buffer);
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
 
   multifilesink = GST_MULTI_FILE_SINK (sink);
 
@@ -550,8 +547,7 @@ gst_multi_file_sink_render (GstBaseSink * sink, GstBuffer * buffer)
           goto stdio_write_error;
       }
 
-      ret = fwrite (GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 1,
-          multifilesink->file);
+      ret = fwrite (data, size, 1, multifilesink->file);
       if (ret != 1)
         goto stdio_write_error;
 
@@ -580,8 +576,7 @@ gst_multi_file_sink_render (GstBaseSink * sink, GstBuffer * buffer)
         gst_multi_file_sink_write_stream_headers (multifilesink);
       }
 
-      ret = fwrite (GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 1,
-          multifilesink->file);
+      ret = fwrite (data, size, 1, multifilesink->file);
       if (ret != 1)
         goto stdio_write_error;
 
@@ -592,8 +587,11 @@ gst_multi_file_sink_render (GstBaseSink * sink, GstBuffer * buffer)
           goto stdio_write_error;
       }
 
-      ret = fwrite (GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 1,
-          multifilesink->file);
+      if (!gst_multi_file_sink_write_stream_headers (multifilesink))
+        goto stdio_write_error;
+
+      ret = fwrite (data, size, 1, multifilesink->file);
+
       if (ret != 1)
         goto stdio_write_error;
 
@@ -601,7 +599,7 @@ gst_multi_file_sink_render (GstBaseSink * sink, GstBuffer * buffer)
     case GST_MULTI_FILE_SINK_NEXT_MAX_SIZE:{
       guint64 new_size;
 
-      new_size = multifilesink->cur_file_size + GST_BUFFER_SIZE (buffer);
+      new_size = multifilesink->cur_file_size + size;
       if (new_size > multifilesink->max_file_size) {
 
         GST_INFO_OBJECT (multifilesink, "current size: %" G_GUINT64_FORMAT
@@ -620,19 +618,19 @@ gst_multi_file_sink_render (GstBaseSink * sink, GstBuffer * buffer)
         gst_multi_file_sink_write_stream_headers (multifilesink);
       }
 
-      ret = fwrite (GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 1,
-          multifilesink->file);
+      ret = fwrite (data, size, 1, multifilesink->file);
 
       if (ret != 1)
         goto stdio_write_error;
 
-      multifilesink->cur_file_size += GST_BUFFER_SIZE (buffer);
+      multifilesink->cur_file_size += size;
       break;
     }
     default:
       g_assert_not_reached ();
   }
 
+  gst_buffer_unmap (buffer, data, size);
   return GST_FLOW_OK;
 
   /* ERRORS */
@@ -653,6 +651,7 @@ write_error:
     g_error_free (error);
     g_free (filename);
 
+    gst_buffer_unmap (buffer, data, size);
     return GST_FLOW_ERROR;
   }
 stdio_write_error:
@@ -665,35 +664,41 @@ stdio_write_error:
       GST_ELEMENT_ERROR (multifilesink, RESOURCE, WRITE,
           ("Error while writing to file."), ("%s", g_strerror (errno)));
   }
+  gst_buffer_unmap (buffer, data, size);
   return GST_FLOW_ERROR;
 }
 
-static GstBufferListItem
-buffer_list_calc_size (GstBuffer ** buf, guint group, guint idx, gpointer data)
+static gboolean
+buffer_list_calc_size (GstBuffer ** buf, guint idx, gpointer data)
 {
   guint *p_size = data;
   guint buf_size;
 
-  buf_size = GST_BUFFER_SIZE (*buf);
-  GST_TRACE ("buffer %u in group %u has size %u", idx, group, buf_size);
+  buf_size = gst_buffer_get_size (*buf);
+  GST_TRACE ("buffer %u has size %" G_GSIZE_FORMAT, idx, buf_size);
   *p_size += buf_size;
 
-  return GST_BUFFER_LIST_CONTINUE;
+  return TRUE;
 }
 
-static GstBufferListItem
-buffer_list_copy_data (GstBuffer ** buf, guint group, guint idx, gpointer data)
+static gboolean
+buffer_list_copy_data (GstBuffer ** buf, guint idx, gpointer data)
 {
   GstBuffer *dest = data;
+  guint num, i;
+
+  if (idx == 0)
+    gst_buffer_copy_into (dest, *buf, GST_BUFFER_COPY_METADATA, 0, -1);
 
-  if (group == 0 && idx == 0)
-    gst_buffer_copy_metadata (dest, *buf, GST_BUFFER_COPY_ALL);
+  num = gst_buffer_n_memory (*buf);
+  for (i = 0; i < num; ++i) {
+    GstMemory *mem;
 
-  memcpy (GST_BUFFER_DATA (dest) + GST_BUFFER_SIZE (dest),
-      GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
-  GST_BUFFER_SIZE (dest) += GST_BUFFER_SIZE (*buf);
+    mem = gst_buffer_peek_memory (*buf, i, GST_MAP_READ);
+    gst_buffer_take_memory (dest, -1, gst_memory_ref (mem));
+  }
 
-  return GST_BUFFER_LIST_CONTINUE;
+  return TRUE;
 }
 
 /* Our assumption for now is that the buffers in a buffer list should always
@@ -710,10 +715,9 @@ gst_multi_file_sink_render_list (GstBaseSink * sink, GstBufferList * list)
 
   /* copy all buffers in the list into one single buffer, so we can use
    * the normal render function (FIXME: optimise to avoid the memcpy) */
-  buf = gst_buffer_new_and_alloc (size);
-  GST_BUFFER_SIZE (buf) = 0;
+  buf = gst_buffer_new ();
   gst_buffer_list_foreach (list, buffer_list_copy_data, buf);
-  g_assert (GST_BUFFER_SIZE (buf) == size);
+  g_assert (gst_buffer_get_size (buf) == size);
 
   gst_multi_file_sink_render (sink, buf);
   gst_buffer_unref (buf);
@@ -781,7 +785,6 @@ gst_multi_file_sink_event (GstBaseSink * sink, GstEvent * event)
 {
   GstMultiFileSink *multifilesink;
   gchar *filename;
-  gboolean res = TRUE;
 
   multifilesink = GST_MULTI_FILE_SINK (sink);
 
@@ -833,12 +836,16 @@ gst_multi_file_sink_event (GstBaseSink * sink, GstEvent * event)
   }
 
 out:
-  return res;
+  return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);
 
+  /* ERRORS */
 stdio_write_error:
-  GST_ELEMENT_ERROR (multifilesink, RESOURCE, WRITE,
-      ("Error while writing to file."), (NULL));
-  return FALSE;
+  {
+    GST_ELEMENT_ERROR (multifilesink, RESOURCE, WRITE,
+        ("Error while writing to file."), (NULL));
+    gst_event_unref (event);
+    return FALSE;
+  }
 }
 
 static gboolean