fix: SSTV VIS detector stuck in DETECTED state on validation failure

The previous fix (f29ae3d) introduced a regression: when VIS parity
check failed or the VIS code was unrecognized, the detector entered
DETECTED state permanently and never resumed scanning. Now it resets
to IDLE on validation failure and only enters DETECTED on success.

Also resets partial image progress counter between consecutive decodes
and adds SDR device claiming to general SSTV route to prevent conflicts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Smittix
2026-02-18 21:12:12 +00:00
parent f29ae3d5a8
commit 3a962ca207
3 changed files with 44 additions and 10 deletions

View File

@@ -475,6 +475,7 @@ class SSTVDecoder:
mode_spec = get_mode(vis_code)
if mode_spec:
current_mode_name = mode_name
last_partial_pct = -1
image_decoder = SSTVImageDecoder(
mode_spec,
sample_rate=SAMPLE_RATE,

View File

@@ -298,16 +298,26 @@ class VISDetector:
if self._tone_counter >= self._bit_windows:
result = self._validate_and_decode()
# Do NOT call reset() here. self._buffer still holds samples
# that arrived after the STOP_BIT window — those are the very
# first samples of the image. Wiping the buffer here causes all
# of them to be lost, making the image decoder start mid-stream
# and producing garbled/diagonal output.
# feed() will advance past the current window, leaving
# self._buffer pointing at the image start. The caller must
# read remaining_buffer and then call reset() explicitly.
self._state = VISState.DETECTED
return result
if result is not None:
# Do NOT call reset() here. self._buffer still holds
# samples that arrived after the STOP_BIT window — those
# are the very first samples of the image. Wiping the
# buffer here causes all of them to be lost, making the
# image decoder start mid-stream and producing
# garbled/diagonal output.
# feed() will advance past the current window, leaving
# self._buffer pointing at the image start. The caller
# must read remaining_buffer and then call reset().
self._state = VISState.DETECTED
return result
else:
# Parity failure or unknown VIS code — reset and
# continue scanning for the next VIS header.
self._tone_counter = 0
self._data_bits = []
self._parity_bit = 0
self._bit_accumulator = []
self._state = VISState.IDLE
elif self._state == VISState.DETECTED:
# Waiting for caller to call reset() after reading remaining_buffer.