mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
matroskamux: reduce newsegment event spam and set discont flag where needed
Only send newsegment events with new positions downstream when actually needed, instead of sending multiple newsegment events with new seek positions in a row. Also set the discont flag on buffers after a discontinuity.
This commit is contained in:
parent
84e47e579b
commit
7a8ebc4a79
2 changed files with 32 additions and 25 deletions
|
@ -41,7 +41,6 @@ GST_BOILERPLATE_FULL (GstEbmlWrite, gst_ebml_write, GstObject, GST_TYPE_OBJECT,
|
||||||
|
|
||||||
static void gst_ebml_write_finalize (GObject * object);
|
static void gst_ebml_write_finalize (GObject * object);
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_ebml_write_base_init (gpointer g_class)
|
gst_ebml_write_base_init (gpointer g_class)
|
||||||
{
|
{
|
||||||
|
@ -60,6 +59,7 @@ gst_ebml_write_init (GstEbmlWrite * ebml, GstEbmlWriteClass * klass)
|
||||||
{
|
{
|
||||||
ebml->srcpad = NULL;
|
ebml->srcpad = NULL;
|
||||||
ebml->pos = 0;
|
ebml->pos = 0;
|
||||||
|
ebml->last_pos = G_MAXUINT64; /* force newsegment event */
|
||||||
|
|
||||||
ebml->cache = NULL;
|
ebml->cache = NULL;
|
||||||
ebml->streamheader = NULL;
|
ebml->streamheader = NULL;
|
||||||
|
@ -89,6 +89,7 @@ gst_ebml_write_finalize (GObject * object)
|
||||||
gst_caps_unref (ebml->caps);
|
gst_caps_unref (ebml->caps);
|
||||||
ebml->caps = NULL;
|
ebml->caps = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +127,7 @@ void
|
||||||
gst_ebml_write_reset (GstEbmlWrite * ebml)
|
gst_ebml_write_reset (GstEbmlWrite * ebml)
|
||||||
{
|
{
|
||||||
ebml->pos = 0;
|
ebml->pos = 0;
|
||||||
|
ebml->last_pos = G_MAXUINT64; /* force newsegment event */
|
||||||
|
|
||||||
if (ebml->cache) {
|
if (ebml->cache) {
|
||||||
gst_byte_writer_free (ebml->cache);
|
gst_byte_writer_free (ebml->cache);
|
||||||
|
@ -133,7 +135,6 @@ gst_ebml_write_reset (GstEbmlWrite * ebml)
|
||||||
}
|
}
|
||||||
ebml->last_write_result = GST_FLOW_OK;
|
ebml->last_write_result = GST_FLOW_OK;
|
||||||
ebml->timestamp = GST_CLOCK_TIME_NONE;
|
ebml->timestamp = GST_CLOCK_TIME_NONE;
|
||||||
ebml->need_newsegment = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -204,6 +205,22 @@ gst_ebml_write_set_cache (GstEbmlWrite * ebml, guint size)
|
||||||
ebml->cache_pos = ebml->pos;
|
ebml->cache_pos = ebml->pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_ebml_writer_send_new_segment_event (GstEbmlWrite * ebml, guint64 new_pos)
|
||||||
|
{
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
GST_INFO ("seeking to %" G_GUINT64_FORMAT, new_pos);
|
||||||
|
|
||||||
|
res = gst_pad_push_event (ebml->srcpad,
|
||||||
|
gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, new_pos, -1, 0));
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
GST_WARNING ("seek to %" G_GUINT64_FORMAT "failed", new_pos);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_ebml_write_flush_cache:
|
* gst_ebml_write_flush_cache:
|
||||||
* @ebml: a #GstEbmlWrite.
|
* @ebml: a #GstEbmlWrite.
|
||||||
|
@ -225,11 +242,9 @@ gst_ebml_write_flush_cache (GstEbmlWrite * ebml, gboolean is_keyframe)
|
||||||
GST_BUFFER_OFFSET (buffer) = ebml->pos - GST_BUFFER_SIZE (buffer);
|
GST_BUFFER_OFFSET (buffer) = ebml->pos - GST_BUFFER_SIZE (buffer);
|
||||||
GST_BUFFER_OFFSET_END (buffer) = ebml->pos;
|
GST_BUFFER_OFFSET_END (buffer) = ebml->pos;
|
||||||
if (ebml->last_write_result == GST_FLOW_OK) {
|
if (ebml->last_write_result == GST_FLOW_OK) {
|
||||||
if (ebml->need_newsegment) {
|
if (GST_BUFFER_OFFSET (buffer) != ebml->last_pos) {
|
||||||
GstEvent *ev;
|
gst_ebml_writer_send_new_segment_event (ebml, GST_BUFFER_OFFSET (buffer));
|
||||||
ev = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0);
|
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
|
||||||
if (gst_pad_push_event (ebml->srcpad, ev))
|
|
||||||
ebml->need_newsegment = FALSE;
|
|
||||||
}
|
}
|
||||||
if (ebml->writing_streamheader) {
|
if (ebml->writing_streamheader) {
|
||||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS);
|
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS);
|
||||||
|
@ -237,6 +252,7 @@ gst_ebml_write_flush_cache (GstEbmlWrite * ebml, gboolean is_keyframe)
|
||||||
if (!is_keyframe) {
|
if (!is_keyframe) {
|
||||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
|
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
}
|
}
|
||||||
|
ebml->last_pos = ebml->pos;
|
||||||
ebml->last_write_result = gst_pad_push (ebml->srcpad, buffer);
|
ebml->last_write_result = gst_pad_push (ebml->srcpad, buffer);
|
||||||
} else {
|
} else {
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
|
@ -394,13 +410,6 @@ gst_ebml_write_element_push (GstEbmlWrite * ebml, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ebml->last_write_result == GST_FLOW_OK) {
|
if (ebml->last_write_result == GST_FLOW_OK) {
|
||||||
if (ebml->need_newsegment) {
|
|
||||||
GstEvent *ev;
|
|
||||||
|
|
||||||
ev = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0);
|
|
||||||
if (gst_pad_push_event (ebml->srcpad, ev))
|
|
||||||
ebml->need_newsegment = FALSE;
|
|
||||||
}
|
|
||||||
buf = gst_buffer_make_metadata_writable (buf);
|
buf = gst_buffer_make_metadata_writable (buf);
|
||||||
gst_buffer_set_caps (buf, ebml->caps);
|
gst_buffer_set_caps (buf, ebml->caps);
|
||||||
GST_BUFFER_OFFSET (buf) = ebml->pos - GST_BUFFER_SIZE (buf);
|
GST_BUFFER_OFFSET (buf) = ebml->pos - GST_BUFFER_SIZE (buf);
|
||||||
|
@ -409,6 +418,12 @@ gst_ebml_write_element_push (GstEbmlWrite * ebml, GstBuffer * buf)
|
||||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
|
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
|
||||||
}
|
}
|
||||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
|
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
|
|
||||||
|
if (GST_BUFFER_OFFSET (buf) != ebml->last_pos) {
|
||||||
|
gst_ebml_writer_send_new_segment_event (ebml, GST_BUFFER_OFFSET (buf));
|
||||||
|
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
|
||||||
|
}
|
||||||
|
ebml->last_pos = ebml->pos;
|
||||||
ebml->last_write_result = gst_pad_push (ebml->srcpad, buf);
|
ebml->last_write_result = gst_pad_push (ebml->srcpad, buf);
|
||||||
} else {
|
} else {
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
@ -426,8 +441,6 @@ gst_ebml_write_element_push (GstEbmlWrite * ebml, GstBuffer * buf)
|
||||||
void
|
void
|
||||||
gst_ebml_write_seek (GstEbmlWrite * ebml, guint64 pos)
|
gst_ebml_write_seek (GstEbmlWrite * ebml, guint64 pos)
|
||||||
{
|
{
|
||||||
GstEvent *event;
|
|
||||||
|
|
||||||
if (ebml->writing_streamheader) {
|
if (ebml->writing_streamheader) {
|
||||||
GST_DEBUG ("wanting to seek to pos %" G_GUINT64_FORMAT, pos);
|
GST_DEBUG ("wanting to seek to pos %" G_GUINT64_FORMAT, pos);
|
||||||
if (pos >= ebml->streamheader_pos &&
|
if (pos >= ebml->streamheader_pos &&
|
||||||
|
@ -447,6 +460,7 @@ gst_ebml_write_seek (GstEbmlWrite * ebml, guint64 pos)
|
||||||
/* within bounds? */
|
/* within bounds? */
|
||||||
if (pos >= ebml->cache_pos &&
|
if (pos >= ebml->cache_pos &&
|
||||||
pos <= ebml->cache_pos + ebml->cache->parent.size) {
|
pos <= ebml->cache_pos + ebml->cache->parent.size) {
|
||||||
|
GST_DEBUG ("seeking in cache to %" G_GUINT64_FORMAT, pos);
|
||||||
ebml->pos = pos;
|
ebml->pos = pos;
|
||||||
gst_byte_writer_set_pos (ebml->cache, ebml->pos - ebml->cache_pos);
|
gst_byte_writer_set_pos (ebml->cache, ebml->pos - ebml->cache_pos);
|
||||||
return;
|
return;
|
||||||
|
@ -456,13 +470,7 @@ gst_ebml_write_seek (GstEbmlWrite * ebml, guint64 pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, pos, -1, 0);
|
GST_INFO ("scheduling seek to %" G_GUINT64_FORMAT, pos);
|
||||||
if (gst_pad_push_event (ebml->srcpad, event)) {
|
|
||||||
GST_DEBUG ("Seek'd to offset %" G_GUINT64_FORMAT " from %" G_GUINT64_FORMAT,
|
|
||||||
pos, ebml->pos);
|
|
||||||
} else {
|
|
||||||
GST_WARNING ("Seek to offset %" G_GUINT64_FORMAT " failed", pos);
|
|
||||||
}
|
|
||||||
ebml->pos = pos;
|
ebml->pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ typedef struct _GstEbmlWrite {
|
||||||
|
|
||||||
GstPad *srcpad;
|
GstPad *srcpad;
|
||||||
guint64 pos;
|
guint64 pos;
|
||||||
|
guint64 last_pos;
|
||||||
GstClockTime timestamp;
|
GstClockTime timestamp;
|
||||||
|
|
||||||
GstByteWriter *cache;
|
GstByteWriter *cache;
|
||||||
|
@ -54,8 +55,6 @@ typedef struct _GstEbmlWrite {
|
||||||
|
|
||||||
GstFlowReturn last_write_result;
|
GstFlowReturn last_write_result;
|
||||||
|
|
||||||
gboolean need_newsegment;
|
|
||||||
|
|
||||||
gboolean writing_streamheader;
|
gboolean writing_streamheader;
|
||||||
GstByteWriter *streamheader;
|
GstByteWriter *streamheader;
|
||||||
guint64 streamheader_pos;
|
guint64 streamheader_pos;
|
||||||
|
|
Loading…
Reference in a new issue