mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
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:
parent
81bf657aa7
commit
b8fd1a91f1
3 changed files with 31 additions and 14 deletions
|
@ -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
|
* @ebml: #GstEbmlWrite
|
||||||
* @startpos: Master starting position.
|
* @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
|
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;
|
guint64 pos = ebml->pos;
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
|
|
||||||
gst_ebml_write_seek (ebml, startpos);
|
gst_ebml_write_seek (ebml, startpos);
|
||||||
buf = gst_ebml_write_element_new (ebml, 0);
|
buf = gst_buffer_new_and_alloc (8);
|
||||||
startpos =
|
GST_WRITE_UINT64_BE (GST_BUFFER_DATA (buf),
|
||||||
GUINT64_TO_BE ((G_GINT64_CONSTANT (1) << 56) | (pos - startpos - 8));
|
(G_GINT64_CONSTANT (1) << 56) | (pos - startpos - 8 + extra_size));
|
||||||
memcpy (GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf), (guint8 *) & startpos,
|
|
||||||
8);
|
|
||||||
GST_BUFFER_SIZE (buf) += 8;
|
|
||||||
gst_ebml_write_element_push (ebml, buf);
|
gst_ebml_write_element_push (ebml, buf);
|
||||||
gst_ebml_write_seek (ebml, pos);
|
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:
|
* gst_ebml_write_binary:
|
||||||
|
|
|
@ -107,6 +107,9 @@ guint64 gst_ebml_write_master_start (GstEbmlWrite *ebml,
|
||||||
guint32 id);
|
guint32 id);
|
||||||
void gst_ebml_write_master_finish (GstEbmlWrite *ebml,
|
void gst_ebml_write_master_finish (GstEbmlWrite *ebml,
|
||||||
guint64 startpos);
|
guint64 startpos);
|
||||||
|
void gst_ebml_write_master_finish_full (GstEbmlWrite * ebml,
|
||||||
|
guint64 startpos,
|
||||||
|
guint64 extra_size);
|
||||||
void gst_ebml_write_binary (GstEbmlWrite *ebml,
|
void gst_ebml_write_binary (GstEbmlWrite *ebml,
|
||||||
guint32 id,
|
guint32 id,
|
||||||
guchar *binary,
|
guchar *binary,
|
||||||
|
|
|
@ -2524,10 +2524,12 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad)
|
||||||
gst_ebml_write_master_finish (ebml, mux->cluster);
|
gst_ebml_write_master_finish (ebml, mux->cluster);
|
||||||
mux->prev_cluster_size = ebml->pos - mux->cluster_pos;
|
mux->prev_cluster_size = ebml->pos - mux->cluster_pos;
|
||||||
mux->cluster_pos = ebml->pos;
|
mux->cluster_pos = ebml->pos;
|
||||||
|
gst_ebml_write_set_cache (ebml, 0x20);
|
||||||
mux->cluster =
|
mux->cluster =
|
||||||
gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CLUSTER);
|
gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CLUSTER);
|
||||||
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE,
|
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE,
|
||||||
GST_BUFFER_TIMESTAMP (buf) / mux->time_scale);
|
GST_BUFFER_TIMESTAMP (buf) / mux->time_scale);
|
||||||
|
gst_ebml_write_flush_cache (ebml);
|
||||||
mux->cluster_time = GST_BUFFER_TIMESTAMP (buf);
|
mux->cluster_time = GST_BUFFER_TIMESTAMP (buf);
|
||||||
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_PREVSIZE,
|
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_PREVSIZE,
|
||||||
mux->prev_cluster_size);
|
mux->prev_cluster_size);
|
||||||
|
@ -2536,9 +2538,11 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad)
|
||||||
/* first cluster */
|
/* first cluster */
|
||||||
|
|
||||||
mux->cluster_pos = ebml->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);
|
mux->cluster = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CLUSTER);
|
||||||
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE,
|
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE,
|
||||||
GST_BUFFER_TIMESTAMP (buf) / mux->time_scale);
|
GST_BUFFER_TIMESTAMP (buf) / mux->time_scale);
|
||||||
|
gst_ebml_write_flush_cache (ebml);
|
||||||
mux->cluster_time = GST_BUFFER_TIMESTAMP (buf);
|
mux->cluster_time = GST_BUFFER_TIMESTAMP (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2611,26 +2615,32 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad)
|
||||||
hdr =
|
hdr =
|
||||||
gst_matroska_mux_create_buffer_header (collect_pad->track,
|
gst_matroska_mux_create_buffer_header (collect_pad->track,
|
||||||
relative_timestamp, flags);
|
relative_timestamp, flags);
|
||||||
|
gst_ebml_write_set_cache (ebml, 0x40);
|
||||||
gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_SIMPLEBLOCK,
|
gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_SIMPLEBLOCK,
|
||||||
GST_BUFFER_SIZE (buf) + GST_BUFFER_SIZE (hdr));
|
GST_BUFFER_SIZE (buf) + GST_BUFFER_SIZE (hdr));
|
||||||
gst_ebml_write_buffer (ebml, hdr);
|
gst_ebml_write_buffer (ebml, hdr);
|
||||||
|
gst_ebml_write_flush_cache (ebml);
|
||||||
gst_ebml_write_buffer (ebml, buf);
|
gst_ebml_write_buffer (ebml, buf);
|
||||||
|
|
||||||
return gst_ebml_last_write_result (ebml);
|
return gst_ebml_last_write_result (ebml);
|
||||||
} else {
|
} 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);
|
blockgroup = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_BLOCKGROUP);
|
||||||
hdr =
|
hdr =
|
||||||
gst_matroska_mux_create_buffer_header (collect_pad->track,
|
gst_matroska_mux_create_buffer_header (collect_pad->track,
|
||||||
relative_timestamp, 0);
|
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) {
|
if (write_duration) {
|
||||||
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_BLOCKDURATION,
|
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_BLOCKDURATION,
|
||||||
block_duration / mux->time_scale);
|
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);
|
return gst_ebml_last_write_result (ebml);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue