pub struct ChainOutcome {
pub bytes: Vec<u8>,
pub inner_ok: bool,
pub outer_ok: bool,
pub crc_ok: bool,
pub crc_present: bool,
pub outer_present: bool,
pub outer_corrected_bytes: Option<u32>,
pub inner_out_bits: Vec<u8>,
}Expand description
The outcome of decoding one logical block: the recovered bytes plus each stage’s success, reported separately.
The concatenated scheme has two independent decoders, and folding them into
one flag destroys the only signal that distinguishes a marginal link from a
failing one. Errors the inner code corrects never reach the outer code, so
inner_ok == false with outer_ok == true is a link running hot but still
delivering — precisely the state a pre-FEC error rate is meant to surface,
and indistinguishable from success once folded.
Use is_valid to decide whether to accept the block;
the individual flags are diagnostics.
Fields§
§bytes: Vec<u8>The recovered info bytes, CRC stripped.
inner_ok: boolEvery inner-FEC block converged. Always true for
InnerFec::None, and for the convolutional arm, whose soft Viterbi
has no per-block convergence flag — the outer code and CRC decide.
outer_ok: boolEvery outer-FEC block decoded. Always true for OuterFec::None.
crc_ok: boolThe block’s CRC checked.
crc_present: boolWhether the configuration provides a CRC at all. Without this,
crc_ok is ambiguous: CrcKind::None reports true because there
was nothing to fail, not because anything was verified.
outer_present: boolWhether the configuration provides an outer code at all, on the same
reasoning as crc_present.
outer_corrected_bytes: Option<u32>How many codeword bytes the outer decoder corrected across this
block, or None when the outer code reports no such count — every arm
but OuterFec::ReedSolomon, since BCH is binary and corrects bits.
The measurement outer_ok cannot make. That flag
saturates — a codeword one error from the cliff and a pristine one both
read true — whereas this rises smoothly with the channel, so it shows
a link approaching failure while it is still delivering. It is the
count real DVB-T receivers report, and it costs nothing: the Forney
correction loop already computed every magnitude.
Counted only over codewords that decoded. A block the code could not
correct contributes nothing, because a correction the decoder does not
trust is not a correction to report. So on a frame with
outer_ok == false this is a lower bound; read the two together.
inner_out_bits: Vec<u8>What the inner decoder produced, untrimmed — every bit it decided, including the zero-padding tail of the final codeword that the block plan discards before the outer decoder sees it.
Kept rather than dropped so a caller can compare it against a re-encode of the recovered message and obtain a post-inner-FEC bit error rate instead of a pass/fail flag. Costs nothing: the vector is already allocated, and is moved out rather than copied.
Untrimmed because re-encoding a trimmed copy zero-pads that tail back
to zero, which silently asserts the decoder got the padding right. For a
184-byte payload on the default ladder that is 168 bits of 5120 — enough
to paint a real decoder error Clean in a correction map, and far too
few to notice in one. Consumers that want only the bits the outer
decoder saw take [..plan.outer_il_bits]; [bit_error_rate] compares
over the shorter of its two inputs, so the trim is implicit there.
Implementations§
Source§impl ChainOutcome
impl ChainOutcome
Sourcepub fn is_valid(&self) -> bool
pub fn is_valid(&self) -> bool
Whether the recovered bytes can be trusted, judged by the strongest end-to-end check the configuration actually provides.
inner_ok is deliberately not part of this. It reports whether the
inner decoder’s parity checks converged — how hard it worked, not
whether the result is right. Requiring it discards frames whose payload
is verifiably correct: measured across a noise sweep, a CRC-carrying
link delivers byte-exact payloads with inner_ok == false over a wide
band, and rejecting those costs real sensitivity for nothing.
The precedence:
- A CRC decides on its own. It is computed over the recovered payload end to end, so passing it means the bytes are right whatever the stages beneath did — including an outer decoder that reported a block it could not correct.
- Otherwise the outer code decides. DVB-T carries no CRC
(
CrcKind::None), so its Reed–Solomon stage is the integrity check; RS reports failure when it cannot correct a codeword. - Otherwise
inner_okis all there is. A link with neither a CRC nor an outer code has only the inner decoder’s convergence to go on, and dropping it there would accept anything.
Trait Implementations§
Source§impl Clone for ChainOutcome
impl Clone for ChainOutcome
Source§fn clone(&self) -> ChainOutcome
fn clone(&self) -> ChainOutcome
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more