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
This commit is contained in:
Edward Hervey 2012-05-20 13:27:29 +02:00
parent 09209045b6
commit 6d01f5f1b3
2 changed files with 18 additions and 11 deletions

View File

@ -33,6 +33,7 @@
/* maximal PCR time */ /* maximal PCR time */
#define PCR_MAX_VALUE (((((guint64)1)<<33) * 300) + 298) #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) #define PTS_DTS_MAX_VALUE (((guint64)1) << 33)
#include "mpegtspacketizer.h" #include "mpegtspacketizer.h"
@ -2956,6 +2957,7 @@ mpegts_packetizer_reset_skew (MpegTSPacketizer2 * packetizer)
packetizer->skew = 0; packetizer->skew = 0;
packetizer->prev_send_diff = GST_CLOCK_TIME_NONE; packetizer->prev_send_diff = GST_CLOCK_TIME_NONE;
packetizer->prev_out_time = GST_CLOCK_TIME_NONE; packetizer->prev_out_time = GST_CLOCK_TIME_NONE;
packetizer->wrap_count = 0;
GST_DEBUG ("reset skew correction"); GST_DEBUG ("reset skew correction");
} }
@ -3053,10 +3055,8 @@ calculate_skew (MpegTSPacketizer2 * packetizer, guint64 pcrtime,
GstClockTime gstpcrtime, out_time; GstClockTime gstpcrtime, out_time;
guint64 slope; guint64 slope;
gstpcrtime = PCRTIME_TO_GSTTIME (pcrtime); gstpcrtime =
PCRTIME_TO_GSTTIME (pcrtime) + packetizer->wrap_count * PCR_GST_MAX_VALUE;
/* keep track of the last extended pcrtime */
packetizer->last_pcrtime = gstpcrtime;
/* first time, lock on to time and gstpcrtime */ /* first time, lock on to time and gstpcrtime */
if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (packetizer->base_time))) { 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)) if (G_LIKELY (gstpcrtime >= packetizer->base_pcrtime))
send_diff = gstpcrtime - packetizer->base_pcrtime; send_diff = gstpcrtime - packetizer->base_pcrtime;
else if (GST_CLOCK_TIME_IS_VALID (time)) { else if (GST_CLOCK_TIME_IS_VALID (time)
/* elapsed time at sender, timestamps can go backwards and thus be smaller && (packetizer->last_pcrtime - gstpcrtime > PCR_GST_MAX_VALUE / 2)) {
* than our base time, take a new base time in that case. */ /* Detect wraparounds */
GST_WARNING ("backward timestamps at server, taking new base time"); GST_DEBUG ("PCR wrap");
mpegts_packetizer_resync (packetizer, time, gstpcrtime, FALSE); packetizer->wrap_count++;
send_diff = 0; gstpcrtime =
PCRTIME_TO_GSTTIME (pcrtime) +
packetizer->wrap_count * PCR_GST_MAX_VALUE;
send_diff = gstpcrtime - packetizer->base_pcrtime;
} else { } else {
GST_WARNING ("backward timestamps at server but no timestamps"); GST_WARNING ("backward timestamps at server but no timestamps");
send_diff = 0; send_diff = 0;
/* at least try to get a new timestamp.. */ /* 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 %" 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 (gstpcrtime), GST_TIME_ARGS (time),
GST_TIME_ARGS (packetizer->base_pcrtime), GST_TIME_ARGS (send_diff)); 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 /* 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 */ * should still apply a timestamp based on RTP timestamp and base_time */
if (!GST_CLOCK_TIME_IS_VALID (time) if (!GST_CLOCK_TIME_IS_VALID (time)

View File

@ -104,6 +104,7 @@ struct _MpegTSPacketizer2 {
gint64 window_min; gint64 window_min;
gint64 skew; gint64 skew;
gint64 prev_send_diff; gint64 prev_send_diff;
gint wrap_count;
/* offset/bitrate calculator */ /* offset/bitrate calculator */
gboolean calculate_offset; gboolean calculate_offset;