Skip to content

perf(mux): parse an MPTS once for every program - #6371

Merged
kixelated merged 10 commits into
mainfrom
quest/m1/ts-reliability/shared-parser
Oct 24, 2026
Merged

kixelated merged 10 commits into
mainfrom
quest/m1/ts-reliability/shared-parser

Conversation

@kixelated

@kixelated kixelated commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

ts::Programs (moq publish ... import ts --program all) fed the whole multiplex to an independent Import per program. Framing, continuity, the PAT, SI reassembly and TR 101 290 grading all ran once per program, so an MPTS ingest cost program count times input rate. Completes Shared parser, which the stream routes and PAT changes quests were waiting on.

Approach

  • New ts::demux::Demux frames the input and reads what every program shares: sync, per-PID continuity, the latest PCR on each PID, the PAT, and the standalone SI sections. It hands out one Packet at a time with those results.
  • Import keeps its per-program logic behind Import::packet; Import::decode runs its own Demux, so the single-program path and Programs share one code path.
  • Programs runs one Demux and routes each packet only to the programs whose PAT entry or PMT claims its PID (a PID-indexed reader table, updated when a PAT or PMT is handled). The PAT and completed SI sections go to every program. It flushes SI and announces only the programs a decode call touched, so a 1316-byte SRT/UDP datagram costs what it carried, not a pass over every program.
  • health::Health splits into Multiplex (sync, continuity, transport errors, counted once) and the per-program Health (PAT/PMT/PCR/PTS timers on that program's clock). mux_rate::Meter takes the parser's cumulative packet count instead of counting packets itself; Passthrough passes its own.
  • The PCR-before-PMT candidate table moves to the parser; a program seeds its clock from it only with a PCR seen since it last had no clock, as before.

Measurements

New rs/moq-mux/benches/ts_programs.rs: one second of a generated H.264 MPTS, sweeping program count and per-program bitrate, asserting every program delivers every frame. Throughput over the whole input (MiB/s):

programs main 1 Mb/s main 4 Mb/s this 1 Mb/s this 4 Mb/s
1 684 1002 717 943
4 308 333 712 925
16 83 87 635 767

The single-program rows are within run-to-run noise: interleaved repeats measured 948/887 on main against 953/957 here. The remaining dip at 16 programs and 1 Mb/s is the PAT, which every program still reads.

Impact

  • Public API: none. Import, Programs and their methods keep their signatures. Internal: si::Capture::section takes Bytes, so one reassembled SI section is shared by every program without copying.
  • Wire: none.
  • Behavior: under --program all, sync, continuity and transport errors before the first PAT are now graded too, since one parser reads the whole input. A duplicate packet no longer refreshes the PCR a later PMT starts its clock from. When two programs read the same elementary PID, a PMT that re-routes it in one program restarts the shared continuity chain for both.

Notes

  • SI capture still runs per program (each filters EIT/SDT to its own service), so SI sections fan out N times; only their reassembly is shared.
  • The downstream quests are updated in place: stream routes now classifies a PID through Programs::readers and extends this bench, and PAT changes notes that Programs sees each whole PAT first.

Validation

  • just check: passed (Rust lint and tests, quest, markdown, flake).
  • cargo test -p moq-mux --lib container::ts: 606 passed.
  • cargo bench --bench ts_programs on main (with the bench copied in) and on this branch, numbers above.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EeyiEy5FWz3z44DYZVo7vU

(Written by Claude Opus 5.5)

kixelated and others added 2 commits October 22, 2026 11:57
`ts::Programs` fed the whole multiplex to an independent `Import` per
program, so framing, continuity, the PAT, SI reassembly and health
grading ran once per program: ingest cost was program count times
input rate.

A shared `Demux` now frames the input and reads what every program
shares (sync, per-PID continuity, the latest PCR per PID, the PAT, SI
sections). `Programs` routes each packet only to the programs whose PAT
entry or PMT claims its PID, through a PID-indexed reader table, and
flushes only programs a call touched. A single `Import` runs the same
parser. `health::Health` splits into the multiplex checks and the
per-program timers; the mux-rate meter takes the parser's packet count.

New `ts_programs` bench: at 16 programs, 4 Mb/s each, throughput goes
from 87 to ~770-850 MiB/s, flat with program count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EeyiEy5FWz3z44DYZVo7vU
@kixelated kixelated changed the title One TS packet parser serves every program perf(mux): parse an MPTS once for every program Oct 22, 2026
@kixelated
kixelated marked this pull request as ready for review October 22, 2026 19:41
@kixelated

Copy link
Copy Markdown
Collaborator Author

Outcome: the quest is complete and the quest file is deleted in this PR. One shared parser now serves every program under --program all; ingest throughput is flat with program count (16 programs at 4 Mb/s: 87 to ~770 MiB/s). Public API and wire are unchanged. There are no open decisions. The behavior notes in the description (pre-PAT grading, duplicate PCR seeding, a shared continuity chain on a shared PID) are implementation choices, open to review.

Suggested follow-ups: none new. Stream routes and PAT changes unblock once this merges.

(Written by Claude Opus 5.5)

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 31 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 7ba15ecb-c17a-4f84-b1dd-156c075091f0
Commits

Reviewing files that changed from the base of the PR and between 23ddc78 and 83e41ff.

Files selected for processing: 17
  • quest/m1/ts-reliability/README.md
  • quest/m1/ts-reliability/pat-lifecycle.md
  • quest/m1/ts-reliability/program-cap.md
  • quest/m1/ts-reliability/shared-parser.md
  • quest/m1/ts-reliability/stream-routes.md
  • rs/moq-mux/Cargo.toml
  • rs/moq-mux/benches/ts_programs.rs
  • rs/moq-mux/src/container/ts/demux.rs
  • rs/moq-mux/src/container/ts/export_test.rs
  • rs/moq-mux/src/container/ts/health.rs
  • rs/moq-mux/src/container/ts/import.rs
  • rs/moq-mux/src/container/ts/mod.rs
  • rs/moq-mux/src/container/ts/mux_rate.rs
  • rs/moq-mux/src/container/ts/passthrough.rs
  • rs/moq-mux/src/container/ts/programs.rs
  • rs/moq-mux/src/container/ts/si.rs
  • sh/gh/nightly.sh

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 5b2fb50d-fab7-4033-a932-08c8f1404114
Commits

Reviewing files that changed from the base of the PR and between 0f986d9 and 23ddc78.

Files selected for processing: 17
  • quest/m1/ts-reliability/README.md
  • quest/m1/ts-reliability/pat-lifecycle.md
  • quest/m1/ts-reliability/program-cap.md
  • quest/m1/ts-reliability/shared-parser.md
  • quest/m1/ts-reliability/stream-routes.md
  • rs/moq-mux/Cargo.toml
  • rs/moq-mux/benches/ts_programs.rs
  • rs/moq-mux/src/container/ts/demux.rs
  • rs/moq-mux/src/container/ts/export_test.rs
  • rs/moq-mux/src/container/ts/health.rs
  • rs/moq-mux/src/container/ts/import.rs
  • rs/moq-mux/src/container/ts/mod.rs
  • rs/moq-mux/src/container/ts/mux_rate.rs
  • rs/moq-mux/src/container/ts/passthrough.rs
  • rs/moq-mux/src/container/ts/programs.rs
  • rs/moq-mux/src/container/ts/si.rs
  • sh/gh/nightly.sh
Files with no reviewable changes: 2
  • quest/m1/ts-reliability/program-cap.md
  • quest/m1/ts-reliability/shared-parser.md

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.

Walkthrough

The change adds shared MPEG-TS packet parsing and uses PID claims to route packets to programs. It separates multiplex-wide continuity checks from per-program health checks, updates PCR packet-count metering, and adds a Criterion benchmark for multi-program ingestion. The reliability plans now describe whole-PAT handling and PID routing, and remove references to the deleted shared-parser plan.

Priority: Normal

Severity of issue fixed: Medium

Merge Risk: Minimal · up to 23ddc

This change parses a multi-program transport stream once and routes packets to programs by PID, which improves ingest throughput. No concrete merge-blocking issue was identified in the supplied evidence, and the author reports that tests and lint passed.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly summarizes the main change: parsing an MPTS once for all programs.
Description check Passed The description explains the problem, implementation, performance measurements, impact, and validation. It is directly related to the changeset.
Docstring Coverage Passed Docstring coverage is 81.18% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 85 functions across 11 files. (4 skipped: 4…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 81.18% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 85 functions across 11 files. (4 skipped: 4 unsupported.)

Finishing Touches
✨ Simplify code
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-24T09:14:51.594617Z 83e41ff New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@kixelated

Copy link
Copy Markdown
Collaborator Author

Merging. Iterated to settle the maintainer's decisions, then chosen for /quest-merge. CI is green, the current head has a non-Grok review, and quest check passes against main.

(Written by Claude Opus 5.5)

@kixelated
kixelated enabled auto-merge October 23, 2026 21:07
…ty/shared-parser

# Conflicts:
#	quest/m1/ts-reliability/README.md
#	quest/m1/ts-reliability/shared-parser.md
@kixelated
kixelated added this pull request to the merge queue Oct 23, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0d85e9036b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread rs/moq-mux/src/container/ts/programs.rs Outdated
…laims it

The shared demux tracks one continuity chain per PID. A program registering
a PID another program already reads reset that chain, so a duplicate packet
right after the PMT read as contiguous and a counter gap went uncounted for
the existing reader. Only the PID's sole reader restarts it now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated removed this pull request from the merge queue due to a manual request Oct 23, 2026
@kixelated

Copy link
Copy Markdown
Collaborator Author

Merge summary:

  • Merged main into the branch (0d85e90). Conflicts were quest-only: shared-parser.md stays deleted (this PR finishes it), the epic's Required list keeps main's wording for decode order and PMT export, and the stale link in program-cap.md is dropped.
  • Addressed the Codex finding on the merged head (3bcceff): a program claiming a PID another program already reads no longer resets the shared continuity chain. New test a_shared_pid_keeps_its_chain_when_another_program_claims_it.
  • Local checks: Rust lint and tests for the affected crates, quest, drill, markdown, shell, TOML, ts-paths and gh lint passed. nix flake check could not build the runner VM image in this sandbox (unshare uid_map denied), unrelated to this diff.

(Written by Claude Opus 5.5)

@kixelated
kixelated enabled auto-merge October 23, 2026 23:33
…ty/shared-parser

# Conflicts:
#	quest/m1/ts-reliability/README.md
#	quest/m1/ts-reliability/pat-lifecycle.md
@kixelated
kixelated added this pull request to the merge queue Oct 23, 2026
@kixelated

Copy link
Copy Markdown
Collaborator Author

Addendum: merged main again (ba4fc4e) after moq-dev/moq#6543 and moq-dev/moq#6554 landed. Quest conflicts: dropped the deleted pmt-export.md and shared-parser.md links from the epic and pat-lifecycle.md. Semantic conflict: #6543's Import::finish released self.scratch, which this PR moved into Demux, so Demux::finish now releases it, called from both Import::finish and Programs::finish. Rust lint and tests for the affected crates pass locally.

(Written by Claude Opus 5.5)

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 24, 2026
@kixelated
kixelated enabled auto-merge October 24, 2026 02:30
@kixelated
kixelated added this pull request to the merge queue Oct 24, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 24, 2026
# Conflicts:
#	rs/moq-mux/src/container/ts/import.rs
#	sh/gh/nightly.sh
@kixelated
kixelated added this pull request to the merge queue Oct 24, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 24, 2026
@kixelated
kixelated enabled auto-merge October 24, 2026 09:12
@kixelated
kixelated added this pull request to the merge queue Oct 24, 2026
Merged via the queue into main with commit 2833498 Oct 24, 2026
10 checks passed
@kixelated
kixelated deleted the quest/m1/ts-reliability/shared-parser branch October 24, 2026 11:46
kixelated added a commit that referenced this pull request Oct 24, 2026
#6371 replaced the per-program reparse with one Demux. On it,
Programs no longer hands scan state to a late importer: it watches the
PMT PIDs of waiting programs, and when a PMT for one completes it creates
the importer (seeded with the PAT and that PID's reassembler as it stood
before the packet) and routes the packet through the importer's own PMT
path. The shared parser already owns the PAT reader, grading and PCR
samples, so rounds 1 to 4 of review findings fall away. The
`Import::resume` handoff, `Resume` and `reads_pmt` are gone; only
`Import::with_pmt` remains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant