x264 – rate_estimate_qscale

  • Post author:
  • Post category:其他


// 依据到目前为止编码bit数估算一帧的qscale

// update qscale for 1 frame based on actual bits used so far

static float rate_estimate_qscale( x264_t *h )

{


float q;

x264_ratecontrol_t *rcc = h->rc;

ratecontrol_entry_t UNINIT(rce);

int pict_type = h->sh.i_type;

// 获取统计的总bits数

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

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 */

// 距当前帧最近的参考帧列表0, 1里的帧的类型是否是I帧

int i0 = IS_X264_TYPE_I(h->fref_nearest[0]->i_type);

int i1 = IS_X264_TYPE_I(h->fref_nearest[1]->i_type);

// 获取当前待编码帧与两最近参考帧的POC之距离

int dt0 = abs(h->fenc->i_poc – h->fref_nearest[0]->i_poc);

int dt1 = abs(h->fenc->i_poc – h->fref_nearest[1]->i_poc);

// 获取两最近参考帧的平均qp

float q0 = h->fref_nearest[0]->f_qp_avg_rc;

float q1 = h->fref_nearest[1]->f_qp_avg_rc;

// 如果两参考帧是B帧, 并用作参考帧,将获取的平均qp

// 各减去pb_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帧,则取q0, q1的平均,再加上ip_offset

// 否则如果list0最近参考帧是I帧,则q = q0

// 或list1最近参考帧是I帧,则q = q1

// 如果两帧都不是I帧,则进行插值计算q

if( i0 && i1 )

q = (q0 + q1) / 2 + rcc->ip_offset;

else if( i0 )

q = q1;

else if( i1 )

q = q0;

else

q = (q0*dt1 + q1*dt0) / (dt0 + dt1);

// 依据当前待编码帧是否将作为参考帧,来对

// 当前帧qp作相应调整

if( h->fenc->b_kept_as_ref )

q += rcc->pb_offset/2;

else

q += rcc->pb_offset;

// 对于两阶段, 并且b_vbv生效

// 根据rce的tex_bits, mv_bits和misc_bits

// 以及当前帧的qscale,来估算当前帧的bits

// 见下面 qscale2bits

if( rcc->b_2pass && rcc->b_vbv )

rcc->frame_size_planned = qscale2bits( &rce, qp2qscale( q ) );

else   // 见下面 predict_size

rcc->frame_size_planned = predict_size( rcc->pred_b_from_p, qp2qscale( q ), h->fref[1][h->i_ref[1]-1]->i_satd );

/* Limit planned size by 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;

/* For row SATDs */

if( rcc->b_vbv )  // 见下面 x264_rc_analyse_slice

rcc->last_satd = x264_rc_analyse_slice( h );

rcc->qp_novbv = q;

return qp2qscale( q );

}

else

{


// 非B帧情况

// 自适应缓冲区

double abr_buffer = 2 * rcc->rate_tolerance * rcc->bitrate;

// 两阶段

if( rcc->b_2pass )

{

double lmin = rcc->lmin[pict_type];

double lmax = rcc->lmax[pict_type];

int64_t diff;

int64_t predicted_bits = total_bits;

// 统计预测的bits

if( rcc->b_vbv )

{


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 += (int64_t)bits;

}

}

}

else

{


if( h->i_frame < h->i_thread_frames )

predicted_bits += (int64_t)h->i_frame * rcc->bitrate / rcc->fps;

else

predicted_bits += (int64_t)(h->i_thread_frames – 1) * rcc->bitrate / rcc->fps;

}

/* Adjust ABR buffer based on distance to the end of the video. */

if( rcc->num_entries > h->i_frame )

