[BUG] MAX_CC_COUNT = 31 in ccxr_process_cc_data silently discards CEA-708 data on H.264 frames with multiple SEI messages
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 68/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- audio-video-rtc, backend
Research direction
Start with ccxr_process_cc_data in src/rust/src/lib.rs and trace callers in avc_functions.c, core.rs, and mp4_rust_bridge.c. Compare the processing limit with store_hdcc capacity, then inspect mcc_encode_cc_data and ccx_encoders_mcc.c for the wire-format constraint. Done means large caption batches are processed without discarding CEA-708 data while MCC output still respects its per-envelope limit.
Written by the indexing model from the issue text.
Description
Summary
ccxr_process_cc_data (src/rust/src/lib.rs:~411) rejects any call with more than 31 caption triplets, discarding the entire frame's 708 data (returns -1, logs "discarding frame"). This cap is misapplied: 31 is a real constraint, but it applies to a single envelope's wire-format encoding (a 5-bit cc_count field in ATSC A/53, H.264 SEI, SCTE-20, and CDP), not to how many triplets a decoder call may process at once. The two are being conflated.
Root cause
The 31 cap was added in 65df24e6 (#2241) as an integer-overflow guard, a legitimate fix for a real problem, but placed at the wrong layer. The commit's own reasoning cites the 5-bit cc_count field width in the wire formats as justification, correctly identifying where 31 comes from, but incorrectly applying that per-envelope wire limit as a per-call processing limit.
Nothing downstream in the general decode path actually needs this cap:
- The triplets get copied into a heap-allocated
Vecsized to the actualcc_count, no fixed-size array bound - The DTVCC packet assembler processes one triplet at a time across calls; its only real limit is a 128-byte packet length, unrelated to triplet count per call
- The real storage bound that does matter is the
store_hdccslot capacity,cc_data_pkts[SORTBUF][10*31*3+1], i.e. room for 310 triplets, not 31
Reachability, this is a live bug today, independent of #2350
process_avc (H.264/HEVC extraction) already accumulates every SEI message in a single video picture via copy_ccdata_to_buffer (avc_functions.c:448 / Rust core.rs:444), with no cap, before calling process_cc_data. Any H.264 or HEVC frame carrying enough SEI-embedded caption data to exceed 31 triplets, on real broadcast content this is plausible whenever a frame carries dense caption bursts, has its entire 708 payload for that frame silently discarded, while the 608 data from the same buffer processes normally (since the C do_cb loop has no such cap). This requires no concat, no multi-envelope collision, nothing from #2350, it's independently reachable on unmodified master right now.
Same applies to MP4 files with c708 samples (mp4_rust_bridge.c:174, cc_count = payload_len / 3, bounded only by sample size, not 31).
Where 31 actually is a hard limit, and should stay one
Only mcc_encode_cc_data (--out=mcc), since it packs cc_count into the CDP's real 5-bit field (cc_count | 0xE0, ccx_encoders_mcc.c). That's a genuine wire-format constraint for that one output path, not a general processing limit.
Proposed fix
- Raise
MAX_CC_COUNTinccxr_process_cc_datato the real storage bound (310, matching thestore_hdccslot capacity), or otherwise remove the artificial 31 ceiling from general-purpose processing - Move the actual ≤31-per-envelope chunking into
mcc_encode_cc_dataspecifically, looping over the buffer in chunks of ≤31 triplets, one CDP per chunk, since that's the only place the 5-bit constraint is real mcc_encode_cc_data'suint8 data_size = cc_count * 3should also be widened or bounded by the chunking, to avoid the wraparound the earlier investigation flagged
Note
Found while investigating #2350 (store_hdcc concat behavior), but this bug is fully independent, it doesn't require #2350's fix or concat to be involved at all, and should be fixed on its own regardless of how #2350 proceeds.
@cfsmp3 tagging for a read, this one looks like a straightforward, well-scoped fix if the reasoning checks out. Happy to work on it.
- Dominant language
- C
- Stars
- 901
- Forks
- 592
- Avg merge
- 5d 19h
- Merged PRs (30d)
- 5
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from CCExtractor/ccextractor
-
[BUG] Legacy options -608, -708, -90090, -UCLA, -CC2, -LF, -DF, -parsepat, -parsepmt still rejected after #1856Possibly taken @Deepak-negi11 claimed this 1 day ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
CCExtractor/ccextractor#2367 ·
Maintainers usually reply within 1 day
-
[BUG] Memory leak in free_sub_track(): blockaddition and message buffer never freed for WebVTT tracksPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 1/5 Under an hour Newbie friendliness 86/100
CCExtractor/ccextractor#2247 ·
Maintainers usually reply within 1 day
-
`--out=mcc`: CDP cc_count field overflows above 31 triplets; uint8 `data_size` corrupts lengths and over-reads at higher countsPossibly taken @kaihere14 claimed this 8 days ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 72/100
CCExtractor/ccextractor#2365 · 1 comment ·
Maintainers usually reply within 1 day
-
--tpages-all extracts less than --tpagePossibly taken @SajalDevX claimed this 16 days ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 65/100
CCExtractor/ccextractor#2355 ·
Maintainers usually reply within 1 day
-
[BUG] store_hdcc() silently overwrites buffered caption data instead of concatenating when the same seq_index is reused with an unchanged timestampMay be free again @kaihere14 claimed this 23 days ago, and no pull request is open. Open
Difficulty 4/5 3-5 days Newbie friendliness 48/100
CCExtractor/ccextractor#2350 · 2 comments ·
Maintainers usually reply within 1 day
All issues in CCExtractor/ccextractor
Similar issues
-
backlog
Difficulty 1/5 Under an hour Newbie friendliness 82/100
EchoTools/nevr-runtime#454 ·
Maintainers usually reply within 1 day
-
initramfs: -type f (#18686) skips the libcurl.so.4 symlink, libcurl no longer copied into initramfsOpen
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 2 days
-
common/json_parse: json_to_bitcoin_amount fails to detect overflow and accepts negative/empty inputsPossibly taken @bhuvan-somisetty claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
ElementsProject/lightning#9617 ·
Maintainers usually reply within 2 days
-
Difficulty 1/5 Under an hour Newbie friendliness 62/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
zephyrproject-rtos/zephyr#121795 ·
Maintainers usually reply within 2 days