Commit Graph
2 Commits
Author SHA1 Message Date
Tzuhany 3569293c66 fix(lint): float slop in overlapping_clips_same_track compare (#1851)
parseFloat('0.1') + parseFloat('0.2') = 0.30000000000000004, so authored
adjacencies whose sum is exact in decimal drift a few ulps and fire the
overlap rule under the strict compare.

Compare on end - start > 1e-6 instead — 11 orders above the worst observed
drift, 4 below one 60fps frame.
2026-07-01 19:58:27 -07:00
TzuhanyandJames 7db84fc0ad fix(producer): rebuildExtractedFramesFromPlanDir off-by-one in framePaths key indexing (#1730)
* fix(producer): rebuildExtractedFramesFromPlanDir off-by-one in framePaths key indexing

In distributed chunk-lambda render mode, every <video>'s first-paint
frame (the moment a vid first becomes visible on the composition
timeline) renders as PRISTINE Y=16 black. For a 3-vid back-to-back
composition (v1: 0-4s, v2: 4-8s, v3: 8-12s at 30fps), frames 0, 121,
242 are all PRISTINE black; the render then either stays black for 1
frame, or shows body bg + persistent overlays only (Y~22 with sparse
highlights from text/logo). The symptom only reproduces in distributed
mode — local single-process renders are unaffected.

Root cause: rebuildExtractedFramesFromPlanDir builds the framePaths Map
with 1-based keys, but the consumer (getFrameAtTime at
engine/videoFrameExtractor.ts:958) computes a 0-based frame index via
Math.floor(localTime * fps + 1e-9). For each vid's first-paint frame
(localTime === 0 → frameIndex === 0), framePaths.get(0) returns
undefined; the vid is silently dropped from activePayloads,
videoFrameInjector doesn't fire, syncVideoFrameVisibility hides
everything, and BeginFrame screenshots an empty composition.

Every other site in the codebase builds/consumes framePaths with
0-based keys:

  - engine/videoFrameExtractor.ts:317     framePaths.set(index, ...)
  - engine/extractionCache.ts:204          framePaths.set(idx, ...)
  - engine/videoFrameExtractor.test.ts:264/1066  framePaths.set(i, ...)
  - engine/videoFrameExtractor.ts:958 (consumer) Math.floor 0-based
  - producer/renderOrchestrator.test.ts:287/315/349  framePaths.get(0)

Only producer/distributed/renderChunk.ts:198 was 1-based, with a
stale comment claiming FrameLookupTable indexes frames 1-based —
which the surrounding evidence contradicts. This is why local tests
pass while distributed-lambda renders always had cold black at each
vid first paint.

Verified locally against a 3-vid composition and a single-vid 4-worker
case in a Lambda render fleet. Before fix: every vid first-paint frame
is PRISTINE Y=16 black. After fix: all frames are valid source content,
blackdetect reports zero black regions outside legitimate source video
content (intentional fade-ins / hard cuts in source mp4).

* test(producer): pin rebuildExtractedFramesFromPlanDir 0-based framePaths contract

Regression guard for the off-by-one fix in HF#1730. The pre-fix code
indexed framePaths 1-based while the consumer (getFrameAtTime in
engine/videoFrameExtractor.ts:958) reads 0-based, dropping every
<video>'s first-paint frame in distributed chunk-lambda renders.

Asserts framePaths.get(0) resolves to the first extracted frame, and
framePaths.get(N-1) resolves to the last — pre-fix the keys were
shifted to [1..N], so get(0) returned undefined and get(N) resolved.
Verified to fail against the previous i+1 indexing.

Also exports rebuildExtractedFramesFromPlanDir (was module-local) so the
test can call it directly. Pure logic worth testing in isolation — the
bug only reproduces under distributed mode and the existing
renderChunk.test.ts already pays a multi-second Chrome smoke probe in
its module-level beforeAll, so the regression check lives in its own
file (rebuildExtractedFrames.test.ts) and runs Chrome-free in ~10ms.

The function's doc comment said "1-based framePaths" — updated to
"0-based" with a pointer to the consumer site and the bug context.

Per Miguel's REQUEST_CHANGES on HF#1730.

— Jerrai (https://claude.com/claude-code)

---------

Co-authored-by: James <james.russo@heygen.com>
2026-06-26 00:44:17 -04:00