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

📄 ratecontrol.c

📁 H.264 source codes
💻 C
📖 第 1 页 / 共 3 页
字号:
// apply VBV constraints and clip qscale to between lmin and lmaxstatic double clip_qscale( x264_t *h, int pict_type, double q ){    x264_ratecontrol_t *rcc = h->rc;    double lmin = rcc->lmin[pict_type];    double lmax = rcc->lmax[pict_type];    double q0 = q;    /* B-frames are not directly subject to VBV,     * since they are controlled by the P-frames' QPs.     * FIXME: in 2pass we could modify previous frames' QP too,     *        instead of waiting for the buffer to fill */    if( rcc->buffer_size &&        ( pict_type == SLICE_TYPE_P ||          ( pict_type == SLICE_TYPE_I && rcc->last_non_b_pict_type == SLICE_TYPE_I ) ) )    {        if( rcc->buffer_fill/rcc->buffer_size < 0.5 )            q /= x264_clip3f( 2.0*rcc->buffer_fill/rcc->buffer_size, 0.5, 1.0 );    }    /* Now a hard threshold to make sure the frame fits in VBV.     * This one is mostly for I-frames. */    if( rcc->buffer_size && rcc->last_satd > 0 )    {        double bits = predict_size( &rcc->pred[rcc->slice_type], q, rcc->last_satd );        double qf = 1.0;        if( bits > rcc->buffer_fill/2 )            qf = x264_clip3f( rcc->buffer_fill/(2*bits), 0.2, 1.0 );        q /= qf;        bits *= qf;        if( bits < rcc->buffer_rate/2 )            q *= bits*2/rcc->buffer_rate;        q = X264_MAX( q0, q );    }    if(lmin==lmax)        return lmin;    else if(rcc->b_2pass)    {        double min2 = log(lmin);        double max2 = log(lmax);        q = (log(q) - min2)/(max2-min2) - 0.5;        q = 1.0/(1.0 + exp(-4*q));        q = q*(max2-min2) + min2;        return exp(q);    }    else        return x264_clip3f(q, lmin, lmax);}// update qscale for 1 frame based on actual bits used so farstatic float rate_estimate_qscale(x264_t *h, int pict_type){    float q;    x264_ratecontrol_t *rcc = h->rc;    ratecontrol_entry_t rce;    double lmin = rcc->lmin[pict_type];    double lmax = rcc->lmax[pict_type];    int64_t total_bits = 8*(h->stat.i_slice_size[SLICE_TYPE_I]                          + h->stat.i_slice_size[SLICE_TYPE_P]                          + h->stat.i_slice_size[SLICE_TYPE_B]);    if( rcc->b_2pass )    {        rce = *rcc->rce;        if(pict_type != rce.pict_type)        {            x264_log(h, X264_LOG_ERROR, "slice=%c but 2pass stats say %c\n",                     slice_type_to_char[pict_type], slice_type_to_char[rce.pict_type]);        }    }    if( pict_type == SLICE_TYPE_B )    {        rcc->last_satd = 0;        if(h->fenc->b_kept_as_ref)            q = rcc->last_qscale * sqrtf(h->param.rc.f_pb_factor);        else            q = rcc->last_qscale * h->param.rc.f_pb_factor;        return x264_clip3f(q, lmin, lmax);    }    else    {        double abr_buffer = 2 * rcc->rate_tolerance * rcc->bitrate;        if( rcc->b_2pass )        {            //FIXME adjust abr_buffer based on distance to the end of the video            int64_t diff = total_bits - (int64_t)rce.expected_bits;            q = rce.new_qscale;            q /= x264_clip3f((double)(abr_buffer - diff) / abr_buffer, .5, 2);            if( h->fenc->i_frame > 30 )            {                /* Adjust quant based on the difference between                 * achieved and expected bitrate so far */                double time = (double)h->fenc->i_frame / rcc->num_entries;                double w = x264_clip3f( time*100, 0.0, 1.0 );                q *= pow( (double)total_bits / rcc->expected_bits_sum, w );            }            q = x264_clip3f( q, lmin, lmax );        }        else /* 1pass ABR */        {            /* Calculate the quantizer which would have produced the desired             * average bitrate if it had been applied to all frames so far.             * Then modulate that quant based on the current frame's complexity             * relative to the average complexity so far (using the 2pass RCEQ).             * Then bias the quant up or down if total size so far was far from             * the target.             * Result: Depending on the value of rate_tolerance, there is a             * tradeoff between quality and bitrate precision. But at large             * tolerances, the bit distribution approaches that of 2pass. */            double wanted_bits, overflow, lmin, lmax;            rcc->last_satd = x264_rc_analyse_slice( h );            rcc->short_term_cplxsum *= 0.5;            rcc->short_term_cplxcount *= 0.5;            rcc->short_term_cplxsum += rcc->last_satd;            rcc->short_term_cplxcount ++;            rce.p_tex_bits = rcc->last_satd;            rce.blurred_complexity = rcc->short_term_cplxsum / rcc->short_term_cplxcount;            rce.i_tex_bits = 0;            rce.mv_bits = 0;            rce.p_count = rcc->nmb;            rce.i_count = 0;            rce.s_count = 0;            rce.qscale = 1;            rce.pict_type = pict_type;            rcc->last_rceq = get_qscale(h, &rce, 1);            wanted_bits = h->fenc->i_frame * rcc->bitrate / rcc->fps;            abr_buffer *= X264_MAX( 1, sqrt(h->fenc->i_frame/25) );            overflow = x264_clip3f( 1.0 + (total_bits - wanted_bits) / abr_buffer, .5, 2 );            q = rcc->last_rceq * overflow * rcc->cplxr_sum / rcc->wanted_bits_window;            if( pict_type == SLICE_TYPE_I                /* should test _next_ pict type, but that isn't decided yet */                && rcc->last_non_b_pict_type != SLICE_TYPE_I )            {                q = qp2qscale( rcc->accum_p_qp / rcc->accum_p_norm );                q /= fabs( h->param.rc.f_ip_factor );                q = clip_qscale( h, pict_type, q );            }            else            {                if( h->stat.i_slice_count[SLICE_TYPE_P] < 5 )                {                    float w = h->stat.i_slice_count[SLICE_TYPE_P] / 5.;                    float q2 = qp2qscale(ABR_INIT_QP);                    q = q*w + q2*(1-w);                }                /* Asymmetric clipping, because symmetric would prevent                 * overflow control in areas of rapidly oscillating complexity */                lmin = rcc->last_qscale_for[pict_type] / rcc->lstep;                lmax = rcc->last_qscale_for[pict_type] * rcc->lstep;                if( overflow > 1.1 )                    lmax *= rcc->lstep;                else if( overflow < 0.9 )                    lmin /= rcc->lstep;                q = x264_clip3f(q, lmin, lmax);                q = clip_qscale(h, pict_type, q);                //FIXME use get_diff_limited_q() ?            }        }        rcc->last_qscale_for[pict_type] =        rcc->last_qscale = q;        return q;    }}static int init_pass2( x264_t *h ){    x264_ratecontrol_t *rcc = h->rc;    uint64_t all_const_bits = 0;    uint64_t all_available_bits = (uint64_t)(h->param.rc.i_bitrate * 1000 * (double)rcc->num_entries / rcc->fps);    double rate_factor, step, step_mult;    double qblur = h->param.rc.f_qblur;    double cplxblur = h->param.rc.f_complexity_blur;    const int filter_size = (int)(qblur*4) | 1;    double expected_bits;    double *qscale, *blurred_qscale;    int i;    /* find total/average complexity & const_bits */    for(i=0; i<rcc->num_entries; i++){        ratecontrol_entry_t *rce = &rcc->entry[i];        all_const_bits += rce->misc_bits;        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 * rce->qscale;        rcc->frame_count[rce->pict_type] ++;    }    if( all_available_bits < all_const_bits)    {        x264_log(h, X264_LOG_ERROR, "requested bitrate is too low. estimated minimum is %d kbps\n",                 (int)(all_const_bits * rcc->fps / (rcc->num_entries * 1000)));        return -1;    }    /* Blur complexities, to reduce local fluctuation of QP.     * We don't blur the QPs directly, because then one very simple frame     * could drag down the QP of a nearby complex frame and give it more     * bits than intended. */    for(i=0; i<rcc->num_entries; i++){        ratecontrol_entry_t *rce = &rcc->entry[i];        double weight_sum = 0;        double cplx_sum = 0;        double weight = 1.0;        int j;        /* weighted average of cplx of future frames */        for(j=1; j<cplxblur*2 && j<rcc->num_entries-i; j++){            ratecontrol_entry_t *rcj = &rcc->entry[i+j];            weight *= 1 - pow( (float)rcj->i_count / rcc->nmb, 2 );            if(weight < .0001)                break;            weight_sum += weight;            cplx_sum += weight * qscale2bits(rcj, 1);        }        /* weighted average of cplx of past frames */        weight = 1.0;        for(j=0; j<=cplxblur*2 && j<=i; j++){            ratecontrol_entry_t *rcj = &rcc->entry[i-j];            weight_sum += weight;            cplx_sum += weight * qscale2bits(rcj, 1);            weight *= 1 - pow( (float)rcj->i_count / rcc->nmb, 2 );            if(weight < .0001)                break;        }        rce->blurred_complexity = cplx_sum / weight_sum;    }    qscale = x264_malloc(sizeof(double)*rcc->num_entries);    if(filter_size > 1)        blurred_qscale = x264_malloc(sizeof(double)*rcc->num_entries);    else        blurred_qscale = qscale;    /* Search for a factor which, when multiplied by the RCEQ values from     * each frame, adds up to the desired total size.     * There is no exact closed-form solution because of VBV constraints and     * because qscale2bits is not invertible, but we can start with the simple     * approximation of scaling the 1st pass by the ratio of bitrates.     * The search range is probably overkill, but speed doesn't matter here. */    expected_bits = 1;    for(i=0; i<rcc->num_entries; i++)        expected_bits += qscale2bits(&rcc->entry[i], get_qscale(h, &rcc->entry[i], 1.0));    step_mult = all_available_bits / expected_bits;    rate_factor = 0;    for(step = 1E4 * step_mult; step > 1E-7 * step_mult; step *= 0.5){        expected_bits = 0;        rate_factor += step;        rcc->last_non_b_pict_type = -1;        rcc->last_accum_p_norm = 1;        rcc->accum_p_norm = 0;        rcc->buffer_fill = rcc->buffer_size * h->param.rc.f_vbv_buffer_init;        /* find qscale */        for(i=0; i<rcc->num_entries; i++){            qscale[i] = get_qscale(h, &rcc->entry[i], rate_factor);        }        /* fixed I/B qscale relative to P */        for(i=rcc->num_entries-1; i>=0; i--){            qscale[i] = get_diff_limited_q(h, &rcc->entry[i], qscale[i]);            assert(qscale[i] >= 0);        }        /* smooth curve */        if(filter_size > 1){            assert(filter_size%2==1);            for(i=0; i<rcc->num_entries; i++){                ratecontrol_entry_t *rce = &rcc->entry[i];                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 = qblur==0 ? 1.0 : exp(-d*d/(qblur*qblur));                    if(index < 0 || index >= rcc->num_entries) continue;                    if(rce->pict_type != rcc->entry[index].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++){            ratecontrol_entry_t *rce = &rcc->entry[i];            double bits;            rce->new_qscale = clip_qscale(h, rce->pict_type, blurred_qscale[i]);            assert(rce->new_qscale >= 0);            bits = qscale2bits(rce, rce->new_qscale) + rce->misc_bits;            rce->expected_bits = expected_bits;            expected_bits += bits;            update_vbv(h, bits);        }//printf("expected:%llu available:%llu factor:%lf avgQ:%lf\n", (uint64_t)expected_bits, all_available_bits, rate_factor);        if(expected_bits > all_available_bits) rate_factor -= step;    }    x264_free(qscale);    if(filter_size > 1)        x264_free(blurred_qscale);    if(fabs(expected_bits/all_available_bits - 1.0) > 0.01)    {        double avgq = 0;        for(i=0; i<rcc->num_entries; i++)            avgq += rcc->entry[i].new_qscale;        avgq = qscale2qp(avgq / rcc->num_entries);        x264_log(h, X264_LOG_ERROR, "Error: 2pass curve failed to converge\n");        x264_log(h, X264_LOG_ERROR, "target: %.2f kbit/s, expected: %.2f kbit/s, avg QP: %.4f\n",                 (float)h->param.rc.i_bitrate,                 expected_bits * rcc->fps / (rcc->num_entries * 1000.),                 avgq);        if(expected_bits < all_available_bits && avgq < h->param.rc.i_qp_min + 2)        {            if(h->param.rc.i_qp_min > 0)                x264_log(h, X264_LOG_ERROR, "try reducing target bitrate or reducing qp_min (currently %d)\n", h->param.rc.i_qp_min);            else                x264_log(h, X264_LOG_ERROR, "try reducing target bitrate\n");        }        else if(expected_bits > all_available_bits && avgq > h->param.rc.i_qp_max - 2)        {            if(h->param.rc.i_qp_max < 51)                x264_log(h, X264_LOG_ERROR, "try increasing target bitrate or increasing qp_max (currently %d)\n", h->param.rc.i_qp_max);            else                x264_log(h, X264_LOG_ERROR, "try increasing target bitrate\n");        }        else            x264_log(h, X264_LOG_ERROR, "internal error\n");    }    return 0;}

⌨️ 快捷键说明

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