view ratecontrol.c @ 11980:263b4ef7ad87 libavcodec

tablegen: implement and use WRITE_ARRAY macros Two macros (WRITE_ARRAY and WRITE_ARRAY_2D) take the prefix (modifiers) (not all tables are static, and they might not be constant either), the type, and the name of the array. It'll be copied with same name and type, and with the correct size of the currently-defined object.
author flameeyes
date Sun, 27 Jun 2010 12:21:12 +0000
parents e522dbf60abd
children
line wrap: on
line source

/*
 * Rate control for video encoders
 *
 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * Rate control for video encoders.
 */

#include "libavutil/intmath.h"
#include "avcodec.h"
#include "dsputil.h"
#include "ratecontrol.h"
#include "mpegvideo.h"
#include "libavutil/eval.h"

#undef NDEBUG // Always check asserts, the speed effect is far too small to disable them.
#include <assert.h>

#ifndef M_E
#define M_E 2.718281828
#endif

static int init_pass2(MpegEncContext *s);
static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_factor, int frame_num);

void ff_write_pass1_stats(MpegEncContext *s){
    snprintf(s->avctx->stats_out, 256, "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d;\n",
            s->current_picture_ptr->display_picture_number, s->current_picture_ptr->coded_picture_number, s->pict_type,
            s->current_picture.quality, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits,
            s->f_code, s->b_code, s->current_picture.mc_mb_var_sum, s->current_picture.mb_var_sum, s->i_count, s->skip_count, s->header_bits);
}

static inline double qp2bits(RateControlEntry *rce, double qp){
    if(qp<=0.0){
        av_log(NULL, AV_LOG_ERROR, "qp<=0.0\n");
    }
    return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits+1)/ qp;
}

static inline double bits2qp(RateControlEntry *rce, double bits){
    if(bits<0.9){
        av_log(NULL, AV_LOG_ERROR, "bits<0.9\n");
    }
    return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits+1)/ bits;
}

