]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
parsers: implement PTS clock recovery for ugly encoder, issue #4662
authorJaroslav Kysela <perex@perex.cz>
Mon, 16 Oct 2017 06:53:47 +0000 (08:53 +0200)
committerJaroslav Kysela <perex@perex.cz>
Fri, 20 Oct 2017 14:24:32 +0000 (16:24 +0200)
src/parsers/parsers.c

index 711c6f35a445384211176cb87313a53238e8bb07..a99f7d2cfd5075d05d03ae02dd043e44d04e6ae6 100644 (file)
@@ -931,7 +931,7 @@ static int
 parse_pes_header(service_t *t, elementary_stream_t *st, 
                  const uint8_t *buf, size_t len)
 {
-  int64_t dts, pts, d;
+  int64_t dts, pts, d, d2;
   int hdr, flags, hlen;
 
   if (len < 3)
@@ -954,8 +954,25 @@ parse_pes_header(service_t *t, elementary_stream_t *st,
     dts = getpts(buf + 5);
 
     d = (pts - dts) & PTS_MASK;
-    if(d > 180000) // More than two seconds of PTS/DTS delta, probably corrupt
+    if(d > 180000) {
+      /* More than two seconds of PTS/DTS delta, probably corrupt */
+      if (st->es_curpts != PTS_UNSET && st->es_frame_duration > 10) {
+        /* try to do a recovery for this:
+         * dts 2954743318 pts 2954746828
+         * dts 2954746918 pts 2419836508 ERROR
+         * dts 2954750518 pts 2419843708 ERROR
+         * dts 2954754118 pts 2954757628
+         * dts 2954757718 pts 2954761228
+         */
+        d2 = pts_diff(st->es_curdts, dts);
+        if (d2 != PTS_UNSET && d2 < 10000)
+          pts = st->es_curpts + st->es_frame_duration;
+        d = (pts - dts) & PTS_MASK;
+        if (d <= 180000)
+          goto cont;
+      }
       pts = dts = PTS_UNSET;
+    }
 
   } else if((flags & 0xc0) == 0x80) {
     if(hlen < 5)
@@ -965,6 +982,7 @@ parse_pes_header(service_t *t, elementary_stream_t *st,
   } else
     return hlen + 3;
 
+ cont:
   if(st->es_buf.sb_err) {
     st->es_curdts = PTS_UNSET;
     st->es_curpts = PTS_UNSET;