How to use Constrained Quality?

1,237 views
Skip to first unread message

Philip Jägenstedt

unread,
Apr 8, 2011, 2:12:50 PM4/8/11
to WebM Discussion
After reading
http://blog.webmproject.org/2011/03/vp8-constrained-quality-cq-encoding.html
and trying to use CQ myself I have some questions.

The example command line is:

vpxenc infile.yv12 -o outfile.webm --end-usage=2 --cq-level=28
--target-bitrate=800 --good -v -t 0 -w 640 -h 360 -p 1 --cpu-used=0
--fps=30000/1000 --lag-in-frames=25 --min-q=6 --max-q=48 --codec=vp8
--auto-alt-ref=1 --kf-max-dist=150 --kf-min-dist=0 --drop-frame=0
--static-thresh=0 --bias-pct=50 --minsection-pct=10 --maxsection-pct=800
--arnr-maxframes=7 --arnr-strength=5 --arnr-type=3 --sharpness=0
--undershoot-pct=100

This seems a little bit confused. It's a 1-pass command, but the vpxenc
warnings makes me wonder if it was supposed to be 2-pass encoding:

Warning: option bias-pct=50 ignored in one-pass mode.
Warning: option minsection-pct=10 ignored in one-pass mode.
Warning: option maxsection-pct=800 ignored in one-pass mode.

Is there any tangible benefit from running CQ in 2-pass, or is it just a
waste of time?

Further, the slides state for --cq-level that "Allowed range is 0-63 :
mapping to quantizer as in --minq and --maxq"

Is there then any benefit in also specifying --min-q and --max-q as in the
example command, is --bitrate not enough to effectively keep the maximum
bitrate under control? Wanting to have a maximum quality setting seems
extremely odd, so why ever use --min-q?

Basically, what I'm looking for is a configuration that approximates a
certain perceptual quality, that I could use independent of resolution. Is
--cq-level the answer, or is it necessary to also set some of the other
parameters appropriately to get good results?

Background: I'm adding support for CQ to GStreamer vp8enc, so basically
what I'm trying to understand is how to map the quality property.
Currently, for VBR it's a 0-10 value that maps to minq=maxq=63-5*quality,
i.e. a fixed quantizer 13-63. I'm hoping that making it work for CQ is as
simple as mapping 0-10 to a cq-level in some suitable range (13-63 seems
odd, but maybe it would work).

Any guidance is appreciated!

--
Philip Jägenstedt
Core Developer
Opera Software

John Koleszar

unread,
Apr 8, 2011, 2:59:59 PM4/8/11
to webm-d...@webmproject.org, Philip Jägenstedt
On Fri, Apr 8, 2011 at 2:12 PM, Philip Jägenstedt <phi...@opera.com> wrote:
> After reading
> http://blog.webmproject.org/2011/03/vp8-constrained-quality-cq-encoding.html
> and trying to use CQ myself I have some questions.
>
> The example command line is:
>
> vpxenc infile.yv12 -o outfile.webm --end-usage=2 --cq-level=28
> --target-bitrate=800 --good -v -t 0 -w 640 -h 360 -p 1 --cpu-used=0
> --fps=30000/1000 --lag-in-frames=25 --min-q=6 --max-q=48 --codec=vp8
> --auto-alt-ref=1 --kf-max-dist=150 --kf-min-dist=0 --drop-frame=0
> --static-thresh=0 --bias-pct=50 --minsection-pct=10 --maxsection-pct=800
> --arnr-maxframes=7 --arnr-strength=5 --arnr-type=3 --sharpness=0
> --undershoot-pct=100
>
> This seems a little bit confused. It's a 1-pass command, but the vpxenc
> warnings makes me wonder if it was supposed to be 2-pass encoding:
>
> Warning: option bias-pct=50 ignored in one-pass mode.
> Warning: option minsection-pct=10 ignored in one-pass mode.
> Warning: option maxsection-pct=800 ignored in one-pass mode.
>

Probably just lazy cut and paste.

> Is there any tangible benefit from running CQ in 2-pass, or is it just a
> waste of time?

Absolutely. In fact it's primarily useful in 2-pass. It does work in
1-pass (in Git, Bali was broken in 1-pass CQ)

>
> Further, the slides state for --cq-level that "Allowed range is 0-63 :
> mapping to quantizer as in --minq and --maxq"
>
> Is there then any benefit in also specifying --min-q and --max-q as in the
> example command, is --bitrate not enough to effectively keep the maximum
> bitrate under control? Wanting to have a maximum quality setting seems
> extremely odd, so why ever use --min-q?

min/max q are still the ultimate constraints, and the encoder will use
a lower q than the specified cq level for certain frames. but in
general, you should be fine just setting min/max q near their limits
and setting the cq level.

>
> Basically, what I'm looking for is a configuration that approximates a
> certain perceptual quality, that I could use independent of resolution. Is
> --cq-level the answer, or is it necessary to also set some of the other
> parameters appropriately to get good results?
>
> Background: I'm adding support for CQ to GStreamer vp8enc, so basically what
> I'm trying to understand is how to map the quality property. Currently, for
> VBR it's a 0-10 value that maps to minq=maxq=63-5*quality, i.e. a fixed
> quantizer 13-63. I'm hoping that making it work for CQ is as simple as
> mapping 0-10 to a cq-level in some suitable range (13-63 seems odd, but
> maybe it would work).
>
> Any guidance is appreciated!
>

cq really wants both the cq level and bitrate as variables, but if you
don't have bitrate (or want to approximate "don't care") then set the
bitrate to $BIGNUM, this will be much much better than the old
behavior of setting minq==maxq in any case.

Basil Mohamed Gohar

unread,
Apr 8, 2011, 3:04:08 PM4/8/11
to webm-d...@webmproject.org, Philip Jägenstedt
John already replied to you with a more technical discussion, but I thought I'd share some options I've used that I've found to give me good quality and acceptable bitrates.  My main target is uploading to YouTube in HD, so that is guiding my choices.

vpxenc --output=output.webm --passes=2 --fpf=fpf --best --verbose --threads=4 --lag-in-frames=25 --end-usage=cq --target-bitrate=1000000 --min-q=10 --max-q=20 --kf-max-dist=250 --auto-alt-ref=1 --tune=ssim --cq-level=15 input.y4m

Philip Jägenstedt

unread,
Apr 9, 2011, 2:36:40 AM4/9/11
to webm-d...@webmproject.org, John Koleszar
On Fri, 08 Apr 2011 20:59:59 +0200, John Koleszar <jkol...@google.com>
wrote:

> On Fri, Apr 8, 2011 at 2:12 PM, Philip Jägenstedt <phi...@opera.com>
> wrote:
>> After reading
>> http://blog.webmproject.org/2011/03/vp8-constrained-quality-cq-encoding.html
>> and trying to use CQ myself I have some questions.
>>
>> The example command line is:
>>
>> vpxenc infile.yv12 -o outfile.webm --end-usage=2 --cq-level=28
>> --target-bitrate=800 --good -v -t 0 -w 640 -h 360 -p 1 --cpu-used=0
>> --fps=30000/1000 --lag-in-frames=25 --min-q=6 --max-q=48 --codec=vp8
>> --auto-alt-ref=1 --kf-max-dist=150 --kf-min-dist=0 --drop-frame=0
>> --static-thresh=0 --bias-pct=50 --minsection-pct=10 --maxsection-pct=800
>> --arnr-maxframes=7 --arnr-strength=5 --arnr-type=3 --sharpness=0
>> --undershoot-pct=100

>> Is there any tangible benefit from running CQ in 2-pass, or is it just a


>> waste of time?
>
> Absolutely. In fact it's primarily useful in 2-pass. It does work in
> 1-pass (in Git, Bali was broken in 1-pass CQ)

Oh, this was the opposite answer from what I expected. 2-pass is obviously
useful for distributing a fixed number of bits, but you're saying that
distributing "quality" can also benefit from the first pass analysis? If
anyone wants to elaborate on why this is the case and what kind of edge
cases it helps the most in I'd be very interested in learning more.

Also, is there any point in combining 2-pass and lagged encoding, or is
that just silly?

