Linux на борту : Работа с камерой Nokia N800

Создание приложения, работающего с Web-камерой

Три этих выпуска Linux на борту показывают, как начать создавать приложения, на рабочем примере: использовании встроенной камеры для создания Web-камеры. В этом выпуске мы начнем создавать приложение для работы с камерой, используя gstreamer для доступа к камере устройства Nokia N800. (Это не так сложно, как может показаться, особенно учитывая, что мы заимствуем кое-что из уже существующего приложения.)

Питер Сибах, автор, Независимый

Питер Сибах (Peter Seebach) работает с компьютерами много лет и постепенно приспособился. Хотя он до сих пор не понимает, почему мышку надо чистить так часто.



31.01.2008

В первом выпуске этой серии из трёх частей мы показали конфигурацию Linux на Nokia N800 ® , привели технические спецификации и физические характеристики этого устройства, а также объяснили, как установить и настроить среду разработки.

Необходимые условия

Отправной точкой для этого выпуска является приложение для работы с камерой, описанное в учебном пособии на сайте maemo.org. Вместо того чтобы повторять выполненные там действия и приведенные объяснения, я просто дам ссылку на статью maemo и предложу вам ознакомиться с содержащейся в ней информацией самостоятельно: Как использовать Camera API."

Другие статьи developerWorks по разработке для Nokia N770 и N800

Несмотря на то, что приложение камеры на N800 можно запустить без доступа к командному процессору, я считаю крайне полезным загрузить на N800 программу терминала. Я также установил сервер ssh, что позволило мне во время тестирования пользоваться реальной клавиатурой. Небольшое напоминание: Если на N800 (как и на 770 ранее) установить сервер ssh, система предоставит доступ root по ssh (пароль "rootme"). Само собой разумеется, это пароль нужно изменить, но в мире, где люди по-прежнему открывают почтовые вложения, чтобы посмотреть, что они делают, я всё же скажу еще раз: Измените пароль root.

Знакомьтесь: GStreamer

GStreamer - это мультимедийная среда с открытым исходным кодом. —За этой набившей оскомину фразой скрывается связующий программный код для соединения различных медиапотоков (таких как звукч и видео). Само по себе это не очень интересно; важнее то, что в этой утилите реализована поддержка широкого спектра задач. Библиотеки GStreamer устанавливаются на N800 по умолчанию , однако без утилит командной строки. Если у вас есть доступ к командному процессору с правами root, вы можете исправить это, выполнив несколько дополнительных команд (см. врезку Дополнительное программное обеспечение). Просто установите пакет gstreamer-tools из хранилища maemo, и у вас будет доступ к утилитам из командной строки.

Теперь откройте камеру. Если вы этого еще не сделали, отключите опцию запуска приложения видеочата "start when camera opened" (находится в меню Tools).

Самое главное, чем занимается gstreamer – он организует каналы. Gstreamer соединяет потоки подобно тому, как потоки командных процессоров UNIX® собирают небольшие виджеты в полноценное приложение. Хотя я скоро покажу, как использовать библиотеку gstreamer в программе на, существует также инструмент gst-launch, работающий в командной строке; он находится в пакете gstreamer-tools, который можно установить с помощью apt-get - но не с помощью Application Manager, который показывает лишь часть списка доступных пакетов. (Кроме того, необходимо добавить в конфигурацию apt-get несколько хранилищ; см. врезку Дополнительное программное обеспечение.)

Листинг 1. Установка gstreamer-tools
# apt-get install gstreamer-tools
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
  gstreamer0.10-tools
The following NEW packages will be installed:
  gstreamer-tools gstreamer0.10-tools
0 upgraded, 2 newly installed, 0 to remove and 9 not upgraded.
Need to get 41.1kB of archives.
After unpacking 164kB of additional disk space will be used.
Do you want to continue [Y/n]?
WARNING: The following packages cannot be authenticated!
  gstreamer0.10-tools gstreamer-tools
Install these packages without verification [y/N]? y
[...]
Setting up gstreamer0.10-tools (0.10.9-osso11) ...
Setting up gstreamer-tools (0.10.9-osso11) ...

Дополнительное программное обеспечение

На сайте maemo.org имеется хранилище отличных пакетов. Его можно добавить в список источников утилиты apt на N800, изменив файл /etc/apt/sources.list. Предусмотрено несколько различных хранилищ: одно для обычных пакетов maemo и одно для дополнительных утилит (например, сервер ssh dropbear):

  • deb http://repository.maemo.org/ bora free non-free
  • deb http://maemo-hackers.org/apt bora main

Если у вас есть терминальная программа, вы можете добавить их с помощью следующих команд echo:

# echo "deb http://repository.maemo.org/ bora free non-free" >> /etc/apt/sources.list

Другой способ - вы можете зайти в приложение Application Manager и добавить их как новые каталоги приложений в меню Tools > Application catalog. Слово "bora" – это название дистрибутива, а элементы после него ("free" и "non-free" для основного хранилища maemo) - это компоненты.

