Skip to content

Add speed-aware playback performance HUD - #31

Merged
D-Mad merged 2 commits into
mainfrom
agent/pr25-review
Jul 15, 2026
Merged

Add speed-aware playback performance HUD#31
D-Mad merged 2 commits into
mainfrom
agent/pr25-review

Conversation

@D-Mad

@D-Mad D-Mad commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Summary

  • rebase Eric Levy's Performance HUD from Add playback performance HUD #25 onto current Speed + Proxy main
  • show measured/target FPS, frame, active proxy resolution, frame cost, cache depth and dropped movie frames
  • calculate target FPS from the selected transport multiplier so 0.5x/2x are judged correctly
  • measure presentation only while transport is running and reset the timing window on resume to prevent false STALLED states after scrub/pause
  • count movie frames actually skipped while catching up

Review fixes

The original HUD compared all playback against 1x source FPS, counted paused scrubs as playback frames, and did not populate the proxy label or dropped-frame counter. This replacement makes the readings reflect the current Speed and Proxy state.

Original feature authored by @emlcpfx in #25.

Validation

  • performance HUD module passed (35 tests)
  • full pytest -q passed
  • git diff --check

Replaces #25.

emlcpfx and others added 2 commits July 15, 2026 11:16
View > Performance HUD (Ctrl+Alt+H) overlays measured FPS against target,
frame, resolution, average decode cost and cache depth. It answers the
question a reviewer actually asks when playback feels wrong: is it me, or is
it the machine? A supervisor calling a note on timing needs to know they are
watching 24 fps and not 17, or they are grading the playback and not the shot.

playback/stats.py is pure and takes an injected clock, so the rolling averages
are asserted exactly instead of being slept for.

- Frame rate is measured where frames reach the viewer, which is the only
  honest definition of a displayed frame -- not at the playback timer, which
  keeps firing whether or not a frame made it.
- Decode cost is timed around the decode itself. For sequences that is inside
  the decode thread, so the queue wait in front of it is not blamed on the
  decoder; for movies it covers the proxy scale, RGB conversion and OCIO, which
  is what stands between a packet and the screen.
- A decode slower than its share of the frame budget is flagged: it cannot
  sustain real time however fast the rest of the pipeline is.

A stall and a pause both stop frames arriving and both empty the rolling
window, so measured FPS falls to zero, which is the same reading as playback
never having started. Without telling those apart, a total freeze renders as a
calm placeholder dash, and that is the exact failure this HUD exists to catch.
stalled() tracks whether frames were ever flowing, and the window passes in
whether the player is actually running, so a freeze reads STALLED in red while
a pause stays quiet.

Only a genuinely bad row is coloured, so the eye goes to the thing that is
actually wrong rather than a wall of red.

26 tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TexnzYbmCjjTDB8zzZuUPb
@D-Mad
D-Mad marked this pull request as ready for review July 15, 2026 04:20
@D-Mad
D-Mad merged commit d4238b7 into main Jul 15, 2026
3 checks passed
@D-Mad
D-Mad deleted the agent/pr25-review branch July 15, 2026 04:20
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.

2 participants