diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2014-03-28 17:32:56 +0100 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2014-03-29 10:33:45 +0100 |
commit | 264d7dbd898f44ef511038412a23b8edbf59be11 (patch) | |
tree | a7ce940427d118a0fd7db6848f6c2a15d2a289d3 /gst/mpegtsdemux | |
parent | d986d24d417a05659e5ca94ae539469717139959 (diff) | |
download | gstreamer-plugins-bad-264d7dbd898f44ef511038412a23b8edbf59be11.tar.gz |
tsdemux: Drain remaining data on disconts
Diffstat (limited to 'gst/mpegtsdemux')
-rw-r--r-- | gst/mpegtsdemux/mpegtsbase.c | 18 | ||||
-rw-r--r-- | gst/mpegtsdemux/mpegtsbase.h | 3 | ||||
-rw-r--r-- | gst/mpegtsdemux/tsdemux.c | 24 |
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) { |