Наши партнеры

UnixForum





Библиотека сайта 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 г.
Перевод: А.Панин
Дата перевода: 25 июля 2014 г.

Глава 2. Базовые сведения

В данной главе руководства описываются базовые концепции фреймворка GStreamer. Понимание этих концепций поможет вам преодолеть проблемы, возникающие в ходе расширения возможностей фреймворка GStreamer. Многие из них описаны более подробно в Руководстве разработчика приложений на основе фреймворка GStreamer ("GStreamer application development manual"); присутствующие же в данной главе краткие описания предназначены главным образом для освежения вашей памяти.

2.1. Элементы и плагины

Элементы являются основными примитивами фреймворка GStreamer. В контексте разработки плагинов элемент (element) является объектом на основе класса, унаследованного от класса GstElement. Элементы выполняют какие-либо функции в том случае, если они связаны с другими элементами: например, элемент для ввода данных предоставляет поток данных, а элемент фильтра обрабатывает данные из этого потока. Без элементов фреймворк GStreamer в функциональном плане является всего лишь программным каналом, в рамках которого невозможно установить связь. Большое количество готовых элементов поставляется вместе с фреймворком GStreamer, при этом дополнительные элементы также могут беспрепятственно разрабатываться.

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

Фильтр (filter) является важным типом элемента, обрабатывающим поток данных. Производители и потребители данных называются элементами для ввода (source) и вывода (sink) данных соответственно. Элементы контейнеров (bin) содержат другие элементы. Элемент контейнера одного типа отвечает за синхронизацию работы содержащихся в нем элементов, поэтому через него данные передаются с необходимой интенсивностью. Элемент контейнера другого типа, называемый элементом для автоматической подгрузки плагинов (autoplugger), автоматически добавляет другие элементы в контейнер и связывает их друг с другом для того, чтобы они работали в качестве фильтра между двумя мультимедийными потоками произвольных типов.

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

Обратитесь к Справочной документации библиотеки фреймворка GStreamer ("GStreamer Library Reference") для ознакомления с подробностями текущих реализаций классов GstElement и GstPlugin.

2.2. Точки соединения

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

В данном случае будет полезной аналогия. Точка соединения аналогична разъему или штекеру физического устройства. Рассмотрим, например, систему домашнего кинотеатра, состоящую из усилителя, проигрывателя DVD и видеопроектора (без вывода звука). Соединение проигрывателя DVD и усилителя возможно, так как оба устройства имеют разъемы для кабеля, предназначенного для передачи звука и соединение проектора с проигрывателем DVD также возможно, так как оба устройства имеют совместимые разъемы для кабеля, предназначенного для передачи видео. Соединение проектора и усилителя не может быть осуществлено из-за того, что проектор и усилитель имеют различные типы разъемов. Точки соединения в рамках фреймворка GStreamer служат для той же цели, что и разъемы в системе домашнего кинотеатра.

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

Обратитесь к Справочной документации библиотеки фреймворка GStreamer ("GStreamer Library Reference") для ознакомления с подробностями текущей реализации класса GstPad.

2.3. Структура GstMiniObject, буферы данных и события

Все потоки данных в рамках фреймворка GStreamer разделяются на фрагменты, которые передаются от выходной точки соединения одного элемента на входную точку соединения другого элемента. Структура GstMiniObject предназначена для хранения этих фрагментов данных.

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

Для осуществления передачи данных объявлено два типа структур GstMiniObject: события (для управления процессом передачи данных) и буферы данных (для передачи данных).

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

Буферы данных также содержат метаданные, описывающие их содержимое. Некоторыми наиболее важными типами метаданных являются:
  • Указатели на один и более объектов типа GstMemory. Объекты типа GstMemory являются объектами с подсчетом ссылок, инкапсулирующими фрагменты памяти.
  • Метка времени, указывающая предпочтительное время вывода содержимого буфера данных.

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

События могут содержать некоторые из следующих данных:
  • Идентификатор подтипа, указывающий тип передаваемого события.
  • Другие связанные с событием данные, зависящие от определенного типа события.

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

Обратитесь к Справочной документации библиотеки фреймворка GStreamer ("GStreamer Library Reference") для ознакомления с подробностями текущих реализаций структуры GstMiniObject и объектов GstBuffer и GstEvent.

2.3.1. Резервирование буферов данных

Буферы данных могут хранить фрагменты памяти нескольких различных типов. Наиболее часто использующийся тип буфера данных содержит фрагмент памяти, зарезервированный с помощью функции malloc(). Такие буферы данных, хотя и являются удобными, не всегда достаточно быстры, так как данные должны определенным образом копироваться в буфер.

