diff --git a/gst/mpegtsdemux/mpegtspacketizer.c b/gst/mpegtsdemux/mpegtspacketizer.c
index 5c04cbb..0827074 100644
--- a/gst/mpegtsdemux/mpegtspacketizer.c
+++ b/gst/mpegtsdemux/mpegtspacketizer.c
@@ -3030,7 +3030,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;
+  packetizer->pcr_reset_diff = 0;
   GST_DEBUG ("reset skew correction");
 }
 
@@ -3129,7 +3129,7 @@ calculate_skew (MpegTSPacketizer2 * packetizer, guint64 pcrtime,
   guint64 slope;
 
   gstpcrtime =
-      PCRTIME_TO_GSTTIME (pcrtime) + packetizer->wrap_count * PCR_GST_MAX_VALUE;
+      PCRTIME_TO_GSTTIME (pcrtime) + packetizer->pcr_reset_diff;
 
   /* first time, lock on to time and gstpcrtime */
   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (packetizer->base_time))) {
@@ -3145,16 +3145,23 @@ calculate_skew (MpegTSPacketizer2 * packetizer, guint64 pcrtime,
         GST_TIME_ARGS (gstpcrtime));
   }
 
-  if (G_LIKELY (gstpcrtime >= packetizer->base_pcrtime))
+  if (G_LIKELY (gstpcrtime >= packetizer->base_pcrtime &&
+      ((gstpcrtime > packetizer->last_pcrtime &&
+        gstpcrtime <= packetizer->last_pcrtime + (TS_RESET_THRES * GST_SECOND)) ||
+       !GST_CLOCK_TIME_IS_VALID(packetizer->last_pcrtime)))) {
     send_diff = gstpcrtime - packetizer->base_pcrtime;
-  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++;
+  } else if (GST_CLOCK_TIME_IS_VALID (time) &&
+      (packetizer->last_pcrtime > gstpcrtime) &&
+      (packetizer->last_pcrtime - gstpcrtime > TS_RESET_THRES * GST_SECOND)) {
+    /* Detect pcr resets */
+    packetizer->pcr_reset_diff += packetizer->last_pcrtime - gstpcrtime;
+    GST_DEBUG ("PCR wrap about %" GST_TIME_FORMAT " (%" G_GUINT64_FORMAT ")"
+        " pcr_reset_diff=%" GST_TIME_FORMAT " (%" G_GUINT64_FORMAT ")",
+        GST_TIME_ARGS (packetizer->last_pcrtime - gstpcrtime),
+        packetizer->last_pcrtime - gstpcrtime,
+        GST_TIME_ARGS (packetizer->pcr_reset_diff), packetizer->pcr_reset_diff);
     gstpcrtime =
-        PCRTIME_TO_GSTTIME (pcrtime) +
-        packetizer->wrap_count * PCR_GST_MAX_VALUE;
+        PCRTIME_TO_GSTTIME (pcrtime) + packetizer->pcr_reset_diff;
     send_diff = gstpcrtime - packetizer->base_pcrtime;
   } else {
     GST_WARNING ("backward timestamps at server but no timestamps");
diff --git a/gst/mpegtsdemux/mpegtspacketizer.h b/gst/mpegtsdemux/mpegtspacketizer.h
index cf4bbcc..49ac132 100644
--- a/gst/mpegtsdemux/mpegtspacketizer.h
+++ b/gst/mpegtsdemux/mpegtspacketizer.h
@@ -43,6 +43,8 @@
 
 #define MAX_WINDOW 512
 
+#define TS_RESET_THRES 10LL
+
 G_BEGIN_DECLS
 
 #define GST_TYPE_MPEGTS_PACKETIZER \
@@ -115,7 +117,8 @@ struct _MpegTSPacketizer2 {
   gint64         window_min;
   gint64         skew;
   gint64         prev_send_diff;
-  gint           wrap_count;
+  gint64         pcr_reset_diff;
+  gint64         last_pcr_diff;
 
   /* offset/bitrate calculator */
   gboolean       calculate_offset;
@@ -162,7 +165,7 @@ typedef struct
   guint8   current_next_indicator;
 
   guint32  crc;
-} MpegTSPacketizerSection; 
+} MpegTSPacketizerSection;
 
 typedef struct
 {
diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c
index 7aa2dc2..a580fe8 100644
--- a/gst/mpegtsdemux/tsdemux.c
+++ b/gst/mpegtsdemux/tsdemux.c
@@ -141,8 +141,10 @@ struct _TSDemuxStream
   guint64 fixed_pts;
   guint64 fixed_dts;
   /* Number of rollover seen for PTS/DTS (default:0) */
-  guint nb_pts_rollover;
   guint nb_dts_rollover;
+  /* PTS diff for PTS reset correction: */
+  guint64 pts_reset_diff;
+  guint64 last_pts_diff;
 
   /* Whether this stream needs to send a newsegment */
   gboolean need_newsegment;
@@ -1016,8 +1018,9 @@ gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * bstream,
     stream->raw_dts = 0;
     stream->fixed_pts = 0;
     stream->fixed_dts = 0;
-    stream->nb_pts_rollover = 0;
     stream->nb_dts_rollover = 0;
+    stream->pts_reset_diff = 0;
+    stream->last_pts_diff = 0;
   }
   stream->flow_return = GST_FLOW_OK;
 }
@@ -1098,8 +1101,9 @@ gst_ts_demux_stream_flush (TSDemuxStream * stream)
   stream->raw_dts = 0;
   stream->fixed_pts = 0;
   stream->fixed_dts = 0;
-  stream->nb_pts_rollover = 0;
   stream->nb_dts_rollover = 0;
+  stream->pts_reset_diff = 0;
+  stream->last_pts_diff = 0;
 }
 
 static void
@@ -1205,28 +1209,27 @@ gst_ts_demux_record_pts (GstTSDemux * demux, TSDemuxStream * stream,
       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:%"
+          ABSDIFF (stream->raw_pts, pts) > TS_RESET_THRES * CLOCK_FREQ)) {
+    /* Detect reset if diff > 10s */
+    GST_LOG ("Detected reset (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--;
-    }
+
+    stream->pts_reset_diff += stream->raw_pts + stream->last_pts_diff - pts;
+  } else {
+    if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (stream->raw_pts)))
+      stream->last_pts_diff = ABSDIFF (stream->raw_pts, pts);
+    /* FIXME: use avg? check for valid pts_diff? */
   }
 
   /* Compute PTS in GstClockTime */
   stream->raw_pts = pts;
-  stream->fixed_pts = pts + stream->nb_pts_rollover * PTS_DTS_MAX_VALUE;
+  stream->fixed_pts = pts + stream->pts_reset_diff;
   stream->pts = MPEGTIME_TO_GSTTIME (stream->fixed_pts);
 
-  GST_LOG ("pid 0x%04x Stored PTS %" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT ")",
-      bs->pid, stream->raw_pts, GST_TIME_ARGS (stream->pts));
+  GST_LOG ("pid 0x%04x Stored PTS %" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT "), "
+      "pts_reset_diff=%" G_GUINT64_FORMAT "(%" GST_TIME_FORMAT ")",
+      bs->pid, stream->raw_pts, GST_TIME_ARGS (stream->pts),
+      stream->pts_reset_diff, GST_TIME_ARGS(stream->pts_reset_diff));
 
 
   if (G_UNLIKELY (demux->emit_statistics)) {
