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

📄 ratecontrol.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*        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    };#else    double const_values[21];    const_values[ 0] = M_PI;    const_values[ 1] = M_E;    const_values[ 2] = rce->i_tex_bits*rce->qscale;    const_values[ 3] = rce->p_tex_bits*rce->qscale;    const_values[ 4] = (rce->i_tex_bits + rce->p_tex_bits)*(double)rce->qscale;    const_values[ 5] = rce->mv_bits/mb_num;    const_values[ 6] = rce->pict_type == FF_B_TYPE ? (rce->f_code + rce->b_code)*0.5 : rce->f_code;    const_values[ 7] = rce->i_count/mb_num;    const_values[ 8] = rce->mc_mb_var_sum/mb_num;    const_values[ 9] = rce->mb_var_sum/mb_num;    const_values[10] = rce->pict_type == FF_I_TYPE;    const_values[11] = rce->pict_type == FF_P_TYPE;    const_values[12] = rce->pict_type == FF_B_TYPE;    const_values[13] = rcc->qscale_sum[pict_type] / (double)rcc->frame_count[pict_type];    const_values[14] = a->qcompress;    const_values[15] = rcc->i_cplx_sum[FF_I_TYPE] / (double)rcc->frame_count[FF_I_TYPE];    const_values[16] = rcc->i_cplx_sum[FF_P_TYPE] / (double)rcc->frame_count[FF_P_TYPE];    const_values[17] = rcc->p_cplx_sum[FF_P_TYPE] / (double)rcc->frame_count[FF_P_TYPE];    const_values[18] = rcc->p_cplx_sum[FF_B_TYPE] / (double)rcc->frame_count[FF_B_TYPE];    const_values[19] = (rcc->i_cplx_sum[pict_type] + rcc->p_cplx_sum[pict_type]) / (double)rcc->frame_count[pict_type];    const_values[20] = 0;#endif    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)*3, 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/3, 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 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;    const float border_masking = s->avctx->border_masking;    float bits_sum= 0.0;    float cplx_sum= 0.0;#ifdef __CW32__    float *cplx_tab;    float *bits_tab;#else    float cplx_tab[s->mb_num];    float bits_tab[s->mb_num];#endif    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;#ifdef __CW32__    cplx_tab = av_malloc(sizeof(float)*s->mb_num);    bits_tab = av_malloc(sizeof(float)*s->mb_num);#endif    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;

⌨️ 快捷键说明

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