Usando várias webcams USB no Linux

30

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 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 pela execução de cheese e xawtv.

Aparentemente, isso é causado por webcams solicitando toda a largura de banda disponível no controlador host USB. Com isso em mente, decidi executar o wireshark e o 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 de 320x240 funcionam, mas qualquer resolução maior falha. É como se meu controlador USB estivesse operando apenas na velocidade USB 1, mas o lsusb mostra as duas webcams pertencentes a um dispositivo que supostamente suporta 480 megabits por segundo.

Uma solução proposta forçou as webcams a calcular seu uso de 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 publicação no StackOverflow sugeriu que minhas webcams usassem um FPS menor ou formato de vídeo compactado como MJPEG, mas depois de executar a lista v4lctl , não parece que nenhuma das minhas webcams suporta a alteração do modo de vídeo.

E é aí que eu 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 mostra alterações quando as webcams são iniciadas.

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

rachelderp
fonte

Respostas:

25

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

Para encurtar a história: 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, prometo. Usando v4l2-ctl , descobri que uma de 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 parecido com isto.

 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ê poderá executar apenas uma câmera por controlador USB *, pois esses formatos não são compactados. O uso de várias webcams compatíveis com MJPEG ou alguma outra forma de compactação funcionará bem.

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

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

rachelderp
fonte
11
Oi, se possível, você pode me dizer como devo definir o formato de pixel de duas câmeras para que eu possa capturar as duas em 640x480? Estou usando o OpenCV e atualmente estou enfrentando a mesma situação em que as duas câmeras funcionam apenas em 320x240 ou menos
lexma
Aha! v4l2-ctlé realmente uma excelente ferramenta para depuração. Descobri muito sobre minha câmera e consegui resolver o problema. De qualquer forma, consegui corrigi-lo forçando a resolução da câmera 320x240e usando-o YUYVcomo modo de saída da câmera. guvcviewtambém ajudou muito.
Sheharyar 22/03
Ao usar resoluções de 320x240 ou inferiores, obtenho resultados variados. Comprei 4 webcams USB baratas, todas da mesma marca / modelo. Ao tentar executar 2 em 160x120, alguns deles funcionariam bem juntos e outros causavam erro de memória. Não vejo rima ou razão para isso. É verdade que essas webcams custam US $ 3 / cada, então acho que recebi o que paguei.
Cerin
Conectar duas ou mais dessas câmeras ao USB3.0 funciona bem, mesmo através de um hub USB2.0. Verificado com YUYV.
Michał Leon
7

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 o OpenWrt, com sucesso. A versão na qual estou executando o é o OpenWRT DESIGNATED DRIVER (Bleeding Edge, r48130), em um roteador tplink wdr3600:

RESULTADO: Posso ter 3 * c270 (logitech) executando 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.

Também posso ter 2 * c270 e 1 * GEMBIRD 640 * 480 * 15fps no formato YUV, mas adicionar um segundo GEMBIRD leva ao temido "Não é possível iniciar a captura: não resta espaço 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 suporte, acho que o SwDevRefugee está disposto a inserir o código no uvc-linux.

reikred
fonte
4

Eu olhei para o driver uvcvideo e o parâmetro quirks = 128 module será ignorado se o fluxo for mjpeg compactado.

Minhas webcams escolhidas foram o Logitech C500 e o Logitech C270, e descobri que a imagem produzida pelo C500 em 1280x1024 tem 100kbytes e a imagem produzida pelo C270 em 1280x960 é 200kbytes.

Se eu rodar o C270 a 10fps, a taxa de bits necessária é 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 é um porco da largura de banda.

Modifiquei o driver uvcvideo para fornecer um fator de "compactaçã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 determinar qual largura de banda USB usar.

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

Se alguém estiver interessado nesse recurso, tentarei convencer os mantenedores do uvcvideo a considerar o conceito do fator "compressão".

SwDevAlien
fonte
Eu e potencialmente outros na comunidade OpenROV gostariam de ver seu mod no driver uvc @SwDevRefugee. Estou trabalhando na tentativa de integrar duas webcams no OpenROV (uma para odometria visual de aparência descendente e outra para pilotagem / visualização normal), mas com o mesmo problema de BW. Você já pensou em postar seu mod / ou enviar uma solicitação de pull para sua alteração?
A maneira oficial de solicitar alterações no driver uvc é através desta lista de discussão: [email protected]. Publiquei minha solicitação de alteração em 30 de dezembro de 2015, juntamente com outras postagens subsequentes com mais informações. Não recebi resposta de um mantenedor. Duas outras pessoas manifestaram interesse na mudança. Não sei quantas são necessárias para executar qualquer ação. Talvez @laughlinb também possa postar na lista de discussão.
SwDevAlien
@SwDevRefugee: Gostaria do seu conselho unix.stackexchange.com/q/287279/52764
Ragav
@Ragav: Eu acho que você precisa isolar o problema, abrindo todas as câmeras simultaneamente nas resoluções apropriadas, usando um aplicativo bem comportado como o luvcview, que deve fornecer mensagens de erro informativas se houver uma falha.
SwDevAlien
11
O problema de Ragav é que suas câmeras suportam apenas YUYV e, quando ele usa a sinalização peculiaridade = 0x80, o motorista o força a usar pelo menos 1024 bytes / microframe (65,5 Mbit / s) por câmera. Isso é agravado pelo fato de que a largura de banda maior mais baixa suportada pelas câmeras é de 2040 bytes / microframe, mesmo que ele queira apenas 320x240 a 6fps, ele pode ter apenas duas câmeras em um barramento USB. A restrição mínima de 1024 bytes / microframe foi adicionada ao driver uvcvideo em algum lugar entre as versões 2.6.32 e 3.16 do kernel.
precisa saber é o seguinte
-1

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

Peter Thejll
fonte