Рейтинг@Mail.ru

Наши друзья и партнеры

UnixForum
купить дешевый 
компьютер родом из Dhgate.com




Библиотека сайта rus-linux.net

Фреймворк GStreamer. Руководство разработчика плагинов. Создание шаблона плагина

Оригинал: GStreamer Plugin Writer's Guide
Авторы: Richard John Boulton, Erik Walthinsen, Steve Baker, Leif Johnson, Ronald S. Bultje, Stefan Kost, Tim-Philipp Muller, Wim Taymans
Дата публикации: 19 июля 2014 г.
Перевод: А.Панин
Дата перевода: 26 июля 2014 г.

Часть II. Создание плагина

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

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

Код примеров из данной части руководства размещен в поддиректории examples/pwg/examplefilter/ вашей директории с исходным кодом фреймворка GStreamer.

Глава 3. Создание шаблона плагина

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

3.1. Получение шаблонов кода плагинов фреймворка GStreamer

На данный момент существует два способа разработки нового плагина для фреймворка GStreamer: вы можете разработать весь код плагина вручную или же скопировать шаблон кода плагина и разработать только тот код, который вам необходим. Второй метод является наиболее простым, поэтому первый метод даже не будет описываться. (Если говорить точнее, то этот метод разработки плагина может использоваться читателем в качестве упражнения).

Первый шаг заключается в создании копии модуля git под названием gst-template с целью получения важного инструмента и шаблона исходного кода для простейшего плагина фреймворка GStreamer. Для копирования модуля gst-template вначале следует убедиться в том, что вы установили подключение к сети Интернет, после чего выполнить следующую команду в консоли:
shell $ git clone git://anongit.freedesktop.org/gstreamer/gst-template.git
Initialized empty Git repository in /some/path/gst-template/.git/
remote: Counting objects: 373, done.
remote: Compressing objects: 100% (114/114), done.
remote: Total 373 (delta 240), reused 373 (delta 240)
Receiving objects: 100% (373/373), 75.16 KiB | 78 KiB/s, done.
Resolving deltas: 100% (240/240), done.

Данная команда позволит скопировать наборы файлов и директорий в директорию gst-template. Шаблон исходного кода плагина, который вы будете использовать, находится в директории gst-template/gst-plugin/. Вам следует рассмотреть файлы в данной директории для того, чтобы получить общее представление о структуре дерева исходного кода плагина.

Если по каким-то причинам вы не можете получить доступ к репозиторию git, вы также можете загрузить снимок репозитория последней ревизии с помощью веб-интерфейса cgit.

3.2. Ввод идентификационных данных плагина

Первое действие, которое необходимо выполнить при создании нового элемента, заключается в указании некоторых базовых сведений о нем: его названия, автора, номера версии, и.т.д. Нам также придется объявить объект для представления элемента и хранения данных, которые требуются элементу. Набор этих сведений называется "шаблоном плагина" (boilerplate).

Стандартный способ создания шаблона плагина заключается в простом написании кода и заполнении полей некоторых структур. Как говорилось в предыдущей главе, простейший способ выполнения этой задачи заключается в копировании шаблона кода плагина и добавлении функций в соответствии с вашими потребностями. При этом в директории ./gst-plugins/tools/ находится специальный инструмент, облегчающий выполнение описанной задачи. Этот инструмент, make_element является утилитой с интерфейсом командной строки, которая создает шаблон кода плагина для вас.

Для того, чтобы использовать утилиту make_element, следует в первую очередь открыть окно терминала. После этого нужно изменить текущую директорию на директорию gst-template/gst-plugin/src и выполнить команду make_element. Аргументами утилиты make_element являются:
  1. название плагина и
  2. имя файла исходного кода, который утилита будет использовать. По умолчанию используется имя файла gstplugin.
Например, следующие команды позволяют создать плагин под названием MyFilter на основе шаблона кода плагина и разместить выходные файлы в директории gst-templates/gst-plugin/src:
shell $ cd gst-template/gst-plugin/src
shell $ ../tools/make_element MyFilter
Примечание
Регистр символов важен при написании названия плагина. Помните о том, что в некоторых операционных системах регистр символов также в общем случае важен при задании имен директорий и файлов.

