From c7eeb18d7c4ac514a233c8224919125befcbbfda Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Mon, 12 Oct 2026 21:44:12 -0700 Subject: [PATCH 1/3] quest(m1): bound TS export reads like FLV and MKV Co-Authored-By: Claude Opus 5.5 --- quest/m1/README.md | 1 + quest/m1/ts-export-backlog.md | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 quest/m1/ts-export-backlog.md diff --git a/quest/m1/README.md b/quest/m1/README.md index 83f44048ba..4cec7efa1a 100644 --- a/quest/m1/README.md +++ b/quest/m1/README.md @@ -190,6 +190,7 @@ demand (#5214), each ranked beside the work it shares code with. - [moqsink first catalog](/quest/m1/gst-first-catalog.md) - a restarted `moqsink` lists every requested pad in its first catalog, so `moqsrc` resumes each on its held pad - [moqsrc A/V alignment](/quest/m1/gst-src-av-sync.md) - every `moqsrc` pad of a run shares one timestamp reference and segment base - [TS passthrough export](/quest/m1/ts-passthrough-export.md) - `export ts --passthrough` writes the `m2ts` track back byte-identical (less late drops) on a fixed delay +- [TS export backlog](/quest/m1/ts-export-backlog.md) - `export ts` reads a track only until a frame is due, like FLV and MKV, so a backlog stays in the source - [FLV and MKV export delay](/quest/m1/export-delay.md) - FLV and MKV interleave through the shared jitter buffer on a fixed delay, breaking the CLI once - [Bindings size profile](/quest/m1/ffi-size-profile.md) - a benchmark decides whether the moq-ffi builds ship at opt-level "s", which halves the dylib - [Go mirror delivery](/quest/m1/go-mirror-delivery.md) - the Go binding's staticlibs stop growing git history by ~210 MiB per release diff --git a/quest/m1/ts-export-backlog.md b/quest/m1/ts-export-backlog.md new file mode 100644 index 0000000000..9a765b1a40 --- /dev/null +++ b/quest/m1/ts-export-backlog.md @@ -0,0 +1,33 @@ +# [S] TS export leaves a backlog in its sources + +## Goal + +`moq export ts` reads a track only until it has a frame due, so a backlog (a +stalled sink, a large retained group) stays in the source and goes out as it +falls due instead of being queued whole in the jitter buffer first. Output +order, deadlines, and late drops are unchanged. A regression test on mock time +shows the bound, at zero and nonzero delay. + +## Plan + +[#5309](https://github.com/moq-dev/moq/pull/5309) bounded FLV and MKV this way +with the jitter buffer's `full` check: a track is full once a frame of it is +due, or holds any frame without a delay. TS `fill` still drains every ready +frame, as it did before that PR. Reuse the same check rather than a TS-specific +bound. + +Wait for the TS work in flight to land first, so this does not fight it: +[#5349](https://github.com/moq-dev/moq/pull/5349) (passthrough export) still +reshapes the export, and [#5305](https://github.com/moq-dev/moq/pull/5305) +(stitch catalog bound) has landed. + +Watch for TS-only interactions: the zero-delay path lays grid slots from each +released frame, the program tables hold one frame per track before they are +built, and tune-in alignment drops audio ahead of the first video. Do not cap +how far ahead of now a track is read: a track sent ahead of the others (TS video +often leads audio) would be read late, skewing the leads and drift the clock +measures. Run the TS export benchmarks to show the cost. + +## Required + +- [TS passthrough export](/quest/m1/ts-passthrough-export.md) - `export ts --passthrough` lands, settling the export's read path From 1e0027960bb7b9eeb73ea109d1188638f1e960aa Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Tue, 13 Oct 2026 00:33:41 -0700 Subject: [PATCH 2/3] quest(m1): judge bounded TS reads on when the source was last empty Co-Authored-By: Claude Opus 5.5 --- quest/m1/ts-export-backlog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quest/m1/ts-export-backlog.md b/quest/m1/ts-export-backlog.md index be9bc9a1ae..297a58eb2f 100644 --- a/quest/m1/ts-export-backlog.md +++ b/quest/m1/ts-export-backlog.md @@ -15,6 +15,10 @@ with the jitter buffer's `full` check: a track is full once a frame of it is due, or holds any frame without a delay. TS still drains every ready frame, as it did before that PR. Reuse the same check rather than a TS-specific bound, and cover `--passthrough` too if its release path reads the same way. +Bounding reads leaves arrived frames unread, so each read must judge a frame's +deadline on when its source was last empty, as FLV and MKV do, not on when it +was read: otherwise a slow sink makes frames that arrived on time late. The +regression test covers that slow-sink case for each path. This waited for the TS work then in flight, [#5349](https://github.com/moq-dev/moq/pull/5349) (passthrough export) and From fc86c0f648e19cac6dded59c392aba5640a0907b Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Tue, 13 Oct 2026 00:37:56 -0700 Subject: [PATCH 3/3] quest(m1): bound TS passthrough reads too Co-Authored-By: Claude Opus 5.5 --- quest/m1/ts-export-backlog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quest/m1/ts-export-backlog.md b/quest/m1/ts-export-backlog.md index 297a58eb2f..f5dd6866ef 100644 --- a/quest/m1/ts-export-backlog.md +++ b/quest/m1/ts-export-backlog.md @@ -14,7 +14,7 @@ shows the bound, at zero and nonzero delay. with the jitter buffer's `full` check: a track is full once a frame of it is due, or holds any frame without a delay. TS still drains every ready frame, as it did before that PR. Reuse the same check rather than a TS-specific bound, -and cover `--passthrough` too if its release path reads the same way. +and bound `--passthrough` too, whose release path drains ready frames the same way. Bounding reads leaves arrived frames unread, so each read must judge a frame's deadline on when its source was last empty, as FLV and MKV do, not on when it was read: otherwise a slow sink makes frames that arrived on time late. The