Утилиты apt-get нельзя использовать при запущенном Application Manager, даже в фоновом режиме. Для целей разработки я считаю полезным установить пакет dropbear-server (с maemo-hackers.org), что позволит мне обращаться к N800 по протоколу ssh. Помните, что пароль "rootme", назначенный по умолчанию, является источником большой опасности, если его не изменить!

Обратите внимание, что эти пакеты не являются "одобренными"—но в данном случае они достаточно безобидны. Вот пример вызова в командной строке:

$ gst-launch v4l2src ! xvimagesink

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

Программа gst-launch - это просто оболочка, которая открывает указанные плагины и соединяет их между собой. (Все виджеты, которые может подключить gstreamer, называются плагинами; плагины вызываются по имени и загружаются динамически в процессе работы программы.) Восклицательный знак используется так же, как символ канала в командах командного процессора. В этом контексте каждый плагин называется элементом.

Чтобы понять, что делает gstreamer, обратите внимание на следующее:

  • src: Источник - это что угодно, что формирует медиа-поток.
  • sink: Приёмник - это что угодно, что принимает медиа-поток.

В нашем случае плагин v4l2src - это источник video4linux2; по умолчанию он ищет первое поддерживаемое видеоустройство, известное ядру, и выводит с него поток видео. Плагин xvimagesink отображает поток видео на графическом дисплее.

Некоторые элементы являются и источниками, и приёмниками. Каждый плагин определяет выводы или соединители; каждый вывод лапка может быть либо источником, либо приёмником. Многие плагины поддерживают оба варианта, преобразуя входной поток в выходной.

Существует ряд специальных элементов. Например, специальный элемент fakesink, который ничего не делает, а просто принимает поток. Зачем это нужно? Потому что элемент, выдающий поток и не соединенный с другим элементом, будет просто ждать, пока какой-либо элемент не примет поток.

Некоторые элементы во время работы могут приобретать дополнительные выводы. Наиболее важный пример - это вывод-тройник, к которому можно подключать несколько приёмников, разделяя поток и создавая несколько его копий. Это может быть полезно в том случае, если вы хотите выполнить над одним потоком две операции, для которых требуются разные несовместимые между собой фильтры.

Разработать приложение Web-камеры с помощью gstreamer можно несколькими способами. Основная идея состоит в том, чтобы соединить видеоисточник с приёмником изображений (например, с экраном) и где-нибудь по пути перехватывать копию изображения и кодировать её в JPEG. По умолчанию поток видео от камеры идет не в формате RGB. Здесь gstreamer вступает в игру в полную силу; автоматическое согласование возможностей позволяет без труда запросить данные в определенном формате или размере, без каких-либо явных преобразований.


Повышение производительности

Давайте кратко рассмотрим имеющийся материал. В качестве отправной точки мы взяли пример программы камеры с сайта maemo (см. раздел Ресурсы ). Эта программа уже готова к работе, хотя иногда работает медленно. Вкратце схема работы выглядит следующим образом: мы берем источник video4linux, фильтруем его в RGB и посылаем одну копию на экран, а вторую - приемнику изображений, который время от времени будет записывать файлы JPEG.

На самом деле преобразование цветового пространства для сохранения файла JPEG -дорогостоящий и ненужный этап. Стандартный элемент xvimagesink отлично выводит кадры в формате камеры YUV.

Первое изменение, которое вы можете попытаться сделать - перенести фильтр цветового пространства на путь, который ведет к преобразованию JPEG. Исходная версия кода подает выход с фильтра в тройник, который раздаёт сигнал приёмнику изображений (который используется для записи файлов JPEG по мере необходимости) и на экран. Для этого необходимо преобразовывать каждый кадр.

Если мы перенесем фильтр цветового пространства на другую сторону тройника, он по-прежнему будет обрабатывать каждый кадр, но теперь это можно изменить. В библиотеке gstreamer есть понятие зондовых функций, которые используются для изменения алгоритма поведения элементов. Зондовые функции вызываются для каждого кадра, пришедшего на заданный вывод. Если зондовая функция возвращает TRUE, кадр передаётся дальше по потоку, но если она возвращает FALSE, кадр отбрасывается. В нашем примере кода при нажатии кнопки пользователем регистрируется специальная зондовая функция save as JPEG (сохранить как JPEG). После этого функция сохраняет кадр и снимает свою регистрацию.

Однако существует и ещё один вариант: зарегистрировать зондовую функцию, которая в нормальном режиме возвращает FALSE, и включать её перед преобразованием цветового пространства. После этого нужно просто сделать так, чтобы функция возвращала TRUE, когда пользователь нажимает на кнопку "сделать снимок". Таким образом, в остальное время в потоке, на котором стоит фильтр цветового пространства, просто не будет данных.

Изменить параметры канала достаточно просто: Добавление зонда на один из выводов тройника. Такой зонд называется буферным—он вызывается только при наличии фактических блоков данных, например, кадров видео. Другая информация не затрагивается.

Вот код для добавления обратного вызова:

Листинг 2. Зондирование потока данных
pad = gst_element_get_static_pad(queue, "src");
if (pad) {
  gst_pad_add_buffer_probe(pad, G_CALLBACK(only_when_saving), appdata);
} else {
  fprintf(stderr, "couldn't get sink.\n");
}

Функция only_when_saving - стандартная зондовая функция обратного вызова. В нашем случае всё особенно просто, поскольку она проверяет всего одно булево значение.

Листинг 3. Остановиться или продолжить?
/* This callback indicates whether or not we want a picture */
static gboolean only_when_saving(
		GstElement *element,
		GstBuffer *buffer, AppData *appdata)
{
	if (appdata->save_next_frame) {
		appdata->save_next_frame = FALSE;
		return TRUE;
	} else {
		return FALSE;
	}
}

Если было установлено значение save_next_frame, функция очищает его, но возвращает TRUE, пропуская кадр дальше по каналу. В противном случае функция возвращает FALSE, и кадр отбрасывается.

Это должно значительно повысить производительность, но я всё ещё чувствую, что моя система запинается. В исходном примере для обоих потоков использовались объекты очереди. Удаление очереди из экранного потока исключает запинки, кроме случаев сохранения изображений. Ощущаемая производительность очереди на другом потоке сильно повышается, так как преобразование JPEG выносится в поток, отделенный от основного вывода на экран. Это также позволяет исключить сложный код регистрации и снятия регистрации из зондовой функции save-as-JPEG и функции обработки нажатия кнопки, заместив его простой записью в булеву переменную save_next_frame. (В этом случае мне не нужно беспокоиться о возможной взаимной блокировке.)


Сохранение файлов JPEG

Изначально я использовал плагин gstreamer jpegenc. Этот плагин делает точно то, что обещает - преобразует кадры изображения в JPEG. К сожалению, в базовом дистрибутиве N800 его нет. Хуже того, пакет, в котором он должен быть, (дистрибутив plugins-good для gstreamer) распространяется на N800 в усеченном виде.

Для целей тестирования можно воспользоваться простым ручным обходным приемом: загрузите плагин в scratchbox, настройте и соберите его, после чего скопируйте общую библиотеку плагина на N800. Тем не менее это достаточно трудоемко. Программа example_camera поставляется с библиотекой gdk_pixbuf, которую значительно проще устанавливать (она уже установлена).

Однако библиотека gdk_pixbuf обладает чрезмерно широкими функциями, а мне всегда нравилась стандартная библиотека libjpeg, также входящая в дистрибутив N800. Есть серьезный аргумент в пользу выбора этой библиотеки; он станет ясен в следующей статье. Сейчас я просто покажу несложный пример кода, используемого для сжатия файла с помощью libjpeg:

Листинг 4. Создание файла JPEG
/* Creates a jpeg file from the buffer's raw image data */
static gboolean create_jpeg(unsigned char *data)
{
             FILE *out;
             struct jpeg_compress_struct comp;
             struct jpeg_error_mgr error;

             out = fopen("test.jpg", "wb");

             comp.err = jpeg_std_error(&error);
             jpeg_create_compress(&comp);
             jpeg_stdio_dest(&comp, out);
             comp.image_width = 640;
             comp.image_height = 480;
             comp.input_components = 3;
             comp.in_color_space = JCS_RGB;
             jpeg_set_defaults(&comp);
             jpeg_set_quality(&comp, 90, TRUE);
             jpeg_start_compress(&comp, TRUE);
             for (int i = 0; i < 480; ++i) {
                         jpeg_write_scanlines(&comp, &data, 1);
                         data += (640 * 3);
             }
             jpeg_finish_compress(&comp);
             fflush(out);
             fclose(out);
             jpeg_destroy_compress(&comp);

             return TRUE;
}

Вот и всё - наш файл сохранен как test.jpg.


Следующий шаг

Теперь приложение для работы с камерой делает то, что оно должно делать —захватывает одиночные кадры видеопотока и преобразует их в популярный формат—. Следующим шагом будет его интеграция с оставшейся частью системы и загрузка файлов. В третьем и последнем выпуске этой серии по N800 я покажу вам, как это сделать.

Ресурсы

Научиться

Получить продукты и технологии

  • GStreamer - это библиотека, которая позволяет строить схемы компонентов обработки мультимедиа, от простого проигрывания Ogg/Vorbis до сложной обработки звука (микширование) и видео (нелинейное редактирование).(EN)
  • Используйте в своем следующем проекте разработки для Linux ознакомительные версии программного обеспечения IBM, которые можно скачать непосредственно с developerWorks. (EN)

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


  • Bluemix

    Узнайте больше информации о платформе IBM Bluemix, создавайте приложения, используя готовые решения!

  • developerWorks Premium

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

  • Библиотека документов

    Более трех тысяч статей, обзоров, руководств и других полезных материалов.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Мобильные приложения, Linux
ArticleID=285110
ArticleTitle=Linux на борту : Работа с камерой Nokia N800
publish-date=01312008