From b8fd1a91f1ef90893549788074ada06c66ac13ab Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Thu, 20 May 2010 14:33:41 +0200 Subject: [PATCH] matroskamux: use write caching also when writing buffer data 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 | 22 +++++++++++++--------- gst/matroska/ebml-write.h | 3 +++ gst/matroska/matroska-mux.c | 20 +++++++++++++++----- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/gst/matroska/ebml-write.c b/gst/matroska/ebml-write.c index 8f2418b1d5..2b1e2fd134 100644 --- a/gst/matroska/ebml-write.c +++ b/gst/matroska/ebml-write.c @@ -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: diff --git a/gst/matroska/ebml-write.h b/gst/matroska/ebml-write.h index b7d645484f..26e9d9efb7 100644 --- a/gst/matroska/ebml-write.h +++ b/gst/matroska/ebml-write.h @@ -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, diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c index e499951653..1ad7ee1559 100644 --- a/gst/matroska/matroska-mux.c +++ b/gst/matroska/matroska-mux.c @@ -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); } }