{


double final_bits = rcc->entry[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 – (int64_t)rce.expected_bits;

q = rce.new_qscale;

q /= x264_clip3f((double)(abr_buffer – diff) / abr_buffer, .5, 2);

if( ((h->i_frame + 1 – h->i_thread_frames) >= rcc->fps) &&

(rcc->expected_bits_sum > 0))

{


/* 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 );

}

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 = 1;

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 / (CLIP_DURATION(h->fenc->f_duration) / BASE_FRAME_DURATION);

rcc->short_term_cplxcount ++;

rce.tex_bits = rcc->last_satd;

rce.blurred_complexity = rcc->short_term_cplxsum / rcc->short_term_cplxcount;

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;

rce.i_duration = h->fenc->i_duration;

if( h->param.rc.i_rc_method == X264_RC_CRF )

{


q = get_qscale( h, &rce, rcc->rate_factor_constant, h->fenc->i_frame );

}

else

{


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 + 1 – h->i_thread_frames;

double time_done = i_frame_done / rcc->fps;

if( h->param.b_vfr_input && i_frame_done > 0 )

time_done = ((double)(h->fenc->i_reordered_pts – h->i_reordered_pts_delay)) * h->param.i_timebase_num / h->param.i_timebase_den;

wanted_bits = time_done * rcc->bitrate;

if( wanted_bits > 0 )

{


abr_buffer *= X264_MAX( 1, sqrt( time_done ) );

overflow = x264_clip3f( 1.0 + (total_bits – wanted_bits) / abr_buffer, .5, 2 );

q *= overflow;

}

}

}

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 )

{


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 )

{


/* Asymmetric clipping, because symmetric would prevent

* overflow control in areas of rapidly oscillating complexity */

double lmin = rcc->last_qscale_for[pict_type] / rcc->lstep;

double lmax = rcc->last_qscale_for[pict_type] * rcc->lstep;

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 )

{


q = qp2qscale( ABR_INIT_QP ) / fabs( h->param.rc.f_ip_factor );

}

rcc->qp_novbv = qscale2qp( q );

//FIXME use get_diff_limited_q() ?

q = clip_qscale( h, pict_type, q );

}

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 && rcc->b_vbv )

rcc->frame_size_planned = qscale2bits(&rce, q);

else

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. */

if( rcc->single_frame_vbv )

rcc->frame_size_planned = rcc->buffer_rate;

/* Limit planned size by 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;

}

}

// 根据rce的tex_bits, mv_bits和misc_bits

// 以及当前帧的qscale,来估算当前帧的bits

/* Texture bitrate is not quite inversely proportional to qscale,

* probably due the the changing number of SKIP blocks.

* MV bits level off at about qp<=12, because the lambda used

* for motion estimation is constant there. */

static inline double qscale2bits( ratecontrol_entry_t *rce, double qscale )

{


if( qscale<0.1 )

qscale = 0.1;

return (rce->tex_bits + .1) * pow( rce->qscale / qscale, 1.1 )

+ rce->mv_bits * pow( X264_MAX(rce->qscale, 1) / X264_MAX(qscale, 1), 0.5 )

+ rce->misc_bits;

}

// p – 预测器, q – qscale, var – satd

static float predict_size( predictor_t *p, float q, float var )

{


return (p->coeff*var + p->offset) / (q*p->count);

}

int x264_rc_analyse_slice( x264_t *h )

