Utilizzo di più webcam USB in Linux


30

L'esecuzione di più di una webcam USB in Debian / Linux provoca il seguente errore:

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

Quello che inizialmente sembrava essere un problema di programmazione in OpenCV si è trasformato in una ricerca di un misterioso problema hardware / software dopo che gli stessi errori sono stati prodotti eseguendo cheese e xawtv.

Apparentemente è causato da webcam che richiedono tutta la larghezza di banda disponibile sul controller host USB. Con questo in mente ho deciso di correre Wireshark e capinfos per vedere quanto la larghezza di banda di una singola telecamera utilizzata.

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

Interessante! Ciò potrebbe spiegare perché due fotocamere a 320x240 funzionano ma una risoluzione più elevata non riesce. È come se il mio controller USB funzionasse solo a velocità USB 1, ma lsusb mostra entrambe le webcam appartenenti a un dispositivo che presumibilmente supporta 480 megabit al secondo.

Una soluzione ha proposto di forzare le webcam a calcolare l'utilizzo della larghezza di banda invece di richiedere il massimo eseguendo i seguenti comandi:

sudo rmmod uvcvideo
sudo modprobe uvcvideo quirks=128

Sfortunatamente ciò non ha fatto differenza, quindi ho deciso di provare un'altra soluzione. Un post su StackOverflow ha suggerito di dire alle mie webcam di usare un FPS inferiore o un formato video compresso come MJPEG, ma dopo aver eseguito l'elenco v4lctl non appare che nessuna delle mie webcam supporti il ​​cambio della loro modalità video.

Ed è qui che sono bloccato. Perché due webcam che funzionano ben al di sotto della velocità massima di USB 2 genererebbero questo errore?

ps: non è un problema di spazio su disco, df non mostra alcun cambiamento all'avvio delle webcam.

pps: se fa la differenza, ecco l'output di lsusb

Risposte:


25

Ding Ding! Riuscito a capirlo con l'aiuto delle belle persone in # v4l su freenode.

Per farla breve: v4l2-ctl è lo strumento migliore per il debug dei problemi della fotocamera USB. Leggi tutti i comandi disponibili e la pagina man, sarà divertente lo prometto. Usando v4l2-ctl ho scoperto che una delle mie fotocamere non supportava alcuna modalità video compressa. Puoi controllare quali modalità supportano le tue fotocamere eseguendo il comando seguente:

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

Che dovrebbe produrre qualcosa del genere.

 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 l'unico formato di pixel restituito è "YUYV", "IUYV", "I420" o "GBRG", sarà possibile eseguire una sola fotocamera per controller USB * poiché tali formati non sono compressi. L'uso di più webcam che supportano MJPEG o qualche altra forma di compressione funzionerà bene.

Se usi OpenCV come me, non preoccuparti se il formato pixel predefinito non è compresso come sembra che OpenCV utilizzi comunque la compressione.

** A meno che tu non sia soddisfatto della risoluzione 320x240 o inferiore. *


1
Ciao, se possibile, puoi dirmi come devo impostare il formato pixel di 2 fotocamere in modo da poterle catturare a 640x480? Sto usando OpenCV e attualmente sto vivendo la stessa situazione in cui avete entrambe le fotocamere funzioneranno solo a 320x240 o meno
lexma

Aha! v4l2-ctlè davvero uno strumento eccellente per il debug. Ho scoperto molto sulla mia macchina fotografica ed è stato in grado di risolvere il problema. Ad ogni modo, sono stato in grado di risolverlo forzando la risoluzione della mia fotocamera 320x240e usando YUYVcome modalità di uscita della fotocamera. guvcviewanche aiutato molto.
Sheharyar,

Quando utilizzo risoluzioni di 320x240 o inferiori, ottengo risultati contrastanti. Ho comprato 4 webcam USB economiche, tutte della stessa marca / modello. Quando si tenta di eseguire 2 a 160x120, alcuni di essi funzionano bene insieme e altri danno l'errore di memoria. Non vedo rime o motivi per questo. Certo, queste webcam costano $ 3 / ciascuna, quindi credo di aver ottenuto quello per cui ho pagato.
Cerin,

Il collegamento di due o più di tali telecamere a USB 3.0 funziona correttamente, anche tramite un hub USB 2.0. Controllato con YUYV.
Michał Leon,

7

La risposta è utilizzare le modifiche uvcvideo scritte da SwDevRefugee e descritte sopra. Lui e io abbiamo lavorato insieme per compilare il codice modificato per OpenWrt, con successo. La versione su cui lo sto eseguendo è OpenWRT DESIGNATED DRIVER (Bleeding Edge, r48130), su un router wdr3600 tplink:

