diff --git a/quest/m1/README.md b/quest/m1/README.md index 1a2a567b44..e7f6d811a1 100644 --- a/quest/m1/README.md +++ b/quest/m1/README.md @@ -199,6 +199,7 @@ disabled rung strands WHEP, HLS, and moq-mux export viewers. - [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 - [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 - [Dart on iOS](/quest/m1/dart-ios.md) - prove the shipped iOS native asset actually loads on a device, which no CI can diff --git a/quest/m1/ts-export-backlog.md b/quest/m1/ts-export-backlog.md new file mode 100644 index 0000000000..f5dd6866ef --- /dev/null +++ b/quest/m1/ts-export-backlog.md @@ -0,0 +1,35 @@ +# [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 still drains every ready frame, as +it did before that PR. Reuse the same check rather than a TS-specific bound, +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 +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 +[#5305](https://github.com/moq-dev/moq/pull/5305) (stitch catalog bound); both +have 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. A joiner still reads its retained group to the live edge while the +clock is acquired, as FLV and MKV do. Run the TS export benchmarks to show the +cost.