Question / Help How to get global_quality to work with nvenc

ezcapper

New Member
When I use the nvenc_hevc ffmpeg encoder, I enter the following additional video settings:

"preset=slow rc=0 global_quality=30"

but OBS does not use the global_quality (constant quality) setting; it is overridden by the specified bitrate. This is not a problem when using ffmpeg directly. What am I doing wrong? Thanks
 
I'm having the very same problem. I'd love to set the CQP setting for nvenc through the advanced ffmpeg parameters in OBS since advanced ffmpeg recording offers me more options (recording without any audio track, setting keyframe interval in number of frames instead of per seconds). However, I cannot figure out how to forward the necessary "global_quality" setting to nvenc this way.
 
Try using "cq" instead and see if that makes a difference.

This is from command-line ffmpeg -h encoder=nvenc_hevc
Code:
Encoder nvenc_hevc [NVIDIA NVENC hevc encoder]:
    General capabilities: delay
    Threading capabilities: none
    Supported pixel formats: yuv420p nv12 p010le yuv444p yuv444p16le bgr0 rgb0 cuda
nvenc_hevc AVOptions:
  -preset            <int>        E..V.... Set the encoding preset (from 0 to 11) (default medium)
     default                      E..V....
     slow                         E..V.... hq 2 passes
     medium                       E..V.... hq 1 pass
     fast                         E..V.... hp 1 pass
     hp                           E..V....
     hq                           E..V....
     bd                           E..V....
     ll                           E..V.... low latency
     llhq                         E..V.... low latency hq
     llhp                         E..V.... low latency hp
     lossless                     E..V.... lossless
     losslesshp                   E..V.... lossless hp
  -profile           <int>        E..V.... Set the encoding profile (from 0 to 4) (default main)
     main                         E..V....
     main10                       E..V....
     rext                         E..V....
  -level             <int>        E..V.... Set the encoding level restriction (from 0 to 186) (default auto)
     auto                         E..V....
     1                            E..V....
     1.0                          E..V....
     2                            E..V....
     2.0                          E..V....
     2.1                          E..V....
     3                            E..V....
     3.0                          E..V....
     3.1                          E..V....
     4                            E..V....
     4.0                          E..V....
     4.1                          E..V....
     5                            E..V....
     5.0                          E..V....
     5.1                          E..V....
     5.2                          E..V....
     6                            E..V....
     6.0                          E..V....
     6.1                          E..V....
     6.2                          E..V....
  -tier              <int>        E..V.... Set the encoding tier (from 0 to 1) (default main)
     main                         E..V....
     high                         E..V....
  -rc                <int>        E..V.... Override the preset rate-control (from -1 to INT_MAX) (default -1)
     constqp                      E..V.... Constant QP mode
     vbr                          E..V.... Variable bitrate mode
     cbr                          E..V.... Constant bitrate mode
     vbr_minqp                    E..V.... Variable bitrate mode with MinQP
     ll_2pass_quality             E..V.... Multi-pass optimized for image quality (only for low-latency presets)
     ll_2pass_size                E..V.... Multi-pass optimized for constant frame size (only for low-latency presets)
     vbr_2pass                    E..V.... Multi-pass variable bitrate mode
  -rc-lookahead      <int>        E..V.... Number of frames to look ahead for rate-control (from -1 to INT_MAX) (default -1)
  -surfaces          <int>        E..V.... Number of concurrent surfaces (from 0 to 64) (default 32)
  -cbr               <boolean>    E..V.... Use cbr encoding mode (default false)
  -2pass             <boolean>    E..V.... Use 2pass encoding mode (default auto)
  -gpu               <int>        E..V.... Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on. (from -2 to INT_MAX) (default any)
     any                          E..V.... Pick the first device available
     list                         E..V.... List the available devices
  -delay             <int>        E..V.... Delay frame output by the given amount of frames (from 0 to INT_MAX) (default INT_MAX)
  -no-scenecut       <boolean>    E..V.... When lookahead is enabled, set this to 1 to disable adaptive I-frame insertion at scene cuts (default false)
  -forced-idr        <boolean>    E..V.... If forcing keyframes, force them as IDR frames. (default false)
  -spatial_aq        <boolean>    E..V.... set to 1 to enable Spatial AQ (default false)
  -temporal_aq       <boolean>    E..V.... set to 1 to enable Temporal AQ (default false)
  -zerolatency       <boolean>    E..V.... Set 1 to indicate zero latency operation (no reordering delay) (default false)
  -nonref_p          <boolean>    E..V.... Set this to 1 to enable automatic insertion of non-reference P-frames (default false)
  -strict_gop        <boolean>    E..V.... Set 1 to minimize GOP-to-GOP rate fluctuations (default false)
  -aq-strength       <int>        E..V.... When Spatial AQ is enabled, this field is used to specify AQ strength. AQ strength scale is from 1 (low) - 15 (aggressive) (from 1 to 15) (default 8)
  -cq                <int>        E..V.... Set target quality level (0 to 51, 0 means automatic) for constant quality mode in VBR rate control (from 0 to 51) (default 0)
  -aud               <boolean>    E..V.... Use access unit delimiters (default false)
  -bluray-compat     <boolean>    E..V.... Bluray compatibility workarounds (default false)
 
