fix: fall back to unbounded packet scan when duration hints missing

The earlier NaN/Infinity guard collapsed both duration hints to 0 when
the container reported invalid values, which turned scanEndSec into
0.5s. The packet scan then read only the first half-second, scannedDuration
capped there, and validateDuration fell back to that wrong value for the
entire export — exactly the Chromium Linux case this PR is meant to fix.

Use a 24h sentinel as the read endpoint when no hint is usable. An
explicit end is still required (some containers are truncated without
one, per prior comment), but the sentinel is large enough to exceed any
realistic recording so the scan reaches real EOF.
This commit is contained in:
Enriquefft
2026-04-16 14:33:27 -05:00
parent 4d4b08db07
commit 0c01db7afa
+8 -1
View File
@@ -71,6 +71,11 @@ const EARLY_DECODE_END_THRESHOLD_SEC = 1;
const METADATA_TAIL_TOLERANCE_SEC = 1.5;
const STREAM_DURATION_MATCH_TOLERANCE_SEC = 0.25;
const DURATION_DIVERGENCE_THRESHOLD_SEC = 1.5;
// Fallback upper bound for the packet scan when no reliable duration hint is
// available. Explicit end is required (some containers are truncated without
// one), but the hint-derived bound would cap the scan prematurely when
// container/stream duration are missing or corrupt.
const SCAN_UNBOUNDED_FALLBACK_SEC = 24 * 60 * 60;
/**
* Validate container duration against actual packet timestamps.
@@ -238,7 +243,9 @@ export class StreamingVideoDecoder {
typeof videoStream?.duration === "number" && Number.isFinite(videoStream.duration)
? videoStream.duration
: 0;
const scanEndSec = Math.max(containerDurationSec, streamDurationSec, 0) + 0.5;
const hintedDurationSec = Math.max(containerDurationSec, streamDurationSec, 0);
const scanEndSec =
hintedDurationSec > 0 ? hintedDurationSec + 0.5 : SCAN_UNBOUNDED_FALLBACK_SEC;
let maxPacketEndUs = 0;
const scanReader = this.demuxer.read("video", 0, scanEndSec).getReader();
try {