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

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

Глава 8. Обзор состояний

Состояние описывает, был ли элемент инициализирован, готов ли он к передаче данных и обрабатывает ли он данные в текущий момент. Существует четыре состояния, объявленных в рамках фреймворка GStreamer:
  • GST_STATE_NULL
  • GST_STATE_READY
  • GST_STATE_PAUSED
  • GST_STATE_PLAYING

для обозначения которых с данного момента мы будем просто использовать строки "отключен" ("NULL"), "готов к работе" ("READY"), "пауза" ("PAUSED") и "воспроизведение" ("PLAYING").

Состояние "отключен" (GST_STATE_NULL) является стандартным состоянием элемента. В этом состоянии элемент не резервирует никаких необходимых для своей работы ресурсов, не загружает никаких разделяемых библиотек и, что очевидно, не обрабатывает данных.

Состояние "готов к работе" (GST_STATE_READY) является следующим состоянием, в котором может находиться элемент. В состоянии готовности к работе (READY) элемент получает доступ ко всем стандартным ресурсам (разделяемым библиотекам, рабочим фрагментам памяти). Однако, он еще не резервирует память для хранения данных или не устанавливает значения каких-либо относящихся к мультимедийному потоку переменных. При переходе из отключенного состояния (NULL) в состояние готовности (READY) (GST_STATE_CHANGE_NULL_TO_READY) элемент должен зарезервировать любые не относящиеся к мультимедийному потоку ресурсы и загрузить динамически загружаемые библиотеки (в том случае, если они используются). При обратном переходе между состояниями (от состояния готовности (READY) к отключенному состоянию (NULL), GST_STATE_CHANGE_READY_TO_NULL), элемент должен выгрузить эти разделяемые библиотеки и освободить все зарезервированные ресурсы. Примерами таких ресурсов являются ресурсы аппаратных устройств. Учтите, что файлы в общем случае представлены потоками данных и, следовательно, эти потоки данных из файлов должны рассматриваться как ресурсы, связанные с основным потоком данных; таким образом, они не должны резервироваться в данном состоянии.

Состояние "пауза" (GST_STATE_PAUSED) является состоянием, в котором элемент готов к приему и обработке данных. Для большинства элементов это состояние не отличается от состояния "воспроизведение" (PLAYING). Единственным исключением из этого правила являются элементы для вывода данных. Элементы для вывода данных в данном состоянии принимают лишь один буфер данных, после чего их работа блокируется. В этот момент конвейер находится 'в подготовленном состоянии' и готов к немедленному выводу данных.

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

8.1. Управление состоянием фильтра

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

В том случае, если вы используете базовый класс, вам придется крайне редко обрабатывать изменения состояний самостоятельно. Все что вам понадобится - это перекрыть виртуальные функции start() и stop() базового класса (они могут называться по-другому в зависимости от базового класса), после чего базовый класс возьмет на себя заботу обо всех изменениях состояний за вас.

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

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

Не используйте функцию g_assert для выявления необработанных изменений состояний; о них позаботится базовый класс GstElement.

Обратите внимание на то, что прямые ("отключен" (NULL)=>"готов к работе" (READY), "готов к работе" (READY)=>"пауза" (PAUSED), "пауза" (PAUSED)=>"воспроизведение" (PLAYING)) и обратные ("воспроизведение" (PLAYING)=>"пауза" (PAUSED), "пауза" (PAUSED)=>"готов к работе" (READY), "готов к работе" (READY)=>"отключен" (NULL)) изменения состояний обрабатываются в двух отдельных блоках, причем обратные изменения состояний обрабатываются только после того, как мы завершаем работу функции обработки изменений состояний родительского класса. Это необходимо для того, чтобы безопасно обрабатывать операции одновременного доступа к данным из множества программных потоков.

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


Следующий раздел : Добавление свойств.