IT News: Digital Camera, OS, Laptop, Smartphone, Smart TV, Sound...

The Author's Project by Valeri N.Kravchuk
Сайт проверен Dr.Web
Меню сайта
  • Главная страница
  • Информация о сайте
  • Дневник
  • Каталог файлов
  • Обратная связь
  • Каталог сайтов
  • FAQ
  • Доска объявлений
  • Форум
  • Фотоальбом
  • Категории раздела
    Автомобильные гаджеты, ремонт... [220]
    Безопасность IT [484]
    Блоки питания, Power Banks, зарядки... [490]
    Видеорегистраторы [220]
    Гаджеты для спорта и здоровья... [190]
    Гаджеты, аксессуары... [625]
    Измерительная техника, инструменты [449]
    Накопители данных [226]
    Нетбуки, Ноутбуки, Ультрабуки [680]
    Мультиварки, блендеры и не только... [158]
    Планшеты [758]
    Радар-детекторы [26]
    Роботы-пылесосы [37]
    Своими руками [357]
    Сети, сетевые технологии, оборудование... [269]
    Смартфоны [4966]
    Фотокамеры, объективы, искусство фотографии.. [543]
    Умный дом [47]
    Электронные книги [96]
    CB, LPD, PMR- связь... [171]
    DECT, IP-телефоны [18]
    Drones, boats, cars... [108]
    electric cars [35]
    GPS-навигаторы, трекеры... [51]
    Linux и не только [4380]
    mini computers и не только... [409]
    News IT, Это интересно, ликбез... [1113]
    Smart TV, UltraHD, приставки, проекторы... [414]
    Smart Watch [263]
    Sound: наушники, плееры, усилители... [616]
    Windows 10... [298]
    Windows 11 [28]
    Погода

  • Метеорадар БРЕСТ
  • Погода в Бресте от www.yr.no

    Яндекс.Погода БРЕСТ

  • Интересные ссылки

    COMPIZOMANIA

    Наш опрос
    Оцените мой сайт
    Всего ответов: 1340
    Статистика
    Анализ веб сайтов

    Яндекс.Метрика

    Рейтинг@Mail.ru Яндекс цитирования

    Russian America Top. Рейтинг ресурсов Русской Америки.

    eXTReMe Tracker

    Правильный CSS!


    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0
    Locations of visitors to this page
    Форма входа
    Главная » 2014 » Февраль » 14 » Работа с usb видеокамерой в Linux. Часть 2
    21:14
    Работа с usb видеокамерой в Linux. Часть 2

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

       Привествую, Хабр!

       Продолжаем цикл статей про программирование видеокамеры в Linux. В первой части [1], мы рассмотрели механизм открытия и считывания первичных параметров видеоустройства. Была написана простенькая утилита catvd. Сегодня расширим функционал нашей маленькой программы, но сначала надо написать обертку для функции ioctl.
    Код метода xioctl
    int videodevice::xioctl(int fd, int request, void *arg)
    {
     int r;
    
     r = ioctl (fd, request, arg);
    
     if(r == -1)
     {
     if (errno == EAGAIN)
     return EAGAIN;
    
     stringstream ss;
    
     ss << "ioctl code " << request << " ";
    
     errno_exit(ss.str());
     }
    
     return r;
    }
    


    Эта обертка позволяет прервать программу если была ошибка и показать сообщение.

      Попробуем считать картинку с камеры и сохранить в файл.
    Код метода getFrame
    void videodevice::getFrame(string file_name)
    {
     initMMAP();
    
     startCapturing();
    
     long int i = 0;
    
     for (;;)
     {
     if(readFrame(file_name))
     break;
    
     i++;
     }
    
     cout << "iter == " << i << endl;
    
     stopCapturing();
    
     freeMMAP();
    }
    


    метод readFrame — отвечает за чтение и обработку полученого изображения.
    методы initMMAP(), freeMMAP() — создание/очистка буфера памяти устройства.
    методы startCapturing(), stopCapturing() — включение/выключение режима streaming у видеоустройства. Наличие этих функций, у камеры, можно проверить флагом V4L2_CAP_STREAMING [*].

      Разберем метод initMMAP
    Код метода initMMAP
    void videodevice::initMMAP()
    {
     struct v4l2_requestbuffers req;
    
     req.count = 1;
     req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     req.memory = V4L2_MEMORY_MMAP;
    
     xioctl(fd, VIDIOC_REQBUFS, &req);
    
     devbuffer = (buffer*) calloc(req.count, sizeof(*devbuffer));
    
     struct v4l2_buffer buf;
    
     memset(&buf, 0, sizeof(buf));
    
     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     buf.memory = V4L2_MEMORY_MMAP;
     buf.index = 0;
    
     xioctl(fd, VIDIOC_QUERYBUF, &buf);
    
     devbuffer->length = buf.length;
     devbuffer->start =
     mmap(NULL,
     buf.length,
     PROT_READ | PROT_WRITE,
     MAP_SHARED,
     fd,
     buf.m.offset);
    
     if (devbuffer->start == MAP_FAILED)
     errno_exit("mmap");
    }
    


    функция VIDIOC_REQBUFS [↓] позволяет проинициализировать буфер памяти внутри устройства. Структура v4l2_requestbuffers задает параметры инициализации
    struct v4l2_requestbuffers {
     __u32 count; //количество буферов
     __u32 type; //тип или цель использования
     __u32 memory; //режим работы с памятью.
     __u32 reserved[2]; //всегда в ноль
    };
    

      После того, как буфер был проинициализирован, его надо отобразить на область памяти (mapping).
    Функция VIDIOC_QUERYBUF [↓] позволяет считать параметры буфера, которые будут использоваться для создания memory-mapping области. Структура v4l2_buffer большая, опишу необходимые поля:
    struct v4l2_buffer {
    //до выполнения VIDIOC_QUERYBUF устанавливаем следующие поля
    __u32 index; // ноль или номер буфера (если v4l2_requestbuffers.cout > 1)
    __u32 type; // тип (совпадает со значением v4l2_requestbuffers.type)
    
    
    //после выполнения VIDIOC_QUERYBUF используем эти поля в качестве параметров для memory-mapping
    union {
    __u32 offset; // смещение буфера относительно начала памяти устройства
     } m;
    __u32 length; // размер буфера
    };
    

    системная функция mmap() [3] позволяет отображать файл или область памяти устройств в оперативную память. Для использования mmap() необходимо подключить
    <sys/mman.h>
    

      Далее необходимо переключить камеру в режим захвата.
    Код метода startCapturing
    void videodevice::startCapturing()
    {
     struct v4l2_buffer buf;
    
     memset(&buf, 0, sizeof(buf));
    
     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     buf.memory = V4L2_MEMORY_MMAP;
     buf.index = 0;
    
     xioctl(fd, VIDIOC_QBUF, &buf);
    
     enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    
     xioctl(fd, VIDIOC_STREAMON, &type);
    }
    


    Функция VIDIOC_QBUF [↓] ставит буфер в очередь обработки драйвером устройства. Поля используются такие же, как и для VIDIOC_REQBUFS или VIDIOC_QUERYBUF.
    Функция VIDIOC_STREAMON[↓] включает камеру в режим захвата.

      Теперь камера включена и захватывает изображения. Но картинку еще надо получить.
    Код метода readFrame
    int videodevice::readFrame(string file_name)
    {
     struct v4l2_buffer buf;
    
     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     buf.memory = V4L2_MEMORY_MMAP;
    
     if (xioctl(fd, VIDIOC_DQBUF, &buf) == EAGAIN)
     return 0;
    
     buffer *temp = devbuffer;
    
     FILE *out_file = fopen(file_name.c_str(),"w");
    
     fwrite(temp->start,temp->length,1,out_file);
    
     fclose(out_file);
    
     return 1;
    }
    


    Функция VIDIOC_DQBUF[↓] освобождает буфер из очереди обработки драйвера. В результате можем получить ошибку EAGAIN. Ничего опасного в этом нет, надо еще раз вызвать VIDIOC_DQBUF. Это происходит потому, что драйвер еще обрабатывает запрос и не может освободить буфер из очереди. При успешном выполнении этой функции, мы получаем в «руки» нашу картинку. В самом начале статьи, в коде был добавлен итератор. Итератор позволяет проследить сколько итераций вхолостую проходит цикл до успешного выполнения VIDIOC_DQBUF.

    Компиляция
    $ cmake .
    $ make
    


    Вывод программы следующий
    $./getimage
    Open device /dev/video0
    Init mmap
    Start capturing
    read frame from buffer and write to file
    iter == 831013
    stop Capturing
    free mmap
    Close device /dev/video0
    

    Из «iter == 831013» видно — картинка скидывается в буфер довольно долго. Для ускорения можно использовать несколько буферов и вытаскивать картинку с первого свободного и т.д.

      Сегодня была рассмотрена инициализация буфера памяти и чтения из него картинки. Изображение сохраняется в raw формате. Можно открыть программой Shotwell. В следующей статье будет рассмотрен вывод изображению в текстуру (через SDL2), затронуты некоторые форматы изображения и настройки камеры.

    Ресурсы используемые в статье:
    1. Работа с usb видеокамерой в Linux. Часть 1
    2. video for Linux API
    3. подробнее про mmap()

    Ссылки на используемые функции:

    Исходный код

    http://habrahabr.ru/post/212531/
    Категория: Linux и не только | Просмотров: 670 | Добавил: laptop | Рейтинг: 0.0/0
    Всего комментариев: 0
    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]
    Волк слабее льва и тигра, но в цирке волк не выступает!
    Волк слабее льва и тигра, но в цирке волк не выступает!
    Волк - единственный из зверей, который может пойти в бой на более сильного противника.
    Если же он проиграл бой, то до последнего вздоха смотрит в глаза противника. После этого умирает...

    Праздники сегодня

    Поиск
    Календарь
    Архив записей
    Друзья сайта
  • Официальный блог
  • JEEP - the best! Mercedes - the best! Автомобильный портал города Бреста: технические характеристики с фото, авторынок, автоспорт...
    Наша кнопка
    IT новости с моего лаптопа...

    Внимание!
    Администратор сайта laptop.ucoz.ru не несет ответственности за содержание рекламных объявлений. Все используемые на сайте зарегистрированные товарные знаки принадлежат своим законным владельцам! Используемая со сторонних источников информация публикуется с обязательными ссылками на эти источники.
    Copyright Valeri N.Kravchuk © 2007-2024