Uso de múltiples cámaras web USB en Linux

30

Ejecutar más de una cámara web USB en Debian / Linux da como resultado el siguiente error:

libv4l2: error turning on stream: No space left on device
VIDIOC_STREAMON: No space left on device

Lo que inicialmente parecía ser un problema de programación en OpenCV se convirtió en una búsqueda de un misterioso problema de hardware / software después de que se produjeran los mismos errores al ejecutar cheese y xawtv.

Aparentemente es causado por cámaras web que solicitan todo el ancho de banda disponible en el controlador host USB. Con eso en mente, decidí ejecutar wireshark y capinfos para ver cuánto ancho de banda usaba una sola cámara.

4 megabits per second at 320x240
14 megabits per second at 640x480
32 megabits per second at 1280x720

¡Interesante! Eso podría explicar por qué funcionan dos cámaras a 320x240 pero falla cualquier resolución más alta. Es como si mi controlador USB solo funcionara a velocidades de USB 1, pero lsusb muestra ambas cámaras web que pertenecen a un dispositivo que supuestamente admite 480 megabits por segundo.

Una solución propuso obligar a las cámaras web a calcular su uso de ancho de banda en lugar de solicitar su máximo ejecutando los siguientes comandos:

sudo rmmod uvcvideo
sudo modprobe uvcvideo quirks=128

Lamentablemente, eso no marcó la diferencia, así que decidí probar otra solución. Una publicación en StackOverflow sugirió decirles a mis cámaras web que utilicen un formato de video comprimido o FPS más bajo como MJPEG, pero después de ejecutar la lista v4lctl , no parece que ninguna de mis cámaras web admita cambiar su modo de video.

Y ahí es donde estoy atrapado. ¿Por qué dos cámaras web que funcionan muy por debajo de la velocidad máxima de USB 2 producirían este error?

ps: no es un problema de espacio en disco, df no muestra ningún cambio cuando se inician las cámaras web.

pps: si hace la diferencia, aquí está la salida de lsusb

rachelderp
fuente

Respuestas:

25

¡Ding Ding! Me las arreglé para resolver esto con la ayuda de la gente agradable en # v4l en freenode.

Larga historia corta: v4l2-ctl es la mejor herramienta para depurar problemas de la cámara USB. Lea todos los comandos disponibles y la página del manual, será divertido, lo prometo. Usando v4l2-ctl descubrí que una de mis cámaras no admitía ningún modo de video comprimido. Puede verificar qué modos admiten sus cámaras ejecutando el siguiente comando:

v4l2-ctl -d /dev/video0 --list-formats

Lo que debería generar algo como esto.

 ioctl: VIDIOC_ENUM_FMT
 Index       : 0
 Type        : Video Capture
 Pixel Format: 'MJPG' (compressed)
 Name        : MJPEG

 Index       : 1
 Type        : Video Capture
 Pixel Format: 'YUYV'
 Name        : YUV 4:2:2 (YUYV)

Si el único formato de píxel devuelto es "YUYV", "IUYV", "I420" o "GBRG", solo podrá ejecutar una cámara por controlador USB * ya que esos formatos no están comprimidos. Usar múltiples cámaras web que admitan MJPEG o alguna otra forma de compresión funcionará bien.

Si usa OpenCV como yo, no se preocupe si el formato de píxeles predeterminado no está comprimido, ya que parece que OpenCV usa de forma predeterminada la compresión.

** A menos que esté satisfecho con una resolución de 320x240 o inferior. *

rachelderp
fuente
1
Hola, si es posible, ¿puede decirme cómo debo configurar el formato de píxel de 2 cámaras para poder capturar ambas a 640x480? Estoy usando OpenCV y actualmente estoy experimentando la misma situación que tú donde ambas cámaras solo funcionan a 320x240 o menos
lexma
¡Ajá! v4l2-ctlDe hecho, es una excelente herramienta para la depuración. Descubrí mucho sobre mi cámara y pude solucionar el problema. De todos modos, pude solucionarlo al forzar la resolución de mi cámara 320x240y usarla YUYVcomo el modo de salida de la cámara. guvcviewTambién ayudó mucho.
Sheharyar
Cuando uso resoluciones de 320x240 o inferiores, obtengo resultados mixtos. Compré 4 cámaras web USB baratas, todas de la misma marca / modelo. Al intentar ejecutar 2 a 160x120, algunos de ellos funcionarían bien juntos y otros dieron el error de memoria. No veo rima ni razón para ello. Por supuesto, estas cámaras web cuestan $ 3 por cada una, así que supongo que obtuve lo que pagué.
Cerin
Conectar dos o más de esas cámaras a USB3.0 funciona bien, incluso a través de un concentrador USB2.0. Comprobado con YUYV.
Michał Leon
7

La respuesta es usar las modificaciones de uvcvideo escritas por SwDevRefugee y descritas anteriormente. Él y yo hemos trabajado juntos para obtener el código modificado compilado para OpenWrt, con éxito. La versión en la que lo estoy ejecutando es OpenWRT DESIGNATED DRIVER (Bleeding Edge, r48130), en un enrutador tplink wdr3600:

