mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 18:26:17 +00:00
fix(capture): bound static dedup verification time (#2457)
## What - cap static-dedup verification at 15 seconds of wall-clock time - disable the optimization and continue normal capture when the verification budget is exhausted - add a regression that models the reported 350-second / ~8,400-frame alpha render ## Why Static-frame verification uses full-page screenshots. Its existing screenshot-count budget still scales with composition duration, so a long composition can spend minutes proving an optimization before frame capture starts. The reported 350.35-second ProRes alpha render spent about eight minutes in this phase before safely disabling dedup. ## How The verifier now records a deadline before seeking verification frames. It checks the deadline before every full-page capture and returns the existing fail-closed `budgetExhausted` result when time is exhausted. This keeps the existing density-based safety checks while bounding their startup cost. ## Test plan - [x] Unit tests added/updated - [ ] Manual testing performed - [ ] Documentation updated (not applicable) - [x] Focused engine test: 9/9 passed - [x] Engine typecheck passed - [x] Pre-commit lint, format, tracked-artifact, fallow, and typecheck gates passed - [x] Full engine suite: 988 passed, 3 skipped; 2 pre-existing environment failures because host FFmpeg 4.2 lacks `-fps_mode`
This commit is contained in:
@@ -2359,6 +2359,13 @@ export async function computeStaticFrameSet(
|
||||
// sampleCount, so that knob's effect on density stays monotonic (see below).
|
||||
const STATIC_VERIFY_REFERENCE_STRIDE = 24;
|
||||
|
||||
// Verification uses full-page screenshots, whose cost scales with canvas size
|
||||
// and page complexity rather than frame count. Bound wall time as well as the
|
||||
// capture count so a long composition cannot spend minutes proving an
|
||||
// optimization before the real render starts. Exhaustion fails closed: dedup is
|
||||
// disabled and normal capture proceeds.
|
||||
const STATIC_VERIFY_MAX_MS = 15_000;
|
||||
|
||||
/**
|
||||
* Interior verification points for a run [a..b], plus the always-included end `b`.
|
||||
* Density used to be a flat point-count cap (min(sampleCount, 8)), so a run's
|
||||
@@ -2414,6 +2421,7 @@ export async function verifyStaticFramesSafe(
|
||||
): Promise<{ badFrame: number; budgetExhausted: boolean } | null> {
|
||||
const frames = [...staticFrames].sort((a, b) => a - b);
|
||||
if (frames.length === 0) return null;
|
||||
const deadline = Date.now() + STATIC_VERIFY_MAX_MS;
|
||||
// Runs are maximal-contiguous (adjacent frames merge), so a run's anchor a-1 is
|
||||
// guaranteed NOT static — always a freshly-captured frame.
|
||||
const runs: Array<{ a: number; b: number }> = [];
|
||||
@@ -2460,9 +2468,11 @@ export async function verifyStaticFramesSafe(
|
||||
for (const { a, b } of runs) {
|
||||
const anchor = a - 1;
|
||||
if (anchor < 0) continue;
|
||||
if (Date.now() >= deadline) return { badFrame: a, budgetExhausted: true };
|
||||
const anchorBuf = await seekCapture(anchor);
|
||||
spent++;
|
||||
for (const f of computeStaticVerificationPoints(a, b, sampleCount)) {
|
||||
if (Date.now() >= deadline) return { badFrame: f, budgetExhausted: true };
|
||||
const cur = await seekCapture(f);
|
||||
spent++;
|
||||
if (!anchorBuf.equals(cur)) return { badFrame: f, budgetExhausted: false };
|
||||
|
||||
Reference in New Issue
Block a user