Soluciona problemas de captura de video en Linux: v4l2, GStreamer, OBS y depuración del kernel

La captura de video en Linux falla silenciosa o crípticamente. La pila es **Kernel (V4L2) → Biblioteca de usuario (libv4l, GStreamer, FFmpeg) → Aplicación (OBS, Zoom, Navegador)**. La ruptura en cualquier capa mata la señal. Aquí está el protocolo de diagnóstico sistemático.

Capa 0: Hardware y Kernel (¿Existe el dispositivo?)

 # 1. Enumeración USB lsusb -t | grep -i video # Busca tu dispositivo (p. ej., 046d:0825 Logitech C920) con "If# 0" y "If# 1" (Video + Audio) # Si falta: Cable malo, puerto, energía del hub, o dispositivo muerto. # 2. Nodos de dispositivos V4L2 ls -l /dev/video* # Deberías ver /dev/video0, /dev/video1... (video0 generalmente webcam, video1 metadatos) # Si está vacío: Controlador no cargado o fallo de enlace. # 3. Mensajes del kernel (La verdad) dmesg -T -k | grep -i -e usb -e video -e uvc -e v4l # Busca: "uvcvideo: Found UVC 1.00 device", "uvcvideo: Failed to query (GET_DEF) UVC control" # Error común: "uvcvideo: Failed to set UVC probe control" → Problema de ancho de banda/ajuste alternativo. # 4. Verificar módulos cargados lsmod | grep -E 'uvc|videodev|v4l2' # uvcvideo, videobuf2_v4l2, videobuf2_common, videodev deben estar presentes. 

Capa 1: Controles V4L2 (Capacidades y formatos)

 # Instalar herramientas sudo apt/dnf/pacman install v4l-utils gstreamer1.0-tools # 1. Listar dispositivos y capacidades v4l2-ctl --list-devices v4l2-ctl -d /dev/video0 --all # Salida muestra: Driver, Tarjeta, Bus, Capacidades (Captura de video, Streaming, Capacidades del dispositivo) # Formatos: [0]: 'YUYV' (YUYV 4:2:2) / [1]: 'MJPG' (Motion-JPEG) / [2]: 'H264' / [3]: 'YV12' / [4]: 'NV12' # Tamaños de frame e intervalos para CADA formato. ANÓTALOS. # 2. Probar captura cruda (Evitar aplicación) # YUYV (No comprimido) - 10 frames a /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 (Comprimido) - generalmente más FPS 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 (Codificado por hardware) - si es compatible 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` funciona → Kernel/Controlador OK. El problema está en Usuario/App.

Capa 2: GStreamer (La tubería de medios)

 # Prueba de tubería (Auto-negociar) gst-launch-1.0 v4l2src device=/dev/video0 ! videoconvert ! autovideosink # Formato explícito (Forzar MJPG 1080p60) gst-launch-1.0 v4l2src device=/dev/video0 ! \ "image/jpeg,width=1920,height=1080,framerate=60/1" ! \ jpegdec ! videoconvert ! autovideosink # Decodificación de hardware H.264 (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 # o gst-launch-1.0 v4l2src device=/dev/video0 ! \ "video/x-h264,width=1920,height=1080,framerate=60/1" ! \ h264parse ! nvh264dec ! videoconvert ! autovideosink # Nvidia # Listar propiedades de GStreamer para el dispositivo gst-device-monitor-1.0 Video/Source 

Capa 3: Aplicación (OBS, Navegador, Zoom)

