Запуск более одной USB-веб-камеры в Debian/Linux приводит к следующей ошибке:
libv4l2: error turning on stream: No space left on device
VIDIOC_STREAMON: No space left on device
То, что изначально казалось проблемой программирования в OpenCV, превратилось в поиск загадочной аппаратной/программной проблемы после того, как те же ошибки возникли при запуске cheese и xawtv.
Видимо, это вызвано тем, что веб-камеры запрашивают всю доступную полосу пропускания на хост-контроллере USB. Имея это в виду, я решил запуститьпроводная акулаи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
решение1
Динь-динь! Удалось разобраться с этим с помощью хороших людей из #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 или ниже.*
решение2
Ответ заключается в использовании модификаций uvcvideo, написанных SwDevRefugee и описанных выше. Мы с ним работали вместе, чтобы скомпилировать модифицированный код для OpenWrt, и с успехом. Версия, на которой я его запускаю, — OpenWRT DESIGNATED DRIVER (Bleeding Edge, r48130) на маршрутизаторе tplink wdr3600:
РЕЗУЛЬТАТ: Я могу запустить 3*c270 (logitech) одновременно с разрешением 1280x960 и частотой 15 кадров в секунду в формате MJPG через концентратор usb 2.0. У меня нет четвертого c270 для подключения, извините.
У меня также могут быть 2*c270 и 1*GEMBIRD 640*480*15 кадров в секунду с форматом YUV, но добавление второго 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.
решение3
Я посмотрел на драйвер 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 в структуре v4l2_pix_format для указания значения. В драйвере он вычисляет размер несжатого изображения, а затем делит его на фактор сжатия, чтобы определить, какую пропускную способность USB использовать.
По умолчанию я использую коэффициент сжатия 10, что дает большой запас, если камера столкнется с особенно сложным для сжатия изображением. C270, работающий с разрешением 1280x960 и частотой 10 кадров в секунду, теперь использует 41 Мбит/с, и я могу легко запустить 4 камеры на одной шине.
Если кого-то интересует эта функция, то я попытаюсь убедить разработчиков uvcvideo рассмотреть концепцию фактора «сжатия».
решение4
У меня тоже была эта ошибка из-за нехватки места. Помогло отключение одной из камер и подключение ее к другому USB-порту на моем стационарном ПК — там их около 6 или 7. Запуск 'show_webcams 0 1' внезапно вывел два изображения.