From: Youness Alaoui Date: Tue, 16 Aug 2011 19:54:04 +0000 (+0000) Subject: tsdemux: interpolate gap and fix timestamps depending on upstream segment X-Git-Tag: 1.19.3~507^2~16042^2~35 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4cc1dfb3603c1cafbb6c2efb0992907ced8b92ca;p=platform%2Fupstream%2Fgstreamer.git tsdemux: interpolate gap and fix timestamps depending on upstream segment --- diff --git a/gst/mpegtsdemux/mpegtsbase.c b/gst/mpegtsdemux/mpegtsbase.c index c079b11..6ab1184 100644 --- a/gst/mpegtsdemux/mpegtsbase.c +++ b/gst/mpegtsdemux/mpegtsbase.c @@ -215,6 +215,8 @@ mpegts_base_reset (MpegTSBase * base) base->mode = BASE_MODE_STREAMING; base->seen_pat = FALSE; base->first_pat_offset = -1; + base->in_gap = 0; + base->first_buf_ts = GST_CLOCK_TIME_NONE; if (klass->reset) klass->reset (base); @@ -1180,6 +1182,8 @@ mpegts_base_sink_event (GstPad * pad, GstEvent * event) gst_segment_set_newsegment_full (&base->segment, update, rate, applied_rate, format, start, stop, position); gst_event_unref (event); + base->in_gap = GST_CLOCK_TIME_NONE; + base->first_buf_ts = GST_CLOCK_TIME_NONE; } break; case GST_EVENT_EOS: @@ -1232,6 +1236,13 @@ mpegts_base_chain (GstPad * pad, GstBuffer * buf) base = GST_MPEGTS_BASE (gst_object_get_parent (GST_OBJECT (pad))); packetizer = base->packetizer; + if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (base->first_buf_ts)) && + GST_BUFFER_TIMESTAMP_IS_VALID (buf)) { + base->first_buf_ts = GST_BUFFER_TIMESTAMP (buf); + GST_DEBUG_OBJECT (base, "first buffer timestamp %" GST_TIME_FORMAT, + GST_TIME_ARGS (base->first_buf_ts)); + } + mpegts_packetizer_push (base->packetizer, buf); while (((pret = mpegts_packetizer_next_packet (base->packetizer, diff --git a/gst/mpegtsdemux/mpegtsbase.h b/gst/mpegtsdemux/mpegtsbase.h index 369078d..1513898 100644 --- a/gst/mpegtsdemux/mpegtsbase.h +++ b/gst/mpegtsdemux/mpegtsbase.h @@ -130,6 +130,10 @@ struct _MpegTSBase { /* Offset from the origin to the first PAT (pullmode) */ guint64 first_pat_offset; + /* interpolation gap between the upstream timestamp and the pts */ + GstClockTime in_gap; + GstClockTime first_buf_ts; + /* Upstream segment */ GstSegment segment; }; diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c index e859ea9..8b685a6 100644 --- a/gst/mpegtsdemux/tsdemux.c +++ b/gst/mpegtsdemux/tsdemux.c @@ -1897,6 +1897,7 @@ TSPcrOffset_find_offset (gconstpointer a, gconstpointer b, gpointer user_data) static GstFlowReturn gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream) { + MpegTSBase *base = (MpegTSBase *) demux; PESHeader header; GstFlowReturn res = GST_FLOW_OK; gint offset = 0; @@ -1945,7 +1946,36 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream) #endif stream->pts = time = MPEGTIME_TO_GSTTIME (header.PTS); - GST_BUFFER_TIMESTAMP (stream->pendingbuffers[0]) = time; + + /* safe default if insufficient upstream info */ + if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (base->in_gap) && + GST_CLOCK_TIME_IS_VALID (base->first_buf_ts) && + base->mode == BASE_MODE_PUSHING && + base->segment.format == GST_FORMAT_TIME)) { + /* Find the earliest current PTS we're going to push */ + GstClockTime firstpts = GST_CLOCK_TIME_NONE; + GList *tmp; + + for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) { + TSDemuxStream *pstream = (TSDemuxStream *) tmp->data; + if (!GST_CLOCK_TIME_IS_VALID (firstpts) || pstream->pts < firstpts) + firstpts = pstream->pts; + } + + base->in_gap = base->first_buf_ts - firstpts; + GST_DEBUG_OBJECT (base, "upstream segment start %" GST_TIME_FORMAT + ", first buffer timestamp: %" GST_TIME_FORMAT + ", first PTS: %" GST_TIME_FORMAT + ", interpolation gap: %" GST_TIME_FORMAT, + GST_TIME_ARGS (base->segment.start), + GST_TIME_ARGS (base->first_buf_ts), GST_TIME_ARGS (firstpts), + GST_TIME_ARGS (base->in_gap)); + } + + if (!GST_CLOCK_TIME_IS_VALID (base->in_gap)) + base->in_gap = 0; + + GST_BUFFER_TIMESTAMP (stream->pendingbuffers[0]) = time + base->in_gap; } if (header.DTS != -1) @@ -2038,9 +2068,7 @@ static void calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream) { MpegTSBase *base = (MpegTSBase *) demux; - GstClockTime firstpts = GST_CLOCK_TIME_NONE; GstEvent *newsegmentevent; - GList *tmp; gint64 start, stop, position; GST_DEBUG ("Creating new newsegment"); @@ -2055,13 +2083,6 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream) * PTS to that remote clock). */ - /* Find the earliest current PTS we're going to push */ - for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) { - TSDemuxStream *pstream = (TSDemuxStream *) tmp->data; - if (!GST_CLOCK_TIME_IS_VALID (firstpts) || pstream->pts < firstpts) - firstpts = pstream->pts; - } - if (base->mode == BASE_MODE_PUSHING) { /* FIXME : We're just ignore the upstream format for the time being */ /* FIXME : We should use base->segment.format and a upstream latency query @@ -2080,10 +2101,9 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream) if (demux->segment.time == 0 && base->segment.format == GST_FORMAT_TIME) demux->segment.time = base->segment.time; - start = firstpts; - stop = GST_CLOCK_TIME_NONE; - position = demux->segment.time ? firstpts - demux->segment.time : 0; - demux->segment.time = start; + start = base->segment.start; + stop = base->segment.stop; + position = base->segment.time; } else { /* pull mode */ GST_DEBUG ("pull-based. Segment start:%" GST_TIME_FORMAT " duration:%"