mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
fix(producer): retry segmented capture on screenshot after a sequential stall
captureSegmentFrames races each frame through raceAgainstStall, which throws SequentialCaptureStallError. The segmented catch only retried drawElement capture, verification and renderer-stall errors, so a drawElement frame that hung without the engine's frame timeout firing failed the whole render, where the streaming path retries the same error on a fresh screenshot session. Retry it when the plan did not already force screenshot. The failure kind is draw_element_capture, which keeps segmenting and forces screenshot; capture_failure would replan to plain streaming, which this catch cannot drive. deFallbackReason stays "capture_error", the value streaming records for a sequential stall. — Via Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b0e8eff4d1
commit
30e2987d52
@@ -190,6 +190,14 @@ function render(resumeSegments = false): Promise<void> {
|
||||
return executeRenderJob(job, root, join(root, "output.mp4"));
|
||||
}
|
||||
|
||||
function sequentialStall(): Error {
|
||||
const err = new Error(
|
||||
"[Render] Sequential drawElement capture stalled: no frame progress for 1000ms (stuck at frame 640/1200).",
|
||||
);
|
||||
err.name = "SequentialCaptureStallError";
|
||||
return err;
|
||||
}
|
||||
|
||||
function stalledRenderer(): Error {
|
||||
const err = new Error("drawElement frame exceeded 5000ms (renderer stopped scheduling)");
|
||||
err.name = "DeFrameTimeoutError";
|
||||
@@ -200,6 +208,7 @@ it.each([
|
||||
["a suspect small frame", () => new DrawElementCaptureError(640, "suspect small frame")],
|
||||
["no cached paint record", () => new DrawElementCaptureError(640, "No cached paint record")],
|
||||
["a stalled renderer", stalledRenderer],
|
||||
["a sequential capture stall", sequentialStall],
|
||||
[
|
||||
"a failed self-verification",
|
||||
() => new DrawElementVerificationError("drawElement PSNR too low", { kind: "psnr" }),
|
||||
|
||||
@@ -4741,8 +4741,13 @@ async function executeRenderPipeline(input: {
|
||||
} catch (err) {
|
||||
const isVerifyError = isDrawElementVerificationError(err);
|
||||
const isDeStall = isDeRendererStallError(err);
|
||||
const isUnforcedSequentialStall =
|
||||
isSequentialCaptureStallError(err) && !capturePlan.forceScreenshot;
|
||||
if (
|
||||
(!isVerifyError && !isDrawElementCaptureError(err) && !isDeStall) ||
|
||||
(!isVerifyError &&
|
||||
!isDrawElementCaptureError(err) &&
|
||||
!isDeStall &&
|
||||
!isUnforcedSequentialStall) ||
|
||||
err instanceof RenderCancelledError ||
|
||||
executionSignal?.aborted === true
|
||||
) {
|
||||
@@ -4759,7 +4764,9 @@ async function executeRenderPipeline(input: {
|
||||
deFallbackFrameIndex = t.frameIndex;
|
||||
deFallbackThresholdDb = t.thresholdDb;
|
||||
log.warn(
|
||||
"[Render] drawElement capture failed on the segmented path; re-rendering via screenshot",
|
||||
isUnforcedSequentialStall
|
||||
? "[Render] segmented capture stalled; retrying on a fresh screenshot session"
|
||||
: "[Render] drawElement capture failed on the segmented path; re-rendering via screenshot",
|
||||
{
|
||||
error: err instanceof Error ? err.message : String(err),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user