Живое кодирование с VP9 с использованием FFmpeg
Параметры кодирования
VP9 предоставляет ряд параметров для оптимизации живого кодирования. Некоторые общие принципы обсуждаются в разделе «Режимы битрейта» .
Пример кодирования FFmpeg VP9
В таблице ниже описаны параметры примера вызова ffmpeg
для кодирования VP9.
Параметр | Описание |
---|---|
-quality realtime | realtime необходим для потоковой передачи в реальном времени и для скоростей выше 5 . |
-speed 6 | Для кодирования в реальном времени следует использовать скорости 5 до 8 Более низкие значения ( 5 или 6 ) обеспечивают более высокое качество, но требуют большей мощности процессора. Более высокие значения ( 7 или 8 ) обеспечивают более низкое качество, но более удобны для использования в сценариях с низкой задержкой и на устройствах с низким энергопотреблением процессора, таких как мобильные устройства. |
-tile-columns 4 | Тайлинг разбивает видео на прямоугольные области, что позволяет использовать многопоточную обработку при кодировании и декодировании. Количество тайлов всегда равно степени двойки. 0 = 1 тайл, 1 = 2, 2 = 4, 3 = 8, 4 = 16, 5 = 32. |
-frame-parallel 1 | Включить функции параллельного декодирования. |
-threads 8 | Максимальное количество используемых потоков. |
-static-thresh 0 | Порог обнаружения движения. |
-max-intra-rate 300 | Максимальный битрейт i-кадра (проценты) |
-deadline realtime | Альтернативная (устаревшая) версия -quality realtime |
-lag-in-frames 0 | Максимальное количество кадров для задержки |
-qmin 4 -qmax 48 | Минимальное и максимальное значения квантизатора. Приведённые здесь значения являются лишь рекомендацией, и их изменение поможет улучшить/ухудшить качество видео за счёт снижения эффективности сжатия. |
-row-mt 1 | Включить многопоточность строк. Позволяет использовать до двух потоков в качестве столбцов плитки. 0 = выкл., 1 = вкл. |
-error-resilient 1 | Включить функции устойчивости к ошибкам. |
Выбор параметров кодирования
В приведенной ниже информации используется кодирование с постоянным битрейтом (CBR) для потоковой передачи в реальном времени с адаптивным битрейтом (ABR), где каждый целевой битрейт явно задан в манифесте упаковщика. Это обеспечит более плавное переключение между скоростями для клиентов. Кодирование с переменным битрейтом (VBR) и режим CQ также доступны, если битрейт может быть более гибким или кодирование выполняется фрагментами. Режим Q может испытывать трудности с кодированием в реальном времени, необходимым для живого видео. Подробнее см. в разделе «Режимы битрейта» .
Для получения более подробной информации о том, как манипулировать VP9, также стоит обратиться к прилагаемой статье о настройках VOD , но с учетом акцента на CBR.
Советы и рекомендации
Помните, что при прямой трансляции всё ограничено минимальной скоростью кодирования в реальном времени 1x (FFmpeg сообщает о скорости кодирования по мере её выполнения). Если скорость кодирования падает ниже 1x, процесс кодирования не будет справляться с потоком видео, и пользователи столкнутся с буферизацией, а прерывания передачи сделают трансляцию непригодной для использования во время прямой трансляции (хотя архив в целом останется пригодным для использования).
Примеры параметров кодирования в действии
Ниже показана загрузка ЦП при 25 кадрах в секунду для различных размеров кадров на настольном компьютере с четырехъядерным процессором i5 3,6 ГГц под управлением Linux:
Разрешение цели | Параметры FFmpeg VP9 | Процессор / Скорость (пример) |
---|---|---|
3840x2160 (2160p) | -r 30 -g 90 -s 3840x2160 -качество в реальном времени -скорость 5 -потоки 16 -строки-метры 1 -столбцы-плитки 3 -параллельные кадры 1 -qmin 4 -qmax 48 -b:v 7800k | ~88% 0,39x |
2560x1440 (1440p) | -r 30 -g 90 -s 2560x1440 -качество в реальном времени -скорость 5 -потоки 16 -строки-метры 1 -столбцы-плитки 3 -параллельные кадры 1 -qmin 4 -qmax 48 -b:v 6000k | ~86% 0,68x |
1920x1080 (1080p) | -r 30 -g 90 -s 1920x1080 -качество в реальном времени -скорость 5 -потоки 8 -строки-метры 1 -столбцы-плитки 2 -параллельные кадры 1 -qmin 4 -qmax 48 -b:v 4500k | ~82% 1,04x |
1280x720 (720p) | -r 30 -g 90 -s 1280x720 -качество в реальном времени -скорость 5 -потоки 8 -строки-метры 1 -столбцы-плитки 2 -параллельные кадры 1 -qmin 4 -qmax 48 -b:v 3000k | ~78% 1,77x |
854x480 (480p) | -r 30 -g 90 -s 854x480 -качество в реальном времени -скорость 6 -потоки 4 -строки-метры 1 -столбцы-плитки 1 -параллельные кадры 1 -qmin 4 -qmax 48 -b:v 1800k | ~64% 3,51x |
640x360 (360p) | -r 30 -g 90 -s 640x360 -качество в реальном времени -скорость 7 -потоки 4 -строки-метры 1 -столбцы-плитки 1 -параллельные кадры 0 -qmin 4 -qmax 48 -b:v 730k | ~62% 5,27x |
426x240 (240p) | -r 30 -g 90 -s 426x240 -качество в реальном времени -скорость 8 -потоки 2 -строки-метры 1 -столбцы-плитки 0 -параллельные-кадры 0 -qmin 4 -qmax 48 -b:v 365k | ~66% 8,27x |
Пример FFmpeg может выглядеть так:
ffmpeg -stream_loop 100 -i /home/id3as/Videos/120s_tears_of_steel_1080p.webm \
-r 30 -g 90 -s 3840x2160 -quality realtime -speed 5 -threads 16 -row-mt 1 \
-tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 7800k -c:v libvpx-vp9 \
-b:a 128k -c:a libopus -f webm pipe1
Советы и рекомендации
Обратите внимание, что здесь мы выводим данные в канал FIFO («pipe1»), который необходимо создать перед выполнением команды FFmpeg. Для этого выполните команду
mkfifo pipe1
в вашем рабочем каталоге. При использовании Shaka Packager этот канал будет использоваться в качестве источника входных данных для заданного потока. Для других моделей упаковки может потребоваться другой метод.Чтобы команды
-row-mt
распознавались, используйте последнюю стабильную версию FFmpeg (в настоящее время 3.3.3) с сайта https://www.ffmpeg.org/download.html
Пример набора адаптивных битрейтов
В зависимости от мощности компьютера, на котором выполняется кодирование FFmpeg, может быть или не быть возможным обеспечить одновременную доставку всех следующих кодировок, поэтому из списка следует выбрать подмножество, соответствующее имеющимся у вас ресурсам и целевой аудитории.
Полный набор ABR для FFmpeg
В идеальном сценарии мы объединяем примеры кодирования, описанные в предыдущем разделе, чтобы создать единую команду, которая выдает их все одновременно:
ffmpeg -stream_loop 100 -i lakes1080p.mp4 \
-y -r 25 -g 75 -s 3840x2160 -quality realtime -speed 5 -threads 8 \
-tile-columns 2 -frame-parallel 1 \
-b:v 7800k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe1 \
-y -r 25 -g 75 -s 2560x1440 -quality realtime -speed 5 -threads 8 \
-tile-columns 2 -frame-parallel 1 \
-b:v 6000k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe2 \
-y -r 25 -g 75 -s 1920x1080 -quality realtime -speed 5 -threads 4 \
-tile-columns 2 -frame-parallel 1 \
-b:v 4500k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe3 \
-y -r 25 -g 75 -s 1280x720 -quality realtime -speed 5 -threads 4 \
-tile-columns 2 -frame-parallel 1 \
-b:v 3000k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe4 \
-y -r 25 -g 75 -s 854x480 -quality realtime -speed 6 -threads 4 \
-tile-columns 2 -frame-parallel 1 \
-b:v 2000k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe5 \
-y -r 25 -g 75 -s 640x360 -quality realtime -speed 7 -threads 2 \
-tile-columns 1 -frame-parallel 0 \
-b:v 730k -c:v libvpx-vp9 -b:a 128k -c:a libopus -f webm pipe6 \
-y -r 25 -g 75 -s 426x240 -quality realtime -speed 8 -threads 2 \
-tile-columns 1 -frame-parallel 0 \
-b:v 365k -c:v libvpx-vp9 -b:a 64k -c:a libopus -f webm pipe7
Однако для полного набора вышеперечисленных функций потребуется очень мощный процессор или, возможно, поддержка аппаратной разгрузки графического процессора, которую всё чаще предлагают некоторые чипсеты. Intel Kabylake (и более поздние версии) имеют полноценный аппаратный конвейер кодирования. (Обратите внимание, что графический процессор Kabylake может кодировать VP9 с разрядностью 8 бит, но не 10 бит).
Практический пример использования Shaka Packager на рабочем столе
Более практичным примером для обычных настольных компьютеров может быть использование Shaka Packager . Простой способ установки Shaka — установить его в контейнер Docker, используя образ DockerHub от Google. Инструкции можно найти здесь:
https://github.com/google/shaka-packager#using-docker-for-testing--development
Для этого примера мы использовали машину следующей конфигурации:
Система | Хост: obs Ядро: 4.4.0-91-lowlatency x86_64 (64 бит) |
Рабочий стол | Дистрибутив Xfce 4.12.3: ОС: https://ubuntustudio.org/2016/10/ubuntu-studio-16-10-released/ |
Процессор | Четырехъядерный процессор Intel Core i5-6500 (-MCP-) кэш: 6144 КБ Тактовые частоты: макс.: 3600 МГц 1: 800 МГц 2: 800 МГц 3: 800 МГц 4: 800 МГц |
Видеокарта | Интегрированная графика Intel Skylake |
Память | 8 ГБ ОЗУ |
На практике эта машина может оптимально производить следующий диапазон кодирований ABR, при этом FFmpeg постоянно сообщает о скорости кодирования 1x:
ffmpeg -stream_loop 100 -i 120s_tears_of_steel_1080p.webm \
-y -r 30 -g 90 -s 1920x1080 -quality realtime -speed 7 -threads 8 \
-row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 \
-b:v 4500k -c:v libvpx-vp9 -b:a 128k -c:a libopus -f webm pipe1 \
-y -r 30 -g 90 -s 1280x720 -quality realtime -speed 8 -threads 6 \
-row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 \
-b:v 3000k -c:v libvpx-vp9 -b:a 128k -c:a libopus -f webm pipe2 \
-y -r 30 -g 90 -s 640x360 -quality realtime -speed 8 -threads 2 \
-row-mt 1 -tile-columns 1 -frame-parallel 1 -qmin 4 -qmax 48 \
-b:v 730k -c:v libvpx-vp9 -b:a 128k -c:a libopus -f webm pipe3
Обратите внимание, что настройки -speed
довольно высокие. Эти настройки были установлены экспериментально и могут различаться в зависимости от модели.
Накладные расходы Shaka Packager
Упаковка не слишком нагружает процессор. Shaka Packager можно настроить на прослушивание всех выходных данных, даже если FFmpeg доставляет только часть из них. Вот настройки упаковщика, протестированные на машине, описанной выше:
packager \
in=pipe1,stream=audio,init_segment=livehd-audio-1080.webm,segment_template=livehd-audio-1080-\$Number\$.webm \
in=pipe1,stream=video,init_segment=livehd-video-1080.webm,template=livehd-video-1080-\$Number\$.webm \
in=pipe2,stream=audio,init_segment=livehd-audio-720.webm,segment_template=livehd-audio-720-\$Number\$.webm \
in=pipe2,stream=video,init_segment=livehd-video-720.webm,template=livehd-video-720-\$Number\$.webm \
in=pipe3,stream=audio,init_segment=livehd-audio-360.webm,segment_template=livehd-audio-360-\$Number\$.webm \
in=pipe3,stream=video,init_segment=livehd-video-360.webm,template=livehd-video-360-\$Number\$.webm \
--mpd_output livehd.mpd --dump_stream_info --min_buffer_time=10 --time_shift_buffer_depth=300 \
--segment_duration=3 --io_block_size 65536