Skip to content

fix: RTSP video PTS stability improvements#23

Merged
themactep merged 4 commits intostablefrom
feature/rtsp-stability-improvements
Mar 10, 2026
Merged

fix: RTSP video PTS stability improvements#23
themactep merged 4 commits intostablefrom
feature/rtsp-stability-improvements

Conversation

@themactep
Copy link
Copy Markdown
Owner

Summary

Fixes a series of RTSP video timestamp anomalies that caused massive A-V desynchronisation and duplicate PTS warnings in players like mpv.

Commits

  • b69411e — Handle both forward and backward IMP encoder timestamp jumps
    The IMP encoder starts with a relative counter (beginning at 0) and silently transitions to absolute system uptime at the first GOP boundary (~4 s), causing a multi-hour forward jump in RTP timestamps. Added a bidirectional re-anchor guard: re-anchor the wall-clock base on any step >2 s forward or >500 ms backward.

  • 92eee4a — Flush encoder after StartRecvPic to prevent startup timestamp anomaly
    Added IMP_Encoder_RequestIDR + IMP_Encoder_FlushStream immediately after StartRecvPic so the ring buffer contains only a fresh IDR with consistent timestamps before the first client connects.

  • 8f691a0 — Ensure strictly monotonic PTS within SPS/PPS/IDR triplets
    SPS, PPS and IDR NAL units returned in one GetStream() call all share the same imp_ts. The previous monotonicity clamp used strict <, so equal deltas passed through unchanged — all three NALs received identical fPresentationTime values and the same RTP timestamp, triggering Invalid video timestamp: X -> X in mpv. Changed to <= and advance delta_us by 12 µs (one 90 kHz tick) per repeated timestamp, guaranteeing each NAL a unique, strictly increasing PTS.

Testing

Verified with ffprobe -show_packets and mpv against a wyze_cam3_t31x_gc2053_atbm6031 camera — stream shows strictly monotonic PTS with no A-V desync.

themactep and others added 4 commits March 10, 2026 07:01
The IMP encoder timestamp can exhibit two anomalies shortly after stream
start:
  - Large forward jump (encoder transitions from near-zero counter to
    absolute system uptime, e.g. +43922s)
  - Backward jump (~1.8-2s) when the encoder resets its internal counter
    without going negative relative to the anchor

The previous guard only detected forward jumps >2s and negative deltas.
It missed backward steps between 0 and 2s which still produced non-
monotonic PTS and triggered mpv's A-V desync warning.

Fix: detect any inter-frame step >2s in either direction and re-anchor.
For smaller backward jitter (<500ms) that doesn't warrant re-anchoring,
clamp delta_us to the previous value to guarantee monotonically non-
decreasing PTS.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…omaly

The IMP hardware encoder initializes its timestamp counter to 0 (relative
to StartRecvPic). After the first complete GOP (~4s at 30fps), it transitions
to absolute system uptime. This causes a one-time large forward jump (e.g.
3.999767 -> 43922s) visible to the first RTSP client that connects after
prudynt starts.

A flush (RequestIDR + FlushStream) immediately after StartRecvPic clears the
encoder ring buffer so the first frames delivered to any client already have
consistent absolute-uptime timestamps.

The re-anchor guard in IMPDeviceSource.cpp remains as a belt-and-suspenders
fallback for any residual jitter or unknown IMP SDK edge cases.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SPS, PPS and IDR NAL units in a single GetStream() call all share the
same imp_ts (taken from the last pack in the group).  In IMPDeviceSource
this caused all three to compute the same delta_us and therefore receive
identical fPresentationTime values, producing duplicate RTP timestamps
that mpv reports as 'Invalid video timestamp: X -> X'.

Change the backward-jitter clamp from strict less-than to less-than-or-
equal and advance delta_us by 12 µs (one 90 kHz tick) per repeated
timestamp.  This gives each NAL in the triplet a unique, still strictly
monotonic PTS without altering the perceived frame rate or reanchoring
the wall-clock base.

Also remove the temporary per-frame GetStream debug logging added during
root-cause investigation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@themactep themactep merged commit e480833 into stable Mar 10, 2026
0 of 21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant