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

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

Глава 13. Различные режимы планирования работы точек соединения элементов

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

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

Перед тем, как мы опишем режим планирования работы точек соединения, называемый режимом заполнения, давайте попытаемся разобраться в том, как различные режимы планирования работы точек соединения выбираются и активируются для отдельных точек соединения.

13.1. Этап активации точки соединения

В процессе изменения состояния элемента с состояния готовности до состояния "пауза" (READY->PAUSED) точки соединения элемента будут активированы. Сначала происходит активация выходных точек соединения элемента, затем - его входных точек соединения. В процессе активации фреймворк GStreamer вызывает функцию _activate () объекта точки соединения. По умолчанию эта функция будет активировать точку соединения в режиме передачи, вызывая функцию gst_pad_activate_mode () с передачей идентификатора режима передачи GST_PAD_MODE_PUSH. Имеется возможность перекрытия этой функции активации точки соединения _activate () и выбора отличного режима планирования ее работы. Вы можете получить информацию об установленном в ходе процесса активации режиме планирования работы точки соединения, также перекрыв функцию _activate_mode ().

Фреймворк GStreamer позволяет использовать различные режимы планирования работы различных точек соединения элемента. Это обстоятельство обуславливает наличие множества различных вариантов использования точек соединения. Ниже приведен обзор некоторых типичных вариантов их использования:

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

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

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

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

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

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

13.2. Точки соединения, управляющие работой конвейера

Входные точки соединения, работающие в режиме заполнения и взаимодействующие с выходными точками соединения, работающими в режиме передачи (или не взаимодействующие с точками соединения в случае использования элемента для вывода данных), могут инициировать исполнение задачи, которая будет управлять передачей данных через конвейер. В рамках функции этой задачи вы сможете осуществлять произвольный доступ к данным через все входные точки соединения и передавать данные через выходные точки соединения. Такой режим работы может успешно использоваться в реализациях элементов различных типов:
  • Демультиплексоров, элементов разбора потоков данных и определенных типов декодеров, которые принимают не разобранные данные (такие, как аудиопотоки формата MPEG или видеопотоки), так как для их разбора необходим (произвольный) доступ с точностью до байта к входным данным. Однако, если это возможно, такие элементы должны быть также готовы и к работе в режиме передачи данных.
  • Элементов для вывода аудиопотоков определенных типов, которые требуют управления потоком входных данных, таких, как элемент, предназначенный для вывода аудиоданных с использованием аудиосервера Jack.

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

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

13.3. Предоставление возможности произвольного доступа к данным мультимедийного потока

В предыдущем разделе мы говорили о том, как элементы (или точки соединения), активированные для управления передачей данных через конвейер средствами их задачи, должны использовать режим заполнения для планирования работы своих точек соединения. Это означает, что все точки соединения, связанные с описанными точками соединения, должны также активироваться в режиме заполнения. Выходные точки соединения, активированные в режиме заполнения, должны использовать заданную с помощью функции gst_pad_set_getrange_function () реализацию функции произвольного доступа к данным _get_range (), причем эта функция будет вызываться тогда, когда соединенная с рассматриваемой точка соединения будет запрашивать данные с помощью функции gst_pad_pull_range (). После этого элемент будет нести ответственность за перемещение к корректной позиции и предоставление запрошенных данных. Элементы некоторых типов могут реализовывать механизмы произвольного доступа к данным:
  • Источники данных, такие, как элемент для чтения данных из файла, который может предоставлять данные из любой позиции в файле с относительно малыми задержками.
  • Фильтры, которые имеют возможность использования режима заполнения, установленного в рамках всего конвейера.
  • Элементы для разбора потоков данных, которые могут без лишних сложностей реализовывать механизм произвольного доступа к данным для осуществления небольших перемещений в рамках входных потоков данных, используя для этого "опережающие" запросы произвольного доступа к данным буквально без какой-либо обработки данных на своей стороне. Примерами таких элементов являются элементы для чтения тэгов (например, ID3) или элементы для разбора отдельных выходных потоков данных, такие, как элемент для разбора аудиопотоков формата WAVE.

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

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


Следующий раздел : Согласование возможностей.