Ding Ding! Sono riuscito a capirlo con l'aiuto delle persone simpatiche 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. Utilizzando v4l2-ctl Ho scoperto che una delle mie fotocamere non supportava alcuna modalità video compressa. Puoi verificare quali modalità sono supportate dalle tue fotocamere eseguendo il seguente comando:
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 pixel restituito è "YUYV", "IUYV", "I420" o "GBRG", sarai in grado di eseguire solo una fotocamera per controller USB* poiché questi formati non sono compressi. L'utilizzo di più webcam che supportano MJPEG o qualche altra forma di compressione funzionerà correttamente.
Se usi OpenCV come me, non preoccuparti se il formato pixel predefinito non è compresso poiché sembra che OpenCV utilizzi comunque la compressione per impostazione predefinita.
**A meno che tu non sia soddisfatto della risoluzione 320x240 o inferiore.*
La risposta è utilizzare le modifiche uvcvideo scritte da SwDevRefugee e descritte sopra. Lui ed io abbiamo lavorato insieme per ottenere il codice modificato compilato per OpenWrt, con successo. La versione su cui lo sto eseguendo è OpenWRT DESIGNATED DRIVER (Bleeding Edge, r48130), su un router tplink wdr3600:
RISULTATO:posso avere 3 * c270 (logitech) in esecuzione simultaneamente a 1280x960 e 15 fps in formato MJPG, tramite un hub USB 2.0. Non ho un quarto c270 da collegare, mi spiace.
Posso anche avere 2*c270 e 1*GEMBIRD 640*480*15fps con formato YUV, ma l'aggiunta di un 2° GEMBIRD porta al temuto "Impossibile avviare l'acquisizione:Spazio esaurito sul dispositivo" (spazio==larghezza di banda qui, come si sapere bene:)). Nota 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 un po' di reputazione e supporto, penso che SwDevRefugee sia disposto a inserire il codice in uvc-linux.
Ho esaminato il driver uvcvideo e il parametro del modulo quirks=128 viene ignorato se il flusso è compresso in mjpeg.
Le mie webcam preferite sono state la Logitech C500 e la Logitech C270, e ho scoperto che l'immagine prodotta dalla C500 a 1280x1024 è di 100kbyte e l'immagine prodotta dalla C270 a 1280x960 è di 200kbyte.
Se eseguo il C270 a 10 fps, il bitrate richiesto è 10x200000x8 =16 Mbit/s. In Ubuntu 14.04 il modulo uvcdriver alloca sempre 196 Mbit/s indipendentemente dal frame rate. Per il C500 si comporta un po 'meglio, ma è ancora un maiale 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 "po 'hacky" in quanto ho usato l'attributo priv nella struct v4l2_pix_format per specificare il valore. Nel driver calcola la dimensione dell'immagine non compressa e quindi la divide per il fattore di compressione per determinare quale larghezza di banda USB utilizzare.
Per impostazione predefinita, utilizzo un fattore di compressione di 10 che consente un ampio margine se la fotocamera incontra un'immagine particolarmente difficile da comprimere. Il C270 che funziona a 1280x960 e 10 fps ora utilizza 41 Mbit/s e posso facilmente far funzionare 4 videocamere su un bus.
Se qualcuno è interessato a questa funzione, cercherò di convincere i manutentori di uvcvideo a considerare il concetto di fattore di "compressione".