# "GPUCPU 1+2pass" stream encoding



## tracker35 (Feb 10, 2017)

The idea is as follows.

If there NVENC or QSV the master record goes through them, but with a high bitrate, say 50Mbps, files for 10 seconds (300/600 frames).

When the first file, the x264 starts first pass (fast), and after second pass, followed by the flow of transmission and so on file by file, thus to have on the flow of ~ 50% better quality of image than if you do the coding sequence.

1pass = nvenc/qsv
2pass = 1pass-x264
3pass = 2pass-x264

p.s. Sorry, google translate.


----------



## tracker35 (Feb 10, 2017)

The 10 seconds is not necessarily stored on disk. They are easy to fit in memory. ~ 63MB (50mbps) or 125MB(100mbps). Logs first passages, is also stored there.


----------



## pervokur (Apr 8, 2017)

I did it with rtmp server (Adobe Media Server on windows7)
OBS with QSV 30Mbps -> Adobe Media Server -> ffmpeg x264 3mbps -> twitch


----------



## tracker35 (Sep 18, 2017)

Manual (russian): https://goodgame.ru/topic/102016/

NVEnc -> nginx - > 3s segments -> 1/2 pass -> creation stream-file -> stream








The idea can be optimized (reduce the response time, 3-4s) if integrated in the functionality of OBS, otherwise ~10s


----------



## tracker35 (Sep 19, 2017)

UPD script to v1.4 - add option keyint and segments size (1 - 10 seconds), need RAMDisk 128MB(3s keyint) - 512MB(10s keyint)

https://yadi.sk/d/8KvDnztR3N5Spk


----------



## R1CH (Sep 20, 2017)

2 pass encoding is done so that available bitrate is proportionally distributed quality wise among the whole file. It doesn't make sense on a live stream. The VBV system takes care of ensuring bitrate constraints for live content.


----------



## tracker35 (Sep 21, 2017)

*R1CH, *If do not limit the bitrate parameter maxrate, within a segment it will be "vbr", but the overall look as "cbr".
As 2-pass codec will optimally fit into the specified bitrate ;) The size of encoded segment will be equal to size of the GOP in the 1st passage.






_2 pass encoding is done so that available bitrate is proportionally distributed quality wise among the whole  ̶f̶i̶l̶e̶  _*segment *;)​

Smaller segment -- less quality and more CBR
1s segment = full CBR, quality = 1pass on the stream (useless mode)

Larger segment -- better quality and less CBR
10s segment = full VBR, quality = 2pass on the file (mode where CBR and waiting time is not important)


Example,
"stream encode (1pass) CBR" vs "3s segment encode (2pass) VBR-in-CBR" - [x264 1080p60 6000kbps medium]
http://screenshotcomparison.com/comparison/118069


----------



## tracker35 (Sep 21, 2017)

UPD script to v1.5 
delete keyint option (auto = time segment), and made vbr-segments in cbr-stream for even better quality ;-)


----------



## tracker35 (Sep 21, 2017)

It would be cool. If someone took over the implementation of this functionality directly in OBS
since I have no programming skills necessary and skills in working memory for buffering nvenc stream, and log files.
script ver1.6: https://yadi.sk/d/u_TxaqwN3N8FWe


----------



## tracker35 (Sep 22, 2017)

The timeline, ideally the implementation of the encoding method. "GPUCPU 1+2pass"





5-6s delays at encoding

UPD: 



Spoiler:  'stream encode CBR' vs 'segment encode (2pass)' 



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

Encoding settings (changed only preset)

*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

The time spent on encoding. CPU load is 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

Screenshots:
preset ---- Stream-CBR --- 2pass (3sec 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

Files (original and results):
https://yadi.sk/d/2QX8Xb4d3N9MGM



UPD script v1.7 https://yadi.sk/d/dMOzNkQE3N9ozQ
Add optimization - launch ffmpeg from ramdisk for better performance


----------



## tracker35 (Sep 24, 2017)

UPD to 1.8 https://yadi.sk/d/z_xeKEir3NBezX
1: RAMdisk (create disk), 2: nginx (start server), 3: This script, and wait for message, 4: Stream-capture (NVENC or other GPU-encode)


----------



## tracker35 (Sep 26, 2017)

*UPD v2.0* https://yadi.sk/d/OUXVwcs73NDgQy
Added flag "stitchable" in script for correct build stream.
Now, all web-players launch the video!


----------



## tracker35 (Sep 27, 2017)

Two recipes of "happiness" ^_^"

1. Use segments of 2s or 3s, keyint is calculated relative to their length.
2. Use segments of 4s and manually calculated keyint=2*fps,
insert "-g <value>" in "settings="

In the second case the segment will be divided into 2 parts keyint intervals, allowing at the same time kept within acceptable norms, but also win with relative 2s and 3s segments with auto-keyint. But it's a little (2-3sec) will add delay to the existing 8-10sec delay, and increase vbr.


----------

