Skip to content

perf(video): defer deinterlace warmup until needed - #877

Open
jonluca wants to merge 1 commit into
superuser404notfound:mainfrom
jonluca:perf/lazy-deinterlace-warmup
Open

jonluca wants to merge 1 commit into
superuser404notfound:mainfrom
jonluca:perf/lazy-deinterlace-warmup

Conversation

@jonluca

@jonluca jonluca commented Oct 25, 2026

Copy link
Copy Markdown

Summary

Constructing an engine starts a process-wide hardware deinterlace warm-up, and every software load in auto mode waits for it. Progressive VP8/VP9/AV1 playback therefore builds and waits for a Metal/VideoToolbox graph it never uses.

Start the shared task on the first potentially interlaced auto-mode load. Concrete interlaced metadata qualifies for every codec; H.264's unknown field order consults its SPS, and unknown MPEG-2/MPEG-4/VC-1 sources remain conservative. Progressive sources and forced-software deinterlace skip warm-up.

Audio reloads preserve the decision. Disc-title switches recompute it from the reopened title, stop clears it, and the load generation is rechecked after the asynchronous gate. Concurrent waiters still share one task, and cancellation of one waiter does not cancel process-wide work.

Test plan

  • Apple M4 Max, macOS 27.0.1, Xcode 27.1.
  • Routing tests cover progressive, interlaced, unknown legacy, SPS fallback, and interlaced long-tail codecs.
  • Injected-operation tests verify zero warm-up invocations for skipped requests, one invocation shared by concurrent demand, unavailable hardware, and cancellation ownership.
  • Existing real hardware-deinterlacer tests included; no playback-speed or memory benchmark claim is made.
  • Final run: 88 Swift Testing tests in 9 suites and 4 API-documentation XCTest cases pass. The integration cases load and reload genuine interlaced H.264 and progressive H.264 with an interlaced container declaration, then verify stop clears the decision.
  • The real Metal deinterlacer tests pass on this M4 Max, including frame output, field-rate cadence, and a fresh graph after warm-up.
  • swift build --target AetherEngine -Xswiftc -warnings-as-errors --disable-automatic-resolution --jobs 4 passes. Focused tests use the same isolated scratch directory and resolved pins.
  • Documentation links and git diff --check pass. Disc-title transition wiring was source-reviewed; a physical-disc title switch and iOS/tvOS runtime were not exercised.

Checklist

  • Changelog and architecture documentation updated
  • Regression coverage in the existing cold-start, routing, and interlace test files
  • Conventional commit
  • No public API or dependency changes

Copilot AI balanced review requested due to automatic review settings October 25, 2026 16:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Same-title custom-disc reloads can discard verified progressive evidence and unnecessarily start hardware warm-up.

1 open issue
What changed in this PR

This PR makes hardware deinterlace warm-up demand-driven, avoiding unnecessary Metal/VideoToolbox setup during engine construction and progressive software playback.

Changes:

  • Start one shared warm-up task only for potentially interlaced auto-mode loads.
  • Carry the warm-up decision through reloads, recompute it for disc-title overrides, and clear it on stop.
  • Add routing, lazy-start, cancellation, and lifecycle coverage, with supporting documentation.
File Description
Tests/​AetherEngineTests/​VideoRoutingPolicyTests.swift Tests warm-up eligibility across codecs and field orders.
Tests/​AetherEngineTests/​Issue232InterlaceProbeTests.swift Tests load, reload, and stop decision state.
Tests/​AetherEngineTests/​Issue203SoftwareColdStartTests.swift Tests lazy warm-up, shared demand, and skipped requests.
Sources/​AetherEngine/​Decoder/​VideoRoutingPolicy.swift Classifies sources that may need deinterlace warm-up.
Sources/​AetherEngine/​Decoder/​DeinterlaceHardwareWarmup.swift Lazily creates a lock-protected shared task.
Sources/​AetherEngine/​AetherEngine+Loading.swift Gates warm-up and carries decisions through reloads.
Sources/​AetherEngine/​AetherEngine.swift Removes construction-time warm-up and manages source decisions.
docs/​architecture.md Documents demand-driven warm-up and reload behavior.
CHANGELOG.md Records the warm-up performance change.

Review effort: Balanced

}
}

let reopenedRequiresDeinterlaceWarmup: Bool = if discTitleIDOverride != nil,
@jonluca
jonluca force-pushed the perf/lazy-deinterlace-warmup branch from 890c14d to 3c1e9d0 Compare October 25, 2026 18:29
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