Последняя команда создает два файла: gstmyfilter.c и gstmyfilter.h.

Примечание
Рекомендуется создать копию директории gst-plugin перед продолжением работы.

Теперь остается только скорректировать файл Makefile.am для использования новых имен файлов и запустить сценарий autogen.sh из родительской директории для создания окружения сборки. После этого сборка и установка проекта могут осуществляться с использованием широко известных команд make && sudo make install.

Примечание
Будьте готовы к тому, что стандартные сценарии autogen.sh и configure будут выбирать директорию /usr/local в качестве стандартной директории для установки. Вам придется добавить путь к директории /usr/local/lib/gstreamer-1.0 в качестве параметра переменной окружения GST_PLUGIN_PATH для того, чтобы новый плагин был доступен для библиотек фреймворка gstreamer, установленных из пакетов.
Примечание
Информация, изложенная в данной главе, незначительно устарела. Утилита gst-template все еще может использоваться в качестве генератора минимальной структуры директорий окружения сборки плагина. Однако, на сегодняшний день для создания элементов рекомендуется использовать инструмент gst-element-maker из пакета gst-plugins-bad.

3.3. Рассмотрение основного кода плагина

Для начала мы рассмотрим код, который вы наверняка будете размещать в заголовочном файле (хотя ввиду того, что интерфейс для работы с кодом плагинов в полном объеме объявлен на уровне системы плагинов, причем ее работа не зависит от чтения заголовочного файла плагина, этот файл не является необходимым.). Приведенный код может быть обнаружен в файле examples/pwg/examplefilter/boiler/gstexamplefilter.h.

Пример 3.1. Заголовочный файл демонстрационного плагина

В случае использования данного заголовочного файла, вы сможете использовать приведенный ниже макрос для регистрации объекта объектной модели GObject в вашем файле исходного кода с целью последующего корректного использования функций этого объекта:
#include "filter.h"

G_DEFINE_TYPE (GstMyFilter, gst_my_filter, GST_TYPE_ELEMENT);

3.4. Метаданные элемента

Метаданные элемента предоставляют дополнительную информацию об элементе. Они могут быть заданы с помощью функции gst_element_class_set_metadata или функции gst_element_class_set_static_metadata, принимающей следующие параметры:
  • Полное название элемента на английском языке.
  • Тип элемента; обратитесь к документу, расположенному в директории docs/design/draft-klass.txt исходного кода ядра фреймворка GStreamer для получения дополнительной информации и ознакомления с примерами типов элементов.
  • Краткое описание назначения элемента.
  • Имя автора элемента с необязательным адресом электронной почты для связи, помещенным в угловые скобки.
Например:
gst_element_class_set_static_metadata (klass,
  "An example plugin",
  "Example/FirstExample",
  "Shows the basic structure of a plugin",
  "your name <your.name@your.isp>");

Параметры элемента регистрируются вместе с плагином в ходе исполнения функции _class_init (), объявленной в рамках объектной модели GObject. Функция _class_init () для объекта плагина на основе класса GObject устанавливается при регистрации типа плагина средствами библиотеки GLib.

3.5. Статический шаблон точки соединения типа GstStaticPadTemplate

Статический шаблон точки соединения типа GstStaticPadTemplate содержит описание точки соединения, которую элемент будет (или может) создавать и использовать. Она содержит:
  • Короткое название точки соединения.
  • Направление точки соединения.
  • Режим работы. Он указывает на то, доступна ли точка соединения постоянно ("постоянно доступная" точка соединения), только в некоторых случаях ("не постоянно доступная" точка соединения) или только в том случае, если приложение запросит создание такой точки соединения ("доступная по запросу" точка соединения).
  • Поддерживаемые элементом типы мультимедийных потоков (возможности).
Например:
static GstStaticPadTemplate sink_factory =
GST_STATIC_PAD_TEMPLATE (
  "sink",
  GST_PAD_SINK,
  GST_PAD_ALWAYS,
  GST_STATIC_CAPS ("ANY")
);

