From e4d4ce284bf47fb3d9ebd2186a7a571b53c3c23a Mon Sep 17 00:00:00 2001 From: Azeru Date: Sat, 11 Apr 2026 17:55:05 +0100 Subject: [PATCH] fix(export): compute requiredEndSec for decode termination handling Add requiredEndSec calculation to properly handle early decode termination by using the last segment's end time. This addresses issues with export processing on Windows platforms. --- src/lib/exporter/streamingDecoder.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/lib/exporter/streamingDecoder.ts b/src/lib/exporter/streamingDecoder.ts index cb5bf7b..6001cac 100644 --- a/src/lib/exporter/streamingDecoder.ts +++ b/src/lib/exporter/streamingDecoder.ts @@ -253,6 +253,8 @@ export class StreamingVideoDecoder { this.computeSegments(this.metadata.duration, trimRegions), speedRegions, ); + const requiredEndSec = segments[segments.length - 1]?.endSec ?? 0; + const segmentOutputFrameCounts = segments.map((segment) => Math.ceil(((segment.endSec - segment.startSec) / segment.speed) * targetFrameRate), ); @@ -510,11 +512,13 @@ if (shouldFailDecodeEndedEarly({ const decodedAtLabel = lastDecodedFrameSec === null ? "no decoded frame" : `${lastDecodedFrameSec.toFixed(3)}s`; const decodeGapSec = lastDecodedFrameSec === null ? Infinity : requiredEndSec - lastDecodedFrameSec; - // On Windows, tolerate a small decode gap (<= 3 seconds) to work around driver quirks. - // For severe failures (no frames at all, or a large gap), still throw. - if (isWindows && lastDecodedFrameSec !== null && decodeGapSec <= 3.0) { + // On Windows, tolerate a small decode gap: up to 10% of required duration, capped at 3 seconds. + const maxToleratedGap = Math.min(3.0, requiredEndSec * 0.1); + + if (isWindows && lastDecodedFrameSec !== null && decodeGapSec <= maxToleratedGap) { console.warn( - `[StreamingVideoDecoder] Decode ended early on Windows with a small gap (${decodeGapSec.toFixed(2)}s) – proceeding anyway.`, + `[StreamingVideoDecoder] Decode ended early on Windows with a gap of ${decodeGapSec.toFixed(2)}s ` + + `(max tolerated: ${maxToleratedGap.toFixed(2)}s) – proceeding anyway.`, ); } else { throw new Error( @@ -522,6 +526,8 @@ if (shouldFailDecodeEndedEarly({ ); } } + } + private computeSegments( totalDuration: number, trimRegions?: TrimRegion[],