GStreamer
Кратко обо мне.
● Разработчик одного из подразделений ITransition.
● Четко выраженной сферы интересов нет, по возможности
использую весь багаж знаний полученный в альма-матер, и
расширяемый за последние 10 лет – сетевые протоколы,
микропроцессорные архитектуры, внутренние механизмы
операционных систем, обработка изображений.
● На данный момент занимаюсь разработкой сервера системы
видеонаблюдения на базе платформы iMX6.
● Ну и конечно же C/C++ 
Gstreamer: что это?
● Фреймворк, для построения мультимедийных приложений.
● GStreamer написан на языке C, с использованием ООП-
парадигмы, которая реализована на базе GObject.
● Приложение строится путем объединения элементарных
строительных блоков – элементов, в цепочку, которая образует
путь следования данных – pipeline.
Сравните
● Linux Pipeline:
● grep 'Starting' /var/log/boot.log |
sort > recently-started.txt
● Gstreamer pipeline:
● gst-launch-1.0 filesrc
location='movie.mkv' ! matroskademux
! avdec_h264 ! avenc_mpeg2video !
filesink location='videostream.mp4'
GStreamer:пример использования
GStreamer:пример использования
rtspsrc tee
rtph264
depay
h264parse
queue splitmuxsink
queue appsink
SD-card
appsrc h264dec videoconvert motiondetection
Remote
storage
WebRTC
Аналоги: ffmpeg
По набору предоставляемых возможностей и возможным областям применения,
наиболее близким аналогом является ffmpeg. Однако они отличаются
«философией» написания приложения.
ffmpeg - Доменные сущности (файлы, потоки, кодеки) представляются
разработчику в виде контекстов, для работы с контекстами используется
предоставляемый API.
GStreamer – разработчику предоставляется набор функционально законченных
элементов, которые комбинируются и объединяются, образуя путь следования
данных в порядке их обработки.
На мой взгляд, основная сложность использования ffmpeg для обработки медиа-
данных – это необходимость «ручной» синхронизации потоков к единой шкале
времени.
GStreamer скрывает детали синхронизации времени, кроме того, обеспечивает
механизм согласования форматов данных. Модульная архитектура способствует
разработке элементов, поддерживающих аппаратные ускорители.
GStreamer: возможности
● Принимать и передавать аудио/видео данные, используя
протоколы HTTP, RTSP/RTP и др.
● Разбирать и собирать потоки в разных форматах
(контейнерах): MPEG, AVI, ASF, FLV, MKV и др.
● Декодировать/кодировать потоки в различных комбинациях
кодеков (в том числе можно задействовать и аппаратные
ресурсы, реализующие необходимый алгоритм)
● Получать потоки данных из различных источников и
отправлять их (потоки данных) в различные приемники
Компоненты
● Набор плагинов, поставляемых в виде динамических
библиотек.
● Утилиты командной строки, предназначенные для
запуска pipelin'а, перечисления списка имеющихся
элементов и их свойств (gst-launch, gst-inspect).
Gstreamer: инструментарий
● Уже упомянутые утилиты командной строки: gst-
launch, gst-inspect
● Возможность визуализации pipeline в формат graphviz.
● Основным WYSIWYG-построителем является
GStreamer Pipeline Editor.
● Система логирования с широким диапазоном log-level
Строительные блоки: элементы
● Элементы являются минимальными строительными
блоками. 5 категорий:
– Источники данных
– Фильтры
– Приемники данных
– Анализаторы потока
– Вспомогательные элементы
Строительные блоки: элементы
● Любой элемент является конечным автоматом, в течение
времени функционирования приложения переходя из одного
состояния в другое.
● В соответствии с философией GLib элементы имеют
именованные свойства.
● Для соединения элементов в цепочку используются точки
подключения, т.н. pads:
– sinkpad – вход потока данных в элемент
– srcpad – вывод потока данных из элемента
У элемента может быть несколько точек подключения.
Элементы: источники
● Источники – это класс плагинов, которые
позволяют читать медиаданные из различных
источников:
– Filesystem (filesrc, multifilesrc)
– Network (souphttpsrc, rtspsrc, udpsrc)
– Devices (alsasrc, v4l2src)
– Others (fakesrc, audiotestsrc, videotestsrc)
Элементы: приемники
● Приемники – это оконечные элементы pipeline,
они “выводят медиаданные” за его пределы.
– Filesystem (filesink, multifilesink)
– X-server (ximagesink, xvimagesink)
– Network (udpsink)
Элементы: фильтры
● Фильтры – это элементы, которые выполняют
различные преобразования над потоком данных. Это,
пожалуй, самый обширный класс элементов, который
объединяет мультиплексоры/демультиплексоры
потоков, парсеры, кодеры/декодеры и многое другое.
Элементы: прочие элементы
● Анализаторы потока – элементы этой категории
пропускают через себя поток данных, не
модифицируя его, но изменняют свое состояние
и/или генерируют событие.
● Вспомогательные элементы – к этой категории
относятся очереди, “разветвители” потока
данных и некоторые другие элементы.
Элемент: конечный-автомат
● Состояния элемента в течение времени жизни:
– NULL – элемент неактивен и не владеет никакими
ресурсами
– READY – элементу предоставлена часть ресурсов, не
относящихся напрямую к обработке потока данных
(динамические библиотеки, ресурсы аппаратуры)
– PAUSED – элемент готов принимать и обрабатывать потоки
данных
– PLAYING – элемент обрабатывает поток данных
Элемент: конечный автомат
● Диаграмма переходов
NULL READY PAUSED PLAYING
Строительные блоки: контейнеры
● Контейнеры представляют собой особую
категорию элементов.
● Контейнеры объединяют несколько элементов,
позволяя управлять ими одновременно
(например, изменять состояние)
Контейнеры
Контейнеры
Pipeline: пример
Pipeline: пример
gst-launch-1.0 filesrc location='movie.mkv'
! matroskademux name=d
! queue ! avdec_h264 ! xvimagesink
d. ! queue ! avdec_mp3 ! alsasink
Взаимодействие элементов
● Для взаимодействия элементов между собой и с
приложением верхнего уровня используются
следующие сущности:
– Pad
– Bus
– Buffers
– Events
– Messages
– Query
Взаимодействие элементов
Gstreamer: пишем код
void Recorder::init_pipeline() {
std::string pipeline(“rtspsrc name=src ! rtph264_depay ! H264parse ! tee name=t”
“ t. ! queue ! appsink name=h264sink “
“ t. ! queue ! splitmuxsink max-size-time=90000000000 muxer=qtmux“);
_pipeline = gst_parse_launch(pipeline.c_str(), NULL);
_rtspsrc = gst_bin_get_by_name(GST_BIN(_pipeline), “src”);
_h264sink = gst_bin_get_by_name(GST_BIN(_pipeline), “h264sink”);
g_object_set(_h264sink, “emit-signals”, TRUE, NULL);
_new_sample_id = g_signal_connect(_h264sink, “new-sample”,
G_CALLBACK(new_sample), this);
GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(_pipeline));
_bus_watch_id = gst_bus_add_watch(bus, on_bus_message, this);
g_object_unref(bus);
}
Gstreamer: пишем код
GstFlowReturn Recorder::new_sample(GstElement *element, gpointer userdata) {
Recorder *recorder = static_cast<Recorder*>(userdata);
GstSample *sample = NULL;
g_signal_emit_by_name(element, “pull-sample”, &sample);
if (sample) {
if (element == recorder->_appsink)
recorder->_detector.push_sample(sample);
gst_sample_unref(sample);
}
return GST_FLOW_OK;
}
Gstreamer: пишем код
gboolean Recorder::on_bus_message(GstBus *bus, GstMessage *msg, gpointer userdata) {
Recorder *recorder = static_cast<Recorder*>(userdata);
switch (GST_MESSAGE_TYPE(msg)) {
case GST_MESSAGE_ERROR:
recorder->on_message_error(msg);
break;
case GST_MESSAGE_EOS:
recorder->on_message_eos(msg);
break;
case GST_MESSAGE_STATE_CHANGED:
recorder->on_message_state_changed(msg);
break;
default:
recorder->on_message_other(msg);
}
return TRUE;
}
GStreamer: пишем код
void Recorder::start() {
GstStateChangeReturn ret = gst_element_set_state(_pipeline, GST_STATE_PLAYING);
_detector.start();
}
void Recorder::stop() {
_detector.stop();
GstStateChangeReturn ret = gst_element_set_state(_pipeline, GST_STATE_NULL);
}
GStreamer: пишем код
void Detector::init_pipeline() {
std::string pipeline(“appsrc ! ”
#if defined BUILD_PROFILE_IMX
“ vpudec ! imxvideoconvert_g2d ! capsfilter caps=”video/x-raw,width=640,height=480” !
videoconvert ! ”
#elif defined BUILD_PROFILE_PC
“ avdec_h264 ! videoconvert ! videoscale ! capsfilter caps=”video/x-
raw,width=640,height=480, format=RGB” ! ”
#else
#error “Undefined build profile”
#endif
“ motioncells name=mdcells display=FALSE gridx=32 gridy=32 ! videorate name=vrate “);
_pipeline = gst_parse_launch(pipeline.c_str(), NULL);
GStreamer: пишем код
_mdcells = gst_bin_get_by_name(GST_BIN(_pipeline), “mdcells”);
_vrate = gst_bin_get_by_name(GST_BIN(_pipeline), “vrate”);
GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(_pipeline));
_bus_watch_id = gst_bus_add_watch(bus, on_bus_message, this);
g_object_unref(bus);
}
Gstreamer: пишем код
gboolean Detector::on_bus_message(GstBus *bus, GstMessage *msg, gpointer userdata)
{
Detector *detector = static_cast<Detector*>(userdata);
if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ELEMENT
&& GST_MESSAGE_SRC(msg) == _mdcells) {
const GstStructure *msg_struct = gst_message_get_structure(msg);
if (gst_structure_has_name(msg_struct, “motion”) {
if (gst_structure_has_field(msg_struct, “motion_begin”)
_recorder.start_recording();
else if (gst_structure_has_field(msg_struct, “motion_finished”)
_recorder.stop_recording();
}
}
return TRUE;
}
GStreamer: итоги
Подводя итоги, я хочу отметить некоторые достоинства и
недостатки фреймворка:
● Достоинства
– Возможность быстрого прототипирования сложных схем
обработки аудио/видеоданных
– Модульная архитектура
– Поддержка широкого спектра устройств ввода-вывода
● Недостатки
– Написан на C
– Далеко не все элементы качественно реализованы

More Related Content

PPTX
Asynchrony and coroutines
PDF
Hunting for a C++ package manager
PDF
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
PDF
Алексей Фомкин, Практическое применение Web Workers
ODP
Boost.Algorithm: что, зачем и почему
PDF
Быстрое прототипирование бэкенда игры с геолокацией на OpenResty, Redis и Doc...
PDF
Профилирование кода на C/C++ в *nix системах
PDF
Девять кругов ада или PostgreSQL Vacuum / Алексей Лесовский (PostgreSQL-Consu...
Asynchrony and coroutines
Hunting for a C++ package manager
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Алексей Фомкин, Практическое применение Web Workers
Boost.Algorithm: что, зачем и почему
Быстрое прототипирование бэкенда игры с геолокацией на OpenResty, Redis и Doc...
Профилирование кода на C/C++ в *nix системах
Девять кругов ада или PostgreSQL Vacuum / Алексей Лесовский (PostgreSQL-Consu...

What's hot (20)

PDF
Семь тысяч Rps, один go
PDF
Последние новости постгреса с PGCon / О.Бартунов, А.Коротков, Ф.Сигаев (Postg...
PPTX
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
PPTX
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
PDF
noBackend, или Как выжить в эпоху толстеющих клиентов / Самохвалов Николай
PDF
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
PDF
Павел Довгалюк, Обратная отладка
PDF
Реализация восстановления после аварий / Сергей Бурладян (Avito)
PDF
ПВТ - весна 2015 - Лекция 7. Модель памяти С++. Внеочередное выполнение инстр...
PDF
Современная операционная система: что надо знать разработчику / Александр Кри...
PDF
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
PDF
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
PDF
Практика Lock-free. RealTime-сервер
PDF
Использование юнит-тестов для повышения качества разработки
PDF
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
PDF
CUDA-Aware MPI
PDF
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
PDF
Streaming replication in practice
PDF
Для чего мы делали свой акторный фреймворк и что из этого вышло?
PPTX
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Семь тысяч Rps, один go
Последние новости постгреса с PGCon / О.Бартунов, А.Коротков, Ф.Сигаев (Postg...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
noBackend, или Как выжить в эпоху толстеющих клиентов / Самохвалов Николай
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Павел Довгалюк, Обратная отладка
Реализация восстановления после аварий / Сергей Бурладян (Avito)
ПВТ - весна 2015 - Лекция 7. Модель памяти С++. Внеочередное выполнение инстр...
Современная операционная система: что надо знать разработчику / Александр Кри...
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Практика Lock-free. RealTime-сервер
Использование юнит-тестов для повышения качества разработки
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
CUDA-Aware MPI
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Streaming replication in practice
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Ad

Similar to Применение фреймворка GStreamer в системе видеонаблюдения (20)

PPTX
мониторинг производительности Web приложений на python
PDF
Программируемость коммутаторов для ЦОД Cisco Nexus
PDF
Пакетное ядро мобильного оператора: ASR5k, поиски устранение неисправностей
PPTX
вебинар взаимодействие Info watch traffic monitor c субд oracle
PPT
Где кончается react native? / Павел Кондратенко (Rambler&Co)
PDF
Дмитрий Кремер, МИА «Россия сегодня» (РИА Новости). «Построение новостного we...
PPTX
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
PPTX
Git for you
PPT
Hl2008 Spy Log Architechture 169
PDF
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
PDF
Перевод новостного приложения на БД PostgreSQL
PPTX
Транзакционный фреймворк для сингловых игр и игр с асинхронным мультиплеером ...
PPT
New SpyLOG architechture (Highload 2008)
PPTX
Асинхронность и сопрограммы
PDF
StackLight (aka LMA)
PPTX
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
PPTX
Мониторинг в высоконагруженных (и не только) проектах: сравнительный анализ с...
PPTX
Мониторинг в высоконагруженных (и не только) проектах: сравнительный анализ с...
PPTX
Мониторинг веб-проектов: штаб оперативного реагирования и аналитический центр
PPT
The Best Portlet
мониторинг производительности Web приложений на python
Программируемость коммутаторов для ЦОД Cisco Nexus
Пакетное ядро мобильного оператора: ASR5k, поиски устранение неисправностей
вебинар взаимодействие Info watch traffic monitor c субд oracle
Где кончается react native? / Павел Кондратенко (Rambler&Co)
Дмитрий Кремер, МИА «Россия сегодня» (РИА Новости). «Построение новостного we...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Git for you
Hl2008 Spy Log Architechture 169
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Перевод новостного приложения на БД PostgreSQL
Транзакционный фреймворк для сингловых игр и игр с асинхронным мультиплеером ...
New SpyLOG architechture (Highload 2008)
Асинхронность и сопрограммы
StackLight (aka LMA)
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Мониторинг в высоконагруженных (и не только) проектах: сравнительный анализ с...
Мониторинг в высоконагруженных (и не только) проектах: сравнительный анализ с...
Мониторинг веб-проектов: штаб оперативного реагирования и аналитический центр
The Best Portlet
Ad

More from corehard_by (20)

PPTX
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
PPTX
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
PDF
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
PPTX
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
PPTX
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
PPTX
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
PPTX
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
PPTX
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
PPTX
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
PPTX
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
PDF
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
PPTX
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
PPTX
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
PDF
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
PDF
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
PDF
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
PDF
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
PPTX
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
PDF
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
PDF
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019

Применение фреймворка GStreamer в системе видеонаблюдения

  • 2. Кратко обо мне. ● Разработчик одного из подразделений ITransition. ● Четко выраженной сферы интересов нет, по возможности использую весь багаж знаний полученный в альма-матер, и расширяемый за последние 10 лет – сетевые протоколы, микропроцессорные архитектуры, внутренние механизмы операционных систем, обработка изображений. ● На данный момент занимаюсь разработкой сервера системы видеонаблюдения на базе платформы iMX6. ● Ну и конечно же C/C++ 
  • 3. Gstreamer: что это? ● Фреймворк, для построения мультимедийных приложений. ● GStreamer написан на языке C, с использованием ООП- парадигмы, которая реализована на базе GObject. ● Приложение строится путем объединения элементарных строительных блоков – элементов, в цепочку, которая образует путь следования данных – pipeline.
  • 4. Сравните ● Linux Pipeline: ● grep 'Starting' /var/log/boot.log | sort > recently-started.txt ● Gstreamer pipeline: ● gst-launch-1.0 filesrc location='movie.mkv' ! matroskademux ! avdec_h264 ! avenc_mpeg2video ! filesink location='videostream.mp4'
  • 6. GStreamer:пример использования rtspsrc tee rtph264 depay h264parse queue splitmuxsink queue appsink SD-card appsrc h264dec videoconvert motiondetection Remote storage WebRTC
  • 7. Аналоги: ffmpeg По набору предоставляемых возможностей и возможным областям применения, наиболее близким аналогом является ffmpeg. Однако они отличаются «философией» написания приложения. ffmpeg - Доменные сущности (файлы, потоки, кодеки) представляются разработчику в виде контекстов, для работы с контекстами используется предоставляемый API. GStreamer – разработчику предоставляется набор функционально законченных элементов, которые комбинируются и объединяются, образуя путь следования данных в порядке их обработки. На мой взгляд, основная сложность использования ffmpeg для обработки медиа- данных – это необходимость «ручной» синхронизации потоков к единой шкале времени. GStreamer скрывает детали синхронизации времени, кроме того, обеспечивает механизм согласования форматов данных. Модульная архитектура способствует разработке элементов, поддерживающих аппаратные ускорители.
  • 8. GStreamer: возможности ● Принимать и передавать аудио/видео данные, используя протоколы HTTP, RTSP/RTP и др. ● Разбирать и собирать потоки в разных форматах (контейнерах): MPEG, AVI, ASF, FLV, MKV и др. ● Декодировать/кодировать потоки в различных комбинациях кодеков (в том числе можно задействовать и аппаратные ресурсы, реализующие необходимый алгоритм) ● Получать потоки данных из различных источников и отправлять их (потоки данных) в различные приемники
  • 9. Компоненты ● Набор плагинов, поставляемых в виде динамических библиотек. ● Утилиты командной строки, предназначенные для запуска pipelin'а, перечисления списка имеющихся элементов и их свойств (gst-launch, gst-inspect).
  • 10. Gstreamer: инструментарий ● Уже упомянутые утилиты командной строки: gst- launch, gst-inspect ● Возможность визуализации pipeline в формат graphviz. ● Основным WYSIWYG-построителем является GStreamer Pipeline Editor. ● Система логирования с широким диапазоном log-level
  • 11. Строительные блоки: элементы ● Элементы являются минимальными строительными блоками. 5 категорий: – Источники данных – Фильтры – Приемники данных – Анализаторы потока – Вспомогательные элементы
  • 12. Строительные блоки: элементы ● Любой элемент является конечным автоматом, в течение времени функционирования приложения переходя из одного состояния в другое. ● В соответствии с философией GLib элементы имеют именованные свойства. ● Для соединения элементов в цепочку используются точки подключения, т.н. pads: – sinkpad – вход потока данных в элемент – srcpad – вывод потока данных из элемента У элемента может быть несколько точек подключения.
  • 13. Элементы: источники ● Источники – это класс плагинов, которые позволяют читать медиаданные из различных источников: – Filesystem (filesrc, multifilesrc) – Network (souphttpsrc, rtspsrc, udpsrc) – Devices (alsasrc, v4l2src) – Others (fakesrc, audiotestsrc, videotestsrc)
  • 14. Элементы: приемники ● Приемники – это оконечные элементы pipeline, они “выводят медиаданные” за его пределы. – Filesystem (filesink, multifilesink) – X-server (ximagesink, xvimagesink) – Network (udpsink)
  • 15. Элементы: фильтры ● Фильтры – это элементы, которые выполняют различные преобразования над потоком данных. Это, пожалуй, самый обширный класс элементов, который объединяет мультиплексоры/демультиплексоры потоков, парсеры, кодеры/декодеры и многое другое.
  • 16. Элементы: прочие элементы ● Анализаторы потока – элементы этой категории пропускают через себя поток данных, не модифицируя его, но изменняют свое состояние и/или генерируют событие. ● Вспомогательные элементы – к этой категории относятся очереди, “разветвители” потока данных и некоторые другие элементы.
  • 17. Элемент: конечный-автомат ● Состояния элемента в течение времени жизни: – NULL – элемент неактивен и не владеет никакими ресурсами – READY – элементу предоставлена часть ресурсов, не относящихся напрямую к обработке потока данных (динамические библиотеки, ресурсы аппаратуры) – PAUSED – элемент готов принимать и обрабатывать потоки данных – PLAYING – элемент обрабатывает поток данных
  • 18. Элемент: конечный автомат ● Диаграмма переходов NULL READY PAUSED PLAYING
  • 19. Строительные блоки: контейнеры ● Контейнеры представляют собой особую категорию элементов. ● Контейнеры объединяют несколько элементов, позволяя управлять ими одновременно (например, изменять состояние)
  • 23. Pipeline: пример gst-launch-1.0 filesrc location='movie.mkv' ! matroskademux name=d ! queue ! avdec_h264 ! xvimagesink d. ! queue ! avdec_mp3 ! alsasink
  • 24. Взаимодействие элементов ● Для взаимодействия элементов между собой и с приложением верхнего уровня используются следующие сущности: – Pad – Bus – Buffers – Events – Messages – Query
  • 26. Gstreamer: пишем код void Recorder::init_pipeline() { std::string pipeline(“rtspsrc name=src ! rtph264_depay ! H264parse ! tee name=t” “ t. ! queue ! appsink name=h264sink “ “ t. ! queue ! splitmuxsink max-size-time=90000000000 muxer=qtmux“); _pipeline = gst_parse_launch(pipeline.c_str(), NULL); _rtspsrc = gst_bin_get_by_name(GST_BIN(_pipeline), “src”); _h264sink = gst_bin_get_by_name(GST_BIN(_pipeline), “h264sink”); g_object_set(_h264sink, “emit-signals”, TRUE, NULL); _new_sample_id = g_signal_connect(_h264sink, “new-sample”, G_CALLBACK(new_sample), this); GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(_pipeline)); _bus_watch_id = gst_bus_add_watch(bus, on_bus_message, this); g_object_unref(bus); }
  • 27. Gstreamer: пишем код GstFlowReturn Recorder::new_sample(GstElement *element, gpointer userdata) { Recorder *recorder = static_cast<Recorder*>(userdata); GstSample *sample = NULL; g_signal_emit_by_name(element, “pull-sample”, &sample); if (sample) { if (element == recorder->_appsink) recorder->_detector.push_sample(sample); gst_sample_unref(sample); } return GST_FLOW_OK; }
  • 28. Gstreamer: пишем код gboolean Recorder::on_bus_message(GstBus *bus, GstMessage *msg, gpointer userdata) { Recorder *recorder = static_cast<Recorder*>(userdata); switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_ERROR: recorder->on_message_error(msg); break; case GST_MESSAGE_EOS: recorder->on_message_eos(msg); break; case GST_MESSAGE_STATE_CHANGED: recorder->on_message_state_changed(msg); break; default: recorder->on_message_other(msg); } return TRUE; }
  • 29. GStreamer: пишем код void Recorder::start() { GstStateChangeReturn ret = gst_element_set_state(_pipeline, GST_STATE_PLAYING); _detector.start(); } void Recorder::stop() { _detector.stop(); GstStateChangeReturn ret = gst_element_set_state(_pipeline, GST_STATE_NULL); }
  • 30. GStreamer: пишем код void Detector::init_pipeline() { std::string pipeline(“appsrc ! ” #if defined BUILD_PROFILE_IMX “ vpudec ! imxvideoconvert_g2d ! capsfilter caps=”video/x-raw,width=640,height=480” ! videoconvert ! ” #elif defined BUILD_PROFILE_PC “ avdec_h264 ! videoconvert ! videoscale ! capsfilter caps=”video/x- raw,width=640,height=480, format=RGB” ! ” #else #error “Undefined build profile” #endif “ motioncells name=mdcells display=FALSE gridx=32 gridy=32 ! videorate name=vrate “); _pipeline = gst_parse_launch(pipeline.c_str(), NULL);
  • 31. GStreamer: пишем код _mdcells = gst_bin_get_by_name(GST_BIN(_pipeline), “mdcells”); _vrate = gst_bin_get_by_name(GST_BIN(_pipeline), “vrate”); GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(_pipeline)); _bus_watch_id = gst_bus_add_watch(bus, on_bus_message, this); g_object_unref(bus); }
  • 32. Gstreamer: пишем код gboolean Detector::on_bus_message(GstBus *bus, GstMessage *msg, gpointer userdata) { Detector *detector = static_cast<Detector*>(userdata); if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ELEMENT && GST_MESSAGE_SRC(msg) == _mdcells) { const GstStructure *msg_struct = gst_message_get_structure(msg); if (gst_structure_has_name(msg_struct, “motion”) { if (gst_structure_has_field(msg_struct, “motion_begin”) _recorder.start_recording(); else if (gst_structure_has_field(msg_struct, “motion_finished”) _recorder.stop_recording(); } } return TRUE; }
  • 33. GStreamer: итоги Подводя итоги, я хочу отметить некоторые достоинства и недостатки фреймворка: ● Достоинства – Возможность быстрого прототипирования сложных схем обработки аудио/видеоданных – Модульная архитектура – Поддержка широкого спектра устройств ввода-вывода ● Недостатки – Написан на C – Далеко не все элементы качественно реализованы