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.
This commit is contained in:
Mark Nauwelaerts 2010-05-20 14:33:41 +02:00
parent 81bf657aa7
commit b8fd1a91f1
3 changed files with 31 additions and 14 deletions

View 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:

View 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,

View 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);
}
}