{


int p0 = 0, p1, b;

int cost;

x264_emms();

// 如果待编码帧是I帧,那么p1, b = 0

// 如果是P帧,则p1=b=h->fenc->i_bframes + 1 ???

// 否则p1取距待编码帧最近的两参考帧(list0, list1中个一个)

// POC之差的平均, b 取 待编码帧与list0最近的参考帧之距的平均

if( IS_X264_TYPE_I(h->fenc->i_type) )

p1 = b = 0;

else if( h->fenc->i_type == X264_TYPE_P )

p1 = b = h->fenc->i_bframes + 1;

else //B帧

{


p1 = (h->fref_nearest[1]->i_poc – h->fref_nearest[0]->i_poc)/2;

b  = (h->fenc->i_poc – h->fref_nearest[0]->i_poc)/2;

}

// 注意这段代码有点诡异。

// 下面frames指向h中的某块内存

// 再下面frames[b] 又指回来了。

// 即&frames[b] 就是 &h->fenc

// frames[b] 就是 h->fenc

/* We don’t need to assign p0/p1 since we are not performing any real analysis here. */

x264_frame_t **frames = &h->fenc – b;

/* cost should have been already calculated by x264_slicetype_decide */

//

cost = frames[b]->i_cost_est[b-p0][p1-b];

assert( cost >= 0 );

// 使能mbtree, 但是没有使能stat_read

if( h->param.rc.b_mb_tree && !h->param.rc.b_stat_read )

{


// 统计行积分,计算帧编码代价

cost = x264_slicetype_frame_cost_recalculate( h, frames, p0, p1, b );

// ???

if( b && h->param.rc.i_vbv_buffer_size )

x264_slicetype_frame_cost_recalculate( h, frames, b, b, b );

}

/* In AQ, use the weighted score instead. */

else if( h->param.rc.i_aq_mode )

cost = frames[b]->i_cost_est_aq[b-p0][p1-b];

// 获取该编码帧和重构帧的行satd

h->fenc->i_row_satd = h->fenc->i_row_satds[b-p0][p1-b];

h->fdec->i_row_satd = h->fdec->i_row_satds[b-p0][p1-b];

// 将计算的代价赋值给重构帧的i_satd

h->fdec->i_satd = cost;

拷贝编码帧的行satd到重构帧的行satd

memcpy( h->fdec->i_row_satd, h->fenc->i_row_satd, h->mb.i_mb_height * sizeof(int) );

// 拷贝I帧的行satd???

if( !IS_X264_TYPE_I(h->fenc->i_type) )

memcpy( h->fdec->i_row_satds[0][0], h->fenc->i_row_satds[0][0], h->mb.i_mb_height * sizeof(int) );

// 帧内刷新???

if( h->param.b_intra_refresh && h->param.rc.i_vbv_buffer_size && h->fenc->i_type == X264_TYPE_P )

{


int ip_factor = 256 * h->param.rc.f_ip_factor; /* fix8 */

for( int y = 0; y < h->mb.i_mb_height; y++ )

{


int mb_xy = y * h->mb.i_mb_stride + h->fdec->i_pir_start_col;

for( int x = h->fdec->i_pir_start_col; x <= h->fdec->i_pir_end_col; x++, mb_xy++ )

{


int intra_cost = (h->fenc->i_intra_cost[mb_xy] * ip_factor + 128) >> 8;

int inter_cost = h->fenc->lowres_costs[b-p0][p1-b][mb_xy] & LOWRES_COST_MASK;

int diff = intra_cost – inter_cost;

if( h->param.rc.i_aq_mode )

h->fdec->i_row_satd[y] += (diff * frames[b]->i_inv_qscale_factor[mb_xy] + 128) >> 8;

else

h->fdec->i_row_satd[y] += diff;

cost += diff;

}

}

}

if( BIT_DEPTH > 8 )

for( int y = 0; y < h->mb.i_mb_height; y++ )

h->fdec->i_row_satd[y] >>= (BIT_DEPTH – 8);

return cost >> (BIT_DEPTH – 8);

}


// 如果mbtree 改变了量化器,我们需要在不重新lookahead

// 情况下计算帧编码代价

/* If MB-tree changes the quantizers, we need to recalculate the frame cost without

* re-running lookahead. */

static int x264_slicetype_frame_cost_recalculate( x264_t *h, x264_frame_t **frames, int p0, int p1, int b )

{


int i_score = 0;

// 获得该帧的行satd

int *row_satd = frames[b]->i_row_satds[b-p0][p1-b];

// 得到qp offset

float *qp_offset = IS_X264_TYPE_B(frames[b]->i_type) ? frames[b]->f_qp_offset_aq : frames[b]->f_qp_offset;

x264_emms();

// 统计行satd,并且计算总的score

for( h->mb.i_mb_y = h->mb.i_mb_height – 1; h->mb.i_mb_y >= 0; h->mb.i_mb_y– )

{


row_satd[ h->mb.i_mb_y ] = 0;

for( h->mb.i_mb_x = h->mb.i_mb_width – 1; h->mb.i_mb_x >= 0; h->mb.i_mb_x– )

{


int i_mb_xy = h->mb.i_mb_x + h->mb.i_mb_y*h->mb.i_mb_stride;

int i_mb_cost = frames[b]->lowres_costs[b-p0][p1-b][i_mb_xy] & LOWRES_COST_MASK;

float qp_adj = qp_offset[i_mb_xy];

i_mb_cost = (i_mb_cost * x264_exp2fix8(qp_adj) + 128) >> 8;

row_satd[ h->mb.i_mb_y ] += i_mb_cost;

if( (h->mb.i_mb_y > 0 && h->mb.i_mb_y < h->mb.i_mb_height – 1 &&

h->mb.i_mb_x > 0 && h->mb.i_mb_x < h->mb.i_mb_width – 1) ||

h->mb.i_mb_width <= 2 || h->mb.i_mb_height <= 2 )

{


i_score += i_mb_cost;

}

}

}

return i_score;

}





版权声明:本文为fanbird2008原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。