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
5 changes: 4 additions & 1 deletion quest/m1/cli-packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ then fails to open a device is the same gap one layer down.
Also enable `v4l2` in the Linux ARM release build, so a released binary on a
Raspberry Pi 4 publishes from `moq import capture` through the V4L2 M2M
hardware encoder (`rs/moq-video/src/v4l2.rs`, already run on a Pi 4's
`bcm2835-codec`) with no GStreamer detour. Verify that once on a Pi 4.
`bcm2835-codec`) with no GStreamer detour. That Pi 4 run covered only
640x360 once, so the Pi 4 check also covers `set_bitrate` on a running
encoder (congestion control retunes through it) and 1080p, which codes as
1088 rows and relies on the compose rectangle to crop back.

Add a board hardware note to `doc/bin/cli.md` next to the capture build
instructions: Raspberry Pi 5 has no video encoder and Jetson Orin Nano ships
Expand Down
6 changes: 3 additions & 3 deletions quest/m1/mobile-ownership.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ carry the Rust codecs, and #4094 added the `CVPixelBuffer` bridge
stack beside one that exists.

What remains is recording the verdict in `rs/moq-ffi/AGENTS.md` (a maintainer
edit) and in [Android capture](/quest/m2/mobile-capture-android.md) and
[iOS capture](/quest/m2/mobile-capture-ios.md), which target `moq-video` as
written and no longer wait on this.
edit). [Android capture](/quest/m2/mobile-capture-android.md),
[iOS capture](/quest/m2/mobile-capture-ios.md), and the MediaCodec audio
quests already record it and no longer wait on this.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
12 changes: 7 additions & 5 deletions quest/m1/perf/group-cost.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@ the next largest source from there. A measured no-win abandons the quest,
per this line's rules.

Decided in the 2026-09-30 audit: two suspected per-group costs merged here
as candidates to measure with `SESSION_ALLOCS`, not separate quests.
as candidates to measure, not separate quests.

- Egress cache refresh: `group::Consumer::keep_alive` takes a state read
guard and calls `Charge::refresh` between completed frame writes on both
the lite and IETF publishers. It protects a drain longer than
`latency_max`, so keep per-frame liveness and
`slow_prefetch_reader_survives_expiry` (rs/moq-net/src/model/track.rs);
fewer refresh calls alone are not a win.
the lite and IETF publishers. That is lock, clock, and atomic work that may
allocate nothing, so time it rather than count allocations: CPU per
viewer-group for fast fanout and flow-controlled readers, over SUBSCRIBE
and FETCH. It protects a drain longer than `latency_max`, so keep
per-frame liveness and `slow_prefetch_reader_survives_expiry`
(rs/moq-net/src/model/track.rs); fewer refresh calls alone are not a win.
- Owned decode copies: `rs/moq-net/src/coding/decode.rs` decodes `Vec<u8>`
through `Buf::copy_to_bytes` then `to_vec`, and `String` consumes that
vector. Measure on the real reader input types (contiguous and chained)
Expand Down
4 changes: 2 additions & 2 deletions quest/m2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ waiting on an upstream release waits in [m4](/quest/m4/README.md).
- [Catalog colour model](/quest/m2/color-catalog.md) - the catalog describes a rendition's colour and HDR properties once a renderer consumes them
- [Archive recovery listing](/quest/m2/archive-recovery-listing.md) - a resumed DVR lists what changed since its checkpoint, not every stored group
- [Relay io_uring packages](/quest/m2/relay-io-uring-package.md) - Linux relay packages ship io_uring once the ring is on par with tokio
- [iOS capture](/quest/m2/mobile-capture-ios.md) - camera and screen capture if the mobile ownership decision selects Rust
- [Android capture](/quest/m2/mobile-capture-android.md) - NDK/JNI capture using the existing codecs if mobile ownership selects Rust
- [iOS capture](/quest/m2/mobile-capture-ios.md) - Rust captures the camera and screen on iOS
- [Android capture](/quest/m2/mobile-capture-android.md) - Rust captures through NDK/JNI on Android, reusing the existing codecs
- [Mobile completion](/quest/m2/mobile-completion.md) - verify the selected native/mobile path before closing #700
- [Opus implementation](/quest/m2/audio-opus-backend.md) - compare Opus codec quality, CPU, build cost, and the loss recovery each backend offers
- [Latency ledger](/quest/m2/latency-ledger.md) - a session reports where its end-to-end audio delay went, stage by stage
Expand Down
8 changes: 4 additions & 4 deletions quest/m2/audio-decode-mediacodec.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ device's codec list opens.

