Usando várias webcams USB no Linux

Usando várias webcams USB no Linux

Executar mais de uma webcam USB no Debian/Linux resulta no seguinte erro:

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

O que inicialmente parecia ser um problema de programação no OpenCV se transformou em uma busca por um misterioso problema de hardware/software depois que os mesmos erros foram produzidos ao executar o cheese e o xawtv.

Aparentemente, isso é causado por webcams que solicitam toda a largura de banda disponível no controlador host USB. Pensando nisso resolvi correrwiresharkecapinfospara ver quanta largura de banda uma única câmera usou.

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

Interessante! Isso pode explicar por que duas câmeras de 320x240 funcionam, mas qualquer resolução mais alta falha. É como se meu controlador USB estivesse operando apenas em velocidades USB 1, maslsusbmostra ambas as webcams pertencentes a um dispositivo que supostamente suporta 480 megabits por segundo.

Uma solução propôs forçar as webcams a calcular o uso da largura de banda em vez de solicitar o máximo executando os seguintes comandos:

sudo rmmod uvcvideo
sudo modprobe uvcvideo quirks=128

Infelizmente isso não fez diferença, então decidi tentar outra solução. Uma postagemno StackOverflowsugeri dizer às minhas webcams para usarem um FPS mais baixo ou um formato de vídeo compactado como MJPEG, mas depois de executarlista v4lctlparece que nenhuma das minhas webcams suporta a alteração do modo de vídeo.

E é aí que estou preso. Por que duas webcams operando bem abaixo da velocidade máxima do USB 2 produziriam esse erro?

ps: Não é um problema de espaço em disco, o df não exibe nenhuma alteração quando as webcams são iniciadas.

pps: Se faz diferença, aqui estáa saída de lsusb

Responder1

Ding Ding! Consegui descobrir isso com a ajuda de pessoas legais em #v4l no freenode.

Longa história curta:v4l2-ctlé a melhor ferramenta para depurar problemas de câmeras USB. Leia todos os comandos disponíveis e a página de manual, será divertido, eu prometo. Usandov4l2-ctlDescobri que uma das minhas câmeras não suportava nenhum modo de vídeo compactado. Você pode verificar quais modos suas câmeras suportam executando o seguinte comando:

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

O que deve gerar algo assim.

 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)

Se o único formato de pixel retornado for "YUYV", "IUYV", "I420" ou "GBRG", você só poderá executar uma câmera por controlador USB*, pois esses formatos não são compactados. Usar várias webcams que suportem MJPEG ou alguma outra forma de compactação funcionará bem.

Se você usa OpenCV como eu, não se preocupe se o formato de pixel padrão não estiver compactado, pois parece que o padrão do OpenCV é usar compactação de qualquer maneira.

**A menos que você esteja satisfeito com a resolução de 320 x 240 ou inferior.*

Responder2

A resposta é usar as modificações uvcvideo escritas por SwDevRefugee e descritas acima. Ele e eu trabalhamos juntos para compilar o código modificado para OpenWrt, com sucesso. A versão em que estou executando é OpenWRT DESIGNATED DRIVER (Bleeding Edge, r48130), em um roteador tplink wdr3600:

RESULTADO: Posso ter 3*c270 (logitech) rodando simultaneamente a 1280x960 e 15fps no formato MJPG, através de um hub usb 2.0. Não tenho um quarto c270 para conectar, desculpe.

Também posso ter 2*c270 e 1*GEMBIRD 640*480*15fps com formato YUV, mas adicionar um segundo GEMBIRD leva ao temido "Incapaz de iniciar a captura: não há espaço restante no dispositivo" (espaço == largura de banda aqui, como você conhecer bem:)). Observe que GEMBIRD (1908:2311) ==http://www.penguin.cz/~utx/hardware/USB_Camera_AX2311/.

O uso da CPU com 3*c270 é bastante razoável em um 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 --

Se a comunidade der alguma reputação e apoio, acho que SwDevRefugee está disposto a colocar o código no uvc-linux.

Responder3

Eu olhei para o driver uvcvideo e o parâmetro do módulo quirks = 128 será ignorado se o fluxo estiver compactado com mjpeg.

Minhas webcams preferidas foram a Logitech C500 e a Logitech C270, e descobri que a imagem produzida pela C500 em 1280x1024 tem 100kbytes e a imagem produzida pela C270 em 1280x960 tem 200kbytes.

Se eu executar o C270 a 10fps, a taxa de bits necessária será 10x200000x8 = 16Mbit/s. No Ubuntu 14.04, o módulo uvcdriver sempre aloca 196Mbits/s, independentemente da taxa de quadros. Para o C500 ele se comporta um pouco melhor, mas ainda consome largura de banda.

Modifiquei o driver uvcvideo para poder fornecer um fator de "compressão" ao driver por meio da interface V4L2. É um "pequeno hacky" porque usei o atributo priv na estrutura v4l2_pix_format para especificar o valor. No driver, ele calcula o tamanho da imagem não compactada e depois divide pelo fator de compactação para descobrir qual largura de banda USB usar.

Por padrão, uso um fator de compactação de 10, que permite uma grande margem caso a câmera encontre uma imagem particularmente difícil de compactar. A C270 rodando a 1280x960 e 10fps agora usa 41Mbit/s e posso facilmente rodar 4 câmeras em um barramento.

Se alguém estiver interessado neste recurso, tentarei fazer com que os mantenedores do uvcvideo considerem o conceito do fator de "compressão".

Responder4

Também recebi esse erro de falta de espaço. O que funcionou foi desconectar uma das câmeras e conectá-la a outra porta USB do meu PC estacionário - há cerca de 6 ou 7 portas USB espalhadas por ela. A execução de 'show_webcams 0 1' trouxe de repente as duas imagens.

informação relacionada