Skip to content

[FIX] Rust teletext decoder: fix bugs that stopped it producing any output, sync with telxcc.c - #2371

Open
Deepak-negi11 wants to merge 1 commit into
CCExtractor:masterfrom
Deepak-negi11:rust-teletext-fixes
Open

Deepak-negi11 wants to merge 1 commit into
CCExtractor:masterfrom
Deepak-negi11:rust-teletext-fixes

Conversation

@Deepak-negi11

@Deepak-negi11 Deepak-negi11 commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

In raising this pull request, I confirm the following (please check boxes):

Reason for this PR:

  • This PR adds new functionality.
  • This PR fixes a bug that I have personally experienced or that a real user has reported and for which a sample exists.
  • This PR is porting code from C to Rust.

Sanity check:

  • I have read and understood the contributors guide.
  • I have checked that another pull request for this purpose does not exist.
  • If the PR adds new functionality, I've added it to the changelog. If it's just a bug fix, I have NOT added it to the changelog.
  • I am NOT adding new C code unless it's to fix an existing, reproducible bug.

Repro instructions:

Sample: DVB-S.teletext_subtitles_777.ts from https://streams.videolan.org/streams/ts/Teletext/ (first 20 MB, teletext page 777).

The Rust decoder isn't called by CCExtractor yet, so I fed the sample to it with this small test program, which reads packets the same way tlt_process_pes_packet() does: https://gist.github.com/Deepak-negi11/346512f8c305ac681e902c4fec0a06d7

ccextractor --teletext (C) Rust decoder, master Rust decoder, this PR
Captions 6 0 (crashes once text arrives) 6, same text
Start times (from first cue) 0, 2260, 4020, 5780, 7540, 10460 ms — same

Problem

lib_ccxr/src/teletext.rs is a Rust port of telxcc.c. It isn't used yet, and as it is it can never produce output:

  1. receiving_data is never set to true (C sets it at telxcc.c:1072), so every text row is dropped.
  2. The parity check is the wrong way round, so every correct letter becomes a space.
  3. The line-trimming loop from telxcc.c:690-701 is missing, so it reads past the end of a row and crashes.
  4. A page number like 0x7a0 is used as an index into a 1000-entry array and crashes. C's atoi() reads it as 7.
  5. close() drops the last caption instead of writing it.

Changes (Rust only; CCExtractor's output doesn't change yet)

Testing

  • 9 new unit tests built from hand-made teletext packets: single page, other pages ignored, auto-detect, last caption on close, non-BCD page number, parity, Hamming errors, forcelatin. Each one fails if its fix is undone.
  • cargo test, cargo fmt --check and cargo clippy -- -D warnings pass.
  • Real sample: see the table above.

Copilot AI balanced review requested due to automatic review settings October 10, 2026 14:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@ccextractor-bot

Copy link
Copy Markdown
Collaborator
CCExtractor CI platform finished running the test files on linux. 170/237 tests matched the approved output:
Report Name Tests Passed
Broken 9/13
CEA-708 2/14
DVB 0/7
DVD 3/3
DVR-MS 2/2
General 24/27
Hardsubx 1/1
Hauppage 3/3
MP4 3/3
NoCC 10/10
Options 69/86
Teletext 0/21
WTV 12/13
XDS 32/34

67 tests do not match the approved output. That is the pass/fail verdict. Whether this branch caused it is a separate question, answered below.


Compared with the tip of master — test 9596, commit e313f70:

  • 0 pass there and fail here
  • 75 fail there and pass here
  • 30 fail on both, with different output
  • 37 fail on both, byte for byte the same

Fail on both but produce different output — behaviour moved even though the verdict did not:

Fail there, pass here:


Compared with the commit this branch was cut from: the same run as the tip of master (test 9596), so the comparison above already covers it.


This branch changes the behaviour of 30 test(s) relative to the tip of master. Those are the ones worth looking at; anything else in the list fails the same way on both sides.

@ccextractor-bot

Copy link
Copy Markdown
Collaborator
CCExtractor CI platform finished running the test files on windows. 154/237 tests matched the approved output:
Report Name Tests Passed
Broken 9/13
CEA-708 2/14
DVB 0/7
DVD 3/3
DVR-MS 2/2
General 24/27
Hardsubx 0/1
Hauppage 3/3
MP4 2/3
NoCC 10/10
Options 69/86
Teletext 0/21
WTV 3/13
XDS 27/34

83 tests do not match the approved output. That is the pass/fail verdict. Whether this branch caused it is a separate question, answered below.


Compared with the tip of master — test 9589, commit 670a5ab:

  • 0 pass there and fail here
  • 0 fail there and pass here
  • 0 fail on both, with different output
  • 83 fail on both, byte for byte the same

Compared with the commit this branch was cut from: the same run as the tip of master (test 9589), so the comparison above already covers it.


No test changes behaviour relative to the tip of master: every failure above fails there too, byte for byte. The approved output for those tests is out of date, which is a baseline to review rather than a regression in this branch.

The Rust port of telxcc.c (lib_ccxr/src/teletext.rs) is not called yet,
and as it stands it could never produce output:
- receiving_data was never set to true (C sets it at telxcc.c:1072), so
  every row packet was dropped
- the parity check was inverted, so every valid character became a space
- the line trimming loop from telxcc.c:690-701 was missing, so col_stop
  stayed 40 and text[row][40] panicked
- a non-BCD page number (e.g. 0x7a0) indexed seen_sub_page[1000] out of
  bounds; read the leading digits like C's atoi()
- close() dropped the last buffered page instead of outputting it

Also bring over later telxcc.c changes: hide a page when the next one
starts (CCExtractor#2292), honour --ttxtforcelatin (CCExtractor#1821), only print the page
notice with file reports, decode Hamming 8/4 errors as 0x0f like
unham_8_4(), and treat a Levenshtein distance equal to the limit as a
match like fuzzy_memcmp(). Multi-page extraction is left out: CCExtractor#2356 is
changing that logic in telxcc.c.
@Deepak-negi11

Deepak-negi11 commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor Author

Rebased on master, dropped the empty CI commit, and removed the multi-page part (#2356 is fixing that in C).

About the Sample Platform: the Linux "30 changed tests" compare against a master run where 75 tests failed that pass here, and Windows shows 0 changes. This PR can't change output yet: nothing calls teletext.rs, and C never reads the new print_file_reports field.

The real-sample check (6/6 cues identical to telxcc.c on the ZDF page 777 sample) uses this small test program: https://gist.github.com/Deepak-negi11/346512f8c305ac681e902c4fec0a06d7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants