Двухпроводное кодирование сегментами < GPUCPU 1+2pass > -- OBS, NVEnc, nginx, RAMDisk, FFMpeg, x264

Двухпроводное сжатие с помощью второго ПК

 

Уникальная в своём роде инструкция, описывающая принцип сегментированного подхода к двухпроводному сжатию непрерывного потока.

 

1-й проход: сбор статистики о видеопотоке и генерация stats-файла.
2-й проход: непосредственно кодирование, с учетом статистики полученной из stats-файла.
Двухпроходное кодирование позволяет добиться значительного увеличения качества, с минимальными потерями в производительности. 

 

Чем меньше сегмент -- тем хуже качество и больше CBR
1сек сегмент = full CBR, качество = 1pass на стрим (бесполезный режим)
Чем больше сегмент -- тем лучше качество и больше VBR
10сек сегмент = full VBR, качество = 2pass на файл (режим где CBR и время ожидания не важно)

 

Оптимальный размер сегмента для стримов 2-4 сек. (по умолчанию 3 сек.)

Какую длину сегмента выбрать именно вам, см. далее (4'ый пункт, настройка ffmpeg)

1080p60, 6000kbps (faster, medium, slower, veryslow)

 

Параметры кодирования (менялся только пресет)

3sec-2pass-Segment:

-profile:v high -level 4.2 -preset veryslow -b:v 6M -bufsize 12M -nal-hrd cbr -aq-mode -pass 1/2

3sec-keyint-Stream-CBR:

-profile:v high -level 4.2 -preset veryslow -b:v 6M -maxrate 6M -bufsize 12M -nal-hrd cbr -aq-mode 2 -g 180

 

Затраченное время на кодирование при нагрузке CPU 95-100% (min:sec)

preset ---- stream - 2pass(segment)
faster ----- 00:20 --- 00:30
medium -- 00:29 --- 00:40
slower ---- 01:02 --- 01:11
veryslow - 01:27 --- 01:38

 

Скриншоты:

preset ---- stream - 2pass(segment)
faster ----- https://goo.gl/9mcuhu --- https://goo.gl/P1fYUA
medium -- https://goo.gl/2NXVvY --- https://goo.gl/Tb2YFd
slower ---- https://goo.gl/iRpuUM --- https://goo.gl/mbYtMH
veryslow - https://goo.gl/QE93ca --- https://goo.gl/vG8xva

source - https://goo.gl/rH9bUh

 

Файлы (оригинал и результаты):

https://yadi.sk/d/2QX8Xb4d3N9MGM

 

Данная методика, является развитием этой идеи https://goodgame.ru/topic/101878/

 

В данном случае, второй компьютер может быть соединен и как по локальной сети и только через HDMI карту захвата.

 

При использовании карты захвата, 2ПК обязан уметь кодировать в NVENC'e

 

1. В случае если 2'ой ПК, только-только вписывается в пресет medium на обычном поточном кодировании, то вы конечно можете попробовать fast-2pass или faster-2pass, но ощутимого прироста качества не ждите, только незначительные улучшения на стоп-кадрах (либо на 10сек сегментах)

 

2. В случае если второй компьютер способен в пресет veryslow на обычном поточном кодировании, то использование slower-2pass или slow-2pass даст примерно ту-же нагрузку на процессор, но с значительными улучшениями в качестве.

 

3. 2pass-veryslow в 1080p60 режим для ультра-топ процессоров, и с заделом на будущее. Когда мощности CPU обычных десктопов будут готовы на это.  На данный момент, только Intel Core i9 и AMD threadripper способны на это. 

 

4. Вы можете понизить FPS захвата (с 60 на 30), и/или изменить формат картинки с 1920:1080 на 1600:900 или 1280:720 (см. инструкцию далее), дабы вписаться в пресеты slow-slower-veryslow. Выбор за вами

 

 

0) Подготовка

 

В случае отсутствия карты захвата :

Необходимо, чтобы 1'ый и 2'ой ПК находились в одной локальной сети. Например подключенные к маршрутизатору/роутеру. И имели статические IP адреса.

Например 192.168.1.2 и 192.168.1.3., 192.168.1.1 у роутера.

 

Так-же, необходимо настроить фаервол на втором ПК, Для беспрепятственного доступа первого ПК, ко второму или по порту 1935 (TCP/UDP)

 

 

1) Настраиваем OBS/NVENC

 

В случае отсутствия карты захвата- выполняется на 1'ом ПК 

В случае карты захвата выполняется на 2'ом ПК с высоким приоритетом (настройки - расширенные - высокий приоритет)

 

Далее переходим в расширенный режим кодировщика, и указываем следующие опции:

 

 

CBR, Битрейт =50 000 !

Ключевые кадры=1, Пресет="малая задержка, высокая производительность"

Профиль=High, Уровень=4.2, Двухпроходное кодирование=да, B-кадры=2

Если вы используете масштабирование картинки - уберите, это мы будем делать позже (см. инструкцию ниже)

 

Далее, в настройках вещания, укажите пользовательский сервер с адресом

rtmp://192.168.1.3/instream

Где <192.168.1.3> - статический адрес 2'го ПК. Или

rtmp://127.0.0.1/instream

В случае карты захвата.

 

 

2) Скачиваем софт для 2'го ПК:

 

nginx: https://github.com/illuspas/nginx-rtmp-win32/archive/nms.zip

ffmpeg: https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-latest-win64-static.7z

RAMDisk: http://memory.dataram.com/__downloads/memory/ramdisk/Dataram_RAMDisk_4_4_0_RC36.msi

start-2pass.bat v2.0: https://yadi.sk/d/OUXVwcs73NDgQy

 

ffmpeg.exe, start-2pass_v2.0.bat, start-nginx.bat и stop-nginx.bat помещаем рядом с nginx.exe

 

 

3) Настраиваем Nginx

 

Для этого необходимо отредактировать nginx-rtmp-win32-master\conf\nginx.conf

worker_processes  1;
error_log  logs/error.log crit;
events {
    worker_connections  1024;
}
rtmp {
    server {
        listen 1935;
        ping 30s;
        notify_method get;
        application instream {
            live on;
            record off;
            allow publish 127.0.0.1;
            allow publish 192.168.1.2;
            deny publish all;
        }
    }
}

Обратите внимание <192.168.1.2> - адрес 1ПК

 

Далее, уже имеющийся файл stop.bat, при наличии stop-nginx.bat можно удалить.

 

Помните, закрывая окно с работающим nginx, вы НЕ останавливаете работу nginx, только через stop-nginx.bat происходит полное завершение его работы!

 

 

4) Настраиваем ffmpeg

 

Необходимые настройки содержатся в start-2pass.bat 

::               -[ Manual ]-
:: "-profile:v high" -- baseline // main // high 
:: "-level 4.2" ------- 3.1 - 720p30 // 3.2 - 720p60 // 4.1 - 1080p30 // 4.2 - 1080p60
:: "-preset veryfast" - veryfast // faster // fast // medium // slow // slower // veryslow
:: "-maxrate 6M -bufsize 12M" - flags in "settings=" for a full CBR (6M = 6000kbps)
:: "scale=" ----------- no resize 
:: "scale=1280:720" - resize to 720p, need -level 3.1 or 3.2
:: "segmenttime=3" - 2-10 second (keyint auto), 1 second not recommended

 

 

Переменной outstream, задаётся сервер отправки, здесь вы можете указать GG или Twitch

set outstream=rtmp://live-fra.twitch.tv/app/<key>

или оставить её пустой, например для тестов нагрузки. Перекодированный поток пойдёт в никуда.

set outstream=

 

1. Используем сегменты 2сек или 3сек; keyint вычисляется авто, относительно их длины.

2. Используем сегмент 4сек и самостоятельно вычисляем keyint=2*fps,

добавляем переменную "-g <знач>" в "settings="

 

Во втором случае, сегмент будет делится на 2 части интервалов keyint, что позволит одновременно держатся в пределах допустимых норм GG (и прочих серверов), но при этом дополнительно выигрывать в качестве относительно 2сек и 3сек сегментов с авто-keyint. Но это слегка (2-3сек) добавит задержку, к существующей 8-10сек задержке скрипта.

 

 

​5) Настраиваем RAMDisk

 

- Размер диска: 150MB (3s keyint) - 500MB (10s keyint)

- Файловая система: unformatted -> FAT32

- Буква диска: X

 

 

6) Порядок запуска

 

0. RAMDisk (2ПК)

1. start-nginx.bat (2ПК)

2. start-2pass.bat (2ПК)

3. OBS (1/2 ПК) 

 

 

7) Рестрим

 

Если необходимо отправлять перекодированный поток сразу на несколько серверов.

1. Укажите адрес отправки

set outstream=rtmp://localhost/outstream

 

2. Добавьте новую <outstream> секцию в nginx.conf

worker_processes  1;
error_log  logs/error.log crit;
events {
    worker_connections  1024;
}
rtmp {
    server {
        listen 1935;
        ping 30s;
        notify_method get;
        application instream {
            live on;
            record off;
            allow publish 127.0.0.1;
            allow publish 192.168.1.2;
            deny publish all;
        }
        application outstream {
            live on;
            record off;
            allow publish 127.0.0.1;
            deny publish all;
            push rtmp://live-fra.twitch.tv/app/<key>;
            push rtmp://msk.goodgame.ru:1940/live/<key>;
        }
    }
}

Указывайте rtmp адреса серверов через push  (не забудьте про ; в конце строк)

 

P.S. Примерная задержка на кодировании составит ~10сек, вместо 1-3сек при поточном кодировании. 

P.P.S Следите за приоритетами, у nginx и OBS (в случае карты-захвата на 2ом ПК) высокий приоритет (дабы не было дропов и просадок с получением и отправкой)