⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ratecontrol.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 2 页
字号:
            q= FFMAX(q, bits2qp(rce, FFMAX(rcc->buffer_index/2, 1)));        }    }//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 Codestatic 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;    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->lmin;    const int qmax= s->avctx->lmax;    Picture * const pic= &s->current_picture;        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;#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]&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(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 cliping */    if(s->flags&CODEC_FLAG_NORMALIZE_AQP){        for(i=0; i<s->mb_num; i++){            float newq= q*cplx_tab[i]/bits_tab[i];            newq*= bits_sum/cplx_sum;            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;            }        }    }       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;    }}//FIXME rd or at least approx for dquantfloat ff_rate_estimate_qscale(MpegEncContext *s){    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;    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();    get_qminmax(&qmin, &qmax, s, pict_type);    fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_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){        const int last_var= s->last_pict_type == 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{        rce= &local_rce;        wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps);    }    diff= s->total_bits - wanted_bits;    br_compensation= (s->bit_rate_tolerance - diff)/s->bit_rate_tolerance;    if(br_compensation<=0.0) br_compensation=0.001;    var= pict_type == 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!=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;        if(picture_number>0)            update_rc_buffer(s, s->frame_bits);        bits= predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var));        if(pict_type== 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);        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==P_TYPE || s->intra_only){ //FIXME type dependant blur like in 2-pass            rcc->short_term_qsum*=s->qblur;            rcc->short_term_qcount*=s->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);        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 codestatic int init_pass2(MpegEncContext *s){    RateControlContext *rcc= &s->rc_context;    int i;    double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base;    double complexity[5]={0,0,0,0,0};   // aproximate bits at quant=1    double avg_quantizer[5];    uint64_t const_bits[5]={0,0,0,0,0}; // quantizer idependant bits    uint64_t available_bits[5];    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)(s->qblur*4) | 1;      double expected_bits;    double *qscale, *blured_qscale;    /* 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[I_TYPE] + const_bits[P_TYPE] + const_bits[B_TYPE];        if(all_available_bits < all_const_bits){        av_log(s->avctx, AV_LOG_ERROR, "requested bitrate is to low\n");        return -1;    }        /* find average quantizers */    avg_quantizer[P_TYPE]=0;    for(step=256*256; step>0.0000001; step*=0.5){        double expected_bits=0;        avg_quantizer[P_TYPE]+= step;                avg_quantizer[I_TYPE]= avg_quantizer[P_TYPE]*ABS(s->avctx->i_quant_factor) + s->avctx->i_quant_offset;        avg_quantizer[B_TYPE]= avg_quantizer[P_TYPE]*ABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset;                expected_bits=             + all_const_bits             + complexity[I_TYPE]/avg_quantizer[I_TYPE]            + complexity[P_TYPE]/avg_quantizer[P_TYPE]            + complexity[B_TYPE]/avg_quantizer[B_TYPE];                    if(expected_bits < all_available_bits) avg_quantizer[P_TYPE]-= step;//printf("%f %lld %f\n", expected_bits, all_available_bits, avg_quantizer[P_TYPE]);    }//printf("qp_i:%f, qp_p:%f, qp_b:%f\n", avg_quantizer[I_TYPE],avg_quantizer[P_TYPE],avg_quantizer[B_TYPE]);    for(i=0; i<5; i++){        available_bits[i]= const_bits[i] + complexity[i]/avg_quantizer[i];    }//printf("%lld %lld %lld %lld\n", available_bits[I_TYPE], available_bits[P_TYPE], available_bits[B_TYPE], all_available_bits);            qscale= av_malloc(sizeof(double)*rcc->num_entries);    blured_qscale= av_malloc(sizeof(double)*rcc->num_entries);    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= s->qblur==0 ? 1.0 : exp(-d*d/(s->qblur * s->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;            }            blured_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, blured_qscale[i], i);            bits= qp2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits;//printf("%d %f\n", rce->new_bits, blured_qscale[i]);            update_rc_buffer(s, bits);            rce->expected_bits= expected_bits;            expected_bits += bits;        }//        printf("%f %d %f\n", expected_bits, (int)all_available_bits, rate_factor);        if(expected_bits > all_available_bits) rate_factor-= step;    }    av_free(qscale);    av_free(blured_qscale);    if(abs(expected_bits/all_available_bits - 1.0) > 0.01 ){        av_log(s->avctx, AV_LOG_ERROR, "Error: 2pass curve failed to converge\n");        return -1;    }    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -