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

UnixForum





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

Фреймворк GStreamer. Руководство разработчика приложений. Манипуляции с конвейером

Оригинал: GStreamer Application Development Manual
Авторы: Wim Taymans, Steve Baker, Andy Wingo, Ronald S. Bultje, Stefan Kost
Дата публикации: 21 мая 2014 г.
Перевод: А.Панин
Дата перевода: 22 июня 2014 г.

19.3. Принудительное использование заданного формата мультимедийных данных

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

19.3.1. Изменение формата мультимедийных данных при работе с конвейером в состоянии "проигрывается" (PLAYING)

Также возможно динамическое измерение формата мультимедийных данных конвейера в состоянии "проигрывается" (PLAYING). Это может быть сделано просто путем изменения значения свойства "caps" элемента "capsfilter". Элемент "capsfilter" отправит событие RECONFIGURE против направления конвейера, в результате приема которого элемент, находящийся перед элементом "capsfilter", предпримет попытку согласования использования нового формата и метода резервирования буферов. Данный подход работает только тогда, когда элемент, находящийся перед элементом "capsfilter", не использует фиксированные возможности выходной точки соединения.

Ниже приведен пример кода, реализующего описанную методику изменения возможностей конвейера, находящегося в состоянии "проигрывается" (PLAYING):

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

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

19.4. Динамическое изменение структуры конвейера

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

Существует несколько важных аспектов, которые необходимо учитывать при создании динамических конвейеров:
  • При удалении элементов из конвейера следует убедиться в том, что не происходит передачи данных через несвязанные точки соединения, так как это приведет к фатальной ошибке конвейера. Всегда блокируйте выходные точки соединения (в режиме заполнения) или входные точки соединения (в режиме передачи) перед разрывом связей точек соединения. Также обратитесь к разделу под названием "Замена элементов в конвейере" для получения дополнительной информации.
  • При добавлении элементов в конвейер следует убедиться в том, что элемент переведен в нужное состояние, обычно совпадающее с состоянием соединяемого с ним элемента, перед тем, как начинать передачу данных через этот элемент. После того, как элемент впервые создается, он находится в отключенном состоянии (NULL) и возвращает ошибку при получении данных. Также обратитесь к разделу под названием "Замена элементов в конвейере" для получения дополнительной информации.
  • При добавлении элементов в конвейер фреймворк GStreamer по умолчанию будет устанавливать значение таймера и базового времени элемента на основе соответствующих текущих значений конвейера. Это значит, что элемент будет иметь возможность вычислять то же затраченное время, что и другие элементы конвейера. Также это значит, что все элементы вывода данных будут синхронизировать буферы точно так же, как и другие элементы вывода данных конвейера, а элементы ввода данных будут генерировать буферы с установленным затраченным временем, которое будет совпадать с затраченным временем других элементов ввода данных.
  • При разрыве связей элементов с цепочкой из предыдущих элементов всегда убеждайтесь в том, что опустошили все буферы элемента с данными очередей путем отправки события завершения потока EOS к точке(ам) соединения элемента вывода данных и ожидания момента, когда событие EOS покинет рассматриваемые элементы (с помощью зонда для отслеживания событий). Также следует обратиться к разделу под названием "Замена элементов в конвейере" для получения дополнительной информации.
  • Источник данных реального времени будет генерировать буферы с меткой затраченного времени, соответствующего текущему затраченному времени конвейера.
    Конвейеры без источников реального времени генерируют буферы с меткой затраченного временем начиная со значения 0. Аналогично после перемещения в потоке с опустошением буферов эти конвейеры сбрасывают счетчик затраченного времени к значению 0.
    Затраченное время может быть изменено с помощью функции gst_pad_set_offset (). Затраченное время элементов в конвейере важно знать для поддержки работоспособности механизма синхронизации мультимедийных потоков.
  • Добавление элементов в конвейер может привести к изменению состояния конвейера. Добавление неподготовленного элемента для вывода данных, например, переведет конвейер назад в состояние подготовки. Удаление неподготовленного элемента для вывода данных, к примеру, может привести к изменению состояния конвейера до состояния "пауза" (PAUSED) или "проигрывается" (PLAYING).
    Добавление источника данных реального времени отменяет этап подготовки и переводит конвейер с состояние "проигрывается". Добавление источника данных реального времени или других элементов реального времени может также привести к изменению задержки конвейера.
    Добавление или удаление элементов конвейера может привести к изменению выбора таймера конвейера. В том случае, если добавленный элемент предоставляет таймер, замена таймера конвейера на новый таймер может оказаться полезной. Если же, с другой стороны, элемент, предоставляющий таймер для конвейера, удаляется, должен быть выбран новый таймер.
  • Добавление и удаление элементов может привести к повторному согласованию элементами впереди и позади текущего элемента в конвейере возможностей и механизмов резервирования буферов. Вам не придется делать что-либо на уровне приложения, так как плагины по большей части самостоятельно адаптируются к новой топологии конвейера с целью оптимизации использования форматов и стратегии резервирования буферов.
    Важным аспектом в данном случае является то, что при добавлении, удалении или изменении элементов в конвейере имеется вероятность того, что конвейеру требуется согласовать использование нового формата, причем это согласование может закончиться неудачей. Обычно вы можете исправить ситуацию, установив дополнительные элементы для корректного преобразования форматов в случае необходимости. Также следует обратиться к разделу с названием "Замена элементов в конвейере" для получения дополнительной информации.

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

