Usando várias webcams USB no Linux

28

A execução de 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 uma questão de programação no OpenCV se transformou em uma busca por um misterioso problema de hardware / software depois que os mesmos erros foram produzidos rodando o queijo e o xawtv.

Aparentemente, é causado por webcams que solicitam toda a largura de banda disponível no controlador host USB. Com isso em mente, decidi rodar wireshark e capinfos para ver quanta largura de banda uma única câmera usava.

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 em 320x240 funcionam, mas qualquer resolução maior falha. É como se meu controlador USB estivesse operando apenas na velocidade USB 1, mas lsusb mostra as duas webcams pertencentes a um dispositivo que supostamente suporta 480 megabits por segundo.

Uma solução proposta forçando as webcams a calcular seu uso de largura de banda, em vez de solicitar seu 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 postagem no StackOverflow sugeria que eu informasse às minhas webcams para usarem um FPS ou formato de vídeo comprimido como MJPEG, mas depois de executar a lista v4lctl , não aparece nenhuma das minhas webcams suportando a alteração do modo de vídeo.

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

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

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

    
por rachelderp 02.06.2012 / 11:09

4 respostas

24

Ding ding! Consegui descobrir isso com alguma ajuda das pessoas legais em # v4l em freenode.

Resumindo: a v4l2-ctl é a melhor ferramenta para depurar problemas da câmera USB. Leia todos os comandos disponíveis e a página de manual, será divertido eu prometo. Usando v4l2-ctl , descobri 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

Qual deve ser 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 serão compactados. Usar várias webcams que suportem MJPEG ou alguma outra forma de compressão funcionará bem.

Se você usar o OpenCV como eu, não se preocupe se o formato de pixel padrão não for compactado, já que o padrão do OpenCV é usar a compactação de qualquer maneira.

** A menos que você esteja satisfeito com a resolução de 320x240 ou menor. *

    
por 06.06.2012 / 08:31
6

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

RESULTADO: Eu posso ter o 3 * c270 (logitech) rodando simultaneamente em 1280x960 e 15fps no formato MJPG, através de um hub usb 2.0. Eu não tenho um quarto c270 para ligar, desculpe.

Eu também posso ter 2 * c270 e 1 * GEMBIRD 640 * 480 * 15fps com formato YUV, mas adicionar um segundo GEMBIRD leva ao temido "Impossível iniciar a captura: Não há espaço disponível no dispositivo" (espaço = = largura de banda aqui , como você bem conhece :)). Observe que o GEMBIRD (1908: 2311) == link .

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 suporte, acho que o SwDevRefugee está disposto a colocar o código no uvc-linux.

    
por 09.01.2016 / 23:02
3

Eu olhei para o driver uvcvideo e o parâmetro quirks = 128 module é ignorado se o fluxo é mjpeg comprimido.

As minhas webcams preferidas foram o Logitech C500 e o Logitech C270, e descobri que a imagem produzida pelo C500 a 1280x1024 é de 100kbytes e a imagem produzida pelo C270 a 1280x960 é de 200kbytes.

Se eu executar o C270 a 10fps, a taxa de bits exigida é 10x200000x8 = 16Mbit / s. No Ubuntu 14.04, o módulo uvcdriver sempre aloca 196Mbits / s, independentemente da taxa de quadros. Para o C500 é um pouco melhor se comportar, mas ainda é um porco de largura de banda.

Eu modifiquei o driver uvcvideo para que eu possa fornecer um fator de "compressão" ao driver através da interface V4L2. É um "pequeno hacky" em que eu usei o atributo priv na estrutura v4l2_pix_format para especificar o valor. No driver, ele calcula o tamanho da imagem descompactada e, em seguida, divide-se pelo fator de compactação para calcular a largura de banda USB a ser usada.

Por padrão, eu uso um fator de compressão de 10, que permite uma grande margem para se a câmera encontrar uma imagem particularmente difícil de compactar. O C270 rodando a 1280x960 e 10fps agora usa 41Mbit / se eu 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 "compressão".

    
por 27.12.2015 / 03:15
-1

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

    
por 19.06.2016 / 08:13