Curious as to what options others are using in FFmpeg for av1_nvenc encoding.
testing
Been playing some Nier Automata; saved off some of my gameplay using FFmpeg and noticed the foliage looked insanely bad.
Here's the base command, usually I'm doing segmentation, but I've removed anything unnecessary for the sake of example:
Most relevant part is the
-rc:v vbr -cq 18
bit. I did some digging because the quality was fairly atrocious, and I eventually came across this HandBrake issue on GitHub. Long story short I was missing some parameters, specifically the following.
Sure enough, my quality drastically increased, but so did my file size; by a factor of 35... This threw me for a loop, because I ostensibly set the same values in OBS. And get much smaller files (5x), with similar visual quality.
From there I upped my -cq
level from 18 to 36 in FFmpeg, which only cut the file down around 15%. After which I returned to that GitHub issue to read the rest of the comments, and some people suggested that -rc:v constqp -qp [int]
was the way to go. So, I changed out the relevant parameters.
Sure enough... much smaller file (3x) with similar quality to the previous commands that were using -cq
. Even when I bump -qp
up to 72
I get pretty good looking results imo.
confused about
1. Nvidia seems to suggest you use -rc:v vbr -cq [int]
instead of -rc:v constqp -cq [int]
in FFmpeg
2. -rc:v constqp -qp [int]
seems to be preferable via mine and others' testing in FFmpeg
3. OBS ostensibly uses cq
and not qp
assuming that their labels are correct. However, output from OBS doesn't seem to be gargantuan like FFmpeg with similar settings.
video examples
1. FFmpeg cq 18 without qmin/qmax & b:v 0 (video example (56MB
) | command)
2. FFmpeg cq 18 with qmin/qmax & b:v 0 (1750MB
) (video example (1750MB
) | command)
3. OBS cq 18 (video example (308MB
) | settings)
4. FFmpeg cq 36 with qmin/qmax & b:v 0 (video example (1333MB
) | command)
5. FFmpeg qp 36 (video example (540MB
) | command)
6. [FFmpeg qp 72 (video example (239MB
) | command)11 Replies
Anywho, seems like I should be using
constqp
with a qp
value somewhere between 36 & 72 to get a similar file size / quality when compared to my OBS configuration.
Interested on what others are doing. Feels like a huge rabbit hole.Yeah Nvidia is wrong about using vbr, that's only useful for actual vbr stuff that you may find in video editor exports (which is a big on Nvidia 's side, not FFmpeg IIRC)
Otherwise OBS uses the Nvidia encoder headers directly rather than through FFmpeg which has its own stuff implemented on top of things.
Vbr-cq is a very different rate control compared to cqp. It's more akin to CRF. If you want cqp, then yes, use that 🙂
I like vbr-cq for final delivery stuff, but would go cqp if you're gonna edit or further handle the files
From my understanding
vbr
& cq
is also quite different from software encoding + crf
.
If I take a the file encoded with the GPU via vbr
& -cq 18
, and re-encode it with software based libsvtav1
at -crf 18
the file is 4.5x (486MB
vs 1750MB
) smaller and visually indifferent. The scale for CRF goes to 63
for libsvtav1
& -crf
as well. So, a more apt comparison would likely be around level 22
.
Of course nothing is apples to apples when comparing encoders. But what I mean to demonstrate is that seemingly the only way to get a similar file size / quality balance in FFmpeg via GPU encoding when compared to software encoded AV1 via FFmpeg or GPU encoded AV1 in OBS is to use constqp
.
No matter how I configure vbr
+ cq
via GPU accelerated encoding in FFmpeg, I always end up with a file 4x+ times larger with no obvious visual quality gain; when compared to OBS or constqp
.I read that software encoding +
crf
allows for a dynamic quantization value, where-as Nvidia's cq and qp options don't.
In Nvidia's documentation there's a section about "adaptive quantiziation" via the -spatial-aq
, -temporal-aq
& -aq-strength
flags, and said options show as available via the av1_nvenc
encoder (ffmpeg -h encoder=av1_nvenc
); but it doesn't appear to affect anything per my testing.You can't really just take the values between encoders. It's not the same rate control, nor the same range. Gotta work out the ranges desperately, and they will lean differently as well, even if you get them close on average . When I say similar, I mean the intent, not that they behave closely
Not true. You can do aq, when when cqp mode (although it is silly to do), but vbr-cq is intended to be used with variable quant, cqp is not (hence the name). At least that is my interpretation
CQP and CRF are also two separate things that aren't directly comparable: CQP will change the bitrate and other stuff to meet that constant QP level, meaning the artifacts/macroblocking across all frames will be basically identical regardless of motion
CRF instead changes the QP based on motion to keep the artifacts/macroblocking minimal
So essentially CQP is the "dumb" or brute force way of maintaining quality, which leads to larger overall file size than CRF which is more intelligent. CPU's don't do CRF because that's more complex and would require more die space for the encoder to hold those instructions, which is already an issue for current NVENC competing for die space with the rest of the hardware
If I remember right, Intel supports true vbr-cq but I think that's only for h264 and hevc
Side note: for testing spatial & temporal AQ, you may want to play with the AQ strength with
-aq-strength
also, from reading this again. using vbr-cq with qmin and qmax at 18 does not make much sense. vbr-cq wants to vary the quant to rd-optmize, but its not being permitted to. I feel like this would be more or less a hacky CQP, as you're just locking the quant, with an ofset. cq 18 essentially becomes qp24 for i,p and b frames.
Also, I think you should vary that your command is may be invalid for vbr-cq. You're not specifying a maxrate nor bufsize, and if (like modern versions of HEVC) this defaults, then you are stuck with a crappy VBR limit (HRD will constrain).
Try setting
-cq 1
and it should really ballon in size. If it does not, then HRD is kicking your butt, and it will hardly matter what cq you specify past a certain threshold. If that is the case, then try adding -maxrate 240M -bufsize 480M
to the -cq 1
, and see if that does not substantially increase the size. Once that is confirmed, vbr-cq should be working the way you intended (pseudo VBR, constant quality, bits placed for human vision).I've messed with vbr-cq a bit, like putting
qmin
& qmax
at different values. But it typically just hugs the higher number.
If you don't specify a bitrate (like I did with 0) it defaults to 2000, some FFmpeg thing. So my first test was to set cq
at 1 and it changed almost nothing. But that was because you also need to set the bit rate separately. With my example commands if I put cq
at 1
I do get a massive file.
But yeah... I've felt the same way, like I must be misusing something. But I see everyone online doing the same stuff. Most people suggest setting cq
to 1
and qmin
& qmax
5 or so levels apart. But no matter how set min/max I get massive files that look no better than using constqp
. For example something like -cq 1 -qmin 30 -qmax 36
.
I'd be interested to understand the difference in implementation for OBS and FFmpeg. Because in OBS you just set it to 18, get a good file size, and great quality. I get a similar result with constqp -qp 52
in FFmpeg. But I can't get anything even approximating the same file size using vbr-cq.
Maybe if I started messing with bitrates manually I could get something going. But in my head that just defeats the purpose of using one of the "constant quality" modes.
Yeah I tried putting that at 1
and 15
, it could be that it just doesn't work with the constant quality modes. Which would make sense logically. But it'd be nice if I get the quality to drop with no movement and rise with a lot of movement. Can't seem to get anything like that going.
constqp
seems like the way to go with GPU acceleration in FFmpeg. I appreciate you guys throwing out some ideas though, I'd just like to understand it all :CH_BigBrain:OBS does not have access to VBR-CQ at all, so it cannot be used there. All you have is CQP (despite it saying CQ value in the UI).
Here is a decent example of how VBR-CQ will generate smaller files than CQP (when adjusted for avg QP), for me, on racing video game
-c:v hevc_nvenc -rc vbr -cq 24 -preset p7 -maxrate 240M -bufsize 480M
maxrate and bufsize is ridiclously high, cus I in essence don't want to be limited, and just want CQ to hit the quants it believes is good.
File is smaller than CQP, but visually comparable, as its cut some data in ranges where human don't really notice much (high frequency areas etc). It also seems to use a lower quant for areas that a bright and sharp (it deems important). Has overall lower accuracy, but that is to be expected, and if that is what you're after, then you should be using CQP anyway (this is not for accuracy)
Personally, I would definitely add inn AQ (For VBR-CQ) for even more savings (or quality gain) for human visual perception. It is up to you tho @ninburaThanks for the follow up, I'll try and mess with this some more tomorrow to see if I get desirable results.