Two bugs made 4K (and any) video playback wrong:
1. Sped-up playback. The VideoManager frame cache was keyed by milliseconds, but
GPU (hardware-decoded) frames bypass the decoder's internal cache. A UI that
refreshes finer than the video frame rate (a 60Hz canvas on a 30fps clip)
therefore missed the cache on every sub-frame request and decoded the NEXT
frame each time — advancing the video ~2x faster than the clock, and racing the
decoder toward EOF. Key the cache on the video frame index (round(ts·fps))
instead, so all requests within one frame share an entry and each frame decodes
exactly once → correct speed.
2. Periodic seek/jerk. The seek decision compared the rounded request frame_ts to
the decoded frame's exact PTS, which sit on slightly different grids — so
frame_ts landed ~1 frame "behind" the just-decoded PTS every ~10 frames and
falsely read as a backward seek (40ms seek + GOP re-decode). Track the previous
request (last_requested_ts), which is strictly monotonic during forward
playback, and detect backward from that instead. Real scrubs still seek.
Per-frame HW decode is ~3-5ms; both bugs were spurious decode/seek work on top.
Keeps a gated LB_VIDEO_DEBUG [Video Seek?] diagnostic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>