Gstreamer — самая популярная *nix библиотека для работы с видео, которая является основой для большинства популярных приложений (основной список можно найти здесь).
Однако, столь гибкий инструмент требует тонкого подхода для стабильной и эффективной работы.
Все действия будут рассмотрены на примере онлайн HD трансляции с HDMI входа по RTMP с помощью blackmagic intensity pro, Debian Linux, gstreamer и Nginx.
Отладка (debugging) (manual)
У gstreamer есть встроенная возможность отладки, справку можно получить командой:
gst-launch --gst-debug-help
Сам вывод отладочной информации включается добавлением в команду:
--gst-debug-level=LEVEL
, где LEVEL — число от 0 (без вывода отладочной информации) до 9 (выводить всё).
Очень полезным является параметр
--gst-debug=GST_CAPS:4
, который будет выводить список возможных форматов элементов конвейера, если два элемента не могут найти подходящие друг другу форматы.
Однако, основной проблемой является огромное количество информации, которую требуется каким-то образом интерпретировать с целью дальнейшей оптимизации.
В данной ситуации есть прекрасная возможность генерации схем конвейера gstreamer, которая позволит наглядно увидеть порядок работы вашего конвейера:
- Для генерации .DOT файла и дальнейшей конвертации требуется установить пакет graphviz.
apt-get install graphviz
- Далее требуется создать переменную окружения:
export GST_DEBUG_DUMP_DOT_DIR=/tmp/dot mkdir -p $GST_DEBUG_DUMP_DOT_DIR
- Запустите Gstreamer с вашим конвейером, в папке /tmp/dot будут созданы .dot файлы для каждого состояния конвейера.
- Сконвертируйте полученные файлы в удобный вам формат:
dot -Tpng input.dot > output.png dot -Tsvg input.dot > output.svg
Использование SVG позволит бесконечно масштабировать полученную схему, так как информации на ней присутствует достаточно.
Пример схемы.
По полученным данным можно будет найти узкие места вашего конвейера и добиться стабильной работы.
Оптимизация
В рамках примера оптимизации будет рассмотрены следующие требования:
- 1920x1080 Full HD разрешение потока
- 30 кадров в секунду
- H264 кодек с битрейтом 768kbit/s
- flv контейнер, передающийся по RTMP
Цель — работа системы в режиме реального времени без потерь кадров и синхронизации звука/видео.
Кадры/сек (fps)
Очень важно сразу выяснить, сколько кадров в секунду требуется и сколько может выдать ваше оборудование.
Оптимальным для динамического изображения является 30fps, но для передачи статичного контента (например, презентации) есть смысл уменьшать fps до минимально комфортного.
Многопоточность (использование queue)
В Gstreamer существует элемент queue, который оправдывает своё название — это очередь (поток) данных.
Использование queue позволит распараллелить вычисления и буферизировать информацию в автоматическом режиме для передачи между элементами.
Данный элемент является одним из ключевых наравне с queue2 (аналог queue с буферизацией на жесткий диск) и tee (разделение потока на несколько, например, для параллельной записи потока на диск), и они все достойны отдельной статьи.
Настройка элементов конвейера
Конечно же, ключевым моментом является настройка элементов конвейера (декодера звука и видео и т.д.).
- По возможности избегайте копирования буферов
- Настройка видео энкодера на работу в режиме реального времени
Критично для онлайн трансляцийx264enc tune=zerolatency
dmaienc_h264 encodingpreset=2 - Использование переменного битрейта для быстрой работы энкодера
Выигрыш в производительности — до 3х разx264enc pass=17
dmaienc_h264 ratecontrol=2
Практика
Пример оптимизированного минимального конвейера:
gst-launch
audiotestsrc ! queue ! audioresample ! voaacenc bitrate=64 ! audio/mpeg,rate=22050,channels=1 !
flvmux streamable=1 name=mux
videotestsrc ! queue ! videorate ! videoscale ! x264enc bitrate=768 tune=zerolatency pass=17 !
mux. mux. !
rtmpsink location="rtmp://localhost/live/test"
В данном случае мы готовим поток с видео битрейтом 768 и одно канальным аудио битрейтом 64 кбит/сек соответственно, используем queue и конвертируем видео с переменным битрейтом.
Посмотреть схему конвейера можно здесь.
Вышеприведенный пример не учитывает некоторые требования поставленной задачи, итоговый конвейер:
gst-launch
audiotestsrc ! queue ! audioresample ! audio/x-raw-int,width=16,depth=16,channels=2,rate=22050 !
audioconvert ! voaacenc bitrate=64 ! audio/mpeg,rate=22050,channels=1 !
flvmux streamable=1 name=mux
videotestsrc ! queue ! videorate ! videoscale ! ffmpegcolorspace !
'video/x-raw-yuv, format=(fourcc)UYVY, framerate=(fraction)30/1' !
ffmpegcolorspace ! x264enc bitrate=768 tune=zerolatency !
mux. mux. !
rtmpsink location="rtmp://localhost/live/test"
В данном конвейере предполагается, что videotestsrc отдаёт 1080p.
Данный пример является реальным и используется на сервере с 16 ядерным процессором и pci-платой Blackmagic intencity pro, итоговая нагрузка составляет 0,5 LA.
В обоих примерах веб-сервером использовался Nginx с прекрасным модулем пользователя rarutyunyan nginx-rtmp-module
Конечно же, существует множество других инструментов и возможностей для отладки и оптимизации Gstreamer,
буду рад вашим примерам!
Непрерывных трансляций вам, коллеги!
Источники и ссылки:
- С возможностями отладочной информации gstreamer можно ознакомиться здесь.
- GStreamer Debugging
- Оптимизация производительности встроенных решений
- Официальный сайт Gstreamer
Автор: gmelikov