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

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

Глава 18. Таймеры

При проигрывании сложных мультимедийных потоков каждый сэмпл элементарного аудио- и видеопотока должен быть воспроизведен в определенной последовательности и в определенное время. Для этой цели фреймворк GStreamer предоставляет механизм синхронизации.

18.1. Механизм таймеров

Время в рамках фреймворка GStreamer измеряется на основе значений, возвращаемых методом gst_clock_get_time () определенного объекта таймера типа GstClock.

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

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

18.2. Затраченное время таймера

Таймер возвращает подсчитанное им абсолютное время (absolute-time) при вызове метода gst_clock_get_time (). На основе абсолютного времени рассчитывается затраченное время (running-time), которое является простой разностью между текущим и предыдущим значением абсолютного времени, называемым также базовым временем (base-time). Таким образом:
затраченное время = абсолютное время - базовое время

Объект конвейера фреймворка GStreamer типа GstPipeline поддерживает работу объекта таймера типа GstClock и подсчитывает базовое время при переводе конвейера в состояние "воспроизведение" (PLAYING). Конвейер передает указатель на объект таймера типа GstClock каждому элементу вместе с выбранным значением базового времени. Конвейер будет выбирать базовое время таким образом, чтобы затраченное время отражало все время, проведенное в состоянии "воспроизведение" (PLAYING). В результате после перевода конвейера в состояние "пауза" (PAUSED) значение затраченного времени остается неизменным.

Так как все объекты конвейера работают с одним и тем же объектом таймера и значением базового времени, они могут рассчитывать значение затраченного времени с помощью таймера конвейера.

18.3. Затраченное время буфера данных

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

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

18.4. Обязанности каждого из элементов

Давайте проясним некоторые соглашения, установленные между фреймворком GStreamer и каждым из элементов конвейера.

18.4.1. Элементы для ввода данных, не работающие в реальном времени

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

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

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

18.4.2. Элементы для ввода данных, работающие в реальном времени

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

18.4.3. Элементы для разбора/декодирования/кодирования мультимедийного потока

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

18.4.4. Элементы для демультиплексирования мультимедийного потока

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

18.4.5. Элементы для мультиплексирования мультимедийных потоков

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

18.4.6. Элементы для вывода данных

Если элемент должен выводить сэмплы в определенное время (в случае воспроизведения мультимедийного потока в реальном времени), он должен потребовать для своей работы объект таймера, и, следовательно, реализовать метод set_clock.

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


Следующий раздел : Качество сервиса (QoS).