Identidad del Componente
| Campo | Valor |
| Repo | github.com/pikvm/ustreamer |
| Versión ref. | v6.55 |
| Lenguaje | C (95.8%) |
| Licencia | GPL-3.0 |
| Proyecto padre | PiKVM |
| RAM típica | ~5–15 MB |
| Install Debian | apt install ustreamer |
| Compile from src | make && sudo make install |
| Deps build | libevent-dev libjpeg-dev libbsd-dev |
CLI Flags — Referencia Rápida
Toda la config es por flags CLI. No hay fichero de configuración YAML/JSON.
| Flag | Default | Qué hace |
| --host | 0.0.0.0 | IP de escucha. Usar 127.0.0.1 si Oasis hace proxy |
| --port | 8080 | Puerto HTTP |
| --device | /dev/video0 | Device V4L2 de captura |
| --encoder | cpu | m2m-image = HW JPEG vía V4L2 M2M (CSI). cpu = libjpeg (USB) |
| --workers | 1 | Hilos JPEG encode paralelos. Recomendado: 3 en RPi 3B |
| --resolution | 640x480 | Resolución de captura. Ej: 1280x720, 1920x1080 |
| --format | auto | Pixel format V4L2: YUYV, MJPEG, RGB24… |
| --desired-fps | max | FPS objetivo. Ej: 15, 30 |
| --quality | 80 | Calidad JPEG (1–100) |
| --drop-same-frames | 0 | Nº frames idénticos a descartar antes de enviar. Ahorra BW si escena estática. Recomendado: 20 |
| --h264-sink | — | Habilita H.264 M2M → shared memory (memsink) para Janus |
| --h264-sink-mode | — | Nombre del memsink. Ej: demo::h264 |
| --static | — | Directorio con ficheros estáticos para la UI web |
| --slowdown | off | Reduce FPS si no hay clientes conectados (ahorro CPU) |
| --exit-on-no-clients | off | Mata el proceso si 0 clientes (para systemd restart on-demand) |
Matriz de Encoders × Cámara
| Cámara |
--encoder |
Prerrequisito |
CPU @ 720p |
Nota |
| CSI (libcamera) |
m2m-image |
kernel ≥5.15.32 + bcm2835-v4l2 |
~3–8% |
HW JPEG via VideoCore IV. Óptimo. |
| CSI (legacy MMAL) |
m2m-image |
sudo modprobe bcm2835-v4l2 |
~3–8% |
Bookworm: prefiere libcamera |
| USB (UVC, YUYV) |
cpu |
— |
~10–20% |
CPU libjpeg, --workers=3 recomendado |
| USB (UVC, MJPEG nativo) |
cpu |
--format=MJPEG |
~2–5% |
La cámara ya entrega JPEG; |
Si la cámara USB ya emite MJPEG nativo (muchas webcams lo hacen), usa --format=MJPEG para zero-copy passthrough: CPU mínima.
Key Concept: V4L2 M2M — Hardware Encode
Memory-to-Memory (M2M): el kernel Linux expone el encoder HW de la GPU (VideoCore IV) como un device V4L2 M2M. µStreamer envía frames RAW al kernel → la GPU los comprime a JPEG → µStreamer los sirve por HTTP. Zero-copy en kernel space.
v4l2-ctl --list-devices
v4l2-ctl -d /dev/video11 --list-formats
Si no aparece el device M2M: sudo modprobe bcm2835-codec. En Yocto/Docker verificar que el module esté incluido en el rootfs.
HTTP Endpoints
| Path | Content-Type | Uso |
| GET /stream | multipart/x-mixed-replace; boundary=… | MJPEG continuo. Para <img src="/video"> |
| GET /snapshot | image/jpeg | Último frame JPEG. Para thumbnails, SSB blobs |
| GET / | text/html | Página de status (si --static activo) |
| GET /state | application/json | JSON con resolución, fps, encoder, connected clients |
/snapshot es útil para generar thumbnails guardados como SSB blobs — un JPEG puntual sin stream continuo. Ideal para previews en el feed SSB.
Comandos de Inicio — Copy-Paste Ready
CSI (Bookworm, libcamera)
sudo modprobe bcm2835-v4l2
libcamerify ustreamer \
--host 127.0.0.1 \
--port 8080 \
--encoder=m2m-image \
--workers=3 \
--resolution=1280x720 \
--desired-fps=15 \
--drop-same-frames=20
USB (webcam UVC)
ustreamer \
--host 127.0.0.1 \
--port 8080 \
--device=/dev/video0 \
--workers=3 \
--resolution=1280x720 \
--desired-fps=15 \
--drop-same-frames=20
USB (cámara MJPEG nativa — zero-copy)
ustreamer \
--host 127.0.0.1 \
--port 8080 \
--device=/dev/video0 \
--format=MJPEG \
--desired-fps=15 \
--drop-same-frames=20
Troubleshooting — Quick Fixes
| Síntoma | Causa probable | Fix |
| m2m-image not available | Module no cargado | sudo modprobe bcm2835-codec |
| /dev/video0 not found | Cámara no detectada | Verificar FFC (CSI) o lsusb (USB). dmesg | grep video |
| Very high CPU | Encoder CPU + alta resolución | Bajar resolución o usar m2m-image (CSI) / --format=MJPEG (USB) |
| Image stuttering | Workers insuficientes | --workers=3 o --workers=4 |
| Address already in use | Otra instancia corriendo | killall ustreamer; verificar puerto |
| Permission denied /dev/video* | User no en grupo video | sudo usermod -aG video $USER |
| libcamerify: not found | libcamera-tools no instalado | apt install libcamera-tools |
| Bandwidth too high on LAN | Alta res + escena dinámica | --drop-same-frames=20 + --quality=60 + 720p |
H.264 Memsink → Janus (Opcional — Solo si Remoto)
memsink: µStreamer puede generar H.264 via V4L2 M2M y exponerlo en shared memory. El plugin Janus lee de esa SHM y lo sirve como WebRTC. Esto permite tener MJPEG local + WebRTC remoto desde una sola instancia.
ustreamer \
--host 127.0.0.1 --port 8080 \
--encoder=m2m-image --workers=3 \
--h264-sink=demo --h264-sink-mode=0777
Janus Gateway añade ~10–20 MB RAM extra. No recomendado para Arq. 6 (solo-LAN). Reservar para cuando se necesite remoto real.
DRY note: si necesitas remoto, evalúa primero Arq. 3 (go2rtc) — integra WebRTC sin Janus ni memsink.
Keywords
V4L2
M2M
MJPEG
libevent
multipart/x-mixed-replace
snapshot
bcm2835-v4l2
libcamerify
memsink
H.264 M2M
drop-same-frames
zero-copy
UVC
libjpeg