RISULTATO: posso avere 3 * c270 (logitech) in esecuzione contemporaneamente a 1280x960 e 15fps in formato MJPG, tramite un hub USB 2.0. Non ho un quarto c270 da collegare, scusate.

Posso anche avere 2 * c270 e 1 * GEMBIRD 640 * 480 * 15fps con formato YUV, ma l'aggiunta di un secondo GEMBIRD porta al temuto "Impossibile avviare l'acquisizione: spazio insufficiente sul dispositivo" (spazio == larghezza di banda qui, come te sapere bene:)). Si noti che GEMBIRD (1908: 2311) == http://www.penguin.cz/~utx/hardware/USB_Camera_AX2311/ .

L'utilizzo della CPU con 3 * c270 è abbastanza ragionevole su 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 --

Se la community offre reputazione e supporto, penso che SwDevRefugee sia disposto a inserire il codice in uvc-linux.


4

Ho guardato il driver uvcvideo e il parametro quirks = 128 module viene ignorato se il flusso è compresso mjpeg.

Le mie webcam preferite sono state Logitech C500 e Logitech C270 e ho scoperto che l'immagine prodotta dal C500 a 1280x1024 è di 100kbyte e l'immagine prodotta dal C270 a 1280x960 è di 200kbyte.

Se eseguo il C270 a 10 fps, il bitrate richiesto è 10x200000x8 = 16Mbit / s. In Ubuntu 14.04 il modulo uvcdriver alloca sempre 196Mbit / s indipendentemente dalla frequenza dei fotogrammi. Per il C500 è un po 'meglio comportato, ma è ancora un porco di larghezza di banda.

Ho modificato il driver uvcvideo in modo da poter fornire un fattore di "compressione" al driver tramite l'interfaccia V4L2. È un "piccolo hacky" in quanto ho usato l'attributo priv in struct v4l2_pix_format per specificare il valore. Nel driver calcola la dimensione dell'immagine non compressa e quindi si divide per il fattore di compressione per capire quale larghezza di banda USB usare.

Per impostazione predefinita, utilizzo un fattore di compressione di 10 che consente un ampio margine se la fotocamera rileva un'immagine particolarmente dura da comprimere. Il C270 a 1280x960 e 10fps ora utilizza 41Mbit / se posso facilmente eseguire 4 telecamere su un bus.

Se qualcuno è interessato a questa funzionalità, cercherò di convincere i manutentori di uvcvideo a considerare il concetto di fattore di "compressione".


Io e potenzialmente altri membri della comunità OpenROV sarei desideroso di vedere la tua mod sul driver uvc @SwDevRefugee. Sto lavorando per cercare di integrare due webcam in OpenROV (una per l'odometria visiva rivolta verso il basso, l'altra per il normale pilotaggio / visualizzazione), ma ho riscontrato lo stesso problema BW. Hai pensato di pubblicare la tua mod / o inviare una richiesta pull per la tua modifica?

Il modo ufficiale per richiedere modifiche al driver uvc è tramite questa mailing list: linux-uvc-devel@lists.sourceforge.net. Ho pubblicato la mia richiesta di modifica il 30-dic-2015 insieme ad altri post successivi con ulteriori informazioni. Non ho avuto risposta da un manutentore. Altre due persone hanno espresso interesse per il cambiamento. Non so quanti sono necessari per ottenere qualsiasi azione. Forse @laughlinb potrebbe pubblicare anche nella mailing list.
SwDevAlien,

@SwDevRefugee: Vorrei il tuo consiglio unix.stackexchange.com/q/287279/52764
Ragav

@Ragav: Penso che sia necessario isolare il problema aprendo tutte le telecamere contemporaneamente alle risoluzioni appropriate usando un'applicazione ben educata come luvcview che dovrebbe darti messaggi di errore informativi in ​​caso di errore.
SwDevAlien,

1
Il problema di Ragav è che le sue telecamere supportano solo YUYV e quando usa la bandiera stranezze = 0x80 il guidatore lo costringe a usare almeno 1024 byte / microframe (65,5 Mbit / s) per telecamera. Ciò è aggravato dal fatto che la larghezza di banda maggiore più bassa supportata dalle telecamere è 2040 byte / microframe, quindi anche se vuole solo 320x240 a 6fps, può avere solo 2 telecamere su un bus USB. Il limite minimo di 1024 byte / microframe è stato aggiunto al driver uvcvideo da qualche parte tra le versioni 2.6.32 e 3.16 del kernel.
SwDevAlien,

-1

Anch'io ho riscontrato questo errore di spazio. Ciò che ha funzionato è stato quello di scollegare una delle telecamere e collegarla a un'altra porta USB sul mio PC fisso - ci sono circa 6 o 7 porte USB sparse su di esso. Eseguendo 'show_webcams 0 1', improvvisamente vengono visualizzate le due immagini.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.