mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-02 16:52:42 +00:00
tsdemux: Use incoming timestamps in live mode
This commit is contained in:
parent
8f433e1677
commit
8b73baeced
2 changed files with 58 additions and 12 deletions
|
@ -310,6 +310,7 @@ gst_ts_demux_init (GstTSDemux * demux, GstTSDemuxClass * klass)
|
||||||
demux->need_newsegment = TRUE;
|
demux->need_newsegment = TRUE;
|
||||||
demux->program_number = -1;
|
demux->program_number = -1;
|
||||||
demux->duration = GST_CLOCK_TIME_NONE;
|
demux->duration = GST_CLOCK_TIME_NONE;
|
||||||
|
demux->pts_delta = GST_CLOCK_TIME_NONE;
|
||||||
GST_MPEGTS_BASE (demux)->stream_size = sizeof (TSDemuxStream);
|
GST_MPEGTS_BASE (demux)->stream_size = sizeof (TSDemuxStream);
|
||||||
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
|
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
|
||||||
demux->first_pcr = (TSPcrOffset) {
|
demux->first_pcr = (TSPcrOffset) {
|
||||||
|
@ -333,6 +334,7 @@ gst_ts_demux_reset (MpegTSBase * base)
|
||||||
demux->need_newsegment = TRUE;
|
demux->need_newsegment = TRUE;
|
||||||
demux->program_number = -1;
|
demux->program_number = -1;
|
||||||
demux->duration = GST_CLOCK_TIME_NONE;
|
demux->duration = GST_CLOCK_TIME_NONE;
|
||||||
|
demux->pts_delta = GST_CLOCK_TIME_NONE;
|
||||||
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
|
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
|
||||||
demux->first_pcr = (TSPcrOffset) {
|
demux->first_pcr = (TSPcrOffset) {
|
||||||
GST_CLOCK_TIME_NONE, 0, 0};
|
GST_CLOCK_TIME_NONE, 0, 0};
|
||||||
|
@ -2039,9 +2041,11 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream)
|
||||||
guint32 length;
|
guint32 length;
|
||||||
guint64 bufferoffset;
|
guint64 bufferoffset;
|
||||||
PESParsingResult parseres;
|
PESParsingResult parseres;
|
||||||
|
GstClockTime origts;
|
||||||
|
|
||||||
data = GST_BUFFER_DATA (stream->pendingbuffers[0]);
|
data = GST_BUFFER_DATA (stream->pendingbuffers[0]);
|
||||||
length = GST_BUFFER_SIZE (stream->pendingbuffers[0]);
|
length = GST_BUFFER_SIZE (stream->pendingbuffers[0]);
|
||||||
|
origts = GST_BUFFER_TIMESTAMP (stream->pendingbuffers[0]);
|
||||||
bufferoffset = GST_BUFFER_OFFSET (stream->pendingbuffers[0]);
|
bufferoffset = GST_BUFFER_OFFSET (stream->pendingbuffers[0]);
|
||||||
|
|
||||||
GST_MEMDUMP ("Header buffer", data, MIN (length, 32));
|
GST_MEMDUMP ("Header buffer", data, MIN (length, 32));
|
||||||
|
@ -2081,8 +2085,24 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream)
|
||||||
time = calc_gsttime_from_pts (&demux->index_pcr, pts);
|
time = calc_gsttime_from_pts (&demux->index_pcr, pts);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (base, "stream PTS %" GST_TIME_FORMAT,
|
GST_DEBUG_OBJECT (base,
|
||||||
GST_TIME_ARGS (stream->pts));
|
"stream PTS %" GST_TIME_FORMAT " DTS %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (stream->pts),
|
||||||
|
GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (header.DTS)));
|
||||||
|
|
||||||
|
/* FIXME : This will only work if the PES header is contained
|
||||||
|
* at the beginning of an incoming GstBuffer */
|
||||||
|
if (base->upstream_live && GST_CLOCK_TIME_IS_VALID (origts)
|
||||||
|
&& !GST_CLOCK_TIME_IS_VALID (demux->pts_delta)) {
|
||||||
|
if (header.DTS != -1)
|
||||||
|
demux->pts_delta = MPEGTIME_TO_GSTTIME (header.DTS) - origts;
|
||||||
|
else
|
||||||
|
demux->pts_delta = stream->pts - origts;
|
||||||
|
GST_DEBUG_OBJECT (base, "buffer timestamp %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (origts));
|
||||||
|
GST_DEBUG_OBJECT (base, "delta %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (demux->pts_delta));
|
||||||
|
}
|
||||||
|
|
||||||
/* safe default if insufficient upstream info */
|
/* safe default if insufficient upstream info */
|
||||||
if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (base->in_gap) &&
|
if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (base->in_gap) &&
|
||||||
|
@ -2112,8 +2132,16 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream)
|
||||||
if (!GST_CLOCK_TIME_IS_VALID (base->in_gap))
|
if (!GST_CLOCK_TIME_IS_VALID (base->in_gap))
|
||||||
base->in_gap = 0;
|
base->in_gap = 0;
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (stream->pendingbuffers[0]) =
|
if (base->upstream_live) {
|
||||||
stream->pts + base->in_gap;
|
if (GST_CLOCK_TIME_IS_VALID (demux->pts_delta))
|
||||||
|
GST_BUFFER_TIMESTAMP (stream->pendingbuffers[0]) =
|
||||||
|
stream->pts - demux->pts_delta;
|
||||||
|
else
|
||||||
|
GST_BUFFER_TIMESTAMP (stream->pendingbuffers[0]) = GST_CLOCK_TIME_NONE;
|
||||||
|
} else
|
||||||
|
GST_BUFFER_TIMESTAMP (stream->pendingbuffers[0]) = stream->pts + base->in_gap;
|
||||||
|
GST_DEBUG ("buf %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (stream->pendingbuffers[0])));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove PES headers */
|
/* Remove PES headers */
|
||||||
|
@ -2250,8 +2278,10 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream)
|
||||||
start = base->segment.start;
|
start = base->segment.start;
|
||||||
stop = base->segment.stop;
|
stop = base->segment.stop;
|
||||||
}
|
}
|
||||||
/* Shift the start depending on our position in the stream */
|
if (!base->upstream_live) {
|
||||||
start += firstpts + base->in_gap - base->first_buf_ts;
|
/* Shift the start depending on our position in the stream */
|
||||||
|
start += firstpts + base->in_gap - base->first_buf_ts;
|
||||||
|
}
|
||||||
position = start;
|
position = start;
|
||||||
} else {
|
} else {
|
||||||
/* pull mode */
|
/* pull mode */
|
||||||
|
@ -2289,10 +2319,12 @@ gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream)
|
||||||
{
|
{
|
||||||
GstFlowReturn res = GST_FLOW_OK;
|
GstFlowReturn res = GST_FLOW_OK;
|
||||||
MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
|
MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
|
||||||
|
/* MpegTSBase *base = (MpegTSBase*) demux; */
|
||||||
|
GstBuffer *firstbuffer = NULL;
|
||||||
|
|
||||||
GST_DEBUG ("stream:%p, pid:0x%04x stream_type:%d state:%d pad:%s:%s",
|
GST_DEBUG_OBJECT (stream->pad,
|
||||||
stream, bs->pid, bs->stream_type, stream->state,
|
"stream:%p, pid:0x%04x stream_type:%d state:%d", stream, bs->pid,
|
||||||
GST_DEBUG_PAD_NAME (stream->pad));
|
bs->stream_type, stream->state);
|
||||||
|
|
||||||
if (G_UNLIKELY (stream->current == NULL)) {
|
if (G_UNLIKELY (stream->current == NULL)) {
|
||||||
GST_LOG ("stream->current == NULL");
|
GST_LOG ("stream->current == NULL");
|
||||||
|
@ -2319,15 +2351,25 @@ gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream)
|
||||||
calculate_and_push_newsegment (demux, stream);
|
calculate_and_push_newsegment (demux, stream);
|
||||||
|
|
||||||
/* We have a confirmed buffer, let's push it out */
|
/* We have a confirmed buffer, let's push it out */
|
||||||
GST_LOG ("Putting pending data into GstBufferList");
|
GST_LOG_OBJECT (stream->pad, "Putting pending data into GstBufferList");
|
||||||
stream->currentlist = g_list_reverse (stream->currentlist);
|
stream->currentlist = g_list_reverse (stream->currentlist);
|
||||||
gst_buffer_list_iterator_add_list (stream->currentit, stream->currentlist);
|
gst_buffer_list_iterator_add_list (stream->currentit, stream->currentlist);
|
||||||
gst_buffer_list_iterator_free (stream->currentit);
|
gst_buffer_list_iterator_free (stream->currentit);
|
||||||
|
|
||||||
|
firstbuffer = gst_buffer_list_get (stream->current, 0, 0);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (stream->pad,
|
||||||
|
"delta %" GST_TIME_FORMAT " stream->pts %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (demux->pts_delta), GST_TIME_ARGS (stream->pts));
|
||||||
|
if (GST_CLOCK_TIME_IS_VALID (demux->pts_delta)
|
||||||
|
&& GST_CLOCK_TIME_IS_VALID (stream->pts)
|
||||||
|
&& !GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (firstbuffer))) {
|
||||||
|
GST_BUFFER_TIMESTAMP (firstbuffer) = stream->pts - demux->pts_delta;
|
||||||
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (stream->pad,
|
GST_DEBUG_OBJECT (stream->pad,
|
||||||
"Pushing buffer list with timestamp: %" GST_TIME_FORMAT,
|
"Pushing buffer list with timestamp: %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (gst_buffer_list_get
|
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (firstbuffer)));
|
||||||
(stream->current, 0, 0))));
|
|
||||||
|
|
||||||
res = gst_pad_push_list (stream->pad, stream->current);
|
res = gst_pad_push_list (stream->pad, stream->current);
|
||||||
GST_DEBUG_OBJECT (stream->pad, "Returned %s", gst_flow_get_name (res));
|
GST_DEBUG_OBJECT (stream->pad, "Returned %s", gst_flow_get_name (res));
|
||||||
|
|
|
@ -81,6 +81,10 @@ struct _GstTSDemux
|
||||||
TSPcrOffset last_pcr;
|
TSPcrOffset last_pcr;
|
||||||
TSPcrOffset cur_pcr;
|
TSPcrOffset cur_pcr;
|
||||||
TSPcrOffset index_pcr;
|
TSPcrOffset index_pcr;
|
||||||
|
|
||||||
|
/* LIVE MODE ONLY */
|
||||||
|
/* Delta between incoming ts and PTS */
|
||||||
|
GstClockTime pts_delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstTSDemuxClass
|
struct _GstTSDemuxClass
|
||||||
|
|
Loading…
Reference in a new issue