Omg, "cq" must be one of the few parameter names I haven't tried. It makes a big difference and seems to work fine. Now I need to also try it in conjunction with other parameters such as the "preset" and "rc" options, but it already seems to do some kind of CQP when leaving the rest of the parameters at their defaults. Thanks a lot!

EDIT: I wonder how OBS does it though... just using "-cq" (and the nvenc encoder) with ffmpeg directly doesn't yield the same effect. Depending on the preset or rate control setting it even expects other options like qmin/qmax being set for using constant quality mode, or it doesn't have any effect. By the way, the options you showed are for the hevc (h265) encoder, but the options for h264 are similar. Just saying since h264 is more popular still, I suppose.
 
Last edited:
After playing around more with OBS and ffmpeg, I think it's not that simple. Actually I think that the options (in ffmpeg) are a mess. If you set the bitrate to zero in OBS and use "cq=..." in the options, it does something that resembles constant quantisation parameter behavior at first sight. But I'm not sure if it's the real thing.

The way CQP rate control is supposed to work in h264_nvenc seems to be to use "rc=constqp" which would force rate control to use CQP. But then this requires "global_quality" to be set as well, see "/libavcodec/nvenc.c" of the ffmpeg source, function "nvenc_override_rate_control". It explicitly outputs a warning when not specifying a global_quality setting.

What OBS does when CQP is chosen as rate control in the advanced recording settings (not the ffmpeg variant of the advanced settings but the regular advanced settings) is to set the bitrate to 0 and set the global_quality of the nvenc_encoder struct to the given cqp (see the "nvenc_update" function in "/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c" of the OBS source). This global_quality is then used in ffmpeg to set B, P and intra frame qualities to this value in the "set_constqp" function in "/libavcodec/nvenc.c" of the ffmpeg source.

And indeed, using ffmpeg directly with e.g. "-rc constqp -global_quality 16" and with "b:v 0 -cq 16" gives very different results in file size even though in both cases varying the "16" to something higher or lower gives different results in quality.

Bottom line is: I still don't know how to use the real constqp mode of nvenc and specify the desired constant quantisation parameter in OBS when using ffmpeg settings directly for recording.
 
When you use constqp, you need to set the value qp=1-51 (thats what i found out by testing)
global_quality and cq had no effect at all.
Anyway, these are my current settings, I was hoping to get some suggestions how to improve them even more here.
Bitrate = 0
Keyframe interval = 30
encoder settings: rc=constqp qp=32 2pass=1
this is using 0.7 - 4 MB /second @ 1080p 60 fps
Quality comparison:
https://www.dropbox.com/s/jzsz4mfw8bcr2rb/el-screenshot.png?raw=1
https://www.dropbox.com/s/vind8ilkgk18hb5/el-video.png?raw=1

EDIT::::::
My new settings are
Bitrate = 0
Keyframe interval = 250
-preset slow -x265-params qp=25 -rc vbr -tier high -2pass=1
i'm not sure about the 2pass=1 parameter, it definitively affects image quality, but the slow preset should actually have 2pass already included
.... the more i test it the more i come to the conclusion that the preset parameter gets ignored or overwritten by the detailed settings....

comparison: (needs gimp to open)
(Maybe not the optimal image for comparisons, but i was too lazy to do it again)
https://www.dropbox.com/s/wj4vstfp4jpmpme/flamingos test.xcf?raw=1
a 10 second file from the 4k test video ( https://www.youtube.com/watch?v=Bey4XXJAqS8&t=95 ) in 2560x1440 @ 60 fps
qp=25 2pass: 19 MB
qp=25: 18 MB
qp=20: 30 MB
qp=18: 41 MB
qp=1: 242 MB
Note that half of my recording was utilizing a pretty low bitrate, it spiked only in the flamingo scene (approx half of the video) so your mileage may vary...
 
Last edited:
Back
Top