Skip to content

Add user-selectable proxy resolution - #24

Closed
emlcpfx wants to merge 1 commit into
D-Mad:mainfrom
emlcpfx:pr14-proxy-scale
Closed

Add user-selectable proxy resolution#24
emlcpfx wants to merge 1 commit into
D-Mad:mainfrom
emlcpfx:pr14-proxy-scale

Conversation

@emlcpfx

@emlcpfx emlcpfx commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Playback > Proxy Resolution picks Full / 2K / 1080p / 720p.

The display proxy was fixed at 2K, but the right answer depends on the machine and the job: a supervisor on a laptop wants 720p to hold real time on an 8K plate, while someone checking grain or edge detail needs the full frame and will happily accept slower playback. The source file and its timeline metadata are never touched — only what the viewer decodes and caches.

playback/proxy.py owns the level and the resolution maths. The level is process-wide state rather than a constructor argument because the readers, the frame cache and the on-disk preview cache all have to agree on it, and they're constructed in different places.

The part that would have bitten

The on-disk preview cache is keyed by proxy size. If the level changed without that key changing, a frame cached at 720p would be served straight back to a viewer that just asked for 2K — the reviewer would silently be looking at the wrong resolution, with no error and nothing on screen to explain it. The key already carried the hardcoded dimensions, so it now carries the level token; test_each_level_has_a_distinct_cache_token fails if two levels ever collide, and test_preview_cache_path_changes_with_the_proxy_level checks the real SequenceReader path changes with the level.

Other details worth knowing

  • The movie path still rounds to even dimensions. yuv420 subsamples chroma by two, so an odd proxy size isn't representable. The sequence path has no such constraint, so fit() takes an even flag rather than forcing it on everyone.
  • Sequence cache depth follows the proxy size — bigger review frames mean fewer of them fit in the same memory budget.
  • Changing level reloads the current source at the frame the reviewer is sitting on (not back at frame one). The open reader and both caches hold frames at the old size, so the level genuinely cannot be swapped under a running player.
  • Full resolution disables the proxy rather than scaling by 1.0, so the EXR mip-level shortcut is skipped too and the full level is decoded.
  • A source already smaller than the bound is never upscaled.

Verification

14 new tests, 252 on the branch, green three runs in a row, compile clean.

Not just unit maths — driven end to end against a real decoded 3840x2160 clip through a real MainWindow, checking the actual decoded QImage dimensions:

Level Decoded size
2K (default) 2048 x 1152
720p 1280 x 720
Full 3840 x 2160
back to 2K 2048 x 1152

Menu radio state stays in sync across all of it.

Branches off current main.

Playback > Proxy Resolution picks Full / 2K / 1080p / 720p. The proxy level
was fixed at 2K; the right answer depends on the machine and the job. A
supervisor on a laptop wants 720p to hold real time on an 8K plate, while
someone checking grain or edge detail needs the full frame and will accept
slower playback.

playback/proxy.py owns the level and the resolution maths. The level is
process-wide rather than a constructor argument because the readers, the frame
cache and the on-disk preview cache all have to agree on it, and they are built
in different places.

- The preview-cache key already carried the proxy dimensions, so it now carries
  the level token instead. Every level has a distinct token, which is what stops
  a frame cached at 720p being served back to a viewer asking for 2K. There is a
  test that fails if two levels ever collide.
- The movie path still rounds to even dimensions: yuv420 subsamples chroma by
  two, so an odd proxy size is not representable. The sequence path does not
  need that constraint.
- Sequence cache depth follows the proxy size, since bigger review frames mean
  fewer of them fit in the same memory budget.
- Changing level reloads the current source at the frame the reviewer is sitting
  on. The open reader and both caches hold frames at the old size, so the level
  cannot be swapped under a running player.

Full resolution disables the proxy entirely rather than scaling by 1.0, so the
EXR mip-level shortcut is skipped too.

14 tests. Verified against a real decoded 3840x2160 clip: it lands at 2048x1152
at 2K, 1280x720 at 720p, and 3840x2160 at Full.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TexnzYbmCjjTDB8zzZuUPb
@D-Mad

D-Mad commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Thank you, Eric. The proxy feature has been preserved and rebased onto current main in #30. Review added a lossless Full Resolution path and RAM-bounded Full 4K/8K sequence caches, and resolved integration with playback speed. Closing this branch in favor of #30.

@D-Mad D-Mad closed this Jul 15, 2026
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