int ff_rate_control_init(MpegEncContext *s)
{
    RateControlContext *rcc= &s->rc_context;
    int i, res;
    static const char * const const_names[]={
        "PI",
        "E",
        "iTex",
        "pTex",
        "tex",
        "mv",
        "fCode",
        "iCount",
        "mcVar",
        "var",
        "isI",
        "isP",
        "isB",
        "avgQP",
        "qComp",
/*        "lastIQP",
        "lastPQP",
        "lastBQP",
        "nextNonBQP",*/
        "avgIITex",
        "avgPITex",
        "avgPPTex",
        "avgBPTex",
        "avgTex",
        NULL
    };
    static double (* const func1[])(void *, double)={
        (void *)bits2qp,
        (void *)qp2bits,
        NULL
    };
    static const char * const func1_names[]={
        "bits2qp",
        "qp2bits",
        NULL
    };
    emms_c();

    res = av_parse_expr(&rcc->rc_eq_eval, s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp", const_names, func1_names, func1, NULL, NULL, 0, s->avctx);
    if (res < 0) {
        av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->avctx->rc_eq);
        return res;
    }

    for(i=0; i<5; i++){
        rcc->pred[i].coeff= FF_QP2LAMBDA * 7.0;
        rcc->pred[i].count= 1.0;

        rcc->pred[i].decay= 0.4;
        rcc->i_cplx_sum [i]=
        rcc->p_cplx_sum [i]=
        rcc->mv_bits_sum[i]=
        rcc->qscale_sum [i]=
        rcc->frame_count[i]= 1; // 1 is better because of 1/0 and such
        rcc->last_qscale_for[i]=FF_QP2LAMBDA * 5;
    }
    rcc->buffer_index= s->avctx->rc_initial_buffer_occupancy;

    if(s->flags&CODEC_FLAG_PASS2){
        int i;
        char *p;

        /* find number of pics */
        p= s->avctx->stats_in;
        for(i=-1; p; i++){
            p= strchr(p+1, ';');
        }
        i+= s->max_b_frames;
        if(i<=0 || i>=INT_MAX / sizeof(RateControlEntry))
            return -1;
        rcc->entry = av_mallocz(i*sizeof(RateControlEntry));
        rcc->num_entries= i;

        /* init all to skipped p frames (with b frames we might have a not encoded frame at the end FIXME) */
        for(i=0; i<rcc->num_entries; i++){
            RateControlEntry *rce= &rcc->entry[i];
            rce->pict_type= rce->new_pict_type=FF_P_TYPE;
            rce->qscale= rce->new_qscale=FF_QP2LAMBDA * 2;
            rce->misc_bits= s->mb_num + 10;
            rce->mb_var_sum= s->mb_num*100;
        }

        /* read stats */
        p= s->avctx->stats_in;
        for(i=0; i<rcc->num_entries - s->max_b_frames; i++){
            RateControlEntry *rce;
            int picture_number;
            int e;
            char *next;

            next= strchr(p, ';');
            if(next){
                (*next)=0; //sscanf in unbelievably slow on looong strings //FIXME copy / do not write
                next++;
            }
            e= sscanf(p, " in:%d ", &picture_number);

            assert(picture_number >= 0);
            assert(picture_number < rcc->num_entries);
            rce= &rcc->entry[picture_number];

            e+=sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d",
                   &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits, &rce->mv_bits, &rce->misc_bits,
                   &rce->f_code, &rce->b_code, &rce->mc_mb_var_sum, &rce->mb_var_sum, &rce->i_count, &rce->skip_count, &rce->header_bits);
            if(e!=14){
                av_log(s->avctx, AV_LOG_ERROR, "statistics are damaged at line %d, parser out=%d\n", i, e);
                return -1;
            }

            p= next;
        }

        if(init_pass2(s) < 0) return -1;

        //FIXME maybe move to end
        if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) {
#if CONFIG_LIBXVID
            return ff_xvid_rate_control_init(s);
#else
            av_log(s->avctx, AV_LOG_ERROR, "Xvid ratecontrol requires libavcodec compiled with Xvid support.\n");
            return -1;
#endif
        }
    }

    if(!(s->flags&CODEC_FLAG_PASS2)){

        rcc->short_term_qsum=0.001;
        rcc->short_term_qcount=0.001;

        rcc->pass1_rc_eq_output_sum= 0.001;
        rcc->pass1_wanted_bits=0.001;

        if(s->avctx->qblur > 1.0){
            av_log(s->avctx, AV_LOG_ERROR, "qblur too large\n");
            return -1;
        }
        /* init stuff with the user specified complexity */
        if(s->avctx->rc_initial_cplx){
            for(i=0; i<60*30; i++){
                double bits= s->avctx->rc_initial_cplx * (i/10000.0 + 1.0)*s->mb_num;
                RateControlEntry rce;

                if     (i%((s->gop_size+3)/4)==0) rce.pict_type= FF_I_TYPE;
                else if(i%(s->max_b_frames+1))    rce.pict_type= FF_B_TYPE;
                else                              rce.pict_type= FF_P_TYPE;

                rce.new_pict_type= rce.pict_type;
                rce.mc_mb_var_sum= bits*s->mb_num/100000;
                rce.mb_var_sum   = s->mb_num;
                rce.qscale   = FF_QP2LAMBDA * 2;
                rce.f_code   = 2;
                rce.b_code   = 1;
                rce.misc_bits= 1;

                if(s->pict_type== FF_I_TYPE){
                    rce.i_count   = s->mb_num;
                    rce.i_tex_bits= bits;
                    rce.p_tex_bits= 0;
                    rce.mv_bits= 0;
                }else{
                    rce.i_count   = 0; //FIXME we do know this approx
                    rce.i_tex_bits= 0;
                    rce.p_tex_bits= bits*0.9;
                    rce.mv_bits= bits*0.1;
                }
                rcc->i_cplx_sum [rce.pict_type] += rce.i_tex_bits*rce.qscale;
                rcc->p_cplx_sum [rce.pict_type] += rce.p_tex_bits*rce.qscale;
                rcc->mv_bits_sum[rce.pict_type] += rce.mv_bits;
                rcc->frame_count[rce.pict_type] ++;

                get_qscale(s, &rce, rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum, i);
                rcc->pass1_wanted_bits+= s->bit_rate/(1/av_q2d(s->avctx->time_base)); //FIXME misbehaves a little for variable fps
            }
        }

    }

    return 0;
}

void ff_rate_control_uninit(MpegEncContext *s)
{
    RateControlContext *rcc= &s->rc_context;
    emms_c();

    av_free_expr(rcc->rc_eq_eval);
    av_freep(&rcc->entry);

#if CONFIG_LIBXVID
    if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID)
        ff_xvid_rate_control_uninit(s);
#endif
}