>> Further, the slides state for --cq-level that "Allowed range is 0-63 :
>> mapping to quantizer as in --minq and --maxq"
>>
>> Is there then any benefit in also specifying --min-q and --max-q as in
>> the
>> example command, is --bitrate not enough to effectively keep the maximum
>> bitrate under control? Wanting to have a maximum quality setting seems
>> extremely odd, so why ever use --min-q?
>
> min/max q are still the ultimate constraints, and the encoder will use
> a lower q than the specified cq level for certain frames. but in
> general, you should be fine just setting min/max q near their limits
> and setting the cq level.

OK, I'll start out with the same max/min quant regardless of cq-level
then. The default limits in vp8_cx_iface.c are 4/63, is this a good
default or is there any point in decreasing min-q to 0 to give the encoder
the maximum amount of freedom?

>> Basically, what I'm looking for is a configuration that approximates a
>> certain perceptual quality, that I could use independent of resolution.
>> Is
>> --cq-level the answer, or is it necessary to also set some of the other
>> parameters appropriately to get good results?
>>
>> Background: I'm adding support for CQ to GStreamer vp8enc, so basically
>> what
>> I'm trying to understand is how to map the quality property. Currently,
>> for
>> VBR it's a 0-10 value that maps to minq=maxq=63-5*quality, i.e. a fixed
>> quantizer 13-63. I'm hoping that making it work for CQ is as simple as
>> mapping 0-10 to a cq-level in some suitable range (13-63 seems odd, but
>> maybe it would work).
>>
>> Any guidance is appreciated!
>>
>
> cq really wants both the cq level and bitrate as variables, but if you
> don't have bitrate (or want to approximate "don't care") then set the
> bitrate to $BIGNUM, this will be much much better than the old
> behavior of setting minq==maxq in any case.

OK, I'll try this!

One further question: since cq-level is a quantizer, how should one
understand it? Is it an "average" quantizer, or how will the actual
quantizer use relate to cq-level? I'd very much like to do some test
encodes and see histograms of the quantizer levels used, is there an
instrumented version of libvpx to do this (in the encoder or decoder), or
am I left to my own devices for that? I'm also curious how you produced
the PSNR/datarate graphs in the slides, is that just using vpxenc --psnr |
grep?

I think it is important for the usability of libvpx that we are able to
recommend configurations that "just work" most of the time, so it would be
great if knowledge like "2-pass and lagged encoding are mutually
exclusive" (if that's true) and "CQ works best in 2-pass" were documented
somewhere. Is http://www.webmproject.org/tools/encoder-parameters/ going
to be updated with information about CQ?

John Koleszar

unread,
Apr 11, 2011, 8:53:27 AM4/11/11
to Philip Jägenstedt, webm-d...@webmproject.org

Maybe I should have chosen my words more carefully. It benefits from
two pass because two pass does a better job of reference frame
selection, and just in general that our two pass rate control is
better. There's nothing I can think of inherent in CQ that makes it
apply in theory more in one case than the other.

> Also, is there any point in combining 2-pass and lagged encoding, or is that
> just silly?
>

Here's another answer opposite of what you expected :) Lagged encoding
is only useful in two pass at the moment. It's required to make use of
alt ref frames, which are only implemented in two pass right now.
We've got some ideas for making more use of it in one pass, but
nothing implemented yet.


>>> Further, the slides state for --cq-level that "Allowed range is 0-63 :
>>> mapping to quantizer as in --minq and --maxq"
>>>
>>> Is there then any benefit in also specifying --min-q and --max-q as in
>>> the
>>> example command, is --bitrate not enough to effectively keep the maximum
>>> bitrate under control? Wanting to have a maximum quality setting seems
>>> extremely odd, so why ever use --min-q?
>>
>> min/max q are still the ultimate constraints, and the encoder will use
>> a lower q than the specified cq level for certain frames. but in
>> general, you should be fine just setting min/max q near their limits
>> and setting the cq level.
>
> OK, I'll start out with the same max/min quant regardless of cq-level then.
> The default limits in vp8_cx_iface.c are 4/63, is this a good default or is
> there any point in decreasing min-q to 0 to give the encoder the maximum
> amount of freedom?
>

min-q of 0 sounds good.

It's used as a lower bound on the quantizer for "normal" frames --
key/golden/alt-ref frames may use a lower Q, and if you start to bump
up against the bitrate limit, then the Q on normal frames will rise as
well. There's no instrumented version that will give you what you
want, but it should be trivial to use the VP8E_GET_LAST_QUANTIZER_64
control on the encoder to get the Q used for the last frame.

