From b4a298c80e1c24a74910e096d08c7f6678d8938b Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 20 Sep 2018 01:05:52 +1000 Subject: [PATCH] tsdemux: Use gst_segment_do_seek() Remove some custom and incomplete seek calculation logic in favour of gst_segment_do_seek(), and short-circuit any actual seeking or recalculation if the position didn't change and just send an updated segment directly. This removes the custom seeking logic in favour of using standard core seek handling. --- gst/mpegtsdemux/tsdemux.c | 105 ++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 44 deletions(-) diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c index 5b5f807bae..84f26c3ba3 100644 --- a/gst/mpegtsdemux/tsdemux.c +++ b/gst/mpegtsdemux/tsdemux.c @@ -835,14 +835,14 @@ gst_ts_demux_do_seek (MpegTSBase * base, GstEvent * event) GstSeekType start_type, stop_type; gint64 start, stop; guint64 start_offset; + gboolean update = FALSE; + GstSegment seeksegment; + + GST_DEBUG ("seek event, %" GST_PTR_FORMAT, event); gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start, &stop_type, &stop); - GST_DEBUG ("seek event, rate: %f start: %" GST_TIME_FORMAT - " stop: %" GST_TIME_FORMAT, rate, GST_TIME_ARGS (start), - GST_TIME_ARGS (stop)); - if (rate <= 0.0) { GST_WARNING ("Negative rate not supported"); goto done; @@ -854,61 +854,74 @@ gst_ts_demux_do_seek (MpegTSBase * base, GstEvent * event) } /* configure the segment with the seek variables */ - GST_DEBUG_OBJECT (demux, "configuring seek"); + memcpy (&seeksegment, &base->out_segment, sizeof (GstSegment)); + GST_LOG_OBJECT (demux, "Before seek, output segment %" GST_SEGMENT_FORMAT, + &seeksegment); + + /* record offset and rate */ + demux->rate = rate; + if (!gst_segment_do_seek (&seeksegment, rate, format, flags, start_type, + start, stop_type, stop, &update)) { + GST_DEBUG_OBJECT (demux, "Seek failed in gst_segment_do_seek()"); + goto done; + } + + GST_DEBUG_OBJECT (demux, + "After seek, update %d output segment now %" GST_SEGMENT_FORMAT, update, + &seeksegment); + + /* If the position actually changed, update == TRUE */ + if (update) { + GstClockTime target = base->out_segment.start; + if (target >= SEEK_TIMESTAMP_OFFSET) + target -= SEEK_TIMESTAMP_OFFSET; + else + target = 0; - if (start_type != GST_SEEK_TYPE_NONE) { start_offset = - mpegts_packetizer_ts_to_offset (base->packetizer, MAX (0, - start - SEEK_TIMESTAMP_OFFSET), demux->program->pcr_pid); - + mpegts_packetizer_ts_to_offset (base->packetizer, target, + demux->program->pcr_pid); if (G_UNLIKELY (start_offset == -1)) { GST_WARNING ("Couldn't convert start position to an offset"); goto done; } - } else { + + base->seek_offset = start_offset; + demux->last_seek_offset = base->seek_offset; + /* Reset segment if we're not doing an accurate seek */ + demux->reset_segment = (!(flags & GST_SEEK_FLAG_ACCURATE)); + + /* Clear any existing segment - it will be recalculated after streaming recommences */ + gst_event_replace (&demux->segment_event, NULL); + for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) { TSDemuxStream *stream = tmp->data; + if (flags & GST_SEEK_FLAG_ACCURATE) + stream->needs_keyframe = TRUE; + + stream->seeked_pts = GST_CLOCK_TIME_NONE; + stream->seeked_dts = GST_CLOCK_TIME_NONE; + stream->first_pts = GST_CLOCK_TIME_NONE; stream->need_newsegment = TRUE; } - gst_segment_init (&base->out_segment, GST_FORMAT_UNDEFINED); - if (demux->segment_event) { - gst_event_unref (demux->segment_event); - demux->segment_event = NULL; + } else { + /* Position didn't change, just update the output segment based on + * our new one */ + gst_event_replace (&demux->segment_event, NULL); + demux->segment_event = gst_event_new_segment (&seeksegment); + if (base->last_seek_seqnum) + gst_event_set_seqnum (demux->segment_event, base->last_seek_seqnum); + for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) { + TSDemuxStream *stream = tmp->data; + stream->need_newsegment = TRUE; } - demux->rate = rate; - res = GST_FLOW_OK; - goto done; } - /* record offset and rate */ - base->seek_offset = start_offset; - demux->last_seek_offset = base->seek_offset; - demux->rate = rate; + /* Commit the new segment */ + memcpy (&base->out_segment, &seeksegment, sizeof (GstSegment)); res = GST_FLOW_OK; - gst_segment_do_seek (&base->out_segment, rate, format, flags, start_type, - start, stop_type, stop, NULL); - /* Reset segment if we're not doing an accurate seek */ - demux->reset_segment = (!(flags & GST_SEEK_FLAG_ACCURATE)); - - if (demux->segment_event) { - gst_event_unref (demux->segment_event); - demux->segment_event = NULL; - } - - for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) { - TSDemuxStream *stream = tmp->data; - - if (flags & GST_SEEK_FLAG_ACCURATE) - stream->needs_keyframe = TRUE; - - stream->seeked_pts = GST_CLOCK_TIME_NONE; - stream->seeked_dts = GST_CLOCK_TIME_NONE; - stream->need_newsegment = TRUE; - stream->first_pts = GST_CLOCK_TIME_NONE; - } - done: return res; } @@ -2492,7 +2505,8 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream, } else { /* Start from the first ts/pts */ GstSegment *seg = &base->out_segment; - GstClockTime base = seg->base + seg->position - seg->start; + GstClockTime base = + seg->base + seg->position - (seg->start + seg->offset); gst_segment_init (seg, GST_FORMAT_TIME); seg->start = firstts; seg->stop = GST_CLOCK_TIME_NONE; @@ -2512,6 +2526,9 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream, } } + GST_LOG_OBJECT (demux, "Output segment now %" GST_SEGMENT_FORMAT, + &base->out_segment); + if (!demux->segment_event) { demux->segment_event = gst_event_new_segment (&base->out_segment);