mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
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:
parent
9d0545d1a2
commit
32d650491c
5 changed files with 45 additions and 38 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue