// 编码一帧后, 保存码率控制状态信息
/* After encoding one frame, save stats and update ratecontrol state */
int x264_ratecontrol_end( x264_t *h, int bits, int *filler )
{
x264_ratecontrol_t *rc = h->rc;
// 宏块类型相关计数
// int i_mb_count[19];
const int *mbs = h->stat.frame.i_mb_count;
x264_emms();
// 统计宏块相关信息
h->stat.frame.i_mb_count_skip = mbs[P_SKIP] + mbs[B_SKIP];
h->stat.frame.i_mb_count_i = mbs[I_16x16] + mbs[I_8x8] + mbs[I_4x4];
h->stat.frame.i_mb_count_p = mbs[P_L0] + mbs[P_8x8];
for( int i = B_DIRECT; i < B_8x8; i++ )
h->stat.frame.i_mb_count_p += mbs[i];
// 计算当前重构帧的qp信息
h->fdec->f_qp_avg_rc = rc->qpa_rc /= h->mb.i_mb_count;
h->fdec->f_qp_avg_aq = (float)rc->qpa_aq / h->mb.i_mb_count;
h->fdec->f_crf_avg = h->param.rc.f_rf_constant + h->fdec->f_qp_avg_rc - rc->qp_novbv;
// 输出统计信息到 stat 文件
if( h->param.rc.b_stat_write )
{
char c_type = h->sh.i_type==SLICE_TYPE_I ? (h->fenc->i_poc==0 ? 'I' : 'i')
: h->sh.i_type==SLICE_TYPE_P ? 'P'
: h->fenc->b_kept_as_ref ? 'B' : 'b';
int dir_frame = h->stat.frame.i_direct_score[1] - h->stat.frame.i_direct_score[0];
int dir_avg = h->stat.i_direct_score[1] - h->stat.i_direct_score[0];
char c_direct = h->mb.b_direct_auto_write ?
( dir_frame>0 ? 's' : dir_frame<0 ? 't' :
dir_avg>0 ? 's' : dir_avg<0 ? 't' : '-' )
: '-';
if( fprintf( rc->p_stat_file_out,
"in:%d out:%d type:%c dur:%"PRId64" cpbdur:%"PRId64" q:%.2f aq:%.2f tex:%d mv:%d misc:%d imb:%d pmb:%d smb:%d d:%c ref:",
h->fenc->i_frame, h->i_frame,
c_type, h->fenc->i_duration,
h->fenc->i_cpb_duration,
rc->qpa_rc, h->fdec->f_qp_avg_aq,
h->stat.frame.i_tex_bits,
h->stat.frame.i_mv_bits,
h->stat.frame.i_misc_bits,
h->stat.frame.i_mb_count_i,
h->stat.frame.i_mb_count_p,
h->stat.frame.i_mb_count_skip,
c_direct) < 0 )
goto fail;
/* Only write information for reference reordering once. */
int use_old_stats = h->param.rc.b_stat_read && rc->rce->refs > 1;
for( int i = 0; i < (use_old_stats ? rc->rce->refs : h->i_ref[0]); i++ )
{
int refcount = use_old_stats ? rc->rce->refcount[i]
: PARAM_INTERLACED ? h->stat.frame.i_mb_count_ref[0][i*2]
+ h->stat.frame.i_mb_count_ref[0][i*2+1]
: h->stat.frame.i_mb_count_ref[0][i];
if( fprintf( rc->p_stat_file_out, "%d ", refcount ) < 0 )
goto fail;
}
if( h->param.analyse.i_weighted_pred >= X264_WEIGHTP_SIMPLE && h->sh.weight[0][0].weightfn )
{
if( fprintf( rc->p_stat_file_out, "w:%d,%d,%d",
h->sh.weight[0][0].i_denom, h->sh.weight[0][0].i_scale, h->sh.weight[0][0].i_offset ) < 0 )
goto fail;
if( h->sh.weight[0][1].weightfn || h->sh.weight[0][2].weightfn )
{
if( fprintf( rc->p_stat_file_out, ",%d,%d,%d,%d,%d ",
h->sh.weight[0][1].i_denom, h->sh.weight[0][1].i_scale, h->sh.weight[0][1].i_offset,
h->sh.weight[0][2].i_scale, h->sh.weight[0][2].i_offset ) < 0 )
goto fail;
}
else if( fprintf( rc->p_stat_file_out, " " ) < 0 )
goto fail;
}
if( fprintf( rc->p_stat_file_out, ";\n") < 0 )
goto fail;
/* Don't re-write the data in multi-pass mode. */
if( h->param.rc.b_mb_tree && h->fenc->b_kept_as_ref && !h->param.rc.b_stat_read )
{
uint8_t i_type = h->sh.i_type;
/* Values are stored as big-endian FIX8.8 */
for( int i = 0; i < h->mb.i_mb_count; i++ )
rc->mbtree.qp_buffer[0][i] = endian_fix16( h->fenc->f_qp_offset[i]*256.0 );
if( fwrite( &i_type, 1, 1, rc->p_mbtree_stat_file_out ) < 1 )
goto fail;
if( fwrite( rc->mbtree.qp_buffer[0], sizeof(uint16_t), h->mb.i_mb_count, rc->p_mbtree_stat_file_out ) < h->mb.i_mb_count )
goto fail;
}
}
// 如果自适应码率控制
if( rc->b_abr )
{
// 计算复杂度之和
if( h->sh.i_type != SLICE_TYPE_B )
rc->cplxr_sum += bits * qp2qscale( rc->qpa_rc ) / rc->last_rceq;
else
{
// B 帧 复杂度之和
/* Depends on the fact that B-frame's QP is an offset from the following P-frame's.
* Not perfectly accurate with B-refs, but good enough. */
rc->cplxr_sum += bits * qp2qscale( rc->qpa_rc ) / (rc->last_rceq * fabs( h->param.rc.f_pb_factor ));
}
rc->cplxr_sum *= rc->cbr_decay;
rc->wanted_bits_window += h->fenc->f_duration * rc->bitrate;
rc->wanted_bits_window *= rc->cbr_decay;
}
if( rc->b_2pass ) // 两阶段,计算预计的bits之和,见qscale2bits
rc->expected_bits_sum += qscale2bits( rc->rce, qp2qscale( rc->rce->new_qp ) );
// 如果 宏块qp可变
if( h->mb.b_variable_qp )
{
if( h->sh.i_type == SLICE_TYPE_B )
{
// 增加B帧bits数
rc->bframe_bits += bits;
if( h->fenc->b_last_minigop_bframe )
{
// 见 update_predictor
update_predictor( rc->pred_b_from_p, qp2qscale( rc->qpa_rc ),
h->fref[1][h->i_ref[1]-1]->i_satd, rc->bframe_bits / rc->bframes );
rc->bframe_bits = 0;
}
}
}
// 更新VBV, 控制下溢,上溢
*filler = update_vbv( h, bits );
rc->filler_bits_sum += *filler * 8;
if( h->sps->vui.b_nal_hrd_parameters_present )
{
if( h->fenc->i_frame == 0 )
{
// access unit initialises the HRD
h->fenc->hrd_timing.cpb_initial_arrival_time = 0;
rc->initial_cpb_removal_delay = h->initial_cpb_removal_delay;
rc->initial_cpb_removal_delay_offset = h->initial_cpb_removal_delay_offset;
h->fenc->hrd_timing.cpb_removal_time = rc->nrt_first_access_unit = (double)rc->initial_cpb_removal_delay / 90000;
}
else
{
h->fenc->hrd_timing.cpb_removal_time = rc->nrt_first_access_unit + (double)(h->fenc->i_cpb_delay - h->i_cpb_delay_pir_offset) *
h->sps->vui.i_num_units_in_tick / h->sps->vui.i_time_scale;
double cpb_earliest_arrival_time = h->fenc->hrd_timing.cpb_removal_time - (double)rc->initial_cpb_removal_delay / 90000;
if( h->fenc->b_keyframe )
{
rc->nrt_first_access_unit = h->fenc->hrd_timing.cpb_removal_time;
rc->initial_cpb_removal_delay = h->initial_cpb_removal_delay;
rc->initial_cpb_removal_delay_offset = h->initial_cpb_removal_delay_offset;
}
else
cpb_earliest_arrival_time -= (double)rc->initial_cpb_removal_delay_offset / 90000;
if( h->sps->vui.hrd.b_cbr_hrd )
h->fenc->hrd_timing.cpb_initial_arrival_time = rc->previous_cpb_final_arrival_time;
else
h->fenc->hrd_timing.cpb_initial_arrival_time = X264_MAX( rc->previous_cpb_final_arrival_time, cpb_earliest_arrival_time );
}
int filler_bits = *filler ? X264_MAX( (FILLER_OVERHEAD - h->param.b_annexb), *filler )*8 : 0;
// Equation C-6
h->fenc->hrd_timing.cpb_final_arrival_time = rc->previous_cpb_final_arrival_time = h->fenc->hrd_timing.cpb_initial_arrival_time +
(double)(bits + filler_bits) / h->sps->vui.hrd.i_bit_rate_unscaled;
h->fenc->hrd_timing.dpb_output_time = (double)h->fenc->i_dpb_output_delay * h->sps->vui.i_num_units_in_tick / h->sps->vui.i_time_scale +
h->fenc->hrd_timing.cpb_removal_time;
}
return 0;
fail:
x264_log( h, X264_LOG_ERROR, "ratecontrol_end: stats file could not be written to\n" );
return -1;
}
typedef struct x264_left_table_t
{
uint8_t intra[4];
uint8_t nnz[4];
uint8_t nnz_chroma[4];
uint8_t mv[4];
uint8_t ref[4];
} x264_left_table_t;
/* Current frame stats */
typedef struct
{
/* MV bits (MV+Ref+Block Type) */
int i_mv_bits;
/* Texture bits (DCT coefs) */
int i_tex_bits;
/* ? */
int i_misc_bits;
/* MB type counts */
int i_mb_count[19];
int i_mb_count_i;
int i_mb_count_p;
int i_mb_count_skip;
int i_mb_count_8x8dct[2];
int i_mb_count_ref[2][X264_REF_MAX*2];
int i_mb_partition[17];
int i_mb_cbp[6];
int i_mb_pred_mode[4][13];
int i_mb_field[3];
/* Adaptive direct mv pred */
int i_direct_score[2];
/* Metrics */
int64_t i_ssd[3];
double f_ssim;
int i_ssim_cnt;
} x264_frame_stat_t;
/* 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;
}
static void update_predictor( predictor_t *p, float q, float var, float bits )
{
float range = 1.5;
if( var < 10 )
return;
float old_coeff = p->coeff / p->count;
float new_coeff = X264_MAX( bits*q / var, p->coeff_min );
float new_coeff_clipped = x264_clip3f( new_coeff, old_coeff/range, old_coeff*range );
float new_offset = bits*q - new_coeff_clipped * var;
if( new_offset >= 0 )
new_coeff = new_coeff_clipped;
else
new_offset = 0;
p->count *= p->decay;
p->coeff *= p->decay;
p->offset *= p->decay;
p->count ++;
p->coeff += new_coeff;
p->offset += new_offset;
}
// 编码一帧后更新VBV
// update VBV after encoding a frame
static int update_vbv( x264_t *h, int bits )
{
int filler = 0;
int bitrate = h->sps->vui.hrd.i_bit_rate_unscaled;
x264_ratecontrol_t *rcc = h->rc;
x264_ratecontrol_t *rct = h->thread[0]->rc;
uint64_t buffer_size = (uint64_t)h->sps->vui.hrd.i_cpb_size_unscaled * h->sps->vui.i_time_scale;
// 更新帧类型预测器
if( rcc->last_satd >= h->mb.i_mb_count )
update_predictor( &rct->pred[h->sh.i_type], qp2qscale( rcc->qpa_rc ), rcc->last_satd, bits );
if( !rcc->b_vbv )
return filler;
// 计算实际剩下的缓冲区大小
rct->buffer_fill_final -= (uint64_t)bits * h->sps->vui.i_time_scale;
if( rct->buffer_fill_final < 0 )
{
// VBV 缓冲区下溢
double underflow = (double)rct->buffer_fill_final / h->sps->vui.i_time_scale;
if( rcc->rate_factor_max_increment && rcc->qpm >= rcc->qp_novbv + rcc->rate_factor_max_increment )
x264_log( h, X264_LOG_DEBUG, "VBV underflow due to CRF-max (frame %d, %.0f bits)\n", h->i_frame, underflow );
else
x264_log( h, X264_LOG_WARNING, "VBV underflow (frame %d, %.0f bits)\n", h->i_frame, underflow );
}
// 重新设置, 计算实际缓冲区大小
rct->buffer_fill_final = X264_MAX( rct->buffer_fill_final, 0 );
if( h->param.i_avcintra_class )
rct->buffer_fill_final += buffer_size;
else
rct->buffer_fill_final += (uint64_t)bitrate * h->sps->vui.i_num_units_in_tick * h->fenc->i_cpb_duration;
// 控制VBV上溢
if( h->param.rc.b_filler && rct->buffer_fill_final > buffer_size )
{
int64_t scale = (int64_t)h->sps->vui.i_time_scale * 8;
filler = (rct->buffer_fill_final - buffer_size + scale - 1) / scale;
bits = h->param.i_avcintra_class ? filler * 8 : X264_MAX( (FILLER_OVERHEAD - h->param.b_annexb), filler ) * 8;
rct->buffer_fill_final -= (uint64_t)bits * h->sps->vui.i_time_scale;
}
else
rct->buffer_fill_final = X264_MIN( rct->buffer_fill_final, buffer_size );
return filler;
}