Многие специализированные элементы создают буферы данных, которые являются указателями на специальные области памяти. Например, элемент filesrc обычно отображает файл в адресное пространство приложения (с помощью функции mmap()) и создает буферы данных, которые являются указателями из полученного в результате диапазона адресов. Эти созданные средствами элемента filesrc буферы данных работают точно таким же образом, как обычные буферы данных, за исключением того, что они предназначены только для чтения. Код освобождения памяти автоматически устанавливает корректный метод освобождения используемой буфером данных памяти. Расположенные по направлению конвейера элементы, которые получают буферы данных таких типов, не должны предпринимать каких-либо специальных действий для их обработки или удаления ссылок на них.

Другим способом получения специализированных буферов данных элементом является запрос их доставки от расположенного по направлению конвейера элемента с использованием объектов пула буферов данных и резервирования фрагментов памяти типов GstBufferPoll и GstAllocator. Элементы могут запрашивать передачу объектов пула буферов данных и резервирования фрагментов памяти типов GstBufferPool или GstAllocator от расположенного по направлению конвейера элемента. В том случае, если расположенный по направлению конвейера элемент имеет возможность предоставления описанных объектов, предыдущий элемент сможет использовать их для резервирования буферов данных. Более подробно данный механизм описан в главе под названием "Резервирование фрагментов памяти".

Многие элементы для вывода данных используют технологии ускорения для копирования данных в буферы аппаратных устройств или имеют прямой доступ к аппаратным устройствам. Обычно эти элементы имеют возможность создавать объекты пула буферов данных и резервирования фрагментов памяти типов GstBufferPool или GstAllocator для находящихся против направления конвейера элементов. Одним из примеров таких элементов является элемент ximagesink. Он создает буферы данных, которые содержат структуры изображений оконной системы X типа Ximage. Таким образом, в том случае, если находящийся против направления конвейера элемент копирует данные в буфер, он копирует их непосредственно в структуру XImage, позволяя элементу ximagesink выводить изображение непосредственно на экран вместо предварительного копирования данных в структуру XImage.

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

2.4. Типы и свойства мультимедийных потоков

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

2.4.1. Базовые типы мультимедийных данных

Фреймворк GStreamer уже поддерживает множество базовых типов мультимедийных данных. Ниже приведена таблица с описанием нескольких базовых типов мультимедийных данных, используемых при работе с буферами данных в рамках фреймворка GStreamer. Таблица содержит название типа мультимедийных данных (в столбце "тип мультимедийных данных") и описание типа мультимедийных данных вместе с описанием свойств, ассоциированных с этим типом, а также комментариями относительно назначения каждого из свойств. Полный список поддерживаемых типов мультимедийных данных приведен в разделе под названием "Список объявленных типов мультимедийных данных".

Таблица 2.1. Таблица с примерами типов мультимедийных данных

Тип мультимедийных данных Описание Свойство Тип значения свойства Значения свойства Описание свойства
audio/* Все типы аудиопотоков. rate целочисленное (integer) больше 0 Частота дискретизации потока аудиоданных в сэмплах (на канал) в секунду.
channels целочисленное (integer) Больше 0 Число каналов потока аудиоданных.
audio/x-raw Неструктурированные и несжатые аудиоданные. format строковое (string) S8 U8 S16LE S16BE U16LE U16BE S24_32LE S24_32BE U24_32LE U24_32BE S32LE S32BE U32LE U32BE S24LE S24BE U24LE U24BE S20LE S20BE U20LE U20BE S18LE S18BE U18LE U18BE F32LE F32BE F64LE F64BE Формат данных сэмплов.
audio/mpeg Аудиоданные, сжатые с использованием схемы кодирования MPEG. mpegversion целочисленное (integer) 1, 2 или 4 Версия схемы MPEG, используемой для кодирования данных. Значение 1 соответствует MPEG-1, -2 и -2.5 layer 1, 2 или 3. Значения 2 и 4 соответствуют схемам кодирования аудиоданных MPEG-AAC.
framed логическое (boolean) 0 или 1 Значение true указывает на то, что каждый буфер содержит именно один фрейм. Значение false указывает на то, что фреймы и буферы не обязательно совпадают.
layer целочисленное (integer) 1, 2 или 3 Уровень схемы компрессии, используемый для сжатия данных (только в том случае, если mpegversion=1).
bitrate целочисленное (integer) больше 0 Скорость потока в битах в секунду. Для потоков данных формата MPEG с непостоянной скоростью (VBR) это средняя скорость потока.
audio/x-vorbis Аудиопотоки, сжатые с помощью кодека Vorbis.       На данный момент для этого типа потока данных не объявлено и не требуется специфичных свойств.

Следующий раздел : Создание шаблона плагина.