int ff_vbv_update(MpegEncContext *s, int frame_size){
    RateControlContext *rcc= &s->rc_context;
    const double fps= 1/av_q2d(s->avctx->time_base);
    const int buffer_size= s->avctx->rc_buffer_size;
    const double min_rate= s->avctx->rc_min_rate/fps;
    const double max_rate= s->avctx->rc_max_rate/fps;

//printf("%d %f %d %f %f\n", buffer_size, rcc->buffer_index, frame_size, min_rate, max_rate);
    if(buffer_size){
        int left;

        rcc->buffer_index-= frame_size;
        if(rcc->buffer_index < 0){
            av_log(s->avctx, AV_LOG_ERROR, "rc buffer underflow\n");
            rcc->buffer_index= 0;
        }

        left= buffer_size - rcc->buffer_index - 1;
        rcc->buffer_index += av_clip(left, min_rate, max_rate);

        if(rcc->buffer_index > buffer_size){
            int stuffing= ceil((rcc->buffer_index - buffer_size)/8);

            if(stuffing < 4 && s->codec_id == CODEC_ID_MPEG4)
                stuffing=4;
            rcc->buffer_index -= 8*stuffing;

            if(s->avctx->debug & FF_DEBUG_RC)
                av_log(s->avctx, AV_LOG_DEBUG, "stuffing %d bytes\n", stuffing);

            return stuffing;
        }
    }
    return 0;
}

/**
 * modifies the bitrate curve from pass1 for one frame
 */
static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_factor, int frame_num){
    RateControlContext *rcc= &s->rc_context;
    AVCodecContext *a= s->avctx;
    double q, bits;
    const int pict_type= rce->new_pict_type;
    const double mb_num= s->mb_num;
    int i;

    double const_values[]={
        M_PI,
        M_E,
        rce->i_tex_bits*rce->qscale,
        rce->p_tex_bits*rce->qscale,
        (rce->i_tex_bits + rce->p_tex_bits)*(double)rce->qscale,
        rce->mv_bits/mb_num,
        rce->pict_type == FF_B_TYPE ? (rce->f_code + rce->b_code)*0.5 : rce->f_code,
        rce->i_count/mb_num,
        rce->mc_mb_var_sum/mb_num,
        rce->mb_var_sum/mb_num,
        rce->pict_type == FF_I_TYPE,
        rce->pict_type == FF_P_TYPE,
        rce->pict_type == FF_B_TYPE,
        rcc->qscale_sum[pict_type] / (double)rcc->frame_count[pict_type],
        a->qcompress,
/*        rcc->last_qscale_for[FF_I_TYPE],
        rcc->last_qscale_for[FF_P_TYPE],
        rcc->last_qscale_for[FF_B_TYPE],
        rcc->next_non_b_qscale,*/
        rcc->i_cplx_sum[FF_I_TYPE] / (double)rcc->frame_count[FF_I_TYPE],
        rcc->i_cplx_sum[FF_P_TYPE] / (double)rcc->frame_count[FF_P_TYPE],
        rcc->p_cplx_sum[FF_P_TYPE] / (double)rcc->frame_count[FF_P_TYPE],
        rcc->p_cplx_sum[FF_B_TYPE] / (double)rcc->frame_count[FF_B_TYPE],
        (rcc->i_cplx_sum[pict_type] + rcc->p_cplx_sum[pict_type]) / (double)rcc->frame_count[pict_type],
        0
    };

    bits = av_eval_expr(rcc->rc_eq_eval, const_values, rce);
    if (isnan(bits)) {
        av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", s->avctx->rc_eq);
        return -1;
    }

    rcc->pass1_rc_eq_output_sum+= bits;
    bits*=rate_factor;
    if(bits<0.0) bits=0.0;
    bits+= 1.0; //avoid 1/0 issues

    /* user override */
    for(i=0; i<s->avctx->rc_override_count; i++){
        RcOverride *rco= s->avctx->rc_override;
        if(rco[i].start_frame > frame_num) continue;
        if(rco[i].end_frame   < frame_num) continue;

        if(rco[i].qscale)
            bits= qp2bits(rce, rco[i].qscale); //FIXME move at end to really force it?
        else
            bits*= rco[i].quality_factor;
    }

    q= bits2qp(rce, bits);

    /* I/B difference */
    if     (pict_type==FF_I_TYPE && s->avctx->i_quant_factor<0.0)
        q= -q*s->avctx->i_quant_factor + s->avctx->i_quant_offset;
    else if(pict_type==FF_B_TYPE && s->avctx->b_quant_factor<0.0)
        q= -q*s->avctx->b_quant_factor + s->avctx->b_quant_offset;
    if(q<1) q=1;

    return q;
}

static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, double q){
    RateControlContext *rcc= &s->rc_context;
    AVCodecContext *a= s->avctx;
    const int pict_type= rce->new_pict_type;
    const double last_p_q    = rcc->last_qscale_for[FF_P_TYPE];
    const double last_non_b_q= rcc->last_qscale_for[rcc->last_non_b_pict_type];

    if     (pict_type==FF_I_TYPE && (a->i_quant_factor>0.0 || rcc->last_non_b_pict_type==FF_P_TYPE))
        q= last_p_q    *FFABS(a->i_quant_factor) + a->i_quant_offset;
    else if(pict_type==FF_B_TYPE && a->b_quant_factor>0.0)
        q= last_non_b_q*    a->b_quant_factor  + a->b_quant_offset;
    if(q<1) q=1;

    /* last qscale / qdiff stuff */
    if(rcc->last_non_b_pict_type==pict_type || pict_type!=FF_I_TYPE){
        double last_q= rcc->last_qscale_for[pict_type];
        const int maxdiff= FF_QP2LAMBDA * a->max_qdiff;

        if     (q > last_q + maxdiff) q= last_q + maxdiff;
        else if(q < last_q - maxdiff) q= last_q - maxdiff;
    }

    rcc->last_qscale_for[pict_type]= q; //Note we cannot do that after blurring

    if(pict_type!=FF_B_TYPE)
        rcc->last_non_b_pict_type= pict_type;

    return q;
}

/**
 * gets the qmin & qmax for pict_type
 */
static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pict_type){
    int qmin= s->avctx->lmin;
    int qmax= s->avctx->lmax;

    assert(qmin <= qmax);

    if(pict_type==FF_B_TYPE){
        qmin= (int)(qmin*FFABS(s->avctx->b_quant_factor)+s->avctx->b_quant_offset + 0.5);
        qmax= (int)(qmax*FFABS(s->avctx->b_quant_factor)+s->avctx->b_quant_offset + 0.5);
    }else if(pict_type==FF_I_TYPE){
        qmin= (int)(qmin*FFABS(s->avctx->i_quant_factor)+s->avctx->i_quant_offset + 0.5);
        qmax= (int)(qmax*FFABS(s->avctx->i_quant_factor)+s->avctx->i_quant_offset + 0.5);
    }

    qmin= av_clip(qmin, 1, FF_LAMBDA_MAX);
    qmax= av_clip(qmax, 1, FF_LAMBDA_MAX);

    if(qmax<qmin) qmax= qmin;

    *qmin_ret= qmin;
    *qmax_ret= qmax;
}

static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, double q, int frame_num){
    RateControlContext *rcc= &s->rc_context;
    int qmin, qmax;
    const int pict_type= rce->new_pict_type;
    const double buffer_size= s->avctx->rc_buffer_size;
    const double fps= 1/av_q2d(s->avctx->time_base);
    const double min_rate= s->avctx->rc_min_rate / fps;
    const double max_rate= s->avctx->rc_max_rate / fps;

    get_qminmax(&qmin, &qmax, s, pict_type);

    /* modulation */
    if(s->avctx->rc_qmod_freq && frame_num%s->avctx->rc_qmod_freq==0 && pict_type==FF_P_TYPE)
        q*= s->avctx->rc_qmod_amp;

//printf("q:%f\n", q);
    /* buffer overflow/underflow protection */
    if(buffer_size){
        double expected_size= rcc->buffer_index;
        double q_limit;

        if(min_rate){
            double d= 2*(buffer_size - expected_size)/buffer_size;
            if(d>1.0) d=1.0;
            else if(d<0.0001) d=0.0001;
            q*= pow(d, 1.0/s->avctx->rc_buffer_aggressivity);

            q_limit= bits2qp(rce, FFMAX((min_rate - buffer_size + rcc->buffer_index) * s->avctx->rc_min_vbv_overflow_use, 1));
            if(q > q_limit){
                if(s->avctx->debug&FF_DEBUG_RC){
                    av_log(s->avctx, AV_LOG_DEBUG, "limiting QP %f -> %f\n", q, q_limit);
                }
                q= q_limit;
            }
        }

        if(max_rate){
            double d= 2*expected_size/buffer_size;
            if(d>1.0) d=1.0;
            else if(d<0.0001) d=0.0001;
            q/= pow(d, 1.0/s->avctx->rc_buffer_aggressivity);

            q_limit= bits2qp(rce, FFMAX(rcc->buffer_index * s->avctx->rc_max_available_vbv_use, 1));
            if(q < q_limit){
                if(s->avctx->debug&FF_DEBUG_RC){
                    av_log(s->avctx, AV_LOG_DEBUG, "limiting QP %f -> %f\n", q, q_limit);
                }
                q= q_limit;
            }
        }
    }
//printf("q:%f max:%f min:%f size:%f index:%d bits:%f agr:%f\n", q,max_rate, min_rate, buffer_size, rcc->buffer_index, bits, s->avctx->rc_buffer_aggressivity);
    if(s->avctx->rc_qsquish==0.0 || qmin==qmax){
        if     (q<qmin) q=qmin;
        else if(q>qmax) q=qmax;
    }else{
        double min2= log(qmin);
        double max2= log(qmax);

        q= log(q);
        q= (q - min2)/(max2-min2) - 0.5;
        q*= -4.0;
        q= 1.0/(1.0 + exp(q));
        q= q*(max2-min2) + min2;

        q= exp(q);
    }

    return q;
}

//----------------------------------
// 1 Pass Code

static double predict_size(Predictor *p, double q, double var)
{
     return p->coeff*var / (q*p->count);
}

/*
static double predict_qp(Predictor *p, double size, double var)
{
//printf("coeff:%f, count:%f, var:%f, size:%f//\n", p->coeff, p->count, var, size);
     return p->coeff*var / (size*p->count);
}
*/

static void update_predictor(Predictor *p, double q, double var, double size)
{
    double new_coeff= size*q / (var + 1);
    if(var<10) return;

    p->count*= p->decay;
    p->coeff*= p->decay;
    p->count++;
    p->coeff+= new_coeff;
}

static void adaptive_quantization(MpegEncContext *s, double q){
    int i;
    const float lumi_masking= s->avctx->lumi_masking / (128.0*128.0);
    const float dark_masking= s->avctx->dark_masking / (128.0*128.0);
    const float temp_cplx_masking= s->avctx->temporal_cplx_masking;
    const float spatial_cplx_masking = s->avctx->spatial_cplx_masking;
    const float p_masking = s->avctx->p_masking;
    const float border_masking = s->avctx->border_masking;
    float bits_sum= 0.0;
    float cplx_sum= 0.0;
    float cplx_tab[s->mb_num];
    float bits_tab[s->mb_num];
    const int qmin= s->avctx->mb_lmin;
    const int qmax= s->avctx->mb_lmax;
    Picture * const pic= &s->current_picture;
    const int mb_width = s->mb_width;
    const int mb_height = s->mb_height;

    for(i=0; i<s->mb_num; i++){
        const int mb_xy= s->mb_index2xy[i];
        float temp_cplx= sqrt(pic->mc_mb_var[mb_xy]); //FIXME merge in pow()
        float spat_cplx= sqrt(pic->mb_var[mb_xy]);
        const int lumi= pic->mb_mean[mb_xy];
        float bits, cplx, factor;
        int mb_x = mb_xy % s->mb_stride;
        int mb_y = mb_xy / s->mb_stride;
        int mb_distance;
        float mb_factor = 0.0;
#if 0
        if(spat_cplx < q/3) spat_cplx= q/3; //FIXME finetune
        if(temp_cplx < q/3) temp_cplx= q/3; //FIXME finetune
#endif
        if(spat_cplx < 4) spat_cplx= 4; //FIXME finetune
        if(temp_cplx < 4) temp_cplx= 4; //FIXME finetune

        if((s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_INTRA)){//FIXME hq mode
            cplx= spat_cplx;
            factor= 1.0 + p_masking;
        }else{
            cplx= temp_cplx;
            factor= pow(temp_cplx, - temp_cplx_masking);
        }
        factor*=pow(spat_cplx, - spatial_cplx_masking);

        if(lumi>127)
            factor*= (1.0 - (lumi-128)*(lumi-128)*lumi_masking);
        else
            factor*= (1.0 - (lumi-128)*(lumi-128)*dark_masking);

        if(mb_x < mb_width/5){
            mb_distance = mb_width/5 - mb_x;
            mb_factor = (float)mb_distance / (float)(mb_width/5);
        }else if(mb_x > 4*mb_width/5){
            mb_distance = mb_x - 4*mb_width/5;
            mb_factor = (float)mb_distance / (float)(mb_width/5);
        }
        if(mb_y < mb_height/5){
            mb_distance = mb_height/5 - mb_y;
            mb_factor = FFMAX(mb_factor, (float)mb_distance / (float)(mb_height/5));
        }else if(mb_y > 4*mb_height/5){
            mb_distance = mb_y - 4*mb_height/5;
            mb_factor = FFMAX(mb_factor, (float)mb_distance / (float)(mb_height/5));
        }

        factor*= 1.0 - border_masking*mb_factor;

        if(factor<0.00001) factor= 0.00001;

        bits= cplx*factor;
        cplx_sum+= cplx;
        bits_sum+= bits;
        cplx_tab[i]= cplx;
        bits_tab[i]= bits;
    }

    /* handle qmin/qmax clipping */
    if(s->flags&CODEC_FLAG_NORMALIZE_AQP){
        float factor= bits_sum/cplx_sum;
        for(i=0; i<s->mb_num; i++){
            float newq= q*cplx_tab[i]/bits_tab[i];
            newq*= factor;

            if     (newq > qmax){
                bits_sum -= bits_tab[i];
                cplx_sum -= cplx_tab[i]*q/qmax;
            }
            else if(newq < qmin){
                bits_sum -= bits_tab[i];
                cplx_sum -= cplx_tab[i]*q/qmin;
            }
        }
        if(bits_sum < 0.001) bits_sum= 0.001;
        if(cplx_sum < 0.001) cplx_sum= 0.001;
    }

    for(i=0; i<s->mb_num; i++){
        const int mb_xy= s->mb_index2xy[i];
        float newq= q*cplx_tab[i]/bits_tab[i];
        int intq;

        if(s->flags&CODEC_FLAG_NORMALIZE_AQP){
            newq*= bits_sum/cplx_sum;
        }

        intq= (int)(newq + 0.5);

        if     (intq > qmax) intq= qmax;
        else if(intq < qmin) intq= qmin;
//if(i%s->mb_width==0) printf("\n");
//printf("%2d%3d ", intq, ff_sqrt(s->mc_mb_var[i]));
        s->lambda_table[mb_xy]= intq;
    }
}

