// update qscale for 1 frame based on actual bits used so far
/*
基于当前实际使用的比特开销来确定当前帧的qscale
过程:
1.计算total_bits,即目前为止编码所有帧所耗费的比特开销总和
2.计算qscale
·B帧
1.根据相邻的两个参考帧来推算当前帧的QP
2.qp to qscale
3.估算当前编码帧的体积
4.将体积进行最大帧体积限制
·I/P帧
1.计算abr buffer和predicted_bits
2.计算scale
·2pass
·1pass
1.得到当前帧的satd
2.更新cplxsum和cplcount
3.计算blurred_complexity = cplxsum/cplxcount
4.初始化ratecontrol_entry_t rce
5.计算qscale
·CRF qscale = get_qscale(), where ratefactor = constant rate factor
·ABR
1.qscale = get_qscale(), where ratefactor = wanted_bits_window/cplxr_sum
2.计算播放到当前帧所需要的时间time_down
3.根据time_down和理想的bitrate计算目前为止理想的比特开销wanted_bits
4.根据理想比特开销wanted_bits和实际比特开销predicted_bits计算abr_buffer上下溢出情况
5.根据abr_buffer上下溢出情况调整qscale
6.做一些收尾工作:
·若当前帧I且上个非B帧P,则通过P的QP和ip_factor来确定当前I帧的qscale
这么做个人觉得是防止I帧被调节的太狠而牺牲画质,进而影响后面帧
·对qscale进行lmin和lmax限制,防止qscale波动大
·上述1pass中的方法无法有效处理第一帧,故对第一帧单独设置初始化qscale
7.进行vbv检验 clip_qscale()
3.存储并更新qscale相关数据
4.估算当前编码帧的体积
5.将体积进行最大帧体积限制
*/
static float rate_estimate_qscale( x264_t *h )
{
float q;
x264_ratecontrol_t *rcc = h->rc;
ratecontrol_entry_t rce = {0};
int pict_type = h->sh.i_type;
/*
得到目前编码的总比特数,其中:
i_frame_size[ SLICE_TYPE_I/ SLICE_TYPE_P/ SLICE_TYPE_B]分别表示各类型slice所编码的总比特数
*/
int64_t total_bits = 8*(h->stat.i_frame_size[SLICE_TYPE_I]
+ h->stat.i_frame_size[SLICE_TYPE_P]
+ h->stat.i_frame_size[SLICE_TYPE_B])
- rcc->filler_bits_sum;
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 ) //当前B帧
{
/* B-frames don't have independent ratecontrol, but rather get the
* average QP of the two adjacent P-frames + an offset
* B帧不拥有独立的码率控制,而是通过其相邻的两个P帧的平均QP + offset来计算 */
int i0 = IS_X264_TYPE_I(h->fref_nearest[0]->i_type); //L0中最近的参考帧
int i1 = IS_X264_TYPE_I(h->fref_nearest[1]->i_type); //L1中最近的参考帧
int dt0 = abs(h->fenc->i_poc - h->fref_nearest[0]->i_poc); //该帧到L0最近的参考帧的距离
int dt1 = abs(h->fenc->i_poc - h->fref_nearest[1]->i_poc); //该帧到L1最近的参考帧的距离
float q0 = h->fref_nearest[0]->f_qp_avg_rc; //L0中最近参考帧通过码率控制得到的qp
float q1 = h->fref_nearest[1]->f_qp_avg_rc; //L1中最近参考帧通过码率控制得到的qp
/* 检查该帧的两个参考帧是否存在BREF
若L0L1最近的参考帧是BREF,则其qp减去一个offset */
if( h->fref_nearest[0]->i_type == X264_TYPE_BREF )
q0 -= rcc->pb_offset/2;
if( h->fref_nearest[1]->i_type == X264_TYPE_BREF )
q1 -= rcc->pb_offset/2;
/* 检查该帧的两个最近参考帧是否存在I帧 */
if( i0 && i1 ) //L0L1中最近参考帧都是I帧
q = (q0 + q1) / 2 + rcc->ip_offset; //计算当前帧qp
else if( i0 ) //只有L0中最近参考帧是I帧,L1中最近参考帧是P帧
q = q1;
else if( i1 ) //只有L1中最近参考帧是I帧,L0中最近参考帧是P帧
q = q0;
else //L0L1中最近参考帧都不是I帧,即都是P
q = (q0*dt1 + q1*dt0) / (dt0 + dt1);
/* 若当前帧是否作为参考帧,
若作为参考帧,则 + offset */
if( h->fenc->b_kept_as_ref )
q += rcc->pb_offset/2;
else
q += rcc->pb_offset;
rcc->qp_novbv = q; //当前帧在1pass中不使用vbv时的qp
q = qp2qscale( q ); //qp to qscale
/* 估算一下当前帧的体积 */
if( rcc->b_2pass ) //2pass,根据tex_bits,mv_bits,misc_bits和qscale估算出当前帧体积
rcc->frame_size_planned = qscale2bits( &rce, q );
else //1pass
//predict_size(p,q,var) (p->coeff*var + p->offset) / (q*p->count);
rcc->frame_size_planned = predict_size( rcc->pred_b_from_p, q, h->fref[1][h->i_ref[1]-1]->i_satd );
/* Limit planned size by MinCR
MinCR (minimum compress rate) 最小压缩比
frame_size_maximum为最小压缩比限制下的最大帧体积大小 */
if( rcc->b_vbv )
rcc->frame_size_planned = X264_MIN( rcc->frame_size_planned, rcc->frame_size_maximum );
h->rc->frame_size_estimated = rcc->frame_size_planned;
/* For row SATDs */
if( rcc->b_vbv )
rcc->last_satd = x264_rc_analyse_slice( h );
//返回qscale
return q;
}
else //当前I、P帧
{
//计算abr_buffer
double abr_buffer = 2 * rcc->rate_tolerance * rcc->bitrate;
//计算predicted_bits
double predicted_bits = total_bits;
if( h->i_thread_frames > 1 )
{
int j = h->rc - h->thread[0]->rc;
for( int i = 1; i < h->i_thread_frames; i++ )
{
x264_t *t = h->thread[(j+i) % h->i_thread_frames];
double bits = t->rc->frame_size_planned;
if( !t->b_thread_active )
continue;
bits = X264_MAX(bits, t->rc->frame_size_estimated);
predicted_bits += bits;
}
}
if( rcc->b_2pass ) //是2pass
{
double lmin = rcc->lmin[pict_type];
double lmax = rcc->lmax[pict_type];
double diff;
/* Adjust ABR buffer based on distance to the end of the video. */
if( rcc->num_entries > h->i_frame )
{
double final_bits = rcc->entry_out[rcc->num_entries-1]->expected_bits;
double video_pos = rce.expected_bits / final_bits;
double scale_factor = sqrt( (1 - video_pos) * rcc->num_entries );
abr_buffer *= 0.5 * X264_MAX( scale_factor, 0.5 );
}
diff = predicted_bits - rce.expected_bits;
q = rce.new_qscale;
q /= x264_clip3f((abr_buffer - diff) / abr_buffer, .5, 2);
if( h->i_frame >= rcc->fps && rcc->expected_bits_sum >= 1 )
{
/* Adjust quant based on the difference between
* achieved and expected bitrate so far */
double cur_time = (double)h->i_frame / rcc->num_entries;
double w = x264_clip3f( cur_time*100, 0.0, 1.0 );
q *= pow( (double)total_bits / rcc->expected_bits_sum, w );
}
rcc->qp_novbv = qscale2qp( q );
if( rcc->b_vbv )
{
/* Do not overflow vbv */
double expected_size = qscale2bits( &rce, q );
double expected_vbv = rcc->buffer_fill + rcc->buffer_rate - expected_size;
double expected_fullness = rce.expected_vbv / rcc->buffer_size;
double qmax = q*(2 - expected_fullness);
double size_constraint = 1 + expected_fullness;
qmax = X264_MAX( qmax, rce.new_qscale );
if( expected_fullness < .05 )
qmax = lmax;
qmax = X264_MIN(qmax, lmax);
while( ((expected_vbv < rce.expected_vbv/size_constraint) && (q < qmax)) ||
((expected_vbv < 0) && (q < lmax)))
{
q *= 1.05;
expected_size = qscale2bits(&rce, q);
expected_vbv = rcc->buffer_fill + rcc->buffer_rate - expected_size;
}
rcc->last_satd = x264_rc_analyse_slice( h );
}
q = x264_clip3f( q, lmin, lmax );
} // end of if( rcc->b_2pass )
else /* 1pass */
{
/* 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.
*
* 先产生一个QP,该QP如果用于截至目前所有编码帧将会得到我们期望的平均比特率,
* 然后再根据 当前帧的复杂度 相对于 截至目前所有编码帧的平均复杂度 来调节QP,
* 最后基于 目前所有编码帧实际编码总比特开销 与 我们所期望的比特流开销 来调节QP */
double wanted_bits, overflow = 1;
//得到当前编码帧的satd
rcc->last_satd = x264_rc_analyse_slice( h );
/* 更新cplxsum (complexity sum) 和 cplcount (complexity count)
satd(n)
cplxsum(n) = cplxsum(n-1) * 0.5 + -----------------------------------------
frame duration / frame duration base
cplxcount(n) = cplxcount(n-1) * 0.5 + 1
*/
rcc->short_term_cplxsum *= 0.5;
rcc->short_term_cplxcount *= 0.5;
rcc->short_term_cplxsum += rcc->last_satd / (CLIP_DURATION(h->fenc->f_duration) / BASE_FRAME_DURATION);
rcc->short_term_cplxcount ++;
/* 计算blurred complexity
cplxsum
blurred_complexity = ---------------
cplxcount
*/
rce.blurred_complexity = rcc->short_term_cplxsum / rcc->short_term_cplxcount;
/*
初始化rce,用于后面
*/
rce.tex_bits = rcc->last_satd; //残差系数bit开销
rce.mv_bits = 0; //mv ref mode 开销
rce.p_count = rcc->nmb; //mb宏块个数
rce.i_count = 0;
rce.s_count = 0;
rce.qscale = 1;
rce.pict_type = pict_type;
rce.i_duration = h->fenc->i_duration;
/* get qscale based on rate factor and rceq
rceq
qscale = -------------
rate factor
其中rceq是非线性化压缩后的blur_complexity:
(1-qcompress)
rceq = blur_complexity
when method = CRF:
rate factor = constant rate factor
when method = ABR:
wanted_bits_window
rate factor = ---------------------
cplxr_sum
where
bits(n-1) bits(n-2) bits(0)
cplxr_sum(n) = ----------------------- + ----------------------- + ... + -----------------------
qscale(n-1) * rceq(n-1) qscale(n-2) * rceq(n-2) qscale(0) * rceq(0)
*/
if( h->param.rc.i_rc_method == X264_RC_CRF ) //若是CRF
{ //rate factor = rate_factor_constant
q = get_qscale( h, &rce, rcc->rate_factor_constant, h->fenc->i_frame );
}
else //ABR,使用abr_buffer
{ //rate_factor = wanted_bits_window / cplxr_sum
q = get_qscale( h, &rce, rcc->wanted_bits_window / rcc->cplxr_sum, h->fenc->i_frame );
/* ABR code can potentially be counterproductive in CBR, so just don't bother.
* Don't run it if the frame complexity is zero either. */
if( !rcc->b_vbv_min_rate && rcc->last_satd )
{
// FIXME is it simpler to keep track of wanted_bits in ratecontrol_end?
int i_frame_done = h->i_frame;
//播放到该帧所需要的时间
double time_done = i_frame_done / rcc->fps;
if( h->param.b_vfr_input && i_frame_done > 0 ) //variable frame rate
time_done = ((double)(h->fenc->i_reordered_pts - h->i_reordered_pts_delay)) * h->param.i_timebase_num / h->param.i_timebase_den;
//得到目前为止我们所期望的比特总开销:时间 * 期望bitrate = 期望bits
wanted_bits = time_done * rcc->bitrate;
if( wanted_bits > 0 )
{
//更新abr_buffer
abr_buffer *= X264_MAX( 1, sqrt( time_done ) );
//计算abr_buffer的上溢下溢
overflow = x264_clip3f( 1.0 + (predicted_bits - wanted_bits) / abr_buffer, .5, 2 );
//根据abr_buffer的上溢下溢情况调整qscale
q *= overflow;
}
}
} // end of ABR
/* 做一些收尾工作:
·若当前帧I且上个非B帧P,则通过P的QP和ip_factor来确定当前I帧的qscale
·对qscale进行lmin和lmax限制,防止qscale波动大
·上述1pass中的方法无法有效处理第一帧,故对第一帧单独设置初始化qscale */
if( pict_type == SLICE_TYPE_I && h->param.i_keyint_max > 1
/* should test _next_ pict type, but that isn't decided yet */
&& rcc->last_non_b_pict_type != SLICE_TYPE_I )
{ /* 若当前帧为I帧 && 最大关键帧距离>1 && 上一个非B帧是P帧
则通过得到P帧的qscale和ip_factor来计算当前I帧的 */
q = qp2qscale( rcc->accum_p_qp / rcc->accum_p_norm );
q /= fabs( h->param.rc.f_ip_factor );
}
else if( h->i_frame > 0 ) //非首帧
{
if( h->param.rc.i_rc_method != X264_RC_CRF ) //abr/cqp
{
/* Asymmetric clipping, because symmetric would prevent
* overflow control in areas of rapidly oscillating complexity
* 避免qscale波动太大,计算min和max限制qscale。
* 该min和max与上一个同类型帧的qscale和帧最大qscale改变率计算而得,
* 同时也与abr_buffer的上下溢出情况相关。 */
double lmin = rcc->last_qscale_for[pict_type] / rcc->lstep;
double lmax = rcc->last_qscale_for[pict_type] * rcc->lstep;
//根据abr_buffer的溢出情况再次调节lmin和lmax
if( overflow > 1.1 && h->i_frame > 3 )
lmax *= rcc->lstep;
else if( overflow < 0.9 )
lmin /= rcc->lstep;
q = x264_clip3f(q, lmin, lmax);
}
}// 到这里的帧为首帧
else if( h->param.rc.i_rc_method == X264_RC_CRF && rcc->qcompress != 1 )
{ //若是CRF && qcomp!=1即各帧的rceq!=1
q = qp2qscale( ABR_INIT_QP ) / fabs( h->param.rc.f_ip_factor );
}
rcc->qp_novbv = qscale2qp( q );
//进行vbv检验,并对qscale进行clip
q = clip_qscale( h, pict_type, q );
} // end of 1pass
/*到这里已经确定了qscale
更新last_qscale_for[pict_type]和last_qscale */
rcc->last_qscale_for[pict_type] =
rcc->last_qscale = q;
if( !(rcc->b_2pass && !rcc->b_vbv) && h->fenc->i_frame == 0 )
rcc->last_qscale_for[SLICE_TYPE_P] = q * fabs( h->param.rc.f_ip_factor );
/*
估算一下当前帧的体积
*/
if( rcc->b_2pass ) //若是2pass,则基于tex_bits,mb_bits,misc_bits等来估算帧体积
rcc->frame_size_planned = qscale2bits( &rce, q );
else //若是1pass,则根据satd估算帧体积
rcc->frame_size_planned = predict_size( &rcc->pred[h->sh.i_type], q, rcc->last_satd );
// Always use up the whole VBV in this case. 若使用单帧vbv,则将单帧vbv的最大帧率比特给帧体积
if( rcc->single_frame_vbv )
rcc->frame_size_planned = rcc->buffer_rate;
// Limit planned size by MinCR 基于MinCR来限制帧体积
if( rcc->b_vbv )
rcc->frame_size_planned = X264_MIN( rcc->frame_size_planned, rcc->frame_size_maximum );
h->rc->frame_size_estimated = rcc->frame_size_planned;
return q;
} // end of I、P帧
}
码控-rate_estimate_qscale()
最新推荐文章于 2022-12-13 01:31:06 发布