Korzystanie z wielu kamer USB w systemie Linux

30

Uruchomienie więcej niż jednej kamery internetowej USB w systemie Debian / Linux powoduje następujący błąd:

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

To, co początkowo wydawało się problemem programistycznym w OpenCV, przerodziło się w poszukiwanie tajemniczego problemu ze sprzętem / oprogramowaniem po tym, jak te same błędy powstały podczas uruchamiania sera i xawtv.

Najwyraźniej jest to spowodowane tym, że kamery internetowe żądają całej dostępnej przepustowości na kontrolerze hosta USB. Mając to na uwadze, postanowiłem uruchomić wireshark i capinfos, aby zobaczyć, ile pasma wykorzystuje pojedyncza kamera.

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

Ciekawy! To może wyjaśniać, dlaczego działają dwie kamery o rozdzielczości 320 x 240, ale zawodzi każda wyższa rozdzielczość. To tak, jakby mój kontroler USB działał tylko z szybkościami USB 1, ale lsusb pokazuje obie kamery należące do urządzenia, które podobno obsługuje 480 megabitów na sekundę.

W jednym z rozwiązań zaproponowano wymuszenie na kamerach internetowych obliczania zużycia przepustowości zamiast żądania maksymalnej wartości, uruchamiając następujące polecenia:

sudo rmmod uvcvideo
sudo modprobe uvcvideo quirks=128

Niestety nie miało to znaczenia, więc postanowiłem spróbować innego rozwiązania. Post na StackOverflow zasugerował moim kamerom internetowym użycie niższego FPS lub skompresowanego formatu wideo, takiego jak MJPEG, ale po uruchomieniu listy v4lctl żadna z moich kamer nie obsługuje zmiany trybu wideo.

I właśnie tam utknąłem. Dlaczego dwie kamery działające znacznie poniżej maksymalnej prędkości USB 2 powodują ten błąd?

ps: To nie jest problem z miejscem na dysku, df nie wyświetla żadnych zmian po uruchomieniu kamer internetowych.

pps: Jeśli to robi różnicę, oto wynik działania lsusb

Rachelderp
źródło

Odpowiedzi:

25

Ding ding! Udało się to rozwiązać dzięki pomocy miłych ludzi w # v4l na freenode.

Krótka historia: v4l2-ctl to najlepsze narzędzie do debugowania problemów z kamerami USB. Przeczytaj wszystkie dostępne polecenia i stronę podręcznika, obiecuję, że będzie fajnie. Za pomocą v4l2-ctl odkryłem, że jedna z moich kamer nie obsługuje żadnych skompresowanych trybów wideo. Możesz sprawdzić, jakie tryby obsługują twoje kamery, uruchamiając następujące polecenie:

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

Co powinno dać coś takiego.

 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)

Jeśli jedynym zwracanym formatem pikseli jest „YUYV”, „IUYV”, „I420” lub „GBRG”, będziesz mógł uruchomić tylko jedną kamerę na kontrolerze USB *, ponieważ formaty te są nieskompresowane. Korzystanie z wielu kamer internetowych obsługujących MJPEG lub inną formę kompresji będzie działać poprawnie.

Jeśli używasz OpenCV jak ja, nie martw się, jeśli domyślny format pikseli nie jest skompresowany, ponieważ wydaje się, że OpenCV i tak używa kompresji.

** Chyba że jesteś zadowolony z rozdzielczości 320 x 240 lub niższej. *

Rachelderp
źródło
1
Cześć, jeśli to możliwe, czy możesz mi powiedzieć, jak powinienem ustawić format pikselowy 2 kamer, aby uchwycić oba w rozdzielczości 640x480? Korzystam z OpenCV i obecnie mam taką samą sytuację, jak w przypadku, gdy obie kamery będą działały tylko w rozdzielczości 320 x 240 lub niższej
lexma,
Aha! v4l2-ctljest rzeczywiście doskonałym narzędziem do debugowania. Dowiedziałem się dużo o moim aparacie i udało mi się rozwiązać problem. W każdym razie udało mi się to naprawić, wymuszając rozdzielczość mojej kamery 320x240i używając YUYVjako trybu wyjściowego kamery. guvcviewrównież bardzo pomogło.
Sheharyar
Korzystając z rozdzielczości 320 x 240 lub niższych, otrzymuję mieszane wyniki. Kupiłem 4 tanie kamery internetowe USB, wszystkie tego samego producenta / modelu. Podczas próby uruchomienia 2 przy 160 x 120 niektóre z nich działałyby dobrze razem, a niektóre dawały błąd pamięci. Nie widzę w tym rymu ani powodu. To prawda, że ​​te kamery kosztują 3 USD za każdą, więc chyba dostałem to, za co zapłaciłem.
Cerin,
Podłączenie dwóch lub więcej tych kamer do USB 3.0 działa dobrze, nawet przez hub USB 2.0. Sprawdzone za pomocą YUYV.
Michał Leon,
7

Odpowiedzią jest użycie modyfikacji uvcvideo napisanych przez SwDevRefugee i opisanych powyżej. Wspólnie z nim pracowaliśmy, aby z powodzeniem skompilować zmodyfikowany kod dla OpenWrt. Wersja, na której go uruchamiam, to OpenWRT DESIGNATED DRIVER (Bleeding Edge, r48130), na routerze wdplink wd3600:

WYNIK: Mogę mieć 3 * c270 (logitech) działający jednocześnie przy 1280x960 i 15 klatkach na sekundę w formacie MJPG, przez hub USB 2.0. Przepraszam, nie mam czwartego C270.

Mogę też mieć 2 * c270 i 1 * GEMBIRD 640 * 480 * 15 kl./sw formacie YUV, ale dodanie drugiego GEMBIRD prowadzi do przerażającego „Nie można rozpocząć przechwytywania: Brak miejsca na urządzeniu” (spacja == przepustowość tutaj, jak ty dobrze wiedzieć:)). Zauważ, że GEMBIRD (1908: 2311) == http://www.penguin.cz/~utx/hardware/USB_Camera_AX2311/ .

Wykorzystanie procesora z 3 * c270 jest dość rozsądne na 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 --

Jeśli społeczność zapewni trochę reputacji i wsparcia, myślę, że SwDevRefugee jest skłonny wprowadzić kod do wersji uvc-linux.

ponownie
źródło
4

Spojrzałem na sterownik uvcvideo i parametr modułu quirks = 128 jest ignorowany, jeśli strumień jest skompresowany w formacie mjpeg.

Moje wybrane kamery to Logitech C500 i Logitech C270, i stwierdziłem, że obraz wytworzony przez C500 w rozdzielczości 1280x1024 ma rozmiar 100 kB, a obraz wytworzony przez C270 w rozdzielczości 1280 x 960 ma rozmiar 200 kB.

Jeśli uruchomię C270 przy 10 klatkach na sekundę, wówczas wymagana szybkość transmisji wynosi 10 x 200 000 x 8 = 16 Mb / s. W Ubuntu 14.04 moduł uvcdriver zawsze przydziela 196 Mb / s, niezależnie od częstotliwości klatek. W przypadku C500 jest to nieco lepsze zachowanie, ale nadal jest świnią przepustowości.

Zmodyfikowałem sterownik uvcvideo, dzięki czemu mogę zapewnić współczynnik „kompresji” dla sterownika poprzez interfejs V4L2. Jest to „trochę hacky”, ponieważ użyłem atrybutu priv w struct v4l2_pix_format do określenia wartości. W sterowniku oblicza rozmiar nieskompresowanego obrazu, a następnie dzieli przez współczynnik kompresji, aby ustalić, jakiej przepustowości USB należy użyć.

Domyślnie używam współczynnika kompresji 10, który pozwala na duży margines, jeśli aparat napotka szczególnie trudny do skompresowania obraz. C270 działający w rozdzielczości 1280x960 i 10 klatkach na sekundę wykorzystuje teraz 41 Mb / s i mogę z łatwością obsługiwać 4 kamery na jednej magistrali.

Jeśli ktoś jest zainteresowany tą funkcją, postaram się zachęcić opiekunów uvcvideo do rozważenia koncepcji współczynnika „kompresji”.

SwDevAlien
źródło
Ja i potencjalnie inni członkowie społeczności OpenROV chętnie zobaczymy twój mod w sterowniku uvc @SwDevRefugee. Pracuję nad próbą zintegrowania dwóch kamer internetowych z OpenROV (jedna dla odometrii wizualnej skierowanej w dół, druga dla normalnego pilotowania / oglądania), ale napotykam ten sam problem BW. Czy zastanawiałeś się nad opublikowaniem swojego modu lub przesłaniem prośby o zmianę?
Oficjalnym sposobem żądania zmian w sterowniku uvc jest ta lista mailingowa: [email protected]. Wysłałem prośbę o zmianę w dniu 30 grudnia 2015 r. Wraz z kilkoma innymi późniejszymi wpisami z dalszymi informacjami. Nie otrzymałem odpowiedzi od opiekuna. Dwie inne osoby wyraziły zainteresowanie zmianą. Nie wiem, ile jest wymaganych, aby uzyskać jakiekolwiek działanie. Być może @laughlinb mógłby również publikować na liście mailingowej.
SwDevAlien
@SwDevRefugee: Chciałbym twojej porady unix.stackexchange.com/q/287279/52764
Ragav
@Ragav: Myślę, że musisz odizolować problem, otwierając jednocześnie wszystkie kamery w odpowiednich rozdzielczościach za pomocą dobrze zachowującej się aplikacji, takiej jak luvcview, która powinna wyświetlać informacyjne komunikaty o błędach w przypadku awarii.
SwDevAlien
1
Problem Ragava polega na tym, że jego kamery obsługują tylko YUYV, a gdy używa flagi dziwactwa = 0x80, sterownik zmusza go do korzystania z co najmniej 1024 bajtów / mikroframy (65,5 Mbit / s) na kamerę. Sytuację pogarsza fakt, że najniższa większa przepustowość obsługiwana przez kamery wynosi 2040 bajtów / mikroklatkę, więc nawet jeśli chce tylko 320 x 240 przy 6 klatkach na sekundę, może mieć tylko 2 kamery na jednej magistrali USB. Do sterownika uvcvideo dodano co najmniej 1024 bajty / mikroprawkę pomiędzy wersjami jądra w wersji 2.6.32 i 3.16.
SwDevAlien,
-1

Wystąpił również błąd braku miejsca. Udało się odłączyć jedną z kamer i podłączyć ją do innego portu USB na moim stacjonarnym komputerze - jest tam około 6 lub 7 portów USB. Uruchomienie „show_webcams 0 1”, a następnie nagle wywołało dwa obrazy.

Peter Thejll
źródło