Ding ding! Podařilo se mi to vyřešit s pomocí milých lidí v #v4l na freenode.
Krátký příběh:v4l2-ctl je nejlepším nástrojem pro ladění problémů s USB kamerou. Přečtěte si všechny dostupné příkazy a manuálovou stránku, bude to zábava, slibuji. Pomocí v4l2-ctl Zjistil jsem, že jeden z mých fotoaparátů nepodporuje žádné režimy komprimovaného videa. Můžete zkontrolovat, jaké režimy vaše kamery podporují, spuštěním následujícího příkazu:
v4l2-ctl -d /dev/video0 --list-formats
Což by mělo mít výstup něco takového.
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)
Pokud je jediným vráceným pixelovým formátem "YUYV", "IUYV", "I420" nebo "GBRG", budete moci spustit pouze jednu kameru na USB řadiči*, protože tyto formáty jsou nekomprimované. Použití více webových kamer, které podporují MJPEG nebo jinou formu komprese, bude fungovat dobře.
Pokud používáte OpenCV jako já, nemějte obavy, pokud výchozí formát pixelů není komprimovaný, jak se zdá, OpenCV stejně jako výchozí používá kompresi.
**Pokud nejste spokojeni s rozlišením 320 x 240 nebo nižším.*
Odpověď je použít modifikace uvcvideo napsané SwDevRefugee a popsané výše. On a já jsme spolupracovali, abychom dostali modifikovaný kód zkompilovaný pro OpenWrt s úspěchem. Verze, na které to spouštím, je OpenWRT DESIGNATED DRIVER (Bleeding Edge, r48130), na routeru tplink wdr3600:
VÝSLEDEK:Mohu mít 3*c270 (logitech) spuštěné simultánně v rozlišení 1280x960 a 15fps ve formátu MJPG přes rozbočovač usb 2.0. Nemám čtvrtou c270 k připojení, omlouvám se.
Mohu mít také 2*c270 a 1*GEMBIRD 640*480*15fps s formátem YUV, ale přidání 2. GEMBIRD vede k obávanému „Nelze spustit snímání:Na zařízení nezbývá místo“ (mezera==šířka pásma zde, jak vy dobře znát:)). Všimněte si, že GEMBIRD (1908:2311) ==http://www.penguin.cz/~utx/hardware/USB_Camera_AX2311/ .
Využití CPU s 3*c270 je na wdr3600 celkem rozumné:
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 --
Pokud komunita poskytne nějakou reputaci a podporu, myslím, že SwDevRefugee je ochoten dostat kód do uvc-linux.
Podíval jsem se na ovladač uvcvideo a parametr modulu quirks=128 je ignorován, pokud je stream komprimován mjpeg.
Moje webové kamery byly Logitech C500 a Logitech C270 a zjistil jsem, že obraz produkovaný C500 při 1280x1024 je 100 kbajtů a obraz produkovaný C270 při 1280x960 je 200 kbajtů.
Pokud spustím C270 při 10 snímcích za sekundu, požadovaný bitrate je 10x200000x8 =16Mbit/s. V Ubuntu 14.04 modul uvcdriver vždy přiděluje 196 Mbit/s bez ohledu na snímkovou frekvenci. Pro C500 je trochu lépe chovaný, ale stále je to prase s šířkou pásma.
Upravil jsem ovladač uvcvideo, abych mohl ovladači poskytnout "kompresní" faktor prostřednictvím rozhraní V4L2. Je to "trochu hacky" v tom, že jsem k určení hodnoty použil atribut priv ve struktuře v4l2_pix_format. V ovladači vypočítá velikost nekomprimovaného obrazu a poté vydělí faktorem komprese, aby zjistil, jakou šířku pásma USB použít.
Ve výchozím nastavení používám kompresní faktor 10, který umožňuje velkou rezervu pro případ, že fotoaparát narazí na obzvláště obtížný obraz ke kompresi. C270 běžící na 1280x960 a 10fps nyní používá 41Mbit/s a já mohu snadno provozovat 4 kamery na jedné sběrnici.
Pokud má někdo zájem o tuto funkci, pokusím se přimět správce uvcvideo, aby zvážili koncept faktoru "komprese".