diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/FrameProcessor.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/FrameProcessor.cpp index f3628bc..075b59a 100644 --- a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/FrameProcessor.cpp +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/FrameProcessor.cpp @@ -78,12 +78,27 @@ bool FrameProcessor::ProcessFrame(VavCorePlayer* player, LOGF_INFO("[FrameProcessor] vavcore_decode_to_surface COMPLETED"); if (result != VAVCORE_SUCCESS) { - if (result != VAVCORE_END_OF_STREAM) { - m_decodeErrors++; - LOGF_ERROR("[FrameProcessor] Decode ERROR: result=%d - clearing flag", result); - } else { - LOGF_INFO("[FrameProcessor] End of stream reached - clearing flag"); + if (result == VAVCORE_END_OF_STREAM) { + LOGF_INFO("[FrameProcessor] End of stream reached - stopping playback"); + m_frameProcessing.store(false); + // End of stream is NOT an error - signal success to stop error counting + if (onComplete) onComplete(true); + return false; // Return false to stop playback loop } + + // -4 (VAVCORE_ERROR_DECODE_FAILED) can be display-only frame in B-frame scenarios + // This is NORMAL for AV1 temporal reordering - skip decode but continue playback + if (result == -4) { + LOGF_INFO("[FrameProcessor] Display-only frame (B-frame reordering) - continuing playback"); + m_frameProcessing.store(false); + // Signal success since display-only is not an error + if (onComplete) onComplete(true); + return true; // Return true to keep playback flowing + } + + // Other errors are real failures + m_decodeErrors++; + LOGF_ERROR("[FrameProcessor] Decode ERROR: result=%d - clearing flag", result); m_frameProcessing.store(false); if (onComplete) onComplete(false); return false;