void ff_get_2pass_fcode(MpegEncContext *s){
    RateControlContext *rcc= &s->rc_context;
    int picture_number= s->picture_number;
    RateControlEntry *rce;

    rce= &rcc->entry[picture_number];
    s->f_code= rce->f_code;
    s->b_code= rce->b_code;
}

//FIXME rd or at least approx for dquant

float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
{
    float q;
    int qmin, qmax;
    float br_compensation;
    double diff;
    double short_term_q;
    double fps;
    int picture_number= s->picture_number;
    int64_t wanted_bits;
    RateControlContext *rcc= &s->rc_context;
    AVCodecContext *a= s->avctx;
    RateControlEntry local_rce, *rce;
    double bits;
    double rate_factor;
    int var;
    const int pict_type= s->pict_type;
    Picture * const pic= &s->current_picture;
    emms_c();

#if CONFIG_LIBXVID
    if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID)
        return ff_xvid_rate_estimate_qscale(s, dry_run);
#endif

    get_qminmax(&qmin, &qmax, s, pict_type);

    fps= 1/av_q2d(s->avctx->time_base);
//printf("input_pic_num:%d pic_num:%d frame_rate:%d\n", s->input_picture_number, s->picture_number, s->frame_rate);
        /* update predictors */
    if(picture_number>2 && !dry_run){
        const int last_var= s->last_pict_type == FF_I_TYPE ? rcc->last_mb_var_sum : rcc->last_mc_mb_var_sum;
        update_predictor(&rcc->pred[s->last_pict_type], rcc->last_qscale, sqrt(last_var), s->frame_bits);
    }

    if(s->flags&CODEC_FLAG_PASS2){
        assert(picture_number>=0);
        assert(picture_number<rcc->num_entries);
        rce= &rcc->entry[picture_number];
        wanted_bits= rce->expected_bits;
    }else{
        Picture *dts_pic;
        rce= &local_rce;

        //FIXME add a dts field to AVFrame and ensure its set and use it here instead of reordering
        //but the reordering is simpler for now until h.264 b pyramid must be handeld
        if(s->pict_type == FF_B_TYPE || s->low_delay)
            dts_pic= s->current_picture_ptr;
        else
            dts_pic= s->last_picture_ptr;

//if(dts_pic)
//            av_log(NULL, AV_LOG_ERROR, "%Ld %Ld %Ld %d\n", s->current_picture_ptr->pts, s->user_specified_pts, dts_pic->pts, picture_number);

        if(!dts_pic || dts_pic->pts == AV_NOPTS_VALUE)
            wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps);
        else
            wanted_bits= (uint64_t)(s->bit_rate*(double)dts_pic->pts/fps);
    }

    diff= s->total_bits - wanted_bits;
    br_compensation= (a->bit_rate_tolerance - diff)/a->bit_rate_tolerance;
    if(br_compensation<=0.0) br_compensation=0.001;

    var= pict_type == FF_I_TYPE ? pic->mb_var_sum : pic->mc_mb_var_sum;

    short_term_q = 0; /* avoid warning */
    if(s->flags&CODEC_FLAG_PASS2){
        if(pict_type!=FF_I_TYPE)
            assert(pict_type == rce->new_pict_type);

        q= rce->new_qscale / br_compensation;
//printf("%f %f %f last:%d var:%d type:%d//\n", q, rce->new_qscale, br_compensation, s->frame_bits, var, pict_type);
    }else{
        rce->pict_type=
        rce->new_pict_type= pict_type;
        rce->mc_mb_var_sum= pic->mc_mb_var_sum;
        rce->mb_var_sum   = pic->   mb_var_sum;
        rce->qscale   = FF_QP2LAMBDA * 2;
        rce->f_code   = s->f_code;
        rce->b_code   = s->b_code;
        rce->misc_bits= 1;

        bits= predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var));
        if(pict_type== FF_I_TYPE){
            rce->i_count   = s->mb_num;
            rce->i_tex_bits= bits;
            rce->p_tex_bits= 0;
            rce->mv_bits= 0;
        }else{
            rce->i_count   = 0; //FIXME we do know this approx
            rce->i_tex_bits= 0;
            rce->p_tex_bits= bits*0.9;

            rce->mv_bits= bits*0.1;
        }
        rcc->i_cplx_sum [pict_type] += rce->i_tex_bits*rce->qscale;
        rcc->p_cplx_sum [pict_type] += rce->p_tex_bits*rce->qscale;
        rcc->mv_bits_sum[pict_type] += rce->mv_bits;
        rcc->frame_count[pict_type] ++;

        bits= rce->i_tex_bits + rce->p_tex_bits;
        rate_factor= rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum * br_compensation;

        q= get_qscale(s, rce, rate_factor, picture_number);
        if (q < 0)
            return -1;

        assert(q>0.0);
//printf("%f ", q);
        q= get_diff_limited_q(s, rce, q);
//printf("%f ", q);
        assert(q>0.0);

        if(pict_type==FF_P_TYPE || s->intra_only){ //FIXME type dependent blur like in 2-pass
            rcc->short_term_qsum*=a->qblur;
            rcc->short_term_qcount*=a->qblur;

            rcc->short_term_qsum+= q;
            rcc->short_term_qcount++;
//printf("%f ", q);
            q= short_term_q= rcc->short_term_qsum/rcc->short_term_qcount;
//printf("%f ", q);
        }
        assert(q>0.0);

        q= modify_qscale(s, rce, q, picture_number);

        rcc->pass1_wanted_bits+= s->bit_rate/fps;

        assert(q>0.0);
    }

    if(s->avctx->debug&FF_DEBUG_RC){
        av_log(s->avctx, AV_LOG_DEBUG, "%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f size:%d var:%d/%d br:%d fps:%d\n",
        av_get_pict_type_char(pict_type), qmin, q, qmax, picture_number, (int)wanted_bits/1000, (int)s->total_bits/1000,
        br_compensation, short_term_q, s->frame_bits, pic->mb_var_sum, pic->mc_mb_var_sum, s->bit_rate/1000, (int)fps
        );
    }

    if     (q<qmin) q=qmin;
    else if(q>qmax) q=qmax;

    if(s->adaptive_quant)
        adaptive_quantization(s, q);
    else
        q= (int)(q + 0.5);

    if(!dry_run){
        rcc->last_qscale= q;
        rcc->last_mc_mb_var_sum= pic->mc_mb_var_sum;
        rcc->last_mb_var_sum= pic->mb_var_sum;
    }
#if 0
{
    static int mvsum=0, texsum=0;
    mvsum += s->mv_bits;
    texsum += s->i_tex_bits + s->p_tex_bits;
    printf("%d %d//\n\n", mvsum, texsum);
}
#endif
    return q;
}

//----------------------------------------------
// 2-Pass code

static int init_pass2(MpegEncContext *s)
{
    RateControlContext *rcc= &s->rc_context;
    AVCodecContext *a= s->avctx;
    int i, toobig;
    double fps= 1/av_q2d(s->avctx->time_base);
    double complexity[5]={0,0,0,0,0};   // aproximate bits at quant=1
    uint64_t const_bits[5]={0,0,0,0,0}; // quantizer independent bits
    uint64_t all_const_bits;
    uint64_t all_available_bits= (uint64_t)(s->bit_rate*(double)rcc->num_entries/fps);
    double rate_factor=0;
    double step;
    //int last_i_frame=-10000000;
    const int filter_size= (int)(a->qblur*4) | 1;
    double expected_bits;
    double *qscale, *blurred_qscale, qscale_sum;

    /* find complexity & const_bits & decide the pict_types */
    for(i=0; i<rcc->num_entries; i++){
        RateControlEntry *rce= &rcc->entry[i];

        rce->new_pict_type= rce->pict_type;
        rcc->i_cplx_sum [rce->pict_type] += rce->i_tex_bits*rce->qscale;
        rcc->p_cplx_sum [rce->pict_type] += rce->p_tex_bits*rce->qscale;
        rcc->mv_bits_sum[rce->pict_type] += rce->mv_bits;
        rcc->frame_count[rce->pict_type] ++;

        complexity[rce->new_pict_type]+= (rce->i_tex_bits+ rce->p_tex_bits)*(double)rce->qscale;
        const_bits[rce->new_pict_type]+= rce->mv_bits + rce->misc_bits;
    }
    all_const_bits= const_bits[FF_I_TYPE] + const_bits[FF_P_TYPE] + const_bits[FF_B_TYPE];

    if(all_available_bits < all_const_bits){
        av_log(s->avctx, AV_LOG_ERROR, "requested bitrate is too low\n");
        return -1;
    }

    qscale= av_malloc(sizeof(double)*rcc->num_entries);
    blurred_qscale= av_malloc(sizeof(double)*rcc->num_entries);
    toobig = 0;

    for(step=256*256; step>0.0000001; step*=0.5){
        expected_bits=0;
        rate_factor+= step;

        rcc->buffer_index= s->avctx->rc_buffer_size/2;

        /* find qscale */
        for(i=0; i<rcc->num_entries; i++){
            qscale[i]= get_qscale(s, &rcc->entry[i], rate_factor, i);
        }
        assert(filter_size%2==1);

        /* fixed I/B QP relative to P mode */
        for(i=rcc->num_entries-1; i>=0; i--){
            RateControlEntry *rce= &rcc->entry[i];

            qscale[i]= get_diff_limited_q(s, rce, qscale[i]);
        }

        /* smooth curve */
        for(i=0; i<rcc->num_entries; i++){
            RateControlEntry *rce= &rcc->entry[i];
            const int pict_type= rce->new_pict_type;
            int j;
            double q=0.0, sum=0.0;

            for(j=0; j<filter_size; j++){
                int index= i+j-filter_size/2;
                double d= index-i;
                double coeff= a->qblur==0 ? 1.0 : exp(-d*d/(a->qblur * a->qblur));

                if(index < 0 || index >= rcc->num_entries) continue;
                if(pict_type != rcc->entry[index].new_pict_type) continue;
                q+= qscale[index] * coeff;
                sum+= coeff;
            }
            blurred_qscale[i]= q/sum;
        }

        /* find expected bits */
        for(i=0; i<rcc->num_entries; i++){
            RateControlEntry *rce= &rcc->entry[i];
            double bits;
            rce->new_qscale= modify_qscale(s, rce, blurred_qscale[i], i);
            bits= qp2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits;
//printf("%d %f\n", rce->new_bits, blurred_qscale[i]);
            bits += 8*ff_vbv_update(s, bits);

            rce->expected_bits= expected_bits;
            expected_bits += bits;
        }

        /*
        av_log(s->avctx, AV_LOG_INFO,
            "expected_bits: %f all_available_bits: %d rate_factor: %f\n",
            expected_bits, (int)all_available_bits, rate_factor);
        */
        if(expected_bits > all_available_bits) {
            rate_factor-= step;
            ++toobig;
        }
    }
    av_free(qscale);
    av_free(blurred_qscale);

    /* check bitrate calculations and print info */
    qscale_sum = 0.0;
    for(i=0; i<rcc->num_entries; i++){
        /* av_log(s->avctx, AV_LOG_DEBUG, "[lavc rc] entry[%d].new_qscale = %.3f  qp = %.3f\n",
            i, rcc->entry[i].new_qscale, rcc->entry[i].new_qscale / FF_QP2LAMBDA); */
        qscale_sum += av_clip(rcc->entry[i].new_qscale / FF_QP2LAMBDA, s->avctx->qmin, s->avctx->qmax);
    }
    assert(toobig <= 40);
    av_log(s->avctx, AV_LOG_DEBUG,
        "[lavc rc] requested bitrate: %d bps  expected bitrate: %d bps\n",
        s->bit_rate,
        (int)(expected_bits / ((double)all_available_bits/s->bit_rate)));
    av_log(s->avctx, AV_LOG_DEBUG,
        "[lavc rc] estimated target average qp: %.3f\n",
        (float)qscale_sum / rcc->num_entries);
    if (toobig == 0) {
        av_log(s->avctx, AV_LOG_INFO,
            "[lavc rc] Using all of requested bitrate is not "
            "necessary for this video with these parameters.\n");
    } else if (toobig == 40) {
        av_log(s->avctx, AV_LOG_ERROR,
            "[lavc rc] 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 rc] Error: 2pass curve failed to converge\n");
        return -1;
    }

    return 0;
}