The graphs were probably generated from the opsnr.stt file output when
you configure with --enable-psnr, but vpxenc --psnr | grep should be
equivalent.

> I think it is important for the usability of libvpx that we are able to
> recommend configurations that "just work" most of the time, so it would be
> great if knowledge like "2-pass and lagged encoding are mutually exclusive"
> (if that's true) and "CQ works best in 2-pass" were documented somewhere. Is
> http://www.webmproject.org/tools/encoder-parameters/ going to be updated
> with information about CQ?
>

I agree. Updating that page has been on the TODO for a while. Created
issue #313 to track.

Philip Jägenstedt

unread,
Apr 17, 2011, 1:36:24 PM4/17/11
to John Koleszar, webm-d...@webmproject.org
On Mon, 11 Apr 2011 14:53:27 +0200, John Koleszar <jkol...@google.com>
wrote:

Thanks for your guidance, John. Here I'll reporting back from an
experiment with CQ:

I encoded sunflower.y4m using constant quant and constrained quality, each
at 64 different quality levels $q, using these command lines:

$ ffmpeg -i sunflower.y4m -s 640x360 -f yuv4mpegpipe - 2> /dev/null |
vpxenc - -v --good --end-usage=cq --cq-level=$q --target-bitrate=10000 -o
tmp.webm

$ ffmpeg -i sunflower.y4m -s 640x360 -f yuv4mpegpipe - 2> /dev/null |
vpxenc - -v --good --end-usage=vbr --min-q=$q --max-q=$q -o tmp.webm

I then matched pairs of files between the different configurations that
were the closest possible in size (raw video size excluding WebM
container). I took the 13 pairs with the smallest sizes and put them
through a blind test. Out of the 13 trials, I voted for the constant quant
version 7 times and voted "don't know" the other 6. The one's I voted
"don't know" for were the 6 biggest ones, so including more pairs would
likely only have resulted in more of "don't know".

Here's one representative pair:

CQ --target-bitrate=10000 --cq-level=57 produced a file with total video
size 1077227, while VBR --min-q=31 --max-q=31 produced a file with total
video size 1058712. Of these, I voted the VBR one to be of better quality.
The CQ version has a much sharper first frame, but overall the VBR version
looks better, with a more balanced quality. In the CQ version, the bee's
wings are rather blurry in movement, and since the bee is the focus of the
video it is very noticeable.

Looking at the quantizer distribution, it's not hard to guess why this is
happened:

CQ quantizer use:

25 Q:4
46 Q:52
429 Q:109

VBR quantizer use:

500 Q:41

Due to the practically unlimited target bitrate in CQ mode, some frames
have been encoded with Q:4, which is very different from the normal Q:109.

IIUC, the way constrained quality could beat constant quantizer is by
using a lower (better) quantizer for reference frames and save bits on
later frames by using a higher (worse) quantizer where it's the quality of
the reference frame that's going to dominate anyway. However, this doesn't
seem to work out if the gap between best and worst quantizer is too big --
while the key frames will look better than a similar-bitrate constant
quantizer encode, the quality will deteriorate too much in later frames.

So, based on this (limited) testing, it seems that CQ should not be
recommended over constant quantizer, at least not in 1-pass and not
without limiting min-q in some way, be that by using --min-q or by using a
--target-bitrate that will actually come in to play. Should I file a bug,
or is this expected but need of documentation?

I was using libvpx commit 2de858b9fcdc1b8c0db265047c5bf387fe31de3a with
some local patches to print the frame size to decodestats.stt.

Basil Mohamed Gohar

unread,
Apr 17, 2011, 2:39:00 PM4/17/11
to webm-d...@webmproject.org
Philip,

Your description of the behavior of libvpx in CQ mode is very much in line with what was recommended to me in the #vp8 IRC channel.  Here are the following points as I understood them:
  1. CQ mode does not perform in 1-pass mode.  I was told that CQ mode is tuned for better performance in 2-pass mode.
  2. A wide range between min-q and max-q leads to inconsistent quality.  I was told, similarly, that to get a more even constant-quality behavior, a narrower range for min-q and max-q would be better, as ultimately, it's these values that actually trump the rest.  --cq-level does not override min-q and max-q, rather, they factor in stronger.
  3. 1-pass mode also does not get any benefit from alternative reference frames nor from the lag-in-frames option.  In otherwords, as a whole, libvpx is more thoroughly tested in 2-pass mode than in 1-pass mode.
Having said all of this, I greatly hope that more work will be put into 1-pass mode for libvpx, as consistency is lacking in 1-pass, with keyframe popping at lower bitrates/quantizers being quite visible.

Philip Jägenstedt

unread,
Apr 18, 2011, 2:54:58 AM4/18/11
to webm-d...@webmproject.org, Basil Mohamed Gohar

> 1. CQ mode does not perform in 1-pass mode. I was told that CQ mode


> is tuned for better performance in 2-pass mode.

> 2. A wide range between min-q and max-q leads to inconsistent


> quality. I was told, similarly, that to get a more even
> constant-quality behavior, a narrower range for min-q and max-q
> would be better, as ultimately, it's these values that actually
> trump the rest. --cq-level does not override min-q and max-q,
> rather, they factor in stronger.

> 3. 1-pass mode also does not get any benefit from alternative


> reference frames nor from the lag-in-frames option. In
> otherwords, as a whole, libvpx is more thoroughly tested in 2-pass
> mode than in 1-pass mode.
>
> Having said all of this, I greatly hope that more work will be put into
> 1-pass mode for libvpx, as consistency is lacking in 1-pass, with
> keyframe popping at lower bitrates/quantizers being quite visible.

Reporting back from a second round of blind tests. This time I mad 2-pass
constrained quality encodes, using this command line:

ffmpeg -i $SOURCE -s $SIZE -f yuv4mpegpipe - 2> /dev/null | vpxenc - -v
--good --end-usage=cq --cq-level=$q --target-bitrate=10000 --passes=2
--pass=1 --fpf=tmp.stats -o /dev/null
ffmpeg -i $SOURCE -s $SIZE -f yuv4mpegpipe - 2> /dev/null | vpxenc - -v
--good --end-usage=cq --cq-level=$q --target-bitrate=10000 --passes=2
--pass=2 --fpf=tmp.stats -o tmp.webm

I paired these with the 1-pass VBR constant quant encodes. In the same
bitrate range where I could only make 13 pairs in the previous round,
there were now 57 pairs, as for any given q the resulting file was now
smaller. I put all 57 pairs through my blind test machinery and actually
voted for the 2-pass CQ in all 57 cases. The difference in quality is
staggering for lower bitrates.

The encode that was closest in size to the 2 clips mentioned in my
previous mail was done with --cq-level=38. It had a total size of 1047614
and had this quantizer use:

1 Q:4
16 Q:17
19 Q:14
464 Q:55

This distribution is a lot more balanced than the 1-pass CQ encode and
does beat the quality of using Q:41 for all frames, even though the result
is slightly smaller in size.

So, in summary, one *should* recommend 2-pass constrained quality over
1-pass constant quantizer, at least when encoding sunflower :) It remains
to be seen if constrained quality can beat 2-pass VBR at any given
bitrate. As long as it is not worse, constrained quality does still have
the benefit of not requiring any (relevant) bitrate to be given.

Given how poorly libvpx performs in 1-pass, I filed
http://code.google.com/p/webm/issues/detail?id=314 requesting strong
warnings against it.

Li, Yvonne

unread,
May 4, 2011, 6:06:06 PM5/4/11
to webm-d...@webmproject.org
Hi. What's the best way to control frame rate? I don't see a method in vp8encoder.idl that directly controls this parameter.

Thanks,

Yvonne

Matthew Heaney

unread,
May 4, 2011, 6:28:30 PM5/4/11
to webm-d...@webmproject.org
On Wed, May 4, 2011 at 6:06 PM, Li, Yvonne <yvon...@teamaol.com> wrote:
> Hi. What's the best way to control frame rate? I don't see a method in vp8encoder.idl that directly controls this parameter.

The frame rate is determined by the upstream filter(s). (DirectShow
works in terms of timestamps, not frame rate.)

-Matt

Reply all
Reply to author
Forward
0 new messages