Log in

View Full Version : x265 undershooting 500 Kbps encode by almost 100 Kbps in 2-pass encode


singhkays
16th April 2019, 01:07
I encoded a scene from Tears of Steel 1080p mov source with the following settings

./ffmpeg -i scene1.mp4 -c:v libx265 -an -b:v 500k -filter:v scale=720:-1 -preset veryslow -pass 1 -x265-params 'no-strong-intra-smoothing=1:no-sao=1:deblock=-2\:-2' -f mp4 -y /dev/null &&

./ffmpeg -i scene1.mp4 -movflags faststart -pix_fmt yuv420p -c:v libx265 -an -b:v 500k -filter:v scale=720:-1 -pass 2 -hide_banner -preset veryslow -x265-params 'no-strong-intra-smoothing=1:no-sao=1:deblock=-2\:-2' ./x265/scene1/x265_500k.mp4

The resultant video stream has a bitrate of 400 Kb/s instead of expected 500 Kb/s. Are there any settings I'm missing to constrain the bitrate to 500? Here is the info from ffmpeg

x265 [info]: HEVC encoder version 3.0+1-ed72af837053
x265 [info]: build info [Linux][GCC 6.3.0][64 bit] 8bit+10bit+12bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
x265 [info]: Main profile, Level-2.1 (Main tier)
x265 [info]: Thread pool created using 12 threads
x265 [info]: Slices : 1
x265 [info]: frame threads / pool features : 3 / wpp(5 rows)
x265 [info]: Coding QT: max CU size, min CU size : 64 / 8
x265 [info]: Residual QT: max TU size, max depth : 32 / 3 inter / 3 intra
x265 [info]: ME / range / subpel / merge : star / 57 / 4 / 5
x265 [info]: Keyframe min / max / scenecut / bias: 24 / 250 / 40 / 5.00
x265 [info]: Lookahead / bframes / badapt : 40 / 8 / 2
x265 [info]: b-pyramid / weightp / weightb : 1 / 1 / 1
x265 [info]: References / ref-limit cu / depth : 5 / off / off
x265 [info]: AQ: mode / str / qg-size / cu-tree : 2 / 1.0 / 32 / 1
x265 [info]: Rate Control / qCompress : ABR-500 kbps / 0.60
x265 [info]: tools: rect amp rd=6 psy-rd=2.00 rdoq=2 psy-rdoq=1.00 rskip
x265 [info]: tools: signhide tmvp b-intra deblock(tC=-2:B=-2)
Output #0, mp4, to './x265/scene1/x265_500k.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.27.101
Stream #0:0(eng): Video: hevc (libx265) (hev1 / 0x31766568), yuv420p, 720x300 [SAR 1:1 DAR 12:5], q=2-31, 500 kb/s, 24 fps, 12288 tbn, 24 tbc (default)
Metadata:
handler_name : VideoHandler
encoder : Lavc58.49.100 libx265
Side data:
cpb: bitrate max/min/avg: 0/0/500000 buffer size: 0 vbv_delay: -1
[mp4 @ 0x5708cc0] Starting second pass: moving the moov atom to the beginning of the file.117x
frame= 91 fps=3.1 q=-0.0 Lsize= 189kB time=00:00:03.66 bitrate= 422.4kbits/s speed=0.126x
video:185kB audio:0kB subtitle:0kB other streams:0kB global headers:2kB muxing overhead: 2.205378%
x265 [info]: frame I: 1, Avg QP:24.91 kb/s: 3813.50
x265 [info]: frame P: 24, Avg QP:25.40 kb/s: 1046.35
x265 [info]: frame B: 66, Avg QP:33.79 kb/s: 111.78
x265 [info]: Weighted P-Frames: Y:0.0% UV:0.0%
x265 [info]: Weighted B-Frames: Y:0.0% UV:0.0%
x265 [info]: consecutive B-frames: 4.0% 4.0% 16.0% 76.0% 0.0% 0.0% 0.0% 0.0% 0.0%

