From 6ab0dbbc9c9ee0d722557ac22c2a92d6c33559ea Mon Sep 17 00:00:00 2001 From: psiva01 Date: Tue, 21 Apr 2026 19:08:19 +0530 Subject: [PATCH 1/4] VPAAMP: Fix fluctuating latency Signed-off-by: psiva01 --- priv_aamp.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/priv_aamp.cpp b/priv_aamp.cpp index f38c105c5b..253eead7e0 100644 --- a/priv_aamp.cpp +++ b/priv_aamp.cpp @@ -2722,11 +2722,30 @@ void PrivateInstanceAAMP::MonitorProgress(bool sync, bool beginningOfStream) } else { - // For HLS Live, calculate latency based on live edge; round to nearest ms - latency = static_cast(std::lround(end - reportFormattedCurrPos)); - if(latency < 0) - { // this should never happen! - AAMPLOG_ERR("HLS negative live latency = %ldms, end = %lfms, reportFormattedCurrPos = %lfms", latency, end, reportFormattedCurrPos); + if(mProgramDateTime > 0.0) + { + // For HLS Live with EXT-X-PROGRAM-DATE-TIME: calculate latency as the + // difference between the current wall-clock time and the wall-clock time + // at the player's current playback position (PDT origin + elapsed position). + // This avoids the sawtooth fluctuation caused by the live edge advancing + // in discrete segment-sized steps on each manifest refresh. + long long nowMs = aamp_GetCurrentTimeMS(); + long long pdtAtCurrentPosMs = static_cast((mProgramDateTime + (reportFormattedCurrPos / 1000.0)) * 1000.0); + latency = static_cast(nowMs - pdtAtCurrentPosMs); + if(latency < 0) + { // this should never happen! + AAMPLOG_ERR("HLS PDT-based negative live latency = %ldms, nowMs = %lldms, pdtAtCurrentPosMs = %lldms", latency, nowMs, pdtAtCurrentPosMs); + } + } + else + { + // Fallback for HLS streams without EXT-X-PROGRAM-DATE-TIME: + // calculate latency based on live edge; round to nearest ms. + latency = static_cast(std::lround(end - reportFormattedCurrPos)); + if(latency < 0) + { // this should never happen! + AAMPLOG_ERR("HLS negative live latency = %ldms, end = %lfms, reportFormattedCurrPos = %lfms", latency, end, reportFormattedCurrPos); + } } } SetCurrentLatencyMs(latency); From d3bb153da52f6b6e9ee23bd1408781d7787f81f8 Mon Sep 17 00:00:00 2001 From: psiva01 Date: Tue, 28 Apr 2026 10:23:08 +0530 Subject: [PATCH 2/4] VPAAMP-163: Latency position value is fluctuating during normal playback Signed-off-by: psiva01 --- priv_aamp.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/priv_aamp.cpp b/priv_aamp.cpp index 253eead7e0..a6c29366dd 100644 --- a/priv_aamp.cpp +++ b/priv_aamp.cpp @@ -2730,8 +2730,16 @@ void PrivateInstanceAAMP::MonitorProgress(bool sync, bool beginningOfStream) // This avoids the sawtooth fluctuation caused by the live edge advancing // in discrete segment-sized steps on each manifest refresh. long long nowMs = aamp_GetCurrentTimeMS(); - long long pdtAtCurrentPosMs = static_cast((mProgramDateTime + (reportFormattedCurrPos / 1000.0)) * 1000.0); + static long long firstPDTMs = 0.0; + double diffFromPDTSeconds = (nowMs / 1000.0) - mProgramDateTime; + AAMPLOG_WARN("Time since mProgramDateTime: %.3f seconds (nowMs=%lldms, mProgramDateTime=%.3fs)", diffFromPDTSeconds, nowMs, mProgramDateTime); + if (mProgramDateTime > 0.0 && firstPDTMs == 0.0) + { + firstPDTMs = static_cast(mProgramDateTime * 1000.0); + } + long long pdtAtCurrentPosMs = static_cast(firstPDTMs + reportFormattedCurrPos); latency = static_cast(nowMs - pdtAtCurrentPosMs); + AAMPLOG_WARN("Siva live latency = %ldms, nowMs = %lldms, mProgramDateTime = %lfms, reportFormattedCurrPos = %lfms", latency, nowMs, mProgramDateTime, reportFormattedCurrPos); if(latency < 0) { // this should never happen! AAMPLOG_ERR("HLS PDT-based negative live latency = %ldms, nowMs = %lldms, pdtAtCurrentPosMs = %lldms", latency, nowMs, pdtAtCurrentPosMs); From 210edb89b1932f0a7785055d195629c22c1e5129 Mon Sep 17 00:00:00 2001 From: psiva01 Date: Wed, 29 Apr 2026 13:55:32 +0530 Subject: [PATCH 3/4] VPAAMP-143: Addressed corner case issue Signed-off-by: psiva01 --- priv_aamp.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/priv_aamp.cpp b/priv_aamp.cpp index a6c29366dd..6f6e648a16 100644 --- a/priv_aamp.cpp +++ b/priv_aamp.cpp @@ -2725,21 +2725,31 @@ void PrivateInstanceAAMP::MonitorProgress(bool sync, bool beginningOfStream) if(mProgramDateTime > 0.0) { // For HLS Live with EXT-X-PROGRAM-DATE-TIME: calculate latency as the - // difference between the current wall-clock time and the wall-clock time - // at the player's current playback position (PDT origin + elapsed position). + // difference between the current wall-clock time and the absolute wall-clock + // time at the player's current playback position. + // mProgramDateTime is the current playlist-window start in epoch seconds. + // reportFormattedCurrPos is the player's position in ms, measured from the + // same window start (i.e. relative to culledSeconds). Adding them together + // gives the epoch-based wall-clock time of the current playback position, + // and subtracting from nowMs yields the true live latency. // This avoids the sawtooth fluctuation caused by the live edge advancing // in discrete segment-sized steps on each manifest refresh. long long nowMs = aamp_GetCurrentTimeMS(); - static long long firstPDTMs = 0.0; - double diffFromPDTSeconds = (nowMs / 1000.0) - mProgramDateTime; - AAMPLOG_WARN("Time since mProgramDateTime: %.3f seconds (nowMs=%lldms, mProgramDateTime=%.3fs)", diffFromPDTSeconds, nowMs, mProgramDateTime); - if (mProgramDateTime > 0.0 && firstPDTMs == 0.0) + // playbackOffsetFromWindowStartMs: how far into the current playlist + // window the player is. start is culledSeconds*1000 (in ms), already + // offset-adjusted by GetFormatPositionOffsetInMSecs(). Clamp to >= 0 + // to guard against transient position-behind-start edge cases. + double playbackOffsetFromWindowStartMs = reportFormattedCurrPos - (culledSeconds*1000.0); + if (playbackOffsetFromWindowStartMs < 0.0) { - firstPDTMs = static_cast(mProgramDateTime * 1000.0); + playbackOffsetFromWindowStartMs = 0.0; } - long long pdtAtCurrentPosMs = static_cast(firstPDTMs + reportFormattedCurrPos); + long long pdtAtCurrentPosMs = static_cast( + (mProgramDateTime * 1000.0) + playbackOffsetFromWindowStartMs); latency = static_cast(nowMs - pdtAtCurrentPosMs); - AAMPLOG_WARN("Siva live latency = %ldms, nowMs = %lldms, mProgramDateTime = %lfms, reportFormattedCurrPos = %lfms", latency, nowMs, mProgramDateTime, reportFormattedCurrPos); + AAMPLOG_WARN("HLS PDT latency = %ldms, nowMs = %lldms, mProgramDateTime = %.3fs, " + "start = %.3fms, culledSeconds = %.3fms, reportFormattedCurrPos = %.3fms, playbackOffsetFromWindowStartMs = %.3fms", + latency, nowMs, mProgramDateTime, start, culledSeconds*1000.0, reportFormattedCurrPos, playbackOffsetFromWindowStartMs); if(latency < 0) { // this should never happen! AAMPLOG_ERR("HLS PDT-based negative live latency = %ldms, nowMs = %lldms, pdtAtCurrentPosMs = %lldms", latency, nowMs, pdtAtCurrentPosMs); From cd37dddfe75732f3af89670d0e95d1bb305953f3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 6 May 2026 06:38:55 +0000 Subject: [PATCH 4/4] Fix PDT latency coordinate space: use position instead of reportFormattedCurrPos Agent-Logs-Url: https://github.com/rdkcentral/aamp/sessions/5852c16e-2ee2-4038-93f1-c2e2942fe7f1 Co-authored-by: psiva01 <214551386+psiva01@users.noreply.github.com> --- priv_aamp.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/priv_aamp.cpp b/priv_aamp.cpp index bdb222bff7..555bcc521b 100644 --- a/priv_aamp.cpp +++ b/priv_aamp.cpp @@ -2728,19 +2728,19 @@ void PrivateInstanceAAMP::MonitorProgress(bool sync, bool beginningOfStream) // For HLS Live with EXT-X-PROGRAM-DATE-TIME: calculate latency as the // difference between the current wall-clock time and the absolute wall-clock // time at the player's current playback position. - // mProgramDateTime is the current playlist-window start in epoch seconds. - // reportFormattedCurrPos is the player's position in ms, measured from the - // same window start (i.e. relative to culledSeconds). Adding them together - // gives the epoch-based wall-clock time of the current playback position, - // and subtracting from nowMs yields the true live latency. + // mProgramDateTime is the playlist-window start in epoch seconds. + // position is the player's current position in raw ms (from stream start). + // culledSeconds*1000 is the window start in the same raw coordinate space. + // Adding the offset to mProgramDateTime gives the epoch time of the + // current playback position; subtracting from nowMs yields true latency. // This avoids the sawtooth fluctuation caused by the live edge advancing // in discrete segment-sized steps on each manifest refresh. long long nowMs = aamp_GetCurrentTimeMS(); - // playbackOffsetFromWindowStartMs: how far into the current playlist - // window the player is. start is culledSeconds*1000 (in ms), already - // offset-adjusted by GetFormatPositionOffsetInMSecs(). Clamp to >= 0 - // to guard against transient position-behind-start edge cases. - double playbackOffsetFromWindowStartMs = reportFormattedCurrPos - (culledSeconds*1000.0); + // playbackOffsetFromWindowStartMs: how far (in ms) the player is into + // the current playlist window. Both position and culledSeconds*1000 are + // in the same raw (unadjusted) coordinate space, so no offset skew. + // Clamp to >= 0 to guard against transient position-behind-start cases. + double playbackOffsetFromWindowStartMs = position - (culledSeconds * 1000.0); if (playbackOffsetFromWindowStartMs < 0.0) { playbackOffsetFromWindowStartMs = 0.0; @@ -2748,9 +2748,9 @@ void PrivateInstanceAAMP::MonitorProgress(bool sync, bool beginningOfStream) long long pdtAtCurrentPosMs = static_cast( (mProgramDateTime * 1000.0) + playbackOffsetFromWindowStartMs); latency = static_cast(nowMs - pdtAtCurrentPosMs); - AAMPLOG_WARN("HLS PDT latency = %ldms, nowMs = %lldms, mProgramDateTime = %.3fs, " - "start = %.3fms, culledSeconds = %.3fms, reportFormattedCurrPos = %.3fms, playbackOffsetFromWindowStartMs = %.3fms", - latency, nowMs, mProgramDateTime, start, culledSeconds*1000.0, reportFormattedCurrPos, playbackOffsetFromWindowStartMs); + AAMPLOG_INFO("HLS PDT latency = %ldms, nowMs = %lldms, mProgramDateTime = %.3fs, " + "position = %.3fms, culledSeconds = %.3fms, playbackOffsetFromWindowStartMs = %.3fms", + latency, nowMs, mProgramDateTime, position, culledSeconds*1000.0, playbackOffsetFromWindowStartMs); if(latency < 0) { // this should never happen! AAMPLOG_ERR("HLS PDT-based negative live latency = %ldms, nowMs = %lldms, pdtAtCurrentPosMs = %lldms", latency, nowMs, pdtAtCurrentPosMs);