Add opt-in weighted-mixed-frames progress estimate#4
Closed
kdmukAI-bot wants to merge 1 commit into
Closed
Conversation
Adds a weighted progress estimate for animated (fountain-coded) UR decoding, alongside the existing reference estimate. Ported from SeedSigner/seedsigner#541, where it has been the progress metric shown during SeedSigner's live animated-QR scans in production since 2024. The reference estimate, min(0.99, processed_parts_count / (expected_part_count * 1.75)), is a frame-count guesstimate that reaches its 0.99 cap well before a long animated QR completes and sits there, reporting a misleading "almost done" for many frames -- a common real-world source of user frustration. The weighted estimate counts information actually recovered: a decoded fragment scores 1.0; a fragment present only inside mixed (XOR'd) frames gets partial credit (each mixed frame contributes 1/(fragments mixed) to every fragment it covers, summed across mixed frames), capped at 0.75 per fragment so an undecoded fragment never counts as much as a decoded one and the percentage can't decrease. - fountain_decoder.c/.h: fountain_decoder_estimated_percent_complete_weighted(). - ur_decoder.c/.h: ur_decoder_estimated_percent_complete_weighted() wrapper. - uUR.c: estimated_percent_complete gains an opt-in weight_mixed_frames flag (default False returns the reference estimate byte-for-byte; existing callers are unaffected). Verified on ESP32-P4; weighted values match the reference Python decoder. Co-Authored-By: kdmukai <934746+kdmukai@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Owner
|
@kdmukai I merged your commits from both PRs, together with follow-ups closing some small gaps and formatting. |
Contributor
|
@odudex everything looks good. Confirmed via a P4 build and on-device tests. |
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.
Adds an opt-in weighted progress estimate for animated (fountain-coded) UR
decoding, alongside the existing reference estimate. Ported from
SeedSigner/seedsigner#541, where it has been the progress metric shown during
SeedSigner's live animated-QR scans in production since 2024.
Why
The reference estimate is
min(0.99, processed_parts_count / (expected_part_count * 1.75))— a frame-count guesstimate. On long animated QRsit reaches its 0.99 cap well before the decode completes and sits there,
reporting a misleading "almost done" for many frames. In real-world use this is
a common source of user frustration: the display shows 99% and looks about to
finish, but the scan keeps going for what can feel like a long time.
Method (opt-in)
The weighted estimate counts information actually recovered:
mixed frame contributes
1/(fragments mixed)to every fragment it covers,summed across mixed frames.
never counts as much as a decoded one (and the reported percentage can't
decrease).
estimated_percent_completegains an opt-inweight_mixed_framesflag; thedefault (
False) returns the reference estimate byte-for-byte, so existingcallers are unaffected.
Quantified comparison (on-device, ESP32-P4)
Realistic runs — the user misses the opening systematic frames and only ever
catches fountain frames, with a 30% misframe rate — across message sizes × 3
random seeds each. "Stuck" = the displayed integer percent does not change;
measured before completion:
The reference sits at 99% longer as the QR grows (up to ~74 frames on a
160-fragment QR); the weighted estimate never reports 99% before completion.
Both plateau near the end — the decode itself stalls waiting for a peeling
frame, so the weighted's longest stall is 12-34 frames — but it stalls at a
truthful ~85-90%, not a misleading 99%.
Trade-off
Because it scores information actually recovered rather than frames seen, the
weighted estimate rises faster early in a scan (partial credit for the mixed
frames already held in memory), then slows toward the end as the decode waits on
the last peeling frames. It can give the impression of a faster scan up front
followed by a slowdown — but that shape honestly reflects what is actually being
reassembled in memory at each stage.
The weighted values are identical whether computed by this C implementation or
the reference Python decoder; verified on ESP32-P4.