From adf32da2a248fb3b88fddef783dd6a91e5ec421d Mon Sep 17 00:00:00 2001 From: Tuan Nghia Nguyen Date: Mon, 20 Apr 2026 08:35:23 +1000 Subject: [PATCH] Add early stale-out in ANSRTSPClient::GetImage When the decoder hasn't produced a frame in 5s, skip the call to _playerClient->getImage() entirely and return the cached frame with unchanged _pts. LabVIEW sees STALE PTS one poll earlier and can trigger reconnect sooner. Threshold matches the existing checks on the duplicate-PTS branch and in areImagesIdentical() so all three stale paths agree. Near-zero cost: one getLastFrameAgeMs() call before the main path. Co-Authored-By: Claude Opus 4.7 (1M context) --- modules/ANSCV/ANSRTSP.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/modules/ANSCV/ANSRTSP.cpp b/modules/ANSCV/ANSRTSP.cpp index 7536d5d..b793a16 100644 --- a/modules/ANSCV/ANSRTSP.cpp +++ b/modules/ANSCV/ANSRTSP.cpp @@ -454,6 +454,25 @@ namespace ANSCENTER { return _pLastFrame; // Shallow copy (fast) } + // Early stale-out: if the decoder hasn't produced a frame in 5s the + // camera is dead. Skip _playerClient->getImage() entirely and return + // the cached frame with unchanged _pts so LabVIEW sees STALE PTS one + // poll earlier and triggers reconnect. Matches the 5000ms threshold + // already used on the duplicate-PTS branch below and in + // areImagesIdentical(), so all three stale paths agree. + if (!_pLastFrame.empty()) { + double ageMs = _playerClient->getLastFrameAgeMs(); + if (ageMs >= 5000.0) { + ANS_DBG("RTSP_GetImage", + "EARLY STALE: ageMs=%.1f pts=%lld url=%s — skipping getImage()", + ageMs, (long long)_pts, _url.c_str()); + width = _imageWidth; + height = _imageHeight; + pts = _pts; + return _pLastFrame; + } + } + int imageW = 0, imageH = 0; int64_t currentPts = 0;