Живое кодирование с помощью 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-Frame (проценты)
-deadline realtime Альтернативная (устаревшая) версия -quality realtime
-lag-in-frames 0 Максимальное количество кадров для задержки
-qmin 4 -qmax 48 Минимальное и максимальное значения квантователя. Значения здесь являются всего лишь предложением, и их настройка поможет увеличить/уменьшить качество видео за счет эффективности сжатия.
-row-mt 1 Включить многопоточность строк. Позволяет использовать до 2х потоков в качестве столбцов плитки. 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 -row-mt 1 -tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 7800k ~88% 0,39x
2560x1440 (1440p) -r 30 -g 90 -s 2560x1440 -качество в реальном времени -скорость 5 -потоки 16 -row-mt 1 -tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 6000k ~86% 0,68x
1920x1080 (1080p) -r 30 -g 90 -s 1920x1080 -качество в реальном времени -скорость 5 -потоки 8 -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 4500k ~82% 1,04x
1280x720 (720p) -r 30 -g 90 -s 1280x720 -качество в реальном времени -скорость 5 -потоки 8 -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 3000k ~78% 1,77x
854x480 (480p) -r 30 -g 90 -s 854x480 -качество в реальном времени -скорость 6 -потоки 4 -row-mt 1 -tile-columns 1 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 1800k ~64% 3,51x
640x360 (360p) -r 30 -g 90 -s 640x360 -качество в реальном времени -скорость 7 -потоки 4 -row-mt 1 -tile-columns 1 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 730k ~62% 5,27x
426x240 (240p) -r 30 -g 90 -s 426x240 -качество в реальном времени -скорость 8 -потоки 2 -row-mt 1 -tile-columns 0 -frame-parallel 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 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 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 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 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 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 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 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 vp9 -b:a 64k -c:a libopus -f webm pipe7

Вышеупомянутый полный набор, однако, потребует очень мощного процессора или, возможно, аппаратной поддержки разгрузки графического процессора, которую все чаще предоставляют некоторые наборы микросхем. Intel Kabylake (и более поздние версии) имеет полный аппаратный конвейер кодирования. (Обратите внимание, что графический процессор Kabylake может выполнять 8-битное кодирование VP9, ​​но не 10-битное).

Практический пример рабочего стола с использованием Shaka Packager

Более практичным примером для обычных настольных компьютеров может быть использование Shaka Packager . Простой способ настроить Shaka — установить его в контейнере Docker, используя образ Google DockerHub. Инструкции можно найти здесь:

https://github.com/google/shaka-packager#using-docker-for-testing--разработка

Для этого примера мы использовали машину со следующей конфигурацией:

Система Хост: 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 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 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 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