From 7a8ebc4a798599ed42197fb33660e1bc54844604 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 14 Oct 2010 00:11:27 +0100 Subject: [PATCH] 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. --- gst/matroska/ebml-write.c | 54 +++++++++++++++++++++++++++-------------------- gst/matroska/ebml-write.h | 3 +-- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/gst/matroska/ebml-write.c b/gst/matroska/ebml-write.c index 9ac786d..4d131c3 100644 --- a/gst/matroska/ebml-write.c +++ b/gst/matroska/ebml-write.c @@ -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_base_init (gpointer g_class) { @@ -60,6 +59,7 @@ gst_ebml_write_init (GstEbmlWrite * ebml, GstEbmlWriteClass * klass) { ebml->srcpad = NULL; ebml->pos = 0; + ebml->last_pos = G_MAXUINT64; /* force newsegment event */ ebml->cache = NULL; ebml->streamheader = NULL; @@ -89,6 +89,7 @@ gst_ebml_write_finalize (GObject * object) gst_caps_unref (ebml->caps); ebml->caps = NULL; } + GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); } @@ -126,6 +127,7 @@ void gst_ebml_write_reset (GstEbmlWrite * ebml) { ebml->pos = 0; + ebml->last_pos = G_MAXUINT64; /* force newsegment event */ if (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->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; } +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: * @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_END (buffer) = ebml->pos; 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; + if (GST_BUFFER_OFFSET (buffer) != ebml->last_pos) { + gst_ebml_writer_send_new_segment_event (ebml, GST_BUFFER_OFFSET (buffer)); + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT); } if (ebml->writing_streamheader) { 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) { 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); } else { 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->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); gst_buffer_set_caps (buf, ebml->caps); 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_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); } else { gst_buffer_unref (buf); @@ -426,8 +441,6 @@ gst_ebml_write_element_push (GstEbmlWrite * ebml, GstBuffer * buf) void gst_ebml_write_seek (GstEbmlWrite * ebml, guint64 pos) { - GstEvent *event; - if (ebml->writing_streamheader) { GST_DEBUG ("wanting to seek to pos %" G_GUINT64_FORMAT, pos); if (pos >= ebml->streamheader_pos && @@ -447,6 +460,7 @@ gst_ebml_write_seek (GstEbmlWrite * ebml, guint64 pos) /* within bounds? */ if (pos >= ebml->cache_pos && pos <= ebml->cache_pos + ebml->cache->parent.size) { + GST_DEBUG ("seeking in cache to %" G_GUINT64_FORMAT, pos); ebml->pos = pos; gst_byte_writer_set_pos (ebml->cache, ebml->pos - ebml->cache_pos); 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); - 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); - } + GST_INFO ("scheduling seek to %" G_GUINT64_FORMAT, pos); ebml->pos = pos; } diff --git a/gst/matroska/ebml-write.h b/gst/matroska/ebml-write.h index 2240f4f..7b0ef45 100644 --- a/gst/matroska/ebml-write.h +++ b/gst/matroska/ebml-write.h @@ -47,6 +47,7 @@ typedef struct _GstEbmlWrite { GstPad *srcpad; guint64 pos; + guint64 last_pos; GstClockTime timestamp; GstByteWriter *cache; @@ -54,8 +55,6 @@ typedef struct _GstEbmlWrite { GstFlowReturn last_write_result; - gboolean need_newsegment; - gboolean writing_streamheader; GstByteWriter *streamheader; guint64 streamheader_pos; -- 2.7.4