Guard --ire0_adjust hsync against a degenerate field (ZeroDivisionError aborts the decode) - #340
Merged
harrypm merged 1 commit intoJul 20, 2026
Conversation
…generate fields When --ire0_adjust includes hsync, hz_to_output measures the per-field black level (backporch window) and sync level (hsync window). On a degenerate field (dropout / sync collapse) both windows read the same level, so ire0 == hsync_level, hz_ire = (ire0 - hsync_level)/-vsync_ire = 0, and hz_to_output_array divides out_scale by it -> uncaught ZeroDivisionError that aborts the entire decode. Guard the per-field hz_ire: if non-finite or zero, warn and fall back to the globally calibrated hz_ire for that field, so a bad field yields an imperfect frame instead of killing the decode. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
github-actions
Bot
force-pushed
the
fix/ire0-hsync-divide-by-zero
branch
from
July 20, 2026 10:47
f1c0edf to
9caadd4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist
Description
In
FieldShared.hz_to_output'shsyncsubmode, a degenerate field makes the backporch and hsyncwindows read the same level, so
hz_ire = (ire0 - hsync_level) / -vsync_irebecomes0(
field.py:1074).hz_to_output_arraythen dividesout_scaleby it(
utils.py:1111)and raises
ZeroDivisionError, aborting the decode. This guards the per-fieldhz_ire: if0ornon-finite, warn and fall back to the calibrated
DecoderParams["hz_ire"].Motivation
A single degenerate field currently discards an arbitrarily long decode with no partial output — mine
died at frame 94056 after ~14.6h. It's the exact tape condition the
hsyncsubmode exists to helpwith (out-of-spec / AGC tapes with dropouts; cf. #314, #318).
Related Issues
Fixes #339
Changes Made
vhsdecode/field.py: inhz_to_output'shsyncsubmode, if the computedhz_ireis non-finiteor
0, log a warning and fall back toself.rf.DecoderParams["hz_ire"]for that field.Testing
tests/unit/test_ire0_adjust.py— 3 tests; 2 fail unpatched (ZeroDivisionError athz_to_output), all pass with the guard. Also a full from-frame-0 decode past the failure point.The fallback reuses the global
hz_ire(the value used when the submode is off), so a degeneratefield degrades to "as if hsync adjustment weren't available here" rather than crashing. Happy to take
a different remedy. A no-capture repro script is inlined in #339. Written with AI assistance.