Files
hyperframes/packages
JamesandClaude Opus 4.7 5e4641fb77 refactor(producer): extract captureHdrStage (HDR / shader-transition path)
Move the Z-ordered HDR / shader-transition layered composite branch
(`if (useLayeredComposite)`) out of `executeRenderJob` into
`services/render/stages/captureHdrStage.ts`. The largest extraction by
LOC (~745 lines of body lifted verbatim) and the riskiest by cleanup
invariants. Body is lifted byte-for-byte — only the surrounding scope
changes.

Cleanup invariants preserved verbatim (design doc §11 flagged these
explicitly):
- `hdrEncoderClosed` / `domSessionClosed` flags gate the
  defensive-close paths so they don't run twice when the success path
  already closed.
- `hdrVideoFrameSources` is drained + cleared in the outer `finally`
  regardless of how the body exited.
- `cfg.forceScreenshot = true` is set unconditionally inside the
  layered path because `captureAlphaPng` hangs under
  `--enable-begin-frame-control`.

Other invariants preserved:
- `hdrPerf` is created at the top of the stage and returned; the
  sequencer's `finalizeHdrPerf` consumes it for the perf summary.
- The `Layered compositing frame N/M` `updateJobStatus` payload fires
  at the same per-frame point with `25 + frameProgress * 55`.
- `composition` and `compiled` are read-only in the stage.
- `hdrDiagnostics` is mutated in place (counters incremented at the
  same code points).
- `nativeHdrIds` is recomputed inside the stage from
  `nativeHdrVideoIds` + `nativeHdrImageIds` (the sequencer's
  computation is unchanged; the stage just doesn't need it passed in).

To support the extraction, the following symbols are newly exported
from `renderOrchestrator.ts`:
- Helper functions: `createHdrPerfCollector`, `addHdrTiming`,
  `closeHdrVideoFrameSource`, `blitHdrVideoLayer`, `blitHdrImageLayer`,
  `compositeHdrFrame`.
- Types: `HdrPerfCollector`, `HdrPerfTimingKey`, `HdrVideoFrameSource`,
  `HdrImageBuffer`, `HdrCompositeContext`, `HdrTransitionMeta`,
  `TransitionRange`.

These are internal helpers — the stage is currently the only consumer,
and the cycle (orchestrator imports `runCaptureHdrStage`; stage imports
helpers back) is safe at runtime. A future PR will consolidate the
helpers into a shared module (same follow-up planned for the capture
helpers in PRs 1.6 and 1.7).

Removes the now-orphaned imports from the orchestrator:
`openSync`, `fpsToFfmpegArg`, `spawnStreamingEncoder`,
`StreamingEncoder` type, `runFfmpeg`, `initTransparentBackground`,
`decodePngToRgb48le`, `queryElementStacking`, `TRANSITIONS`,
`crossfade`, `resampleRgb48leObjectFit`, `normalizeObjectFit`,
`TransitionFn` type, `createHdrImageTransferCache`.

Verified inside `Dockerfile.test`:
- **HDR fixtures (3/3 PASS)**: hdr-regression, hdr-hlg-regression,
  vignelli-stacking — audio correlations 1.000 / 1.000 / 0.982.
- **Non-HDR fixtures (4/4 PASS)**: font-variant-numeric, many-cuts,
  sub-composition-video, gsap-letters-render-compat — audio
  correlations 1.000 / 0.994 / 0.947 / 1.000.
- 7/7 fixtures total pass with PSNR / audio correlations matching every
  prior PR in the stack.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 01:40:26 +00:00
..
2026-05-10 18:34:43 +00:00
2026-05-10 18:34:43 +00:00