Описанные шаблоны точек соединения регистрируются в процессе исполнения функции инициализации класса элемента _class_init () с помощью функции gst_element_class_add_pad_template (). Для использования этой функции вам потребуется указатель на шаблон точки соединения типа GstPadTemplate, который вы можете создать на основе статического шаблона точки соединения, воспользовавшись функцией gst_static_pad_template_get (). Подробнее об этом будет сказано ниже.

Точки соединения создаются на основе статических шаблонов в рамках функции инициализации элемента _init () с помощью функции gst_pad_new_from_static_template (). Для создания новой точки соединения на основе упомянутого шаблона точки соединения с помощью функции gst_pad_new_from_static_template () вам придется объявить шаблон точки соединения в качестве глобальной переменной. Более подробно эта тема раскрывается в Главе 4, "Объявление точек соединения".

Последним аргументом шаблона является идентификатор поддерживаемого типа мультимедийного потока или список идентификаторов поддерживаемых типов мультимедийных потоков. В данном примере мы используем идентификатор 'ANY', который позволяет элементу обрабатывать все входные потоки данных. При разработке реального плагина вы можете установить тип мультимедийного потока и необязательный набор свойств для уверенности в том, что будут обрабатываться исключительно входные потоки поддерживаемых типов. Этот аргумент должен быть представлен строкой, которая начинается с идентификатора типа мультимедийного потока с набором разделенных запятыми свойств с поддерживаемыми значениями. В случае разработки аудиофильтра, который поддерживает декодированные целочисленные одно- и двухканальные 16-битные аудиопотоки с любой частотой дискретизации, корректный шаблон будет выглядеть следующим образом:
static GstStaticPadTemplate sink_factory =
GST_STATIC_PAD_TEMPLATE (
  "sink",
  GST_PAD_SINK,
  GST_PAD_ALWAYS,
  GST_STATIC_CAPS (
    "audio/x-raw, "
      "format = (string) " GST_AUDIO_NE (S16) ", "
      "channels = (int) { 1, 2 }, "
      "rate = (int) [ 8000, 96000 ]"
  )
);

Значения, помещенные в фигурные скобки ("{" и "}") являются элементами списков, а значения, помещенные в квадратные скобки ("[" и "]") - границами диапазонов. Также может осуществляться обработка нескольких наборов типов мультимедийных данных, которые должны разделяться с помощью точки с запятой (";"). Далее в главе о точках соединения (Глава 4, "Объявление точек соединения") мы познакомимся с методикой использования типов мультимедийных данных для получения информации о текущем формате мультимедийного потока.

3.6. Функции-конструкторы

Каждый элемент имеет две функции, которые используются для создания экземпляра класса, лежащего в основе элемента. Функция _class_init() однократно используется для инициализации класса (для указания того, какие сигналы, аргументы и виртуальные функции имеет класс, а также для установки значений глобальных параметров состояния); функция _init() используется для инициализации определенного экземпляра класса рассматриваемого типа.

3.7. Функция инициализации плагина plugin_init

После того, как мы разработали код, описывающий все аспекты плагина, нам придется реализовать функцию инициализации плагина plugin_init(). Это специальная функция, которая вызывается тогда, когда плагин загружается и должна возвращать логическое значение TRUE или FALSE в зависимости от того, были ли загружены и корректно инициализированы любые из зависимостей плагина. Также в рамках данной функции должны регистрироваться любые поддерживаемые типы элементов плагина.

Учтите, что информация, возвращаемая из функции plugin_init() будет кэшироваться в центральном реестре. По этой причине важно, чтобы эта функция всегда возвращала одну и ту же информацию: например, фабрики элементов не должны делаться доступными в зависимости от условий работы приложения. В том случае, если элемент может функционировать только в определенных условиях (например, только в том случае, если звуковая карта не используется каким-либо другим процессом), его неработоспособность должна быть отражена с помощью невозможности перехода в состояние готовности к работе "READY", а не с помощью попытки сокрытия существования плагина.


Следующий раздел : Объявление точек соединения.

Если вам понравилась статья, поделитесь ею с друзьями: