[Ffmpeg-devel] [PATCH] fix (?) 2pass convergence errors

Corey Hickey bugfood-ml
Mon Sep 4 21:35:21 CEST 2006

Michael Niedermayer wrote:
> may i suggest a slight modification to the convergence analysis ...
> replace
>     if(expected_bits > all_available_bits) rate_factor-= step;
> by
> int toobig=0
>     ...
>     if(expected_bits > all_available_bits){
>         rate_factor-= step;
>         toobig++;
>     }
> and then
> assert(toobig<=40);

Ok. So far so good.

> <some debuging av_log which prints expected bitrate, wanted bitrate, avg-qp, ...>

I haven't figured out how to get the average qp. The attached code
* sums up rce->qscale for each rcc->entry[i]
* divides the result by rcc->num_entries and then by FF_QP2LAMBDA
* does the same thing for rce->new_qscale
* prints out both the results

According to several tests, the average of qscale more or less matches
the average qp of the first pass and the average of new_qscale sort of
matches the average qp of the second pass. Both of them get thrown off
when lmin is below qmin. Is there a better way? I understand
approximately 5% of the ratecontrol code so far, so I'm probably
overlooking something easy.

> if(toobig==0){
>     av_log(s->avctx, AV_LOG_INFO,
>            "[lavc ratecontrol] Using all of requested bitrate is not "
>            "possible for this video with these parameters. (try decreasing qmin)\n");

I thought about a recommendation like that earlier, but I decided
against it because there are too many possible solutions to include in a
small message.

* decrease qmin
* decrease lmin if necessary
* decrease vratetol if you have a short video
* make sure lavc is getting the right framerate and number of frames
* don't downscale the source video as much
* don't denoise as much
* don't worry about it; be happy with a smaller file
* you can use fewer high-quality options if you want faster processing

For mencoder, at least, I'm loosely planning to add a small section to
the docs with expanded versions of the above possibilities. I'm
definitely open to suggestions, however; how to "make" lavc use the
specified bitrate is a rather common subject on the user lists.

Another thing: I just now changed the phrase:
"Using all of requested bitrate is not possible"
"Using all of requested bitrate is not necessary"

The former implies lavc is deficient in not doing what the user wants,
which isn't the case.

> }else if(toobig==40){
>     av_log(s->avctx, AV_LOG_ERROR,
>            "[lavc ratecontrol] Error: bitrate too low for this video with "
>            "these parameters.\n");
>     return -1;
> }else if(fabs(expected_bits/all_available_bits - 1.0) > 0.01){
>     av_log(s->avctx, AV_LOG_ERROR, "[lavc ratecontrol] 2pass curve failed to converge\n");
>     return -1;
> }
> PS: the step_mult stuff from x264 ratecontrol.c should be ported assuming
> they (loren?) doesnt mind relicensing the few related lines under LGPL of
> course ...

I hadn't realized how similar the two ratecontrol.c files were. :) Are
you talking about simply:

1. add this calculation:
step_mult = all_available_bits / expected_bits;

2. Use this for the corresponding loop control:
for(step = 1E4 * step_mult; step > 1E-7 * step_mult; step *= 0.5){

3. alter the if(toobig==40) you recommended because the for() will loop
a different number of times.

Would I have to change anything else?

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: bitrate_check3.diff
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20060904/2ba6766a/attachment.txt>

More information about the ffmpeg-devel mailing list