Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion quest/m1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,19 @@ transport, benchmark tooling); worktrees isolate commits, not semantics.
- [TS PSI reassembly](/quest/m1/ts-psi-reassembly.md) - `import ts` reads a PAT or PMT that spans packets or follows a nonzero pointer_field instead of aborting, and one corrupted section costs a repetition and a counted `CRC_error`, not the import
- [Same-hop importers](/quest/m1/hop-aligned-import.md) - importers sharing a `--hop` and fed one stream publish identical groups and timestamps, so failover survives
- [Capture control](/quest/m1/capture-control.md) - on dev, `encode::Capture` replaces `CaptureOptions` without a `clock` field (it reads the catalog's), an unsupported `cut()` errors, and dropping the last `Control` cancels in-flight opens
- [Capture by default](/quest/m1/capture-default.md) - moq-video and moq-audio build `capture` by default, so pre-merge checks test it and the capture gate goes away
- [Video surface](/quest/m1/video-surface.md) - on dev, moq-ffi's `native` becomes `surface`, refused on platforms with no surface
- [HLS discontinuity sequence](/quest/m1/hls-discontinuity-sequence.md) - on dev, `Segment::discontinuity` is the absolute sequence, so every cursor agrees
- [Auth client CA](/quest/m1/relay-auth-client-ca.md) - on dev, `auth::Config::validate` and `init` take the client-CA flag, so no caller can skip the check
- [HLS linger](/quest/m1/hls-linger.md) - `moq_hls::Server` serves an ended broadcast for its playlist window plus grace, so the moq.pro edge drops its own pool
- [Remove live()](/quest/m1/remove-live.md) - on dev, importers publish stream timestamps verbatim, the catalog clock maps them to wall time, and an encoder restart becomes a new epoch
- [Data track clock](/quest/m1/data-track-clock.md) - JSON and binary data tracks stamp on the catalog's clock at write time, matching the media's anchored clock
Comment thread
coderabbitai[bot] marked this conversation as resolved.
- [Go and Dart doc samples](/quest/m1/doc-samples-go-dart.md) - Go and Dart doc samples compile against their wrappers
- [Data capture in bindings](/quest/m1/data-capture-bindings.md) - moq-ffi and every wrapper pass a data frame's capture time, and the JSON window producer takes one
- [Moxygen compatibility](/quest/m1/moxygen/README.md) - one subgroup per group, whole-group FETCH, and one datagram per group, never a full moxygen pass
- [JS IETF reprice](/quest/m1/js-ietf-reprice.md) - `@moq/net`'s IETF publisher reprices a held namespace in place, like Rust, instead of withdraw-then-advertise
- [Cluster publisher in place](/quest/m1/cluster-publisher-in-place.md) - under the IETF cluster extension a publisher change updates an advertisement in place, like lite, and never splices across publishers
- [JS IETF datagrams](/quest/m1/js-ietf-datagram.md) - `@moq/net` sends and receives datagram groups over moq-transport, like Rust
- [Datagrams are live-only](/quest/m1/datagram-unfetchable.md) - no FETCH, replay to a new subscriber, or cache fill ever returns a datagram group
- [#2991](/quest/m1/2991-net-coalesce-dynamic-tracks-and-preserve-sequences-across.md) - one dynamic producer per track name in both languages, with the sequence namespace surviving a replacement
- [JavaScript FETCH](/quest/m1/js-fetch.md) - generic on-demand group serving and IETF FETCH for browser publishers
- [JS fetch cancel](/quest/m1/js-fetch-cancel.md) - `FetchGroupOptions.signal` abandons one pending fetch without closing the track
Expand Down
38 changes: 38 additions & 0 deletions quest/m1/capture-default.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# [S] Capture is a default feature

## Goal

`capture` is on by default in moq-video and moq-audio, so the pre-merge
`just check` compiles and tests device capture like any other default code,
and the separate capture CI gate goes away. The flag stays so a minimal build
can opt out. Workspace consumers that set `default-features = false` (the
relay, the language bindings) keep building without it.

## Plan

Decided in planning (09-29), after capture-control (#4545) found that
pre-merge `just check` never runs moq-video's `capture` tests:

- **Default-on, keep the flag.** Removing the flag was rejected: consumers
that don't want device stacks would pay for them.
- moq-video's `capture` already costs nothing to build on any platform. Its
Cargo comment says it stays off only "until every distribution ships it", a
packaging concern this reverses.
- moq-audio's `capture` links libasound when it builds on Linux, which is why
it depends on [ALSA link](/quest/m1/capture-alsa-link.md). Once libasound
loads at runtime, the default costs no system library.
- Delete the special capture gate (`rs capture`, `capture-test`, and the
capture branch in `sh/rs/select.sh` on the tooling line) once default
`just check` covers it. Keep the platform jobs (`just rs macos`,
`just rs windows`).
- Update the Cargo feature comments, moq-cli's `capture` feature (it may
become redundant), and `doc/` wherever capture is described as opt-in.

Verify: `just check` on a moq-video or moq-audio change runs the capture
tests, and a `default-features = false` consumer (for example
`cargo tree -p moq-ffi -e features`) pulls no capture dependency.

## Required

- [Tooling](/quest/m1/tooling/README.md) - rewrites the capture gate this deletes
- [ALSA link](/quest/m1/capture-alsa-link.md) - moq-audio capture can't be on by default while it links libasound at build time
19 changes: 19 additions & 0 deletions quest/m1/data-track-clock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# [XS] Data tracks stamp on the catalog's current clock

## Goal

A JSON or binary data track publishes timestamps on the same clock mapping as
the media next to it, however early it was created. Today a data track copies
the catalog clock when it's created. An importer sets that clock from its
first frame (remove-live, #4543), so a data track created before that frame
maps its timestamps to a different clock than the media.
Comment on lines +7 to +9

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Settle the clock ownership choice before this quest

If remove-live selects its still-documented option where the caller constructs the catalog after learning the first PTS (quest/m1/remove-live.md:26-30), the catalog clock is never changed after a data track is created, so this quest's stated failure and proposed mutable clock lookup do not apply. Settle that prerequisite API decision first, then either retain this quest for the importer-mutates-clock design or remove it for the build-later design.

AGENTS.md reference: AGENTS.md:L23-L23

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Settled already: #4543 (the remove-live PR, which this quest requires) chooses the importer-anchors-the-clock design. catalog::Producer keeps the clock in shared state and an importer anchors it once on its first frame, so a data track created earlier would still hold the provisional clock. The open wording in remove-live.md is removed when that quest completes in #4543, so this quest stays as written.

(Written by Claude Opus 5.5)


## Plan

Have data tracks read the catalog's clock when they stamp, not a copy made
when they were created. Keep it crate-private if possible. Test: a data track
created before an importer's first frame stamps on the anchored clock.

## Required

- [Remove live()](/quest/m1/remove-live.md) - introduces the first-frame clock anchor
45 changes: 45 additions & 0 deletions quest/m1/datagram-unfetchable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# [S] Datagrams are live-only

## Goal

A datagram group is delivered only to subscribers present when it is sent.
FETCH never returns one, a new subscription never replays buffered datagrams,
and a relay fills no cache miss with one. Anything that needs reliable or
late-joiner delivery should use a stream group instead.

## Plan

Decided in planning (09-29), after the moxygen fetch-fill agent found that the
relay's group-fetch decoder refuses a draft-16+ fetch object that carries the
datagram flag, and reports it as "unsupported":

- Keep the existing 64-datagram send buffer per track
(`rs/moq-net/src/model/track.rs`, `MAX_DATAGRAMS`). An age bound was
considered and dropped.
- A new subscription starts at the next datagram sent, not at the buffered
backlog. This covers Rust and `@moq/net`, lite and IETF.
- FETCH never serves a datagram group. A publisher answers a FETCH for one the
way it answers any group it won't deliver (dropped or does not exist),
never with its payload.
- A received fetch object with the datagram flag is refused as not fetchable.
It fails only that fetch or fill, not the session, because draft-16+ allows
the flag (maintainer, 09-29, on Codex's review). That covers the relay's group
fill (`recv_group_fetch_objects`, on the moxygen line) and the joining-fetch
fill (`run_fill_objects`).
- Update `drafts/draft-lcurley-moq-lite.md` to say datagrams are neither
cached nor fetchable, and `doc/concept/`. Run `just drafts check` and
`just test interop --all`.

Not planned: reliable or cached datagrams. If they are ever wanted, the way to
get them is back-pressure in the QUIC library and treating each datagram like
a one-shot stream, not a cache.

Tests: a subscriber joining after datagrams were sent receives only later
ones. A FETCH covering a datagram group gets no payload. A fetch stream
carrying a datagram-flagged object fails that fetch and leaves the session up.

## Related

- [Moxygen compatibility](/quest/m1/moxygen/README.md) - says it carries one datagram per group live; this keeps them out of FETCH
- [JS IETF datagrams](/quest/m1/js-ietf-datagram.md) - JS datagram send and receive over moq-transport
- [SUBSCRIBE_DROP](/quest/m1/subscribe-drop.md) - datagram groups stay best effort there too
37 changes: 0 additions & 37 deletions quest/m1/hls-linger.md

This file was deleted.

1 change: 1 addition & 0 deletions quest/m2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,4 @@ upstream release waits in [m4](/quest/m4/README.md).
- [Audio capture time](/quest/m2/audio-capture-time.md) - native audio stamps a buffer's capture instant, not when the driver reads it
- [X11 capture transport](/quest/m2/x11-capture-shm.md) - move X11 capture to shared memory and RandR events instead of a per-frame socket copy
- [Capture frame buffers](/quest/m2/capture-frame-buffers.md) - stop rebuilding a full-frame buffer every tick in the X11 and Windows backends
- [Demo serve-hls renditions](/quest/m2/serve-hls-renditions.md) - `just pub serve-hls` serves 720p and 144p instead of two 256-wide copies
16 changes: 16 additions & 0 deletions quest/m2/serve-hls-renditions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# [XS] Demo serve-hls publishes distinct renditions

## Goal

`just pub serve-hls` serves two renditions at different resolutions, as
`just pub hls` does. Today both come out 256 wide: the `-vf:0` and `-vf:1`
options aren't per-stream in ffmpeg, so the last filter wins.

## Plan

Use per-stream filters (`-filter:v:0`, `-filter:v:1`), scaled to 720p and
144p to match `hls`. Scaling the 720p source up to 1080p couldn't encode in
real time on a dev machine. The recipe body moves to `sh/demo/serve-hls.sh`
when the [tooling line](/quest/m1/tooling/README.md) lands; fix it wherever it
lives. Check it by fetching `master.m3u8` and comparing the two renditions'
`RESOLUTION` attributes.