Risolvi Problemi di Captura Video su Linux: v4l2, GStreamer, OBS e Debug del Kernel
La captura video su Linux fallisce in silenzio o in modo criptico. Lo stack è **Kernel (V4L2) → Libreria Utente (libv4l, GStreamer, FFmpeg) → Applicazione (OBS, Zoom, Browser)**. La rottura a qualsiasi livello uccide il feed. Ecco il protocollo diagnostico sistematico.
Livello 0: Hardware e Kernel (Il dispositivo esiste?)
# 1. Enumerazione USB
lsusb -t | grep -i video # Cerca il tuo dispositivo (es. 046d:0825 Logitech C920) con "If# 0" e "If# 1" (Video + Audio)
# Se mancante: Cavo, porta, alimentazione hub o dispositivo guasto.
# 2. Nodi Dispositivo V4L2
ls -l /dev/video* # Dovresti vedere /dev/video0, /dev/video1... (video0 solitamente webcam, video1 metadati)
# Se vuoto: Driver non caricato o bind fallito.
# 3. Messaggi Kernel (La Verità)
dmesg -T -k | grep -i -e usb -e video -e uvc -e v4l # Cerca: "uvcvideo: Found UVC 1.00 device", "uvcvideo: Failed to query (GET_DEF) UVC control"
# Errore comune: "uvcvideo: Failed to set UVC probe control" → Problema banda/impostazione alt.
# 4. Controlla Moduli Caricati
lsmod | grep -E 'uvc|videodev|v4l2' # uvcvideo, videobuf2_v4l2, videobuf2_common, videodev devono essere presenti.
Livello 1: Controlli V4L2 (Capacità e Formati)
# Installa strumenti
sudo apt/dnf/pacman install v4l-utils gstreamer1.0-tools
# 1. Elenca Dispositivi e Capacità
v4l2-ctl --list-devices
v4l2-ctl -d /dev/video0 --all # Output mostra: Driver, Scheda, Bus, Capacità (Captura Video, Streaming, Capacità Dispositivo)
# Formati: [0]: 'YUYV' (YUYV 4:2:2) / [1]: 'MJPG' (Motion-JPEG) / [2]: 'H264' / [3]: 'YV12' / [4]: 'NV12'
# Dimensioni Fotogramma e Intervalli per OGNI formato. NOTALI.
# 2. Test Cattura Grezza (Bypassa App)
# YUYV (Non compresso) - 10 fotogrammi su /dev/null
v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=YUYV --stream-mmap --stream-count=10 --stream-to=/dev/null
# MJPG (Compresso) - solitamente FPS più alti
v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=MJPG --stream-mmap --stream-count=10 --stream-to=/dev/null
# H.264 (Codificato Hardware) - se supportato
v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=H264 --stream-mmap --stream-count=10 --stream-to=test.h264
Se `v4l2-ctl --stream-to` funziona → Kernel/Driver OK. Il problema è nello Spazio Utente/App.
Livello 2: GStreamer (La Pipeline Media)
# Test Pipeline (Auto-negozia)
gst-launch-1.0 v4l2src device=/dev/video0 ! videoconvert ! autovideosink
# Formato Esplicito (Forza MJPG 1080p60)
gst-launch-1.0 v4l2src device=/dev/video0 ! \
"image/jpeg,width=1920,height=1080,framerate=60/1" ! \
jpegdec ! videoconvert ! autovideosink
# Decodifica H.264 Hardware (Intel/AMD VAAPI / Nvidia NVDEC)
gst-launch-1.0 v4l2src device=/dev/video0 ! \
"video/x-h264,width=1920,height=1080,framerate=60/1" ! \
h264parse ! vaapih264dec ! videoconvert ! autovideosink # Intel/AMD
# oppure
gst-launch-1.0 v4l2src device=/dev/video0 ! \
"video/x-h264,width=1920,height=1080,framerate=60/1" ! \
h264parse ! nvh264dec ! videoconvert ! autovideosink # Nvidia
# Elenca Proprietà GStreamer per Dispositivo
gst-device-monitor-1.0 Video/Source
Livello 3: Applicazione (OBS, Browser, Zoom)
OBS Studio (Flatpak Preferito)
- Sorgente: **Dispositivo Captura Video (V4L2)** — NON "Dispositivo Captura Video (V4L2) [Deprecato]".
- Dispositivo: `/dev/video0` (o indice corretto).
- Risoluzione/FPS: **Personalizzato** → Corrisponda *esattamente* a una modalità da `v4l2-ctl --list-formats-ext`. (es. 1920x1080 @ 30.000 fps MJPG).
- Spazio Colore: 709. **Gamma Colore:** Parziale.
- Buffering: **Disabilitato** (latenza minima) o **Auto**.
- Wayland: OBS Flatpak + PipeWire → **Cattura Schermo (PipeWire)** funziona. Per webcam, V4L2 funziona nativamente.
- Permessi: Flatpak: `flatpak override --device=all com.obsproject.Studio` o `--device=/dev/video0`.
Browser (Chrome/Firefox) — WebRTC getUserMedia
- Test: webcamtests.com o `chrome://settings/content/camera`.
- Se il browser vede il dispositivo ma OBS no → Problema **PipeWire / WirePlumber**. Assicurati che `pipewire`, `wireplumber`, `libpipewire-0.3-modules`, `gst-plugin-pipewire` siano installati.
- Firefox: `media.navigator.mjs.enabled = true` in `about:config` (per MJPEG/H264).
Livello 4: Modalità di Guasto Comuni e Soluzioni
| Sintomo | Diagnosi | Soluzione |
|---|---|---|
| Immagine Verde/Viola/Rosa | Mancata corrispondenza Formato Pixel (YUYV vs NV12 vs RGB) | Forza formato nell'app: `v4l2-ctl --set-fmt-video=pixelformat=YUYV` o `MJPG`. In OBS: prova "YUYV 4:2:2" o "MJPEG". |
| Schermo Nero / "Nessun fotogramma ricevuto" | Banda Superata (hub USB 2.0, più camere) | Porta USB 3.0 (blu). Direttamente all'hub root. Riduci risoluzione/fps. Quirk `uvcvideo`: `modprobe uvcvideo quirks=128` (forza 500MHz). |
| Bassi FPS (10fps @ 1080p) | Esposizione automatica / Bilanciamento bianco automatico in stallo | `v4l2-ctl -d /dev/video0 -c exposure_auto=1 -c exposure_absolute=156` (manuale). `white_balance_temperature_auto=0`. |
| "Disoccupato" / EBUSY | Un altro processo detiene il dispositivo (Cheese, Zoom, GPhoto2) | `lsof /dev/video0` → Uccidi PID. `systemctl stop gdm` (se il display manager lo afferra). |
| Controlli Mancanti (Luminosità/Contrasto) | Il driver non espone UVC XU (Extension Units) | Usa `guvcview` (GUI) o `uvcdynctrl` (CLI) per controlli specifici Logitech/Microsoft. |
| Scheda di Cattura Non Rilevata | Modulo Kernel Mancante (Blackmagic, AVerMedia, Elgato) | `dkms status` → Installa `blackmagic-desktop-video-dkms`, `avermedia-dvb-dkms`, `elgato-gchd-dkms`. Secure Boot può bloccare moduli non firmati → `mokutil --disable-validation` o firma. |
Avanzato: Calcolo Banda USB
# Controlla Topologia Bus USB
lsusb -t # Guarda "480 Mbps" (USB 2.0) vs "5000 Mbps" (USB 3.0) vs "10000 Mbps" (USB 3.1/3.2)
# Banda Endpoint Isochrono UVC:
# YUYV 1920x1080@30 = ~1.2 Gbps → **Richiede USB 3.0**
# MJPG 1920x1080@30 = ~150 Mbps → Funziona su USB 2.0 (a malapena)
# Se su hub USB 2.0: FORZA MJPG.
Logging per Segnalazioni Bug
# Debug Driver UVC
sudo modprobe -r uvcvideo
sudo modprobe uvcvideo trace=0xFFFF # Logga tutte le richieste UVC
dmesg -wH # Osserva dal vivo
# Riproduci il guasto. Cattura dmesg. Segnala a linux-media@vger.kernel.org / bug tracker distro.
Regola d'Oro: `v4l2-ctl --stream-to=/dev/null` **funziona** → Kernel OK. **App fallisce** → Negoziazione formato / Permessi / PipeWire. Risolvi la negoziazione (caps espliciti in GStreamer/OBS).