Verwenden mehrerer USB-Webcams unter Linux

29

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 bei der Ausführung von cheese und xawtv aufgetreten waren.

Anscheinend wird dies durch Webcams verursacht, die die gesamte verfügbare Bandbreite des USB-Hostcontrollers abfragen. Vor diesem Hintergrund habe ich mich für Wireshark und Capinfos entschieden, um zu sehen, 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, aber lsusb zeigt beide Webcams, die zu einem Gerät gehören, das angeblich 480 Megabits pro Sekunde unterstützt.

In einer Lösung wurde vorgeschlagen, 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. In einem Beitrag auf StackOverflow wurde empfohlen, dass meine Webcams ein niedrigeres FPS- oder komprimiertes Videoformat wie MJPEG verwenden sollen. Nach dem Ausführen von v4lctl list wird jedoch nicht angezeigt, dass eine meiner Webcams das Ändern des Videomodus unterstützt.

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

rachelderp
quelle

Antworten:

25

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

Kurz gesagt: 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. *

rachelderp
quelle
1
Hallo, wenn möglich, kannst du mir sagen, wie ich das Pixelformat von 2 Kameras einstellen soll, damit ich beide mit 640x480 aufnehmen kann? Ich benutze OpenCV und habe momentan die gleiche Situation wie Sie, in der beide Kameras nur mit 320x240 oder niedriger arbeiten werden
Lexma
Aha! v4l2-ctlist in der Tat ein hervorragendes Tool zum Debuggen. Ich habe viel über meine Kamera erfahren und konnte das Problem beheben. Wie auch immer, ich war in der Lage , es zu beheben durch meine Kamera Auflösung zu zwingen 320x240und die Verwendung YUYVals Kamera - Ausgabemodus. guvcviewhat auch sehr geholfen.
Sheharyar
Wenn ich Auflösungen von 320x240 oder niedriger verwende, erhalte ich gemischte Ergebnisse. Ich habe 4 billige USB-Webcams gekauft, alle vom selben Hersteller / Modell. Bei dem Versuch, 2 mit 160 x 120 auszuführen, funktionierten einige von ihnen problemlos zusammen, andere gaben den Speicherfehler an. Ich sehe keinen Reim oder Grund dafür. Zugegeben, diese Webcams kosten jeweils 3 US-Dollar, also habe ich wohl das bekommen, wofür ich bezahlt habe.
Cerin
Das Anschließen von zwei oder mehr dieser Kameras an USB 3.0 funktioniert einwandfrei, auch über einen USB 2.0-Hub. Überprüft mit YUYV.
Michał Leon
7

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 der gefürchteten Meldung "Capture kann nicht gestartet werden: Auf dem Gerät ist kein Speicherplatz mehr verfügbar" (Speicherplatz == Bandbreite hier, so 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.

reikred
quelle
4

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 groß und das vom C270 bei 1280 x 960 erzeugte Bild 200 KB groß ist.

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 Hacky", als ich das Attribut priv in der Struktur v4l2_pix_format verwendet habe, um den Wert anzugeben. Im Treiber wird die Größe des unkomprimierten 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 Betreuer von uvcvideo dazu zu bringen, das Konzept des "Komprimierungsfaktors" zu berücksichtigen.

SwDevAlien
quelle
Ich und möglicherweise auch andere in der OpenROV-Community wären sehr gespannt auf Ihren Mod für den UVC-Treiber @SwDevRefugee. Ich arbeite daran, zwei Webcams in OpenROV zu integrieren (eine für die abwärtsgerichtete visuelle Kilometermessung, die andere für die normale Steuerung / Anzeige), stoße aber auf dasselbe BW-Problem. Hast du darüber nachgedacht, deinen Mod zu posten oder eine Pull-Anfrage für dein Wechselgeld einzureichen?
Der offizielle Weg, Änderungen am uvc-Treiber anzufordern, ist über diese Mailingliste: [email protected]. Ich habe meine Änderungsanforderung am 30.12.2015 zusammen mit einigen anderen nachfolgenden Beiträgen mit weiteren Informationen veröffentlicht. Ich habe keine Antwort von einem Betreuer erhalten. Zwei weitere Personen haben Interesse an der Veränderung bekundet. Ich weiß nicht, wie viele erforderlich sind, um Maßnahmen zu ergreifen. Vielleicht könnte @laughlinb auch auf die Mailingliste setzen.
SwDevAlien
@ SwDevRefugee: Ich möchte Ihren Rat unix.stackexchange.com/q/287279/52764
Ragav
@ Ragav: Ich denke, Sie müssen das Problem eingrenzen, indem Sie alle Kameras gleichzeitig mit den entsprechenden Auflösungen mit einer gut funktionierenden Anwendung wie luvcview öffnen, die Ihnen bei einem Fehler informative Fehlermeldungen geben sollte.
SwDevAlien
1
Ragavs Problem ist, dass seine Kameras nur YUYV unterstützen. Wenn er das Quirks = 0x80-Flag verwendet, wird er vom Treiber gezwungen, mindestens 1024 Bytes / Microframe (65,5 Mbit / s) pro Kamera zu verwenden. Hinzu kommt, dass die niedrigste größere Bandbreite, die die Kameras unterstützen, 2040 Bytes / Mikroframe beträgt. Obwohl er nur 320x240 mit 6 Bildern pro Sekunde will, kann er nur 2 Kameras an einem USB-Bus haben. Die minimale Beschränkung von 1024 Bytes / Microframe wurde dem uvcvideo-Treiber irgendwo zwischen den Releases 2.6.32 und 3.16 des Kernels hinzugefügt.
SwDevAlien
-1

Ich habe den Fehler auch aus dem All bekommen. Was funktionierte, war, eine der Kameras abzuziehen und sie an einen anderen USB-Port meines stationären PCs anzuschließen - es gibt ungefähr 6 oder 7 USB-Ports, die darüber verstreut sind. Wenn Sie 'show_webcams 0 1' ausführen, werden die beiden Bilder plötzlich angezeigt.

Peter Thejll
quelle