OBS Studio (Flatpak preferido)

  • **Fuente:** **Dispositivo de captura de video (V4L2)** — NO "Dispositivo de captura de video (V4L2) [Obsoleto]".
  • **Dispositivo:** `/dev/video0` (o el índice correcto).
  • **Resolución/FPS:** **Personalizado** → Coincide *exactamente* con un modo de `v4l2-ctl --list-formats-ext`. (p. ej., 1920x1080 @ 30.000 fps MJPG).
  • **Espacio de color:** 709. **Rango de color:** Parcial.
  • **Búfer:** **Desactivado** (menor latencia) o **Auto**.
  • Wayland: OBS Flatpak + PipeWire → **Captura de pantalla (PipeWire)** funciona. Para webcam, V4L2 funciona nativamente.
  • Permiso: Flatpak: `flatpak override --device=all com.obsproject.Studio` o `--device=/dev/video0`.

Navegador (Chrome/Firefox) — WebRTC getUserMedia

  • Prueba: webcamtests.com o `chrome://settings/content/camera`.
  • Si el navegador ve el dispositivo pero OBS no → **Problema de PipeWire / WirePlumber**. Asegúrate de que `pipewire`, `wireplumber`, `libpipewire-0.3-modules`, `gst-plugin-pipewire` estén instalados.
  • Firefox: `media.navigator.mjs.enabled = true` en `about:config` (para MJPEG/H264).

Capa 4: Modos de fallo comunes y soluciones

SíntomaDiagnósticoSolución
Imagen verde/morado/rosaDesajuste de formato de píxel (YUYV vs NV12 vs RGB)Forzar formato en la app: `v4l2-ctl --set-fmt-video=pixelformat=YUYV` o `MJPG`. En OBS: prueba "YUYV 4:2:2" o "MJPEG".
Pantalla negra / "No se recibieron frames"Ancho de banda excedido (Hub USB 2.0, múltiples cámaras)Puerto USB 3.0 (azul). Directo al hub raíz. Reduce resolución/fps. Quirks de `uvcvideo`: `modprobe uvcvideo quirks=128` (forzar 500MHz).
Bajo FPS (10fps @ 1080p)Autoexposición / Balance de blancos automático estancándose`v4l2-ctl -d /dev/video0 -c exposure_auto=1 -c exposure_absolute=156` (manual). `white_balance_temperature_auto=0`.
"Dispositivo ocupado" / EBUSYOtro proceso tiene el dispositivo (Cheese, Zoom, GPhoto2)`lsof /dev/video0` → Matar PID. `systemctl stop gdm` (si el gestor de pantalla lo agarra).
Controles faltantes (Brillo/Contraste)El controlador no expone XU de UVC (Unidades de extensión)Usa `guvcview` (GUI) o `uvcdynctrl` (CLI) para controles específicos de Logitech/Microsoft.
Tarjeta de captura no detectadaMódulo del kernel faltante (Blackmagic, AVerMedia, Elgato)`dkms status` → Instala `blackmagic-desktop-video-dkms`, `avermedia-dvb-dkms`, `elgato-gchd-dkms`. Secure Boot puede bloquear módulos sin firmar → `mokutil --disable-validation` o firmar.

Avanzado: Cálculo de ancho de banda USB

 # Verificar topología del bus USB lsusb -t # Busca "480 Mbps" (USB 2.0) vs "5000 Mbps" (USB 3.0) vs "10000 Mbps" (USB 3.1/3.2) # Ancho de banda de punto final isócrono UVC: # YUYV 1920x1080@30 = ~1.2 Gbps → **Requiere USB 3.0** # MJPG 1920x1080@30 = ~150 Mbps → Funciona en USB 2.0 (apenas) # Si estás en hub USB 2.0: FORZAR MJPG. 

Registro para informes de errores

 # Depuración del controlador UVC sudo modprobe -r uvcvideo sudo modprobe uvcvideo trace=0xFFFF # Registra todas las solicitudes UVC dmesg -wH # Observa en vivo # Reproduce el fallo. Captura dmesg. Reporta a linux-media@vger.kernel.org / rastreador de errores de la distro. 

Regla de oro: `v4l2-ctl --stream-to=/dev/null` **funciona** → Kernel OK. **App falla** → Negociación de formato / Permiso / PipeWire. Corrige la negociación (caps explícitos en GStreamer/OBS).