Como você limita a quantidade de largura de banda que um dispositivo USB pode alocar no Linux?
Tenho algumas webcams USB baratas que estou tentando executar simultaneamente. A execução v4l2-ctl --list-formats-ext --device=/dev/videoN
mostra que ambos suportam várias resoluções não compactadas a 30 e 15 FPS.
Porém, mesmo que eu configure uma para capturar a 15 FPS com resolução de 160x120, ela ainda aloca 480 Mbps de largura de banda, geralmente me impedindo de usar qualquer outro dispositivo USB, muito menos a segunda webcam. A tentativa de capturar da segunda webcam com o mesmo FPS/resolução resulta no erro:
libv4l2: error turning on stream: No space left on device
VIDIOC_STREAMON: No space left on device
Pesquisar esse erro no Google geralmente resulta em respostas como "você é SOL, talvez compre uma câmera que suporte MJPG?".
Mas isso não faz absolutamente nenhum sentido.
Capturar RGB 160x120 não compactado é igual a 160*120*3 = 57.600 bytes por quadro. A 15 FPS, isso requer pelo menos 864.000 bytes por segundo de largura de banda (ou seja, uma enorme0,864Mbpsou6.912Mbps)! Eu tenho hub USB2, que suporta480Mbps. Eu deveria ter largura de banda suficiente para rodar dezenas dessas webcams ao mesmo tempo, mas rodar uma única consome quase todos os 480 Mbits do meu hub USB!
Como a câmera não precisa de 480 Mbps para transmitir 160x120, mas está dizendo ao driver para alocar essa quantidade, existe alguma maneira, no nível do sistema operacional, de forçar o driver a alocar uma determinada quantia?
Responder1
Esse cara forneceuma soluçãoisso parece funcionar para algumas pessoas. No meu caso, tentei e não mudou nada, mas depende muito do hardware.
O módulo do kernel uvcvideo pode ser configurado para ignorar a largura de banda solicitada e calcular a largura de banda correta. Tentar:
sudo rmmod uvcvideo sudo modprobe uvcvideo quirks=128
Isso será redefinido a cada reinicialização. Se funcionar, crie o seguinte arquivo:
sudo vi /etc/modprobe.d/uvcvideo.conf
contendo a linha:
options uvcvideo quirks=128
Na verdade, emesta páginadizem que isso nem sempre funciona e ainda dão a opção de alterar o código na função uvc_init_video() do driver:
/* Isochronous endpoint, select the alternate setting. */ bandwidth = stream->ctrl.dwMaxPayloadTransferSize;