📄 ratecontrol.c
字号:
// 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 + -