encoded 91 frames in 29.11s (3.13 fps), 398.94 kb/s, Avg QP:31.48

The original and encoded file can be downloaded from here https://github.com/singhkays/sample-files/raw/master/x265-undershoot-samples.zip

poisondeathray
16th April 2019, 03:48
You're actually only encoding a 1st pass . You can verify with mediainfo and it will say stats-read=0 ; but it's supposed to say stats-read=2 , because in the 2nd or more passes it should be reading the stats file

Another clue is the cutree and log file isn't written, only the ffmpeg2pass-0.log , which is blank


You need to add pass=1, pass=2 for x265-params , and I would also explicitly specify the log to read and write

In windows it looks like this


ffmpeg -i scene1.mp4 -c:v libx265 -an -b:v 500k -filter:v scale=720:-1 -preset veryslow -pass 1 -x265-params "no-strong-intra-smoothing=1:no-sao=1:deblock=-2\:-2:pass=1:stats='mylog.log'" -f mp4 -y NUL && ^
ffmpeg -i scene1.mp4 -movflags faststart -pix_fmt yuv420p -c:v libx265 -an -b:v 500k -filter:v scale=720:-1 -pass 2 -hide_banner -preset veryslow -x265-params "no-strong-intra-smoothing=1:no-sao=1:deblock=-2\:-2:pass=2:stats='mylog.log'" x265_500k_2pass.mp4


But it still undershoots, albeit less (476kb/s instead of the 400kb/s 1st pass)

I'll check x265cli later to see if there is any difference, if there is, I'll report back (maybe libx265 issue)

Also it might be a source timebase issue (12288 tbn ?)

But it might also be too short of a segment to accurately hit bitrate targets

singhkays
16th April 2019, 21:23
You're actually only encoding a 1st pass . You can verify with mediainfo and it will say stats-read=0 ; but it's supposed to say stats-read=2 , because in the 2nd or more passes it should be reading the stats file

Another clue is the cutree and log file isn't written, only the ffmpeg2pass-0.log , which is blank


You need to add pass=1, pass=2 for x265-params , and I would also explicitly specify the log to read and write

In windows it looks like this


ffmpeg -i scene1.mp4 -c:v libx265 -an -b:v 500k -filter:v scale=720:-1 -preset veryslow -pass 1 -x265-params "no-strong-intra-smoothing=1:no-sao=1:deblock=-2\:-2:pass=1:stats='mylog.log'" -f mp4 -y NUL && ^
ffmpeg -i scene1.mp4 -movflags faststart -pix_fmt yuv420p -c:v libx265 -an -b:v 500k -filter:v scale=720:-1 -pass 2 -hide_banner -preset veryslow -x265-params "no-strong-intra-smoothing=1:no-sao=1:deblock=-2\:-2:pass=2:stats='mylog.log'" x265_500k_2pass.mp4


But it still undershoots, albeit less (476kb/s instead of the 400kb/s 1st pass)

I'll check x265cli later to see if there is any difference, if there is, I'll report back (maybe libx265 issue)

Also it might be a source timebase issue (12288 tbn ?)

But it might also be too short of a segment to accurately hit bitrate targets

Thank you! It's weird ffmpeg x265 wiki makes no mention of having to specify x265 params pass info + ffmpeg pass info but your suggestion works!

sneaker_ger
16th April 2019, 21:49
The doc explicitly mentions it.
In pass 1 and 2, use the -x265-params pass=1 and -x265-params pass=2 options, respectively.
[...]
For libx265, the -pass option (that you would use for libx264) is not applicable.
https://trac.ffmpeg.org/wiki/Encode/H.265

singhkays
16th April 2019, 22:43
The doc explicitly mentions it.

https://trac.ffmpeg.org/wiki/Encode/H.265

Oh shoot! I think i looked at 264 wiki and changed libx264 to libx265. Thanks for clarifying!