Al ejecutar más de una cámara web USB en Debian/Linux se produce 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 la búsqueda de un misterioso problema de hardware/software después de que se produjeran los mismos errores al ejecutar cheese y xawtv.
Aparentemente se debe a que las cámaras web solicitan todo el ancho de banda disponible en el controlador del host USB. Con eso en mente decidí corrertiburón de alambreycapinfospara ver cuánto ancho de banda utilizó 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 una resolución más alta. Es como si mi controlador USB sólo funcionara a velocidades de USB 1, perolsusbmuestra ambas cámaras web pertenecientes 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 hizo ninguna diferencia, así que decidí probar otra solución. Una publicaciónen StackOverflowsugirió decirle a mis cámaras web que usen un FPS más bajo o un formato de video comprimido como MJPEG, pero después de ejecutarlista v4lctlNo parece que ninguna de mis cámaras web admita cambiar el modo de vídeo.
Y ahí es donde estoy estancado. ¿Por qué dos cámaras web que funcionan muy por debajo de la velocidad máxima de USB 2 producirían este error?
PD: 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
Respuesta1
¡Ding Ding! Me las arreglé para resolver esto con la ayuda de la buena gente en #v4l en freenode.
Larga historia corta:v4l2-ctles la mejor herramienta para depurar problemas de cámaras USB. Lea todos los comandos disponibles y la página de manual, será divertido, lo prometo. Usandov4l2-ctlDescubrí que una de mis cámaras no admitía ningún modo de vídeo comprimido. Puede comprobar 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 varias 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íxel predeterminado no está comprimido, ya que parece que OpenCV usa compresión de todos modos.
**A menos que esté satisfecho con una resolución de 320x240 o inferior.*
Respuesta2
La respuesta es utilizar las modificaciones de uvcvideo escritas por SwDevRefugee y descritas anteriormente. Él y yo hemos trabajado juntos para compilar el código modificado para OpenWrt, con éxito. La versión en la que lo estoy ejecutando es el CONTROLADOR DESIGNADO OpenWRT (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 concentrador USB 2.0. No tengo un cuarto c270 para conectar, lo siento.
También puedo tener 2*c270 y 1*GEMBIRD 640*480*15fps con formato YUV, pero agregar un segundo GEMBIRD genera el temido "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 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 brinda cierta reputación y apoyo, creo que SwDevRefugee está dispuesto a introducir el código en uvc-linux.
Respuesta3
Miré el controlador uvcvideo y el parámetro del módulo quirks=128 se ignora si la transmisión está comprimida en 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 100 kbytes y la imagen producida por la C270 a 1280x960 es de 200 kbytes.
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 196 Mbits/s independientemente de la velocidad de fotogramas. Para el C500 se comporta un poco mejor, pero sigue consumiendo ancho de banda.
Modifiqué 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 la divide por el factor de compresión para determinar qué ancho de banda USB usar.
De forma predeterminada, utilizo un factor de compresión de 10, lo 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 41 Mbit/s y puedo ejecutar fácilmente 4 cámaras en un bus.
Si alguien está interesado en esta característica, intentaré que los encargados del mantenimiento de uvcvideo consideren el concepto del factor de "compresión".
Respuesta4
También recibí ese error de falta 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 repartidos por ella. Al ejecutar 'show_webcams 0 1', de repente aparecieron las dos imágenes.