From 6d01f5f1b3f14a29bd2cc16f8ddc452ff0928505 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Sun, 20 May 2012 13:27:29 +0200 Subject: [PATCH] mpegtspacketizer: Detect PCR wraparound in skew code If the received PCR is going backwards (by a safe margin), include that wraparound for further calculation. https://bugzilla.gnome.org/show_bug.cgi?id=674536 --- gst/mpegtsdemux/mpegtspacketizer.c | 28 +++++++++++++++++----------- gst/mpegtsdemux/mpegtspacketizer.h | 1 + 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/gst/mpegtsdemux/mpegtspacketizer.c b/gst/mpegtsdemux/mpegtspacketizer.c index 84a0b59..d25bc9e 100644 --- a/gst/mpegtsdemux/mpegtspacketizer.c +++ b/gst/mpegtsdemux/mpegtspacketizer.c @@ -33,6 +33,7 @@ /* maximal PCR time */ #define PCR_MAX_VALUE (((((guint64)1)<<33) * 300) + 298) +#define PCR_GST_MAX_VALUE (PCR_MAX_VALUE * GST_MSECOND / (27000)) #define PTS_DTS_MAX_VALUE (((guint64)1) << 33) #include "mpegtspacketizer.h" @@ -2956,6 +2957,7 @@ mpegts_packetizer_reset_skew (MpegTSPacketizer2 * packetizer) packetizer->skew = 0; packetizer->prev_send_diff = GST_CLOCK_TIME_NONE; packetizer->prev_out_time = GST_CLOCK_TIME_NONE; + packetizer->wrap_count = 0; GST_DEBUG ("reset skew correction"); } @@ -3053,10 +3055,8 @@ calculate_skew (MpegTSPacketizer2 * packetizer, guint64 pcrtime, GstClockTime gstpcrtime, out_time; guint64 slope; - gstpcrtime = PCRTIME_TO_GSTTIME (pcrtime); - - /* keep track of the last extended pcrtime */ - packetizer->last_pcrtime = gstpcrtime; + gstpcrtime = + PCRTIME_TO_GSTTIME (pcrtime) + packetizer->wrap_count * PCR_GST_MAX_VALUE; /* first time, lock on to time and gstpcrtime */ if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (packetizer->base_time))) { @@ -3074,17 +3074,20 @@ calculate_skew (MpegTSPacketizer2 * packetizer, guint64 pcrtime, if (G_LIKELY (gstpcrtime >= packetizer->base_pcrtime)) send_diff = gstpcrtime - packetizer->base_pcrtime; - else if (GST_CLOCK_TIME_IS_VALID (time)) { - /* elapsed time at sender, timestamps can go backwards and thus be smaller - * than our base time, take a new base time in that case. */ - GST_WARNING ("backward timestamps at server, taking new base time"); - mpegts_packetizer_resync (packetizer, time, gstpcrtime, FALSE); - send_diff = 0; + else if (GST_CLOCK_TIME_IS_VALID (time) + && (packetizer->last_pcrtime - gstpcrtime > PCR_GST_MAX_VALUE / 2)) { + /* Detect wraparounds */ + GST_DEBUG ("PCR wrap"); + packetizer->wrap_count++; + gstpcrtime = + PCRTIME_TO_GSTTIME (pcrtime) + + packetizer->wrap_count * PCR_GST_MAX_VALUE; + send_diff = gstpcrtime - packetizer->base_pcrtime; } else { GST_WARNING ("backward timestamps at server but no timestamps"); send_diff = 0; /* at least try to get a new timestamp.. */ - packetizer->base_time = -1; + packetizer->base_time = GST_CLOCK_TIME_NONE; } GST_DEBUG ("gstpcr %" GST_TIME_FORMAT ", buftime %" GST_TIME_FORMAT ", base %" @@ -3092,6 +3095,9 @@ calculate_skew (MpegTSPacketizer2 * packetizer, guint64 pcrtime, GST_TIME_ARGS (gstpcrtime), GST_TIME_ARGS (time), GST_TIME_ARGS (packetizer->base_pcrtime), GST_TIME_ARGS (send_diff)); + /* keep track of the last extended pcrtime */ + packetizer->last_pcrtime = gstpcrtime; + /* we don't have an arrival timestamp so we can't do skew detection. we * should still apply a timestamp based on RTP timestamp and base_time */ if (!GST_CLOCK_TIME_IS_VALID (time) diff --git a/gst/mpegtsdemux/mpegtspacketizer.h b/gst/mpegtsdemux/mpegtspacketizer.h index f588cd3..f4811ca 100644 --- a/gst/mpegtsdemux/mpegtspacketizer.h +++ b/gst/mpegtsdemux/mpegtspacketizer.h @@ -104,6 +104,7 @@ struct _MpegTSPacketizer2 { gint64 window_min; gint64 skew; gint64 prev_send_diff; + gint wrap_count; /* offset/bitrate calculator */ gboolean calculate_offset; -- 2.7.4