## Plan

Rust owns capture and codecs on mobile, settled in the 2026-09-30 audit
([Mobile ownership](/quest/m1/mobile-ownership.md)), so this backend is
the Android audio codec path.

The audio counterpart of `rs/moq-video/src/decode/backend/mediacodec.rs`,
behind a new optional audio `mediacodec` feature and the decode seam, on `target_os
= "android"`.
Expand All @@ -23,10 +27,6 @@ behind a new optional audio `mediacodec` feature and the decode seam, on `target
- The binding ships in the moq-ffi Android slice, which is how Kotlin and Dart
reach it.

## Required

- [Mobile ownership](/quest/m1/mobile-ownership.md) - if Kotlin owns platform codecs, this backend is moot

## Related

- [Android capture](/quest/m2/mobile-capture-android.md) - the video MediaCodec family this sits beside
5 changes: 4 additions & 1 deletion quest/m2/audio-encode-mediacodec.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ where the device's encoder supports it.

## Plan

Rust owns capture and codecs on mobile, settled in the 2026-09-30 audit
([Mobile ownership](/quest/m1/mobile-ownership.md)), so this backend is
the Android audio codec path.

The audio counterpart of `rs/moq-video/src/encode/backend/mediacodec.rs`,
behind the `mediacodec` feature and the encode seam.

Expand All @@ -23,5 +27,4 @@ behind the `mediacodec` feature and the encode seam.

## Required

- [Mobile ownership](/quest/m1/mobile-ownership.md) - if Kotlin owns platform codecs, this backend is moot
- [MediaCodec decode](/quest/m2/audio-decode-mediacodec.md) - the round-trip regression decodes through it
17 changes: 6 additions & 11 deletions quest/m2/mobile-capture-android.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,19 @@ camera, MediaProjection for the screen, and MediaCodec for encode and decode.

## Plan

MediaCodec encode/decode already exist in moq-video. Reuse them rather than
Rust owns capture and codecs on mobile, settled in the 2026-09-30 audit ([Mobile ownership](/quest/m1/mobile-ownership.md)). MediaCodec encode/decode already exist in moq-video. Reuse them rather than
Comment thread
kixelated marked this conversation as resolved.
planning a second backend family. The remaining capture and native Surface
integration needs NDK/JNI lifecycle, synchronization, and actual device proof.

Weigh the cost honestly before starting. `moq-kit` already does this in Kotlin
over `moq-ffi`, and raw frames cannot cross the FFI boundary zero-copy, so a
Rust Android media path pays off for Rust-native consumers and not for the
mobile SDK. That is a real audience (this is the same gap that made
`iroh-live` reimplement the native layer) but it is worth naming, since it
decides whether XL is worth spending.
This is the Android SDK's media path, not a Rust-only extra. `moq-kit`'s
Kotlin capture is the parallel stack the verdict retires once this lands.
Frames cross `moq-ffi` as opaque `HardwareBuffer`/`Surface` handles rather than
copies. Rust-native consumers benefit too (the same gap that made `iroh-live`
reimplement the native layer).

`moq-tokio` already reaches into Android through JNI for `tls::init_android`,
so the mechanism exists.

## Required

- [Ownership boundary](/quest/m1/mobile-ownership.md) - decides whether an NDK/JNI backend family is worth building

## Related

- [iOS capture](/quest/m2/mobile-capture-ios.md) - the other half of mobile, which
Expand Down
6 changes: 1 addition & 5 deletions quest/m2/mobile-capture-ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ through ReplayKit.

## Plan

Not a new codec backend. VideoToolbox already encodes and decodes as the macOS
Rust owns capture and codecs on mobile, settled in the 2026-09-30 audit ([Mobile ownership](/quest/m1/mobile-ownership.md)). Not a new codec backend. VideoToolbox already encodes and decodes as the macOS
backend. Reuse its native PixelBuffer surface and verify the iOS build and
runtime path rather than assuming desktop behavior. The new work is capture
wiring plus the lifecycle iOS imposes and macOS does not.
Expand All @@ -22,10 +22,6 @@ Reuse the `capture::Source` shape the other platforms use rather than growing
an iOS-specific entry point, so device enumeration and selection behave the
same everywhere.

## Required

- [Ownership boundary](/quest/m1/mobile-ownership.md) - decides whether Rust owns capture on mobile at all

## Related

- [Android capture and encode](/quest/m2/mobile-capture-android.md) - the other half of
Expand Down
17 changes: 7 additions & 10 deletions quest/m2/mobile-completion.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ work and deferred mobile phases are complete before #700 closes.
## Plan

This quest owns the cross-phase completion proof, not another implementation.
Use the chosen Rust or platform-owned capture path and the existing binding
APIs. Record the supported path, limitations, and reproducible device results;
wire repeatable coverage into CI and identify the hardware evidence separately.
Update the native/mobile getting-started docs with the working path.

The ownership decision may replace the Rust capture quests with platform-owned
work. In that case, update this quest's Required links to the replacement
implementation and proof quests before removing the abandoned blockers.
Abandoning a backend is not evidence that native/mobile support is complete.
Use the Rust capture path and the existing binding APIs: Rust owns capture
and codecs on mobile, settled in the 2026-09-30 audit
([Mobile ownership](/quest/m1/mobile-ownership.md)). Record the supported
Comment thread
kixelated marked this conversation as resolved.
path, limitations, and reproducible device results; wire repeatable coverage
into CI and identify the hardware evidence separately. Update the
native/mobile getting-started docs with the working path.

Do not close #700 merely because its next subset or a design decision finished.

## Required
Expand All @@ -26,7 +24,6 @@ Do not close #700 merely because its next subset or a design decision finished.
- [Dart codec parity](/quest/m1/dart-codecs.md) - codec-enabled artifacts and Dart video consumer integration
- [iOS capture](/quest/m2/mobile-capture-ios.md) - deliver the selected iOS capture path
- [Android capture](/quest/m2/mobile-capture-android.md) - deliver the selected Android capture and codec path
- [Mobile ownership](/quest/m1/mobile-ownership.md) - select and scope the mobile media architecture

## Closes

Expand Down
1 change: 0 additions & 1 deletion quest/m3/cat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ one. Everything rides `moq_auth::Request` and

## Required

- draft-ietf-moq-c4m registers the moqt claim keys
- [Verify](/quest/m3/cat/verify.md) - `moq_auth::cat` turns a CAT into a
grant and `moq auth serve` admits one; `moq auth sign|verify` mint and
check the format
Expand Down
4 changes: 4 additions & 0 deletions quest/m3/cat/verify.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,7 @@ in the 2026-09-28 quest audit. `@moq/auth` stays flat.

Public API: `moq_auth::cat` new, `moq auth serve` and `moq auth sign|verify`
gain flags. Wire: none.

## Required

- A consumer asks for CAT, or draft-ietf-moq-c4m registers the moqt claim keys
4 changes: 4 additions & 0 deletions quest/m3/cs/generator.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ catches a typed `MoqException`, on the host runtime.
handle cancels its pending calls. If upstream lacks the mapping, it lands in
the fork here, never in the wrapper; the probe above is the acceptance test.

## Required

- A .NET or Unity consumer asks for C# bindings

## Related

- [C++ generator](/quest/m1/cpp/generator.md) - the same port against the C++ generator
Loading