]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Implement recovery mechanism instead of dropping packets on PTS_UNSET
authorcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Mon, 22 Sep 2025 00:47:47 +0000 (00:47 +0000)
committerFlole <Flole998@users.noreply.github.com>
Tue, 30 Dec 2025 13:06:59 +0000 (14:06 +0100)
Replace packet dropping with intelligent recovery when pts_diff() returns
PTS_UNSET. The new approach:
1. Re-establishes local reference timestamp when possible
2. Resets normalization state for potential rollover scenarios
3. Provides detailed trace logging for debugging
4. Maintains stream continuity instead of interrupting playback

This addresses the underlying timestamp inconsistency issues that can occur
during timeshift operations, particularly around timestamp rollover periods.

Co-authored-by: Flole998 <9951871+Flole998@users.noreply.github.com>
src/plumbing/tsfix.c

index d5db580d4329c9e2c537c53a39396a0f70477526..e6cf1b2a1bc3338ee28f28f68155f0699305ec37 100644 (file)
@@ -242,10 +242,32 @@ normalize_ts(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt, int backlog)
   else
     dts = pts_diff(ref, pkt->pkt_dts);
 
-  /* Check for invalid DTS calculation result */
+  /* Handle case where pts_diff returns PTS_UNSET due to inconsistent timestamps */
   if (dts == PTS_UNSET) {
-    tsfix_packet_drop(tfs, pkt, "invalid dts calculation");
-    return;
+    tvhtrace(LS_TSFIX, "%s: DTS calculation failed, attempting recovery (ref=%"PRId64" pkt_dts=%"PRId64")",
+             streaming_component_type2txt(tfs->tfs_type), ref, pkt->pkt_dts);
+    
+    /* Try to re-establish reference using current packet DTS */
+    if (tfs->tfs_local_ref == PTS_UNSET) {
+      tfs->tfs_local_ref = pkt->pkt_dts & PTS_MASK;
+      tvhtrace(LS_TSFIX, "%s: Re-established local reference to %"PRId64,
+               streaming_component_type2txt(tfs->tfs_type), tfs->tfs_local_ref);
+      /* Recalculate with new reference */
+      if (tf->dts_offset_apply)
+        dts = pts_diff(tfs->tfs_local_ref, pkt->pkt_dts + tf->dts_offset);
+      else
+        dts = pts_diff(tfs->tfs_local_ref, pkt->pkt_dts);
+    }
+    
+    /* If still failing, this might be a timestamp rollover case */
+    if (dts == PTS_UNSET) {
+      /* Reset normalization state to handle potential rollover */
+      tfs->tfs_last_dts_norm = PTS_UNSET;
+      tfs->tfs_dts_epoch = 0;
+      dts = 0; /* Start from zero for this stream */
+      tvhtrace(LS_TSFIX, "%s: Reset normalization state due to timestamp inconsistency",
+               streaming_component_type2txt(tfs->tfs_type));
+    }
   }
 
   if (tfs->tfs_last_dts_norm == PTS_UNSET) {