Skip to main content

Module webcam

Module webcam 

Source
Expand description

Virtual camera: the browser’s webcam, delivered to applications as a V4L2 capture device.

The client encodes its camera (H.264/VP8/… over the WebRTC media track or WebCodecs over the WebSocket, MJPEG as the last-resort canvas path) and Selkies hands each encoded frame to VirtualCamera::push, which returns at once. A worker thread decodes, fits the picture into the device’s fixed raw format, and publishes it to every sink at once:

  • the shared-memory ring served over a Unix socket to the Selkies V4L2 interposer (LD_PRELOAD, no privileges, no kernel module), see ring and server;
  • a v4l2loopback output device where one is configured or found, see v4l2out — the kernel path for hosts and privileged containers, as /dev/uinput is for gamepads;
  • a PipeWire Video/Source node where a daemon is reachable, see pipewire — for PipeWire-native consumers and the pipewire-v4l2 wrapper.

Nothing on the hot path copies more than the encoded bytes into a pooled buffer, and no worker thread ever calls back into the consumer.

Modules§

convert
Normalization of decoded frames into the virtual device’s fixed format.
decode
Decoders for the client camera uplink, and for the checks that read a session’s own output back.
pipewire
PipeWire sink: the camera as a Video/Source node.
ring
Shared-memory frame ring consumed by the Selkies V4L2 interposer.
server
Control socket for the Selkies V4L2 interposer.
v4l2out
Kernel-device sink: writes frames into a v4l2loopback output device.

Structs§

CameraRunning
The running camera’s negotiated format and sinks (CameraStats::running).
CameraStats
What VirtualCamera::stats reports: the counters since the camera was created, what the client last sent, and the running camera’s geometry and sinks where one runs.
Job 🔒
MjpegEncoder 🔒
JPEG writer for the MJPEG device: the fitted, full-range I420 picture compressed straight into the ring slot.
Pool 🔒
Recycled encoded-frame buffers so the steady state allocates nothing per frame.
Queue 🔒
Bounded hand-off to the decoder thread that drops the oldest frame when the decoder falls behind: a camera must stay live, never grow latency.
QueueState 🔒
Running 🔒
Stats 🔒
Counters read by VirtualCamera.stats().
VirtualCamera
A virtual camera fed with encoded frames by the consumer.
VirtualCameraSettings
Configuration for VirtualCamera::start.
WorkerConfig 🔒

Constants§

MJPEG_REENCODE_QUALITY 🔒
Re-encode quality for frames that must be fitted into an MJPEG device (a camera of another size, an H.264/VP8 uplink); frames of the device’s own size pass through as received.

Functions§

black_frame 🔒
A black frame in dev’s format, at most capacity bytes; None for an MJPEG device without its encoder.
fan_out 🔒
After a publish: wake the socket clients and mirror the frame into the kernel device and the PipeWire node where those sinks are up, retiring a sink that failed.
monotonic_ns 🔒
parse_pixel_format 🔒
socket_dir
Where the camera socket lives unless a caller names one: the session’s private runtime directory, where no other account can take the name first, else /tmp. The v4l2 interposer looks in the same place.
worker 🔒
Decoder thread body: decode, fit, publish, wake clients. A dropped or undecodable inter-coded frame parks the stream until the next keyframe and asks the client for one, so a consumer never sees the smear of predictions built on a missing reference.