matroskamux: use write caching also when writing buffer data
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Thu, 20 May 2010 12:33:41 +0000 (14:33 +0200)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Tue, 1 Jun 2010 13:54:35 +0000 (15:54 +0200)
Specifically, this reduces pushing several small buffers for each
data buffer and also avoids a seek for each buffer altogether
(though a seek is still needed for each cluster).

Fixes #619273.

gst/matroska/ebml-write.c
gst/matroska/ebml-write.h
gst/matroska/matroska-mux.c

index 8f2418b..2b1e2fd 100644 (file)
@@ -600,29 +600,33 @@ gst_ebml_write_master_start (GstEbmlWrite * ebml, guint32 id)
 
 
 /**
- * gst_ebml_write_master_finish:
+ * gst_ebml_write_master_finish_full:
  * @ebml: #GstEbmlWrite
  * @startpos: Master starting position.
  *
- * Finish writing master element.
+ * Finish writing master element.  Size of master element is difference between
+ * current position and the element start, and @extra_size added to this.
  */
 void
-gst_ebml_write_master_finish (GstEbmlWrite * ebml, guint64 startpos)
+gst_ebml_write_master_finish_full (GstEbmlWrite * ebml, guint64 startpos,
+    guint64 extra_size)
 {
   guint64 pos = ebml->pos;
   GstBuffer *buf;
 
   gst_ebml_write_seek (ebml, startpos);
-  buf = gst_ebml_write_element_new (ebml, 0);
-  startpos =
-      GUINT64_TO_BE ((G_GINT64_CONSTANT (1) << 56) | (pos - startpos - 8));
-  memcpy (GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf), (guint8 *) & startpos,
-      8);
-  GST_BUFFER_SIZE (buf) += 8;
+  buf = gst_buffer_new_and_alloc (8);
+  GST_WRITE_UINT64_BE (GST_BUFFER_DATA (buf),
+      (G_GINT64_CONSTANT (1) << 56) | (pos - startpos - 8 + extra_size));
   gst_ebml_write_element_push (ebml, buf);
   gst_ebml_write_seek (ebml, pos);
 }
 
+void
+gst_ebml_write_master_finish (GstEbmlWrite * ebml, guint64 startpos)
+{
+  gst_ebml_write_master_finish_full (ebml, startpos, 0);
+}
 
 /**
  * gst_ebml_write_binary:
index b7d6454..26e9d9e 100644 (file)
@@ -107,6 +107,9 @@ guint64 gst_ebml_write_master_start  (GstEbmlWrite *ebml,
                                       guint32       id);
 void    gst_ebml_write_master_finish (GstEbmlWrite *ebml,
                                       guint64       startpos);
+void    gst_ebml_write_master_finish_full (GstEbmlWrite * ebml,
+                                      guint64 startpos,
+                                      guint64 extra_size);
 void    gst_ebml_write_binary        (GstEbmlWrite *ebml,
                                       guint32       id,
                                       guchar       *binary,
index e499951..1ad7ee1 100644 (file)
@@ -2524,10 +2524,12 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad)
       gst_ebml_write_master_finish (ebml, mux->cluster);
       mux->prev_cluster_size = ebml->pos - mux->cluster_pos;
       mux->cluster_pos = ebml->pos;
+      gst_ebml_write_set_cache (ebml, 0x20);
       mux->cluster =
           gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CLUSTER);
       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE,
           GST_BUFFER_TIMESTAMP (buf) / mux->time_scale);
+      gst_ebml_write_flush_cache (ebml);
       mux->cluster_time = GST_BUFFER_TIMESTAMP (buf);
       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_PREVSIZE,
           mux->prev_cluster_size);
@@ -2536,9 +2538,11 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad)
     /* first cluster */
 
     mux->cluster_pos = ebml->pos;
+    gst_ebml_write_set_cache (ebml, 0x20);
     mux->cluster = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CLUSTER);
     gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE,
         GST_BUFFER_TIMESTAMP (buf) / mux->time_scale);
+    gst_ebml_write_flush_cache (ebml);
     mux->cluster_time = GST_BUFFER_TIMESTAMP (buf);
   }
 
@@ -2611,26 +2615,32 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad)
     hdr =
         gst_matroska_mux_create_buffer_header (collect_pad->track,
         relative_timestamp, flags);
+    gst_ebml_write_set_cache (ebml, 0x40);
     gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_SIMPLEBLOCK,
         GST_BUFFER_SIZE (buf) + GST_BUFFER_SIZE (hdr));
     gst_ebml_write_buffer (ebml, hdr);
+    gst_ebml_write_flush_cache (ebml);
     gst_ebml_write_buffer (ebml, buf);
 
     return gst_ebml_last_write_result (ebml);
   } else {
+    gst_ebml_write_set_cache (ebml, 0x40);
+    /* write and call order slightly unnatural,
+     * but avoids seek and minizes pushing */
     blockgroup = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_BLOCKGROUP);
     hdr =
         gst_matroska_mux_create_buffer_header (collect_pad->track,
         relative_timestamp, 0);
-    gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_BLOCK,
-        GST_BUFFER_SIZE (buf) + GST_BUFFER_SIZE (hdr));
-    gst_ebml_write_buffer (ebml, hdr);
-    gst_ebml_write_buffer (ebml, buf);
     if (write_duration) {
       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_BLOCKDURATION,
           block_duration / mux->time_scale);
     }
-    gst_ebml_write_master_finish (ebml, blockgroup);
+    gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_BLOCK,
+        GST_BUFFER_SIZE (buf) + GST_BUFFER_SIZE (hdr));
+    gst_ebml_write_buffer (ebml, hdr);
+    gst_ebml_write_master_finish_full (ebml, blockgroup, GST_BUFFER_SIZE (buf));
+    gst_ebml_write_flush_cache (ebml);
+    gst_ebml_write_buffer (ebml, buf);
     return gst_ebml_last_write_result (ebml);
   }
 }