mpegts: Re-work segment tracking

Add an output segment into the base class for sub-classes
to use for their output segment, in a place where the base
class can see it.
This commit is contained in:
Jan Schmidt 2018-08-31 22:43:46 +10:00
parent 9d0545d1a2
commit 32d650491c
5 changed files with 45 additions and 38 deletions

View file

@ -206,6 +206,7 @@ mpegts_base_reset (MpegTSBase * base)
} }
gst_segment_init (&base->segment, GST_FORMAT_UNDEFINED); gst_segment_init (&base->segment, GST_FORMAT_UNDEFINED);
gst_segment_init (&base->out_segment, GST_FORMAT_UNDEFINED);
base->last_seek_seqnum = GST_SEQNUM_INVALID; base->last_seek_seqnum = GST_SEQNUM_INVALID;
base->mode = BASE_MODE_STREAMING; base->mode = BASE_MODE_STREAMING;

View file

@ -148,6 +148,9 @@ struct _MpegTSBase {
/* Upstream segment */ /* Upstream segment */
GstSegment segment; GstSegment segment;
/* Downstream segment, for use by sub-classes */
GstSegment out_segment;
/* Last received seek event seqnum (default GST_SEQNUM_INVALID) */ /* Last received seek event seqnum (default GST_SEQNUM_INVALID) */
guint last_seek_seqnum; guint last_seek_seqnum;

View file

@ -343,14 +343,16 @@ prepare_src_pad (MpegTSBase * base, MpegTSParse2 * parse)
/* If setting output timestamps, ensure that the output segment is TIME */ /* If setting output timestamps, ensure that the output segment is TIME */
if (parse->set_timestamps == FALSE || base->segment.format == GST_FORMAT_TIME) if (parse->set_timestamps == FALSE || base->segment.format == GST_FORMAT_TIME)
gst_pad_push_event (parse->srcpad, gst_event_new_segment (&base->segment)); /* Just use the upstream segment */
base->out_segment = base->segment;
else { else {
GstSegment seg; GstSegment *seg = &base->out_segment;
gst_segment_init (&seg, GST_FORMAT_TIME); gst_segment_init (seg, GST_FORMAT_TIME);
GST_DEBUG_OBJECT (parse, GST_DEBUG_OBJECT (parse,
"Generating time output segment %" GST_SEGMENT_FORMAT, &seg); "Generating time output segment %" GST_SEGMENT_FORMAT, seg);
gst_pad_push_event (parse->srcpad, gst_event_new_segment (&seg));
} }
gst_pad_push_event (parse->srcpad,
gst_event_new_segment (&base->out_segment));
parse->first = FALSE; parse->first = FALSE;

View file

@ -413,7 +413,6 @@ gst_ts_demux_reset (MpegTSBase * base)
GstTSDemux *demux = (GstTSDemux *) base; GstTSDemux *demux = (GstTSDemux *) base;
demux->rate = 1.0; demux->rate = 1.0;
gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
if (demux->segment_event) { if (demux->segment_event) {
gst_event_unref (demux->segment_event); gst_event_unref (demux->segment_event);
demux->segment_event = NULL; demux->segment_event = NULL;
@ -598,17 +597,18 @@ gst_ts_demux_srcpad_query (GstPad * pad, GstObject * parent, GstQuery * query)
GstFormat format; GstFormat format;
gint64 start, stop; gint64 start, stop;
format = demux->segment.format; format = base->out_segment.format;
start = start =
gst_segment_to_stream_time (&demux->segment, format, gst_segment_to_stream_time (&base->out_segment, format,
demux->segment.start); base->out_segment.start);
if ((stop = demux->segment.stop) == -1) if ((stop = base->out_segment.stop) == -1)
stop = demux->segment.duration; stop = base->out_segment.duration;
else else
stop = gst_segment_to_stream_time (&demux->segment, format, stop); stop = gst_segment_to_stream_time (&base->out_segment, format, stop);
gst_query_set_segment (query, demux->segment.rate, format, start, stop); gst_query_set_segment (query, base->out_segment.rate, format, start,
stop);
res = TRUE; res = TRUE;
break; break;
} }
@ -871,7 +871,7 @@ gst_ts_demux_do_seek (MpegTSBase * base, GstEvent * event)
stream->need_newsegment = TRUE; stream->need_newsegment = TRUE;
} }
gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED); gst_segment_init (&base->out_segment, GST_FORMAT_UNDEFINED);
if (demux->segment_event) { if (demux->segment_event) {
gst_event_unref (demux->segment_event); gst_event_unref (demux->segment_event);
demux->segment_event = NULL; demux->segment_event = NULL;
@ -887,7 +887,7 @@ gst_ts_demux_do_seek (MpegTSBase * base, GstEvent * event)
demux->rate = rate; demux->rate = rate;
res = GST_FLOW_OK; res = GST_FLOW_OK;
gst_segment_do_seek (&demux->segment, rate, format, flags, start_type, gst_segment_do_seek (&base->out_segment, rate, format, flags, start_type,
start, stop_type, stop, NULL); start, stop_type, stop, NULL);
/* Reset segment if we're not doing an accurate seek */ /* Reset segment if we're not doing an accurate seek */
demux->reset_segment = (!(flags & GST_SEEK_FLAG_ACCURATE)); demux->reset_segment = (!(flags & GST_SEEK_FLAG_ACCURATE));
@ -1795,7 +1795,8 @@ gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * bstream,
stream->need_newsegment = TRUE; stream->need_newsegment = TRUE;
/* Reset segment if we're not doing an accurate seek */ /* Reset segment if we're not doing an accurate seek */
demux->reset_segment = (!(demux->segment.flags & GST_SEEK_FLAG_ACCURATE)); demux->reset_segment =
(!(base->out_segment.flags & GST_SEEK_FLAG_ACCURATE));
stream->needs_keyframe = FALSE; stream->needs_keyframe = FALSE;
stream->discont = TRUE; stream->discont = TRUE;
stream->pts = GST_CLOCK_TIME_NONE; stream->pts = GST_CLOCK_TIME_NONE;
@ -2482,37 +2483,37 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream,
GST_DEBUG ("lowest_pts %" G_GUINT64_FORMAT " => clocktime %" GST_TIME_FORMAT, GST_DEBUG ("lowest_pts %" G_GUINT64_FORMAT " => clocktime %" GST_TIME_FORMAT,
lowest_pts, GST_TIME_ARGS (firstts)); lowest_pts, GST_TIME_ARGS (firstts));
if (demux->segment.format != GST_FORMAT_TIME || demux->reset_segment) { if (base->out_segment.format != GST_FORMAT_TIME || demux->reset_segment) {
/* It will happen only if it's first program or after flushes. */ /* It will happen only if it's first program or after flushes. */
GST_DEBUG ("Calculating actual segment"); GST_DEBUG ("Calculating actual segment");
if (base->segment.format == GST_FORMAT_TIME) { if (base->segment.format == GST_FORMAT_TIME) {
/* Try to recover segment info from base if it's in TIME format */ /* Try to recover segment info from base if it's in TIME format */
demux->segment = base->segment; base->out_segment = base->segment;
} else { } else {
/* Start from the first ts/pts */ /* Start from the first ts/pts */
GstClockTime base = GstSegment *seg = &base->out_segment;
demux->segment.base + demux->segment.position - demux->segment.start; GstClockTime base = seg->base + seg->position - seg->start;
gst_segment_init (&demux->segment, GST_FORMAT_TIME); gst_segment_init (seg, GST_FORMAT_TIME);
demux->segment.start = firstts; seg->start = firstts;
demux->segment.stop = GST_CLOCK_TIME_NONE; seg->stop = GST_CLOCK_TIME_NONE;
demux->segment.position = firstts; seg->position = firstts;
demux->segment.time = firstts; seg->time = firstts;
demux->segment.rate = demux->rate; seg->rate = demux->rate;
demux->segment.base = base; seg->base = base;
} }
} else if (demux->segment.start < firstts) { } else if (base->out_segment.start < firstts) {
/* Take into account the offset to the first buffer timestamp */ /* Take into account the offset to the first buffer timestamp */
if (demux->segment.rate > 0) { if (base->out_segment.rate > 0) {
demux->segment.start = firstts; base->out_segment.start = firstts;
if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop)) if (GST_CLOCK_TIME_IS_VALID (base->out_segment.stop))
demux->segment.stop += firstts - demux->segment.start; base->out_segment.stop += firstts - base->out_segment.start;
demux->segment.position = firstts; base->out_segment.position = firstts;
} }
} }
if (!demux->segment_event) { if (!demux->segment_event) {
demux->segment_event = gst_event_new_segment (&demux->segment); demux->segment_event = gst_event_new_segment (&base->out_segment);
if (base->last_seek_seqnum != GST_SEQNUM_INVALID) if (base->last_seek_seqnum != GST_SEQNUM_INVALID)
gst_event_set_seqnum (demux->segment_event, base->last_seek_seqnum); gst_event_set_seqnum (demux->segment_event, base->last_seek_seqnum);
@ -2852,6 +2853,7 @@ static GstFlowReturn
gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream, gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream,
MpegTSBaseProgram * target_program) MpegTSBaseProgram * target_program)
{ {
MpegTSBase *base = GST_MPEGTS_BASE (demux);
GstFlowReturn res = GST_FLOW_OK; GstFlowReturn res = GST_FLOW_OK;
MpegTSBaseStream *bs = (MpegTSBaseStream *) stream; MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
GstBuffer *buffer = NULL; GstBuffer *buffer = NULL;
@ -3050,9 +3052,9 @@ gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream,
GST_TIME_ARGS (stream->dts)); GST_TIME_ARGS (stream->dts));
if (GST_CLOCK_TIME_IS_VALID (stream->dts)) if (GST_CLOCK_TIME_IS_VALID (stream->dts))
demux->segment.position = stream->dts; base->out_segment.position = stream->dts;
else if (GST_CLOCK_TIME_IS_VALID (stream->pts)) else if (GST_CLOCK_TIME_IS_VALID (stream->pts))
demux->segment.position = stream->pts; base->out_segment.position = stream->pts;
if (buffer) { if (buffer) {
res = gst_pad_push (stream->pad, buffer); res = gst_pad_push (stream->pad, buffer);
@ -3158,7 +3160,7 @@ gst_ts_demux_flush (MpegTSBase * base, gboolean hard)
if (hard) { if (hard) {
/* For pull mode seeks the current segment needs to be preserved */ /* For pull mode seeks the current segment needs to be preserved */
demux->rate = 1.0; demux->rate = 1.0;
gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED); gst_segment_init (&base->out_segment, GST_FORMAT_UNDEFINED);
} }
} }

View file

@ -84,7 +84,6 @@ struct _GstTSDemux
* the new program becomes active */ * the new program becomes active */
/* segments to be sent */ /* segments to be sent */
GstSegment segment;
GstEvent *segment_event; GstEvent *segment_event;
gboolean reset_segment; gboolean reset_segment;