19.4.1. Замена элементов в конвейере

В приведенном ниже примере мы будем рассматривать следующую цепочку из элементов:

            - ----.      .----------.      .---- -
         element1 |      | element2 |      | element3
                вых. -> вход.     вых. -> вход.
            - ----'      '----------'      '---- -

Мы хотим заменить элемент element2 на элемент element4, причем конвейер будет находиться в состоянии "проигрывается" (PLAYING). Давайте предположим, что элемент element2 является элементом визуализации и мы хотим изменить эффект визуализации в процессе работы конвейера.

Мы не можем просто отвязать входную точку соединения элемента element2 от выходной точки соединения элемента elemtnt1, так как в этом случае выходная точка соединения элемента element1 не будет связана с какой-либо точкой соединения, что приведет к ошибке обработки потока с помощью конвейера в момент, когда данные будут передаваться на эту выходную точку соединения. Техника замены элемента конвейера заключается в блокировании потока данных от выходной точки соединения элемента element1 перед заменой элемента element2 на элемент element4 с последующим восстановлением потока данных, как указано в пошаговом описании алгоритма:
  • Заблокировать выходную точку соединения элемента element2 с помощью блокирующего зонда для точки соединения. Если точка соединения заблокируется, будет активирована функция обратного вызова зонда.
  • После активации функции обратного вызова блокирующего зонда никакие данные не будут передаваться между элементами element1 и element2, причем передача не будет осуществляться до того момента, пока точка соединения не будет разблокирована.
  • Разорвать связь между точками соединения элементов element1 и element2.
  • Убедиться в том, что все накопленные элементом element2 данные переданы по конвейеру. Некоторые элементы могут хранить определенный объем данных с помощью внутренних механизмов, поэтому вам следует убедиться в том, что никакие данные не будут потеряны при удалении элемента element2 из конвейера. Вы можете сделать это, отправив событие окончания потока (EOS) элементу element2 аналогичным описанному ниже способом:
    • Разместить зонд для обработки событий в выходной точке соединения элемента element2.
    • Отправить событие окончания потока (EOS) на входную точку соединения элемента element2. Отправка этого события позволяет гарантировать передачу по конвейеру всех данных, хранимых элементом element2.
    • Ожидать появления события окончания потока в выходной точке соединения элемента element2. В момент приема события окончания потока отбросить его и удалить зонд для обработки событий.
  • Разорвать связь между элементами element2 и element3. Теперь вы можете также удалить элемент element2 из контейнера и перевести его в неопределенное состояние (NULL).
  • Добавить элемент element4 в конвейер в том случае, если он еще не добавлен. Связать элементы element4 и element3. Связать элементы element1 и element4.
  • Убедиться в том, что элемент element4 находится в том же состоянии, что и все оставшиеся элементы конвейера. По крайней мере, он должен находиться в состоянии "пауза" (PAUSED) перед тем, как сможет принимать буферы и события.
  • Разблокировать блокирующий зонд выходной точки соединения элемента element1. Это позволит передавать новые данные элементу element4 и продолжать обработку потока.

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

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

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


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