Работа с usb видеокамерой в Linux. Часть 1

Источник: habrahabr
svistkovr

По популярности видеокамера, сегодня, стоит в одном ряду с микрофоном и наушниками. Она используется в различных направлениях, таких как распознавание объектов, дополненная реальность, видеоконференции и множество других. Но что же скрыто под капотом этих сложнейших программ? Как мы получаем картинку с видеокамеры? Этот цикл статей позволит взглянуть на простоту работы с видеокамерой на низком уровне, обработку полученного изображения.

   Для начала, немного информации о работе с устройствами в системе Linux. Устройства в nix системах представляют собой файл. С некоторыми файлами-устройств мы можем работать как с обычными файлами. Например:

~$ cat /dev/sda эта команда выведет на экран весь диск sda.

Есть устройства с которыми нельзя работать напрямую, к ним относится видеокамера.При попытке это сделать мы получим такую реакцию системы:

~$ cat: /dev/video0: Недопустимый аргумент *Где /dev/video0 это файл-устройство найшей видеокамеры.

Для работы с ней нам понадобится системная функция ioctl детальнее о ней можно ознакомится [1]. Попробуем это применить. Вот код позволяющий считать информации с устройства (альтернатива команде cat для видеоустройств):

Код тут

В первых строках кода считываются параметры с которой запущено приложение. Если параметров нету то device_name принимает стандартоне значение "/dev/video0".

В блоке "Open Device" происходит открытие устройства системной функцией open (нужно подключить header fcntl.h). Обязательный параметр O_RDWR отвечает за открытие устройства считывания/записи. Если при подключении возникла ошибка, то функция open вернет -1.

Блок "Read Params From Device" - это сердце нашей маленькой программы. Для его использования надо подключить билиотеку <linux/videodev2.h>возможно прийдется её установить, у каждого дистрибутива свой пакет под эту библиотеку
Системная функция ioctl имеет три параметра:
file_device - дескриптор нашего устройства
VIDIOC_QUERYCAP - функция ядра, которую применяем для нашего устройства.
device_params - область памяти куда будет сброшен результат функции "VIDIOC_QUERYCAP".

device_params это структура состоящая из таких полей:

struct v4l2_capability {   __u8  driver[16]; // имя модуля драйвера - который обслуживает видеоустройство   __u8  card[32]; // имя видеоустройства   __u8  bus_info[32]; // шина к которой подключена камера (в нашем случае usb-порт)   __u32 version; // версия ядра системы   __u32 capabilities; // свойства(возможности/функции) физического устройства   __u32 device_caps; // функции доступные этому устройству   __u32 reserved[3]; // резервное поле };
если возникла ошибка ioctl вернет -1

Блок "Close Device" закрывает дескриптор устройства.

Посмотрим программу в действии.

скомпилируем
gcc catvd.c -o catdv

запустим
./catvd /dev/video0 /dev/video0 error 2, No such file or directory
устройство не определилось ядром либо не подключено уборщица опять ненужные провода дергала.
Подключаем и заново запуск. Получаем такую информацию:
./catvd /dev/video0 driver : uvcvideo card : UVC Camera (046d:0804) bus_info : usb-0000:00:12.2-3 version : 3.11.10 capabilities: 0x84000001 device capabilities: 0x04000001

поле capabilities и device capabilities можно расшифровать благодаря константам из файла videodev2.h:

V4L2_CAP_DEVICE_CAPS 0x80000000 // устроство содержит поля для изменения параметров. V4L2_CAP_STREAMING 0x04000000 // это потоковое устройство i/o ioctls. V4L2_CAP_VIDEO_CAPTURE 0x00000001 // устроство имеет функцию видеозахвата.

На этом вводная статья заканчивается. В следующих обзорах будут затронуты, такие темы как memory-mapping, виодеформаты изображения, настройка камеры, вывод изображения в текстуру, работа с несколькими камерами.

Ресурсы используемые в статье:

  1. статья о работе ioctl
  2. о работе с video for linux (слегка устаревшая информация)

Страница сайта http://185.71.96.61
Оригинал находится по адресу http://185.71.96.61/home.asp?artId=35912