- PVSM.RU - https://www.pvsm.ru -

Отладка и оптимизация скриптов gstreamer на примере онлайн трансляции (live streaming)

Gstreamer — самая популярная *nix библиотека для работы с видео, которая является основой для большинства популярных приложений (основной список можно найти здесь [1]).

image

Однако, столь гибкий инструмент требует тонкого подхода для стабильной и эффективной работы.
Все действия будут рассмотрены на примере онлайн HD трансляции с HDMI входа по RTMP с помощью blackmagic intensity pro, Debian Linux, gstreamer и Nginx.

Отладка (debugging) (manual [2])

У gstreamer есть встроенная возможность отладки, справку можно получить командой:

gst-launch --gst-debug-help

Сам вывод отладочной информации включается добавлением в команду:

--gst-debug-level=LEVEL

, где LEVEL — число от 0 (без вывода отладочной информации) до 9 (выводить всё).

Очень полезным является параметр

--gst-debug=GST_CAPS:4

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

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

  • Для генерации .DOT файла и дальнейшей конвертации требуется установить пакет graphviz [3].
    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 позволит бесконечно масштабировать полученную схему, так как информации на ней присутствует достаточно.
    Пример схемы. [4]

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

Оптимизация

В рамках примера оптимизации будет рассмотрены следующие требования:

  • 1920x1080 Full HD разрешение потока
  • 30 кадров в секунду
  • H264 кодек с битрейтом 768kbit/s
  • flv контейнер, передающийся по RTMP

Цель — работа системы в режиме реального времени без потерь кадров и синхронизации звука/видео.

Кадры/сек (fps [5])

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

Многопоточность (использование queue [6])

В Gstreamer существует элемент queue, который оправдывает своё название — это очередь (поток) данных.
Использование queue позволит распараллелить вычисления и буферизировать информацию в автоматическом режиме для передачи между элементами.
Данный элемент является одним из ключевых наравне с queue2 [7] (аналог queue с буферизацией на жесткий диск) и tee [8] (разделение потока на несколько, например, для параллельной записи потока на диск), и они все достойны отдельной статьи.

Настройка элементов конвейера

Конечно же, ключевым моментом является настройка элементов конвейера (декодера звука и видео и т.д.).

  • По возможности избегайте копирования буферов

    v4l2src [9] always-copy=false
    filesink [10] enable-last-buffer=false

  • Настройка видео энкодера на работу в режиме реального времени
    Критично для онлайн трансляций

    x264enc [11] tune=zerolatency
    dmaienc_h264 [12] encodingpreset=2

  • Использование переменного битрейта для быстрой работы энкодера
    Выигрыш в производительности — до 3х раз

    x264enc [11] pass=17
    dmaienc_h264 [12] 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 и конвертируем видео с переменным битрейтом.
Посмотреть схему конвейера можно здесь [13].

Вышеприведенный пример не учитывает некоторые требования поставленной задачи, итоговый конвейер:

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 [14] nginx-rtmp-module [15]

Конечно же, существует множество других инструментов и возможностей для отладки и оптимизации Gstreamer,
буду рад вашим примерам!

Непрерывных трансляций вам, коллеги!

Источники и ссылки:

Автор: gmelikov

Источник [19]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/veb-razrabotka/69549

Ссылки в тексте:

[1] здесь: http://gstreamer.freedesktop.org/apps/

[2] manual: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-checklist-debug.html

[3] graphviz: http://www.graphviz.org/

[4] Пример схемы.: http://gstreamer-devel.966125.n4.nabble.com/file/n2297314/player.png

[5] fps: https://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D0%B4%D1%80%D0%BE%D0%B2%D0%B0%D1%8F_%D1%87%D0%B0%D1%81%D1%82%D0%BE%D1%82%D0%B0

[6] queue: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-queue.html

[7] queue2: http://gstreamer.freedesktop.org/data/doc/gstreamer/1.4/gstreamer-plugins/html/gstreamer-plugins-queue2.html

[8] tee: http://gstreamer.freedesktop.org/data/doc/gstreamer/1.4/gstreamer-plugins/html/gstreamer-plugins-tee.html

[9] v4l2src: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-v4l2src.html

[10] filesink: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-filesink.html

[11] x264enc: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-ugly-plugins/html/gst-plugins-ugly-plugins-x264enc.html

[12] dmaienc_h264: http://wiki.virt2real.ru/wiki/Dmaienc_h264

[13] здесь: http://gmelikov.ru/h/i/gstreamer_pipeline.png

[14] rarutyunyan: http://habrahabr.ru/users/rarutyunyan/

[15] nginx-rtmp-module: https://github.com/arut/nginx-rtmp-module

[16] GStreamer Debugging: https://developer.ridgerun.com/wiki/index.php/GStreamer_Debugging

[17] Оптимизация производительности встроенных решений: https://developer.ridgerun.com/wiki/index.php/Embedded_GStreamer_Performance_Tuning

[18] Официальный сайт Gstreamer: http://gstreamer.freedesktop.org/

[19] Источник: http://habrahabr.ru/post/236805/