Использование нескольких веб-камер USB в Linux

Запуск более одной веб-камеры USB в Debian/Linux приводит к следующей ошибке:

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

То, что изначально казалось проблемой программирования в OpenCV, превратилось в поиск загадочной проблемы с аппаратным и программным обеспечением после того, как те же ошибки возникли при запуске cheese и xawtv.

Очевидно, это вызвано тем, что веб-камеры запрашивают всю доступную полосу пропускания на хост-контроллере USB. Имея это в виду, я решил запустить wireshark и capinfos, чтобы увидеть, какую пропускную способность использует одна камера.

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

Интересно! Это может объяснить, почему две камеры с разрешением 320x240 работают, но любое более высокое разрешение дает сбой. Как будто мой USB-контроллер работает только на скорости USB 1, но lsusb показывает обе веб-камеры, принадлежащие устройству, которое предположительно поддерживает 480 мегабит в секунду.

В одном решении предлагалось заставить веб-камеры рассчитывать использование полосы пропускания, а не запрашивать их максимум, выполнив следующие команды:

sudo rmmod uvcvideo
sudo modprobe uvcvideo quirks=128

К сожалению, это не имело никакого значения, поэтому я решил попробовать другое решение. В сообщении на StackOverflow предлагалось указать моим веб-камерам использовать более низкий FPS или сжатый видеоформат, такой как MJPEG, но после запуска списка v4lctl ни одна из моих веб-камер не поддерживает изменение их видео-режима.

И вот где я застрял. Почему две веб-камеры, работающие значительно ниже максимальной скорости USB 2, могут вызвать такую ​​ошибку?

ps: это не проблема дискового пространства, df не отображает изменений при запуске веб-камер.

pps: если это имеет значение, вот вывод команды lsusb

4 ответа

Решение

Дин Дин! Удалось выяснить это с помощью хороших людей из #v4l на freenode.

Короче говоря: v4l2-ctl - лучший инструмент для устранения проблем с USB-камерами. Прочитайте все доступные команды и справочную страницу, это будет весело, я обещаю. Используя v4l2-ctl, я обнаружил, что одна из моих камер не поддерживает режимы сжатого видео. Вы можете проверить, какие режимы поддерживают ваши камеры, выполнив следующую команду:

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

Который должен выводить что-то вроде этого.

 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)

Если возвращается только один формат пикселей: "YUYV", "IUYV", "I420" или "GBRG", вы сможете использовать только одну камеру для каждого контроллера USB *, поскольку эти форматы не сжаты. Использование нескольких веб-камер, которые поддерживают MJPEG или какую-либо другую форму сжатия, будет работать нормально.

Если вы используете OpenCV, как я, не беспокойтесь, если формат пикселя по умолчанию не сжимается, так как в любом случае OpenCV по умолчанию использует сжатие.

** Если вы не довольны разрешением 320x240 или ниже.*

Ответ заключается в использовании модификаций uvcvideo, написанных SwDevRefugee и описанных выше. Он и я работали вместе, чтобы успешно скомпилировать модифицированный код для OpenWrt. Версия, на которой я его запускаю, - это ДРАЙВЕР, ОПИСАННЫЙ OpenWRT (Bleeding Edge, r48130), на маршрутизаторе tplink wdr3600:

РЕЗУЛЬТАТ: у меня может быть 3*c270 (logitech), работающий одновременно с разрешением 1280x960 и 15 кадров в секунду в формате MJPG, через концентратор USB 2.0. У меня нет четвертого с270, чтобы подключить, извините.

Я также могу иметь 2*c270 и 1*GEMBIRD 640*480*15 кадров в секунду в формате YUV, но добавление 2-го GEMBIRD приводит к ужасному "Невозможно начать захват: на устройстве не осталось места" (пробел == пропускная способность здесь, так как вы хорошо знать:)). Обратите внимание, что GEMBIRD (1908: 2311) == http://www.penguin.cz/~utx/hardware/USB_Camera_AX2311/.

Использование процессора с 3 * c270 вполне разумно на 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 --

Если сообщество предоставит некоторую репутацию и поддержку, я думаю, что SwDevRefugee желает получить код в uvc-linux.

Я посмотрел на драйвер uvcvideo и параметр модуля quirks = 128 игнорируется, если поток сжат в формате mjpeg.

Моими любимыми веб-камерами были Logitech C500 и Logitech C270, и я обнаружил, что изображение, создаваемое C500 в разрешении 1280x1024, имеет размер 100 Кбайт, а изображение, создаваемое C270 при разрешении 1280x960, составляет 200 Кбайт.

Если я запускаю C270 со скоростью 10 кадров в секунду, то требуемая скорость передачи данных составляет 10x200000x8 = 16 Мбит / с. В Ubuntu 14.04 модуль uvcdriver всегда выделяет 196 Мбит / с независимо от частоты кадров. Для C500 он немного лучше себя ведет, но все еще является проблемой пропускной способности.

Я изменил драйвер uvcvideo, так что я могу обеспечить коэффициент "сжатия" для драйвера через интерфейс V4L2. Это немного "хакерство", потому что я использовал атрибут priv в struct v4l2_pix_format, чтобы указать значение. В драйвере он вычисляет размер несжатого изображения, а затем делит на коэффициент сжатия, чтобы определить, какую полосу пропускания USB использовать.

По умолчанию я использую коэффициент сжатия 10, который позволяет с большим запасом, если камера сталкивается с особенно жестким изображением для сжатия. C270, работающий со скоростью 1280x960 и 10 кадров в секунду, теперь использует 41 Мбит / с, и я легко могу запустить 4 камеры на одной шине.

Если кого-то заинтересует эта функция, я постараюсь убедить сопровождающих uvcvideo рассмотреть концепцию фактора "сжатия".

Я получил это из-за ошибки космоса тоже. То, что работало, состояло в том, чтобы отключить одну из камер и подключить ее к другому USB-порту на моем стационарном ПК - вокруг него разбросано 6 или 7 USB-портов. Запуск 'show_webcams 0 1', а затем внезапно поднял два изображения.

Другие вопросы по тегам