RESULTADO: Puedo tener 3 * c270 (logitech) ejecutándose simultáneamente a 1280x960 y 15 fps en formato MJPG, a través de un hub usb 2.0. No tengo un cuarto c270 para conectar, lo siento.

También puedo tener 2 * c270 y 1 * GEMBIRD 640 * 480 * 15 fps con formato YUV, pero agregar un segundo GEMBIRD conduce a la temida "No se puede iniciar la captura: no queda espacio en el dispositivo" (espacio == ancho de banda aquí, como usted conocer bien:)). Tenga en cuenta que GEMBIRD (1908: 2311) == http://www.penguin.cz/~utx/hardware/USB_Camera_AX2311/ .

El uso de la CPU con 3 * c270 es bastante razonable en un wdr3600:

Mem: 50600K used, 75444K free, 320K shrd, 3436K buff, 8800K cached

CPU:  16% usr  27% sys   0% nic  45% idle   0% io   0% irq  10% sirq

Load average: 1.20 0.85 0.44 4/60 2546

  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND

 2240  1679 root     S    15348  12%  17% mjpg_streamer --input input_uvc.so --

 2505  1679 root     S    15368  12%  11% mjpg_streamer --input input_uvc.so --

 2239  1679 root     S    15532  12%  11% mjpg_streamer --input input_uvc.so --

Si la comunidad da algo de reputación y apoyo, creo que SwDevRefugee está dispuesto a poner el código en uvc-linux.

reikred
fuente
4

Miré el controlador uvcvideo y el parámetro del módulo quirks = 128 se ignora si la secuencia está comprimida mjpeg.

Mis cámaras web preferidas han sido la Logitech C500 y la Logitech C270, y descubrí que la imagen producida por la C500 a 1280x1024 es de 100kbytes y la imagen producida por la C270 a 1280x960 es de 200kbytes.

Si ejecuto el C270 a 10 fps, entonces la tasa de bits requerida es 10x200000x8 = 16Mbit / s. En Ubuntu 14.04, el módulo uvcdriver siempre asigna 196Mbits / s independientemente de la velocidad de fotogramas. Para el C500, se comporta un poco mejor, pero sigue siendo un cerdo de ancho de banda.

He modificado el controlador uvcvideo para poder proporcionar un factor de "compresión" al controlador a través de la interfaz V4L2. Es un "pequeño truco" porque utilicé el atributo priv en la estructura v4l2_pix_format para especificar el valor. En el controlador, calcula el tamaño de la imagen sin comprimir y luego se divide por el factor de compresión para determinar qué ancho de banda USB usar.

Por defecto, uso un factor de compresión de 10 que permite un gran margen si la cámara encuentra una imagen particularmente difícil de comprimir. El C270 que funciona a 1280x960 y 10 fps ahora usa 41Mbit / sy puedo ejecutar fácilmente 4 cámaras en un bus.

Si alguien está interesado en esta característica, intentaré que los mantenedores de uvcvideo consideren el concepto del factor de "compresión".

SwDevAlien
fuente
Yo, y potencialmente otros en la comunidad de OpenROV, quisiéramos ver tu mod en el controlador uvc @SwDevRefugee. Estoy trabajando para tratar de integrar dos cámaras web en OpenROV (una para la odometría visual descendente, la otra para el pilotaje / visualización normal), pero me encuentro con el mismo problema de BW. ¿Has pensado en publicar tu mod / o enviar una solicitud de extracción para tu cambio?
La forma oficial de solicitar cambios en el controlador uvc es a través de esta lista de correo: [email protected]. Publiqué mi solicitud de cambio el 30 de diciembre de 2015 junto con algunas otras publicaciones posteriores con más información. No he recibido respuesta de un mantenedor. Otras dos personas han expresado interés en el cambio. No sé cuántos se requieren para realizar alguna acción. Quizás @laughlinb también podría publicar en la lista de correo.
SwDevAlien
@SwDevRefugee: me gustaría su consejo unix.stackexchange.com/q/287279/52764
Ragav
@Ragav: Creo que debe aislar el problema abriendo todas las cámaras simultáneamente en las resoluciones apropiadas utilizando una aplicación que se comporte bien, como luvcview, que debería proporcionarle mensajes informativos de error en caso de falla.
SwDevAlien
1
El problema de Ragav es que sus cámaras solo admiten YUYV y cuando usa la bandera peculiaridades = 0x80, el conductor lo obliga a usar al menos 1024 bytes / microframe (65.5 Mbit / s) por cámara. Esto se ve agravado por el hecho de que el ancho de banda mayor más bajo que admiten las cámaras es de 2040 bytes / microframa, por lo que aunque solo quiere 320x240 a 6 fps, solo puede tener 2 cámaras en un bus USB. El mínimo de 1024 bytes / restricción de microframas se agregó al controlador uvcvideo en algún lugar entre las versiones 2.6.32 y 3.16 del núcleo.
SwDevAlien
-1

También lo saqué del error de espacio. Lo que funcionó fue desconectar una de las cámaras y conectarla a otro puerto USB de mi PC estacionaria; hay unos 6 o 7 puertos USB dispersos al respecto. Al ejecutar 'show_webcams 0 1', de repente aparecieron las dos imágenes.

Peter Thejll
fuente