/*
 * 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 libavcodec/ratecontrol.c
 * Rate control for video encoders.
 */

#include "avcodec.h"
#include "dsputil.h"
#include "ratecontrol.h"
#include "mpegvideo.h"
#include "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, int old_bitrate)
{
    RateControlContext *rcc= &s->rc_context;
    int i;
    const char *error = NULL;
    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();

    rcc->rc_eq_eval = ff_parse(s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp", const_names, func1, func1_names, NULL, NULL, &error);
    if (!rcc->rc_eq_eval) {
        av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\": %s\n", s->avctx->rc_eq, error? error : "");
        return -1;
    }
    
    rcc->last_frame_rc_reset = (old_bitrate ? s->picture_number : 0);
    s->total_bits = 0;
    if (!old_bitrate)
    {
		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(!old_bitrate && 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;
                double q;

                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] ++;

                bits= rce.i_tex_bits + rce.p_tex_bits;

                q= 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
            }
        }
		else if (old_bitrate)
		{
	        rcc->pass1_wanted_bits *= ((double)old_bitrate)/s->bit_rate;
	        rcc->pass1_rc_eq_output_sum *= ((double)old_bitrate)/s->bit_rate;
		}
    }

    return 0;
}

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

    ff_eval_free(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= ff_parse_eval(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;
    double bits;
    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;

    bits= qp2bits(rce, q);
//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;
    int64_t wanted_bits;
    RateControlContext *rcc= &s->rc_context;
    int picture_number= s->picture_number - rcc->last_frame_rc_reset;
    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;
}
