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

UnixForum





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

Фреймворк GStreamer. Руководство разработчика плагинов. Портирование плагинов для работы с версией фреймворка 0.10 вместо 0.8

Оригинал: 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 г.
Перевод: А.Панин
Дата перевода: 2 августа 2014 г.

Глава 28. Портирование плагинов для работы с версией фреймворка 0.10 вместо 0.8

В данной главе раздела приложений мы кратко обсудим изменения, которые потребуется внести в код плагинов для быстрого и корректного переноса большинства приложений с GStreamer-0.8 на GStreamer-0.10 со ссылками на соответствующие разделы данного Руководства разработчика плагинов там, где это требуется. При использовании этого списка портирование большинства плагинов для работы с версией фреймворка GStreamer-0.10 не должно занимать больше дня. Исключениями являются элементы, которые требуют использования базового класса в версии 0.10 фреймворка (элементы для ввода и вывода данных), на портирование которых может уйти значительно больше времени в зависимости от навыков разработчика (однако, в случае использования базовых классов GstBaseSink и GstBaseSrc все должно быть не так уж и плохо), а также элементы, требующие использования устаревшего интерфейса байтовых потоков, на замену которого на механизм произвольного доступа к данным может уйти 1-2 дня. Фрагменты кода, отвечающие за планирование работы мультиплексоров, также потребуется переписать, на что может быть потрачено такое же количество времени.

28.1. Список изменений

  • События прерывания мультимедийного потока были заменены на события с информацией о новом сегменте мультимедийного потока. В версии 0.10 необходимо отправлять событие с информацией о новом сегменте мультимедийного потока по направлению конвейера перед тем, как вы отправите первый буфер с данными (несмотря на то, что в версии 0.8 планировщик создает события прерывания потока в том случае, если вы забываете о них, в версии 0.10 аналогичные операции не выполняются).
  • В версии 0.10 буферы данных содержат связанную с ними информацию о возможностях. Элементы должны резервировать новые буферы данных с помощью функции gst_pad_alloc_buffer (). Обратитесь к главе под названием "Согласование возможностей" для ознакомления с подробностями.
  • Большинство функций, возвращающих объекты или значения свойств объектов, было изменено для возврата собственных ссылок вместо возврата постоянных ссылок, которыми владеет сам объект. Причина этого изменения состоит главным образом в повышении потокобезопасности. На самом деле это значит, что память, использованная для хранения значений, возвращаемых такими функциями, как gst_element_get_pad (), gst_pad_get_name (), gst_pad_get_parent (), gst_object_get_parent () и многими другими аналогичными функциями, должна освобождаться после их использования или должны удаляться ссылки на значения. Обратитесь к описанию API каждой из функций для выяснения того, должна ли освобождаться память, использованная для хранения возвращаемых значений.
  • В версии 0.8 планирование работы элемента осуществляется в любом случае. Элементы для ввода данных могут основывать свою работу на использовании функции _get () или _loop (), при этом любой другой элемент может основывать свою работу на использовании функции _chain () или _loop () без каких-либо ограничений. Модель планирования работы элементов в версии 0.10 проще с точки зрения планировщика, но при этом сам элемент должен выполнять некоторую дополнительную работу. Точки соединения учитывают режим планирования работы элемента, в соответствии с которым они могут работать в режиме произвольного доступа к данным мультимедийного потока, в режиме управления работой конвейера или в режиме передачи данных. Все эти режимы подробно документированы в главе под названием "Различные режимы планирования работы точек соединения элементов". В результате этого изменения объект байтового потока прекратил свое существование. Элементы, которым требуется доступ к данным мультимедийного потока на уровне байт, должны использовать режим произвольного доступа к данным на уровне входных точек соединения.
  • Согласование возможностей производится асинхронно. Это значит, что согласование возможностей элементов, расположенных по направлению конвейера, происходит по мере передачи данных по конвейеру, а согласование возможностей элементов, расположенных против направления конвейера - при необходимости повторного согласования возможностей. Все подробности данного процесса описаны в главе под названием "Согласование возможностей".
  • По мере возможностей элементы, работающие совместно с версией фреймворка 0.10, должны пытаться использовать существующие базовые классы. Элементы для ввода и вывода данных, к примеру, могут наследовать свои классы от классов GstBaseSrc и GstBaseSink. Элементы для ввода или вывода аудиопотоков могут наследовать свои классы даже от специфичных для аудиоданных базовых классов. Все существующие базовые классы обсуждались в главе под названием "Предварительно созданные базовые классы" и нескольких следующих главах.
  • В версии фреймворка 0.10 механизмы обработки событий и буферов данных были снова разделены. Это значит, что для того, чтобы принимать события больше не требуется устанавливать флаг GST_FLAG_EVENT_AWARE, а можно просто установить функцию обработки событий для объекта(ов) входной(ых) точки(ек) соединения элемента с помощью функции gst_pad_set_event_function (). Функция цепочки _chain () позволяет принимать исключительно буферы данных.
  • Несмотря на то, что на уровне ядра фреймворка для вас будут устанавливаться все необходимые для многпоточного приложения блокировки (например, будет устанавливаться блокировка функции передачи данных мультимедийного потока перед вызовами ваших функций обработки данных), вы все еще несете ответственность за установку блокировок вокруг определенных функций, например, функций для работы со свойствами объекта. Убедитесь в том, что вы установили корректные блокировки для этих функций, так как приложения будут изменять значения свойств из программного потока, который может не являться программным потоком, выполняющим обработку самих данных! Вы можете использовать вспомогательные макросы GST_OBJECT_LOCK () и GST_OBJECT_UNLOCK () в большинстве случаев, включая случаи блокировки функций для работы со свойствами элемента.
  • Объект GstValueFixedList и все функции *_fixed_list_* () были переименованы в GstValueArray и *_array_* ().
  • Семантики состояний "пауза" (GST_STATE_PAUSED) и "воспроизведение" (GST_STATE_PLAYING) изменились для элементов, не являющихся элементами для вывода данных. Не выводящие данные элементы теперь должны иметь возможность принимать и обрабатывать данные уже в состоянии "пауза" (GST_STATE_PAUSED) (т.е., в процессе подготовки конвейера). Больше информации приводится в Главе 8, "Обзор состояний".
  • В том случае, если механизм изменения состояния вашего плагина не заменяется виртуальными методами start() и stop() одного из новых базовых классов, могут потребоваться модификации функций изменения состояний вашего плагина для того, чтобы безопасно обрабатывать доступ к ним из множества программных потоков. Ваша обычная функция изменения состояния теперь в первую очередь будет обрабатывать прямые изменения состояний, после чего соединяться с функцией изменения состояний родительского класса (обычно в таких случаях это класс GstElement) и только после этого обрабатывать обратные изменения состояний. В качестве примера вы можете рассмотреть код плагина декодера мультимедийного потока формата vorbis из пакета gst-plugins-base.

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

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

  • Функция gst_pad_set_link_function (), используемая для установки функции, которая будет вызываться при согласовании формата между двумя объектами точек соединения на основе класса GstPad, теперь устанавливает функцию, которая будет вызываться тогда, когда два элемента связываются друг с другом с помощью приложения. На данный момент в практических целях вы, скорее всего, захотите использовать функцию gst_pad_set_setcaps_function (), устанавливающую функцию, которая будет вызываться при изменении формата мультимедийного потока, передаваемого через точки соединения (и аналогичную функции _set_link_function () в GStreamer-0.8).

    В том случае, если элемент наследуется от базового класса GstBase, следует перекрыть функцию set_caps ().

  • Функция gst_pad_use_explicit_caps () была заменена на функцию gst_pad_use_fixed_caps (). Вы можете установить фиксированные возможности для их последующего использования точкой соединения с помощью функции gst_pad_set_caps ().

Следующий раздел : Портирование плагинов для работы с версией фреймворка 1.0 вместо 0.10.