Dépanner Capture Vidéo Linux : v4l2, GStreamer, OBS & Débogage Noyau
La capture vidéo Linux échoue silencieusement ou cryptiquement. La pile est **Noyau (V4L2) → Bibliothèque Userspace (libv4l, GStreamer, FFmpeg) → Application (OBS, Zoom, Navigateur)**. Casse à n'importe quelle couche = flux mort. Voici le protocole diagnostique systématique.
Couche 0 : Matériel & Noyau (Le périphérique existe-t-il ?)
# 1. Énumération USB lsusb -t | grep -i video # Cherchez votre device (ex. 046d:0825 Logitech C920) avec "If# 0" et "If# 1" (Vidéo + Audio) # Si absent : Mauvais câble, port, alimentation hub, ou device mort. # 2. Nœuds Device V4L2 ls -l /dev/video* # Doit voir /dev/video0, /dev/video1... (video0 webcam solito, video1 métadonnées) # Si vide : Pilote non chargé ou bind échoué. # 3. Messages Noyau (La Vérité) dmesg -T -k | grep -i -e usb -e video -e uvc -e v4l # Cherchez : "uvcvideo: Found UVC 1.00 device", "uvcvideo: Failed to query (GET_DEF) UVC control" # Erreur courante : "uvcvideo: Failed to set UVC probe control" → Problème bande passante/alt setting. # 4. Modules Chargés lsmod | grep -E 'uvc|videodev|v4l2' # uvcvideo, videobuf2_v4l2, videobuf2_common, videodev doivent être présents.
Couche 1 : Contrôles V4L2 (Capacités & Formats)
# Installez outils sudo apt/dnf/pacman install v4l-utils gstreamer1.0-tools # 1. Liste Devices & Capacités v4l2-ctl --list-devices v4l2-ctl -d /dev/video0 --all # Sortie montre : Driver, Card, Bus, Capabilities (Video Capture, Streaming, Device Capabilities) # Formats : [0]: 'YUYV' (YUYV 4:2:2) / [1]: 'MJPG' (Motion-JPEG) / [2]: 'H264' / [3]: 'YV12' / [4]: 'NV12' # Tailles Images & Intervalles pour CHAQUE format. NOTEZ-LES. # 2. Test Capture Brut (Contourne App) # YUYV (Non compressé) - 10 frames vers /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 (Compressé) - généralement FPS plus haut 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 (Encodé Matériel) - si supporté v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=H264 --stream-mmap --stream-count=10 --stream-to=test.h264
Si `v4l2-ctl --stream-to` marche → Noyau/Pilote OK. Problème dans Userspace/App.
Couche 2 : GStreamer (Le Pipeline Média)
# Pipeline Test (Auto-négociation) gst-launch-1.0 v4l2src device=/dev/video0 ! videoconvert ! autovideosink # Format Explicite (Force MJPG 1080p60) gst-launch-1.0 v4l2src device=/dev/video0 ! \ "image/jpeg,width=1920,height=1080,framerate=60/1" ! \ jpegdec ! videoconvert ! autovideosink # H.264 Décodage Matériel (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 # ou gst-launch-1.0 v4l2src device=/dev/video0 ! \ "video/x-h264,width=1920,height=1080,framerate=60/1" ! \ h264parse ! nvh264dec ! videoconvert ! autovideosink # Nvidia # Liste Propriétés GStreamer pour Device gst-device-monitor-1.0 Video/Source
Couche 3 : Application (OBS, Navigateur, Zoom)
OBS Studio (Flatpak Préféré)
- **Source :** **Périphérique Capture Vidéo (V4L2)** — PAS « Périphérique Capture Vidéo (V4L2) [Obsolète] ».
- **Périphérique :** `/dev/video0` (ou index correct).
- **Résolution/IPS :** **Personnalisé** → Correspond *exactement* à un mode de `v4l2-ctl --list-formats-ext`. (ex. 1920x1080 @ 30.000 fps MJPG).
- **Espace Couleur :** 709. **Gamme Couleur :** Partielle.
- **Tamponnage :** **Désactivé** (latence min) ou **Auto**.
- Wayland : OBS Flatpak + PipeWire → **Capture Écran (PipeWire)** marche. Pour webcam, V4L2 natif.
- Permission : Flatpak : `flatpak override --device=all com.obsproject.Studio` ou `--device=/dev/video0`.
Navigateur (Chrome/Firefox) — WebRTC getUserMedia
- Test : webcamtests.com ou `chrome://settings/content/camera`.
- Si navigateur voit device mais pas OBS → Problème **PipeWire / WirePlumber**. Assurez `pipewire`, `wireplumber`, `libpipewire-0.3-modules`, `gst-plugin-pipewire` installés.
- Firefox : `media.navigator.mjs.enabled = true` dans `about:config` (pour MJPEG/H264).
Couche 4 : Modes Échec Courants & Fixes
| Symptôme | Diagnostic | Fix |
|---|---|---|
| Image Verte/Violette/Rose | Mismatch Format Pixel (YUYV vs NV12 vs RGB) | Force format dans app : `v4l2-ctl --set-fmt-video=pixelformat=YUYV` ou `MJPG`. Dans OBS : essayez "YUYV 4:2:2" ou "MJPEG". |
| Écran Noir / "Aucune frame reçue" | Bande Passante Dépassée (Hub USB 2.0, multi cams) | Port USB 3.0 (bleu). Direct racine hub. Réduisez résolution/ips. Quirks `uvcvideo` : `modprobe uvcvideo quirks=128` (force 500 MHz). |
| Faible IPS (10 fps @ 1080p) | Auto-expo / Auto-balance blanche bloquant | `v4l2-ctl -d /dev/video0 -c exposure_auto=1 -c exposure_absolute=156` (manuel). `white_balance_temperature_auto=0`. |
| "Device Busy" / EBUSY | Autre process tient device (Cheese, Zoom, GPhoto2) | `lsof /dev/video0` → Kill PID. `systemctl stop gdm` (si display manager l'accapare). |
| Contrôles Manquants (Luminosité/Contraste) | Pilote n'expose pas UVC XU (Extension Units) | Utilisez `guvcview` (GUI) ou `uvcdynctrl` (CLI) pour contrôles Logitech/Microsoft spécifiques. |
| Carte Acquisition Non Détectée | Module Noyau Manquant (Blackmagic, AVerMedia, Elgato) | `dkms status` → Installez `blackmagic-desktop-video-dkms`, `avermedia-dvb-dkms`, `elgato-gchd-dkms`. Secure Boot peut bloquer modules non signés → `mokutil --disable-validation` ou signez. |
Avancé : Calcul Bande Passante USB
# Topologie Bus USB lsusb -t # Regardez "480 Mbps" (USB 2.0) vs "5000 Mbps" (USB 3.0) vs "10000 Mbps" (USB 3.1/3.2) # Bande Passante Endpoint Isochrome UVC : # YUYV 1920x1080@30 = ~1,2 Gbps → **Nécessite USB 3.0** # MJPG 1920x1080@30 = ~150 Mbps → Marche USB 2.0 (juste) # Si sur Hub USB 2.0 : FORCEZ MJPG.
Journalisation pour Rapports Bugs
# Debug Driver UVC sudo modprobe -r uvcvideo sudo modprobe uvcvideo trace=0xFFFF # Log toutes requêtes UVC dmesg -wH # Watch live # Reproduisez échec. Capturez dmesg. Signalez à linux-media@vger.kernel.org / tracker bug distro.
Règle d'Or : `v4l2-ctl --stream-to=/dev/null` **marche** → Noyau OK. **App échoue** → Négociation Format / Permission / PipeWire. Fixez la négociation (caps explicites dans GStreamer/OBS).
