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
86 changes: 9 additions & 77 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ members = [
"rs/moq-tokio",
"rs/moq-transcode",
"rs/moq-uring",
"rs/moq-v4l",
"rs/moq-video",
"rs/moq-wasm",
"rs/quest",
Expand Down Expand Up @@ -72,6 +73,7 @@ default-members = [
"rs/moq-tokio",
"rs/moq-transcode",
"rs/moq-uring",
"rs/moq-v4l",
"rs/moq-video",
# "rs/moq-wasm", # wasm32-unknown-unknown target only
"rs/quest",
Expand Down Expand Up @@ -100,6 +102,7 @@ aws-lc-rs = "1"
axum = { version = "0.8", features = ["tokio"] }
axum-server = { version = "0.8", features = ["tls-rustls"] }
base64 = "0.23"
bitflags = "2"
block2 = "0.6.2"
bytes = "1"
clap = { version = "4", features = ["derive"] }
Expand Down Expand Up @@ -165,6 +168,10 @@ moq-transcode = { version = "0.0.19", path = "rs/moq-transcode", default-feature
# stack the io_uring path compiles; cargo features are additive, so a default-on
# backend could not be opted out of.
moq-uring = { version = "0.0.1", path = "rs/moq-uring", default-features = false }
# In-tree fork of `v4l` with the videodev2.h bindings checked in, so moq-video's
# `capture` and `v4l2` need no libclang or kernel headers. Linux only; an empty
# stub elsewhere.
moq-v4l = { version = "0.0.1", path = "rs/moq-v4l" }
# Standalone crate (moq-dev/vaapi); vendored from cros-libva + cros-codecs.
# dlopen's libva at runtime (no libva-dev at build, no NEEDED libva in the binary).
moq-vaapi = "0.0.4"
Expand Down
4 changes: 2 additions & 2 deletions doc/bin/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ M2M) with a built-in H.264 software fallback;
audio is Opus. The camera is opened only while someone is watching, and
`--bitrate` is the opening ceiling. Backends with live bitrate control lower it
to fit the connection's bandwidth estimate. `moq devices` prints every source
id. Requires the `capture` feature; on Linux that needs libclang, V4L2, and
ALSA headers, and `--display` also needs the `pipewire` feature (links
id. Requires the `capture` feature; on Linux that needs the ALSA headers for
the microphone, and `--display` also needs the `pipewire` feature (links
libpipewire).

## Transcode
Expand Down
5 changes: 3 additions & 2 deletions doc/lib/rs/moq-video.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ while let Some(frame) = video.read().await? {

```bash
cargo add moq-video # nvidia, mediacodec, openh264 on by default
cargo add moq-video --features capture # camera + screen capture (Linux: bindgen needs libclang + V4L2 headers)
cargo add moq-video --features capture # camera + screen capture, no system build deps
cargo add moq-video --features render # wgpu rendering
cargo add moq-video --features vaapi,v4l2 # Linux VAAPI + V4L2 M2M codecs (bindgen needs libclang)
cargo add moq-video --features v4l2 # Linux V4L2 M2M codecs, no system build deps
cargo add moq-video --features vaapi # Linux VAAPI codecs (bindgen needs libclang)
cargo add moq-video --features pipewire # Wayland screen capture (links libpipewire)
cargo add moq-video --no-default-features --features openh264 # software H.264 only
cargo add moq-video --no-default-features --features nvidia # Linux NVIDIA only, no C++ or wgpu
Expand Down
8 changes: 4 additions & 4 deletions nix/overlay.nix
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@ let
doCheck = false;
nativeBuildInputs = with final; [
pkg-config
# libmoq is the only nix-built package that pulls moq-video, and on Linux
# that brings v4l -> v4l2-sys-mit, whose build.rs runs bindgen over
# <linux/videodev2.h>. Sets LIBCLANG_PATH + BINDGEN_EXTRA_CLANG_ARGS so it
# finds libclang and the libc headers, same as the devShell in flake.nix.
# libmoq is the only nix-built package that pulls moq-video, and its `vaapi`
# feature brings moq-vaapi, whose build.rs runs bindgen over its vendored
# libva headers. Sets LIBCLANG_PATH + BINDGEN_EXTRA_CLANG_ARGS so it finds
# libclang and the libc headers, same as the devShell in flake.nix.
rustPlatform.bindgenHook
];

Expand Down
5 changes: 2 additions & 3 deletions quest/future/video-vaapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ That is why `vaapi` is off by default while `nvidia` is on. Commit the
generated bindings to the crate and drop the build script and the bindgen
dependency, as `moq-nvenc` does: the output is portable (layout tests off,
fixed-width types, `c_char` left symbolic), so one checked-in file serves
every Linux target. Then the feature can return to default-on here. The
`v4l2` feature has the same shape, but its bindgen lives in the third-party
`v4l` crate, so that is a separate decision.
every Linux target, as `moq-v4l` already does for `videodev2.h`. Then the
feature can return to default-on here.

Note what is already fine: a host with libva present but no usable VA driver
already falls back cleanly, since `Encoder::new` returns `Err` and
Expand Down
1 change: 0 additions & 1 deletion quest/next/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ transport, benchmark tooling); worktrees isolate commits, not semantics.
- [`moq relay`](/quest/next/moq-relay-subcommand.md) - the relay runs under a `moq` verb with its own flags and TOML, while `moq-relay` stays a minimal binary
- [`moq --listen` admission](/quest/next/cli-serve.md) - a listening CLI session is authenticated, scoped, counted, and drained like a relay's instead of accepting everything
- [#709](/quest/next/709-automatic-letsencrypt-support.md) - the relay provisions and renews its own ACME certificate through rustls-acme over TLS-ALPN-01, persisted on disk
- [Capture without V4L2 bindgen](/quest/next/capture-v4l-bindings.md) - moq-video capture builds on Linux without libclang or kernel headers
- [Audio capture without ALSA link](/quest/next/capture-alsa-link.md) - moq-audio capture and playback build on Linux without linking libasound
- [Ship capture and playback](/quest/next/cli-packaging.md) - a released moq binary can capture and play, which no distribution currently enables
- [io_uring flow control](/quest/next/uring-flow-control-windows.md) - the relay's io_uring workers honor the QUIC flow-control windows instead of refusing them
28 changes: 0 additions & 28 deletions quest/next/capture-v4l-bindings.md

This file was deleted.

14 changes: 7 additions & 7 deletions quest/next/cli-packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ is a packaging gap, not a documentation one: `doc/bin/cli.md` already
documents the `--features capture` build.

Turn both on by default and keep the heavy parts individually droppable. The
sub-features already exist for this: `nvidia` is opt-out, and `vaapi`, `v4l2`,
and `pipewire` are opt-in because they need libclang or libpipewire on the
build host, so a self-compiler can shed CUDA or add the Linux extras, and
sub-features already exist for this: `nvidia` is opt-out, `vaapi` and
`pipewire` are opt-in because they need libclang or libpipewire on the build
host, and `v4l2` is opt-in only by habit now that moq-v4l checks its bindings
in, so a self-compiler can shed CUDA or add the Linux extras, and
`--no-default-features` still reaches a minimal build. The cost is real and
lands on Linux source builds: the camera path pulls libclang and V4L2 headers
through bindgen, the microphone pulls ALSA through cpal, and `play` pulls
winit plus a GPU stack. macOS and Windows use OS frameworks and add nothing.
lands on Linux source builds: the microphone pulls ALSA through cpal, and
`play` pulls winit plus a GPU stack. The camera path costs nothing. macOS and
Windows use OS frameworks and add nothing.

Check each distribution actually builds: the Nix overlay needs those system
dependencies present, and a Docker image without them fails at build rather
Expand All @@ -31,5 +32,4 @@ then fails to open a device is the same gap one layer down.

## Required

- [Capture without V4L2 bindgen](/quest/next/capture-v4l-bindings.md) - the camera path must build without libclang before every distribution can ship it
- [Audio capture without runtime system libraries](/quest/next/capture-alsa-link.md) - the microphone path must start without system audio libraries before every distribution can ship it
13 changes: 6 additions & 7 deletions rs/moq-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ noq = ["moq-tokio/noq"]
qlog = ["moq-tokio/qlog"]
websocket = ["moq-tokio/websocket"]
# Device capture (camera + microphone) + encode/publish. Off by default because
# it pulls in moq-video + moq-audio capture, which add system build deps on Linux
# (camera: `v4l`/v4l2-sys-mit needs libclang + V4L2 headers via bindgen; mic: cpal
# needs ALSA/libasound), plus binary size. macOS/Windows use OS frameworks, no
# it pulls in moq-video + moq-audio capture: on Linux the microphone needs
# ALSA/libasound at build time through cpal (the camera needs nothing, moq-v4l
# checks its bindings in), plus binary size. macOS/Windows use OS frameworks, no
# extra install. H.264 is vendored static (openh264), so no system ffmpeg/libav.
# Enable with `cargo build -p moq-cli --features capture`, adding `pipewire` for
# display capture on Linux.
Expand Down Expand Up @@ -70,10 +70,9 @@ nvdec = ["nvidia"]
# pulls in moq-video.
vaapi = ["moq-video?/vaapi", "moq-transcode?/vaapi"]
# The V4L2 M2M codecs of an ARM SoC (a Raspberry Pi's VideoCore and the like),
# opt-in like the moq-video feature it turns on: the `v4l` crate's bindgen needs
# libclang and the kernel headers on the build host. `capture` already pays that
# for the camera, so a capture build adds it for free. Only bites when `capture`,
# `transcode`, or `play` pulls in moq-video.
# opt-in like the moq-video feature it turns on. Costs the build nothing: moq-v4l
# checks its bindings in. Only applies when `capture`, `transcode`, or `play`
# pulls in moq-video.
v4l2 = ["moq-video?/v4l2", "moq-transcode?/v4l2"]
# Screen capture for `capture --display` on Linux (xdg-desktop-portal + PipeWire),
# opt-in like moq-video's own `pipewire` because it links libpipewire-0.3 at
Expand Down
4 changes: 2 additions & 2 deletions rs/moq-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ url = { workspace = true }
moq-audio = { workspace = true, optional = true, features = ["aac"] }
moq-tokio = { workspace = true, default-features = true }
# `openh264`, `nvidia`, and `vaapi` back on, matching rs/libmoq: the workspace turns
# moq-video's defaults off for `capture` (V4L2, libclang), and the codecs are
# collateral rather than the goal. Nothing is paid for them off Linux, since
# moq-video's defaults off for `capture` (device code the bindings don't
# expose), and the codecs are collateral rather than the goal. Nothing is paid for them off Linux, since
# cudarc / moq-nvenc / libloading / moq-vaapi sit behind
# `cfg(target_os = "linux")` and Android is `target_os = "android"`. On Linux
# both dlopen the driver, so the wrappers still link GPU-less and start
Expand Down
7 changes: 4 additions & 3 deletions rs/moq-transcode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ categories = ["multimedia", "multimedia::video", "multimedia::encoding"]
# the zero-copy GPU pipeline, while OpenH264 keeps a software H.264 fallback.
# NVIDIA dlopens its driver and needs nothing on the build host. OpenH264 is
# vendored C++, so a hardware-only build can disable default features and select
# `nvidia`. `vaapi` and `v4l2` stay opt-in because their bindgen needs libclang.
# `nvidia`. `vaapi` stays opt-in because its bindgen needs libclang; `v4l2`
# mirrors moq-video's opt-in too, though it costs the build nothing.
default = ["nvidia", "openh264"]
# NVENC + NVDEC (Linux, dlopen'd at runtime; a no-op elsewhere).
nvidia = ["moq-video/nvidia"]
Expand All @@ -26,8 +27,8 @@ openh264 = ["moq-video/openh264"]
# Intel/AMD VAAPI hardware encoder (Linux; libva dlopen'd at runtime, but
# moq-vaapi's bindgen needs libclang at build time).
vaapi = ["moq-video/vaapi"]
# The V4L2 M2M codecs of an ARM SoC (Linux; the `v4l` crate's bindgen needs
# libclang and the kernel headers at build time).
# The V4L2 M2M codecs of an ARM SoC (Linux; moq-v4l checks its bindings in, so
# nothing is needed on the build host).
v4l2 = ["moq-video/v4l2"]

[dependencies]
Expand Down
17 changes: 17 additions & 0 deletions rs/moq-v4l/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "moq-v4l"
version = "0.0.1"
edition = "2021"
license = "MIT"
rust-version.workspace = true

description = "Safe Video4Linux 2 bindings, forked from raymanfx/libv4l-rs with the kernel bindings checked in (no bindgen, no libclang)"
repository = "https://github.com/moq-dev/moq"
readme = "README.md"

keywords = ["v4l2", "video", "capture", "linux"]
categories = ["multimedia::video", "os::linux-apis"]

[dependencies]
bitflags = { workspace = true }
libc = { workspace = true }
9 changes: 9 additions & 0 deletions rs/moq-v4l/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
MIT License

Copyright (c) 2020 Christopher N. Hesse.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Loading
Loading