it-swarm.com.de

Verwenden mehrerer USB-Webcams unter Linux

Das Ausführen von mehr als einer USB-Webcam unter Debian/Linux führt zu folgendem Fehler:

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

Was anfangs ein Programmierproblem in OpenCV zu sein schien, entwickelte sich zu einer Suche nach einem mysteriösen Hardware-/Softwareproblem, nachdem die gleichen Fehler durch Ausführen von cheese und xawtv verursacht wurden.

Anscheinend wird dies durch Webcams verursacht, die die gesamte verfügbare Bandbreite auf dem USB-Host-Controller abfragen. Aus diesem Grund habe ich beschlossen, wireshark und capinfos zu verwenden, um festzustellen, wie viel Bandbreite eine einzelne Kamera verbraucht.

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

Interessant! Das könnte erklären, warum zwei Kameras mit 320x240 funktionieren, eine höhere Auflösung jedoch ausfällt. Es ist, als würde mein USB-Controller nur mit USB 1-Geschwindigkeit betrieben, doch lsusb zeigt beide Webcams, die zu einem Gerät gehören, das angeblich 480 Megabits pro Sekunde unterstützt.

Eine Lösung sah vor, die Webcams zu zwingen, ihre Bandbreitennutzung zu berechnen, anstatt ihr Maximum durch Ausführen der folgenden Befehle anzufordern:

Sudo rmmod uvcvideo
Sudo modprobe uvcvideo quirks=128

Da dies leider keinen Unterschied machte, habe ich mich für eine andere Lösung entschieden. Ein Post auf StackOverflow schlug vor, dass meine Webcams ein niedrigeres FPS- oder komprimiertes Videoformat wie MJPEG verwenden sollen, aber nachdem v4lctl list ausgeführt wurde Keine meiner Webcams unterstützt das Ändern des Videomodus.

Und da stecke ich fest. Warum würden zwei Webcams, die deutlich unter der maximalen Geschwindigkeit von USB 2 arbeiten, diesen Fehler verursachen?

ps: Es ist kein Speicherplatzproblem, df zeigt beim Starten der Webcams keine Änderung an.

pps: Wenn es einen Unterschied macht, ist hier die Ausgabe von lsusb

29
rachelderp

Ding Ding! Hat es geschafft, dies mit Hilfe der netten Leute in # v4l auf freenode herauszufinden.

Lange Rede kurzer Sinn: v4l2-ctl ist das beste Tool zum Debuggen von Problemen mit USB-Kameras. Lesen Sie alle verfügbaren Befehle und die Manpage. Ich verspreche, es wird Spaß machen. Mit v4l2-ctl habe ich festgestellt, dass eine meiner Kameras keine komprimierten Videomodi unterstützt. Sie können überprüfen, welche Modi Ihre Kameras unterstützen, indem Sie den folgenden Befehl ausführen:

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

Welches sollte so etwas ausgeben.

 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)

Wenn das einzige zurückgegebene Pixelformat "YUYV", "IUYV", "I420" oder "GBRG" ist, können Sie nur eine Kamera pro USB-Controller * ausführen, da diese Formate nicht komprimiert sind. Die Verwendung mehrerer Webcams, die MJPEG oder eine andere Form der Komprimierung unterstützen, funktioniert problemlos.

Wenn Sie OpenCV wie ich verwenden, machen Sie sich keine Sorgen, wenn das Standardpixelformat nicht komprimiert ist, da OpenCV standardmäßig sowieso die Komprimierung verwendet.

** Es sei denn, Sie sind mit einer Auflösung von 320 x 240 oder niedriger zufrieden. *

25
rachelderp

Die Antwort ist, die von SwDevRefugee geschriebenen und oben beschriebenen uvcvideo-Modifikationen zu verwenden. Er und ich haben mit Erfolg zusammengearbeitet, um den modifizierten Code für OpenWrt zu kompilieren. Die Version, auf der ich es ausführe, ist OpenWRT DESIGNATED DRIVER (Bleeding Edge, R48130) auf einem Tplink-WDR3600-Router:

ERGEBNIS: Ich kann 3 * c270 (logitech) gleichzeitig mit 1280 x 960 und 15 fps im MJPG-Format über einen USB 2.0-Hub ausführen. Ich habe keine vierte c270 zum Anschließen, sorry.

Ich kann auch 2 * c270 und 1 * GEMBIRD 640 * 480 * 15fps mit YUV-Format haben, aber das Hinzufügen eines 2. GEMBIRD führt zu dem gefürchteten "Capture kann nicht gestartet werden: Kein Platz mehr auf dem Gerät" (Platz == Bandbreite hier, wie Sie gut kennen:)). Beachten Sie, dass GEMBIRD (1908: 2311) == http://www.penguin.cz/~utx/hardware/USB_Camera_AX2311/ .

CPU-Auslastung mit 3 * c270 ist auf einem wdr3600 ziemlich vernünftig:

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 --

Wenn die Community etwas Ansehen und Unterstützung bietet, ist SwDevRefugee bereit, den Code in uvc-linux zu integrieren.

7
reikred

Ich habe mir den uvcvideo-Treiber angesehen und der Modulparameter quirks = 128 wird ignoriert, wenn der Stream mit MJPEG komprimiert ist.

Meine bevorzugten Webcams waren Logitech C500 und Logitech C270, und ich stellte fest, dass das vom C500 bei 1280 x 1024 erzeugte Bild 100 KB und das vom C270 bei 1280 x 960 erzeugte Bild 200 KB beträgt.

Wenn ich die C270 mit 10fps betreibe, ist eine Bitrate von 10x200000x8 = 16Mbit/s erforderlich. In Ubuntu 14.04 weist das uvcdriver-Modul unabhängig von der Bildrate immer 196 Mbit/s zu. Für den C500 ist es ein bisschen besser, aber es ist immer noch eine Schwäche für Bandbreite.

Ich habe den uvcvideo-Treiber so geändert, dass ich dem Treiber über die V4L2-Schnittstelle einen "Komprimierungsfaktor" zur Verfügung stellen kann. Es ist insofern ein "kleiner Knaller", als ich das Attribut priv in der Struktur v4l2_pix_format verwendet habe, um den Wert anzugeben. Im Treiber wird die Größe des nicht komprimierten Bildes berechnet und dann durch den Komprimierungsfaktor dividiert, um die zu verwendende USB-Bandbreite zu ermitteln.

Standardmäßig verwende ich einen Komprimierungsfaktor von 10, der einen großen Spielraum für den Fall bietet, dass die Kamera auf ein besonders schwer zu komprimierendes Bild stößt. Die C270, die mit 1280x960 und 10 fps läuft, verwendet jetzt 41 Mbit/s und ich kann problemlos 4 Kameras an einem Bus betreiben.

Wenn jemand an dieser Funktion interessiert ist, werde ich versuchen, die uvcvideo-Betreuer dazu zu bringen, das Konzept des "Komprimierungsfaktors" zu berücksichtigen.

4
SwDevAlien