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.
This commit is contained in:
Jan Schmidt 2018-09-20 01:05:52 +10:00
parent b7c4785a22
commit b4a298c80e

View file

@ -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);