mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 13:41:48 +00:00
tsdemux: Handle rollover in PTS and DTS
Also hands back-rollover which can happen with PTS
This commit is contained in:
parent
3d34779e24
commit
24408bce96
1 changed files with 75 additions and 13 deletions
|
@ -63,6 +63,7 @@
|
|||
#define PCR_SMALL 17775000
|
||||
/* maximal PCR time */
|
||||
#define PCR_MAX_VALUE (((((guint64)1)<<33) * 300) + 298)
|
||||
#define PTS_DTS_MAX_VALUE (((guint64)1) << 33)
|
||||
|
||||
/* seek to SEEK_TIMESTAMP_OFFSET before the desired offset and search then
|
||||
* either accurately or for the next timestamp
|
||||
|
@ -72,6 +73,8 @@
|
|||
GST_DEBUG_CATEGORY_STATIC (ts_demux_debug);
|
||||
#define GST_CAT_DEFAULT ts_demux_debug
|
||||
|
||||
#define ABSDIFF(a,b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
|
||||
|
||||
static GQuark QUARK_TSDEMUX;
|
||||
static GQuark QUARK_PID;
|
||||
static GQuark QUARK_PCR;
|
||||
|
@ -116,8 +119,15 @@ struct _TSDemuxStream
|
|||
GstBufferListIterator *currentit;
|
||||
GList *currentlist;
|
||||
|
||||
/* Current PTS for this stream */
|
||||
/* Current PTS/DTS for this stream */
|
||||
GstClockTime pts;
|
||||
GstClockTime dts;
|
||||
/* Raw value of current PTS/DTS */
|
||||
guint64 raw_pts;
|
||||
guint64 raw_dts;
|
||||
/* Number of rollover seen for PTS/DTS (default:0) */
|
||||
guint nb_pts_rollover;
|
||||
guint nb_dts_rollover;
|
||||
};
|
||||
|
||||
#define VIDEO_CAPS \
|
||||
|
@ -1229,7 +1239,13 @@ gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * bstream,
|
|||
/* Create the pad */
|
||||
if (bstream->stream_type != 0xff)
|
||||
stream->pad = create_pad_for_stream (base, bstream, program);
|
||||
|
||||
stream->pts = GST_CLOCK_TIME_NONE;
|
||||
stream->dts = GST_CLOCK_TIME_NONE;
|
||||
stream->raw_pts = 0;
|
||||
stream->raw_dts = 0;
|
||||
stream->nb_pts_rollover = 0;
|
||||
stream->nb_dts_rollover = 0;
|
||||
}
|
||||
stream->flow_return = GST_FLOW_OK;
|
||||
}
|
||||
|
@ -1865,9 +1881,33 @@ gst_ts_demux_record_pts (GstTSDemux * demux, TSDemuxStream * stream,
|
|||
{
|
||||
MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
|
||||
|
||||
GST_LOG ("pid 0x%04x pts:%" GST_TIME_FORMAT " at offset %"
|
||||
G_GUINT64_FORMAT, bs->pid,
|
||||
GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (pts)), offset);
|
||||
GST_LOG ("pid 0x%04x pts:%" G_GUINT64_FORMAT " at offset %"
|
||||
G_GUINT64_FORMAT, bs->pid, pts, offset);
|
||||
|
||||
if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (stream->pts) &&
|
||||
ABSDIFF (stream->raw_pts, pts) > 900000)) {
|
||||
/* Detect rollover if diff > 10s */
|
||||
GST_LOG ("Detected rollover (previous:%" G_GUINT64_FORMAT " new:%"
|
||||
G_GUINT64_FORMAT ")", stream->raw_pts, pts);
|
||||
if (pts < stream->raw_pts) {
|
||||
/* Forward rollover */
|
||||
GST_LOG ("Forward rollover, incrementing nb_pts_rollover");
|
||||
stream->nb_pts_rollover++;
|
||||
} else {
|
||||
/* Reverse rollover */
|
||||
GST_LOG ("Reverse rollover, decrementing nb_pts_rollover");
|
||||
stream->nb_pts_rollover--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute PTS in GstClockTime */
|
||||
stream->raw_pts = pts;
|
||||
stream->pts =
|
||||
MPEGTIME_TO_GSTTIME (pts + stream->nb_pts_rollover * PTS_DTS_MAX_VALUE);
|
||||
|
||||
GST_LOG ("pid 0x%04x Stored PTS %" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT ")",
|
||||
bs->pid, stream->raw_pts, GST_TIME_ARGS (stream->pts));
|
||||
|
||||
|
||||
if (G_UNLIKELY (demux->emit_statistics)) {
|
||||
GstStructure *st;
|
||||
|
@ -1887,9 +1927,32 @@ gst_ts_demux_record_dts (GstTSDemux * demux, TSDemuxStream * stream,
|
|||
{
|
||||
MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
|
||||
|
||||
GST_LOG ("pid 0x%04x dts:%" GST_TIME_FORMAT " at offset %"
|
||||
G_GUINT64_FORMAT, bs->pid,
|
||||
GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (dts)), offset);
|
||||
GST_LOG ("pid 0x%04x dts:%" G_GUINT64_FORMAT " at offset %"
|
||||
G_GUINT64_FORMAT, bs->pid, dts, offset);
|
||||
|
||||
if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (stream->dts) &&
|
||||
ABSDIFF (stream->raw_dts, dts) > 900000)) {
|
||||
/* Detect rollover if diff > 10s */
|
||||
GST_LOG ("Detected rollover (previous:%" G_GUINT64_FORMAT " new:%"
|
||||
G_GUINT64_FORMAT ")", stream->raw_dts, dts);
|
||||
if (dts < stream->raw_dts) {
|
||||
/* Forward rollover */
|
||||
GST_LOG ("Forward rollover, incrementing nb_dts_rollover");
|
||||
stream->nb_dts_rollover++;
|
||||
} else {
|
||||
/* Reverse rollover */
|
||||
GST_LOG ("Reverse rollover, decrementing nb_dts_rollover");
|
||||
stream->nb_dts_rollover--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute DTS in GstClockTime */
|
||||
stream->raw_dts = dts;
|
||||
stream->dts =
|
||||
MPEGTIME_TO_GSTTIME (dts + stream->nb_dts_rollover * PTS_DTS_MAX_VALUE);
|
||||
|
||||
GST_LOG ("pid 0x%04x Stored DTS %" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT ")",
|
||||
bs->pid, stream->raw_dts, GST_TIME_ARGS (stream->dts));
|
||||
|
||||
if (G_UNLIKELY (demux->emit_statistics)) {
|
||||
GstStructure *st;
|
||||
|
@ -1939,7 +2002,6 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream)
|
|||
guint8 *data;
|
||||
guint32 length;
|
||||
guint64 bufferoffset;
|
||||
GstClockTime time;
|
||||
PESParsingResult parseres;
|
||||
|
||||
data = GST_BUFFER_DATA (stream->pendingbuffers[0]);
|
||||
|
@ -1957,6 +2019,9 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream)
|
|||
goto discont;
|
||||
}
|
||||
|
||||
if (header.DTS != -1)
|
||||
gst_ts_demux_record_dts (demux, stream, header.DTS, bufferoffset);
|
||||
|
||||
if (header.PTS != -1) {
|
||||
gst_ts_demux_record_pts (demux, stream, header.PTS, bufferoffset);
|
||||
|
||||
|
@ -1980,7 +2045,6 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream)
|
|||
time = calc_gsttime_from_pts (&demux->index_pcr, pts);
|
||||
#endif
|
||||
|
||||
stream->pts = time = MPEGTIME_TO_GSTTIME (header.PTS);
|
||||
GST_DEBUG_OBJECT (base, "stream PTS %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (stream->pts));
|
||||
|
||||
|
@ -2012,12 +2076,10 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream)
|
|||
if (!GST_CLOCK_TIME_IS_VALID (base->in_gap))
|
||||
base->in_gap = 0;
|
||||
|
||||
GST_BUFFER_TIMESTAMP (stream->pendingbuffers[0]) = time + base->in_gap;
|
||||
GST_BUFFER_TIMESTAMP (stream->pendingbuffers[0]) =
|
||||
stream->pts + base->in_gap;
|
||||
}
|
||||
|
||||
if (header.DTS != -1)
|
||||
gst_ts_demux_record_dts (demux, stream, header.DTS, bufferoffset);
|
||||
|
||||
/* Remove PES headers */
|
||||
GST_DEBUG ("Moving data forward by %d bytes", header.header_size);
|
||||
GST_BUFFER_DATA (stream->pendingbuffers[0]) += header.header_size;
|
||||
|
|
Loading…
Reference in a new issue