summaryrefslogtreecommitdiff
path: root/gst/mpegtsdemux
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2014-03-28 17:32:56 +0100
committerSebastian Dröge <sebastian@centricular.com>2014-03-29 10:33:45 +0100
commit264d7dbd898f44ef511038412a23b8edbf59be11 (patch)
treea7ce940427d118a0fd7db6848f6c2a15d2a289d3 /gst/mpegtsdemux
parentd986d24d417a05659e5ca94ae539469717139959 (diff)
downloadgstreamer-plugins-bad-264d7dbd898f44ef511038412a23b8edbf59be11.tar.gz
tsdemux: Drain remaining data on disconts
Diffstat (limited to 'gst/mpegtsdemux')
-rw-r--r--gst/mpegtsdemux/mpegtsbase.c18
-rw-r--r--gst/mpegtsdemux/mpegtsbase.h3
-rw-r--r--gst/mpegtsdemux/tsdemux.c24
3 files changed, 44 insertions, 1 deletions
diff --git a/gst/mpegtsdemux/mpegtsbase.c b/gst/mpegtsdemux/mpegtsbase.c
index 6296cbd10..dc5a64f4b 100644
--- a/gst/mpegtsdemux/mpegtsbase.c
+++ b/gst/mpegtsdemux/mpegtsbase.c
@@ -997,6 +997,18 @@ gst_mpegts_base_handle_eos (MpegTSBase * base)
return TRUE;
}
+static inline GstFlowReturn
+mpegts_base_drain (MpegTSBase * base)
+{
+ MpegTSBaseClass *klass = GST_MPEGTS_BASE_GET_CLASS (base);
+
+ /* Call implementation */
+ if (klass->drain)
+ return klass->drain (base);
+
+ return GST_FLOW_OK;
+}
+
static inline void
mpegts_base_flush (MpegTSBase * base, gboolean hard)
{
@@ -1096,8 +1108,12 @@ mpegts_base_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
if (klass->input_done)
gst_buffer_ref (buf);
- if (FALSE && GST_BUFFER_IS_DISCONT (buf)) {
+ if (GST_BUFFER_IS_DISCONT (buf)) {
GST_DEBUG_OBJECT (base, "Got DISCONT buffer, flushing");
+ res = mpegts_base_drain (base);
+ if (G_UNLIKELY (res != GST_FLOW_OK))
+ return res;
+
mpegts_base_flush (base, FALSE);
mpegts_packetizer_flush (base->packetizer, TRUE);
}
diff --git a/gst/mpegtsdemux/mpegtsbase.h b/gst/mpegtsdemux/mpegtsbase.h
index d0dd78098..6e0bee1aa 100644
--- a/gst/mpegtsdemux/mpegtsbase.h
+++ b/gst/mpegtsdemux/mpegtsbase.h
@@ -185,6 +185,9 @@ struct _MpegTSBaseClass {
/* seek is called to wait for seeking */
GstFlowReturn (*seek) (MpegTSBase * base, GstEvent * event);
+ /* Drain all currently pending data */
+ GstFlowReturn (*drain) (MpegTSBase * base);
+
/* flush all streams
* The hard inicator is used to flush completelly on FLUSH_STOP events
* or partially in pull mode seeks of tsdemux */
diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c
index 077374166..fe4ba00b1 100644
--- a/gst/mpegtsdemux/tsdemux.c
+++ b/gst/mpegtsdemux/tsdemux.c
@@ -245,6 +245,7 @@ static GstFlowReturn
gst_ts_demux_push (MpegTSBase * base, MpegTSPacketizerPacket * packet,
GstMpegTsSection * section);
static void gst_ts_demux_flush (MpegTSBase * base, gboolean hard);
+static GstFlowReturn gst_ts_demux_drain (MpegTSBase * base);
static void
gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * stream,
MpegTSBaseProgram * program);
@@ -326,6 +327,7 @@ gst_ts_demux_class_init (GstTSDemuxClass * klass)
ts_class->stream_removed = gst_ts_demux_stream_removed;
ts_class->seek = GST_DEBUG_FUNCPTR (gst_ts_demux_do_seek);
ts_class->flush = GST_DEBUG_FUNCPTR (gst_ts_demux_flush);
+ ts_class->drain = GST_DEBUG_FUNCPTR (gst_ts_demux_drain);
}
static void
@@ -1894,6 +1896,28 @@ gst_ts_demux_flush (MpegTSBase * base, gboolean hard)
}
static GstFlowReturn
+gst_ts_demux_drain (MpegTSBase * base)
+{
+ GstTSDemux *demux = GST_TS_DEMUX_CAST (base);
+ GList *tmp;
+ GstFlowReturn res = GST_FLOW_OK;
+
+ if (!demux->program)
+ return res;
+
+ for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
+ TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
+ if (stream->pad) {
+ res = gst_ts_demux_push_pending_data (demux, stream);
+ if (G_UNLIKELY (res != GST_FLOW_OK))
+ break;
+ }
+ }
+
+ return res;
+}
+
+static GstFlowReturn
gst_ts_demux_push (MpegTSBase * base, MpegTSPacketizerPacket * packet,
GstMpegTsSection * section)
{