diff --git a/common/common.h b/common/common.h old mode 100644 new mode 100755 index 1e46ae8..7f15495 --- a/common/common.h +++ b/common/common.h @@ -588,6 +588,7 @@ struct x264_t int i_mb_cbp[6]; /* Adaptive direct mv pred */ int i_direct_score[2]; + int64_t i_direct_score_SSD[2]; /* Metrics */ int64_t i_ssd[3]; double f_ssim; diff --git a/encoder/analyse.c b/encoder/analyse.c old mode 100644 new mode 100755 index 7ec43c8..7acc509 --- a/encoder/analyse.c +++ b/encoder/analyse.c @@ -2463,12 +2463,16 @@ void x264_macroblock_analyse( x264_t *h ) analysis.b_direct_available = x264_mb_predict_mv_direct16x16( h, i && analysis.b_direct_available ? &b_changed : NULL ); if( analysis.b_direct_available ) { + int i_bskip_local_cost = 0; if( b_changed ) { x264_mb_mc( h ); b_skip = x264_macroblock_probe_bskip( h ); + if (b_skip) + i_bskip_local_cost = ssd_mb( h ); } h->stat.frame.i_direct_score[ h->sh.b_direct_spatial_mv_pred ] += b_skip; + h->stat.frame.i_direct_score_SSD[ h->sh.b_direct_spatial_mv_pred ] += i_bskip_local_cost; } else b_skip = 0; diff --git a/encoder/ratecontrol.c b/encoder/ratecontrol.c old mode 100644 new mode 100755 index 2dd34d0..e72c2e4 --- a/encoder/ratecontrol.c +++ b/encoder/ratecontrol.c @@ -1084,7 +1084,18 @@ void x264_ratecontrol_end( x264_t *h, int bits ) 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]; + /* if number of skip blocs in spatial and temporal modes are close, use SSD as a selection criterion*/ + int i_direct_score_0 = h->stat.frame.i_direct_score[0]; + int i_direct_score_1 = h->stat.frame.i_direct_score[1]; + int b_tied_skip_nums = X264_MIN(i_direct_score_1, i_direct_score_0) > (X264_MAX(i_direct_score_1, i_direct_score_0)*95/100) + && i_direct_score_0 && i_direct_score_1; + int b_skip_SSD_dif = X264_MIN(h->stat.frame.i_direct_score_SSD[1], h->stat.frame.i_direct_score_SSD[0]) < + (X264_MAX(h->stat.frame.i_direct_score_SSD[1], h->stat.frame.i_direct_score_SSD[0])*80/100); + + int dir_frame = (b_tied_skip_nums && b_skip_SSD_dif) ? + h->stat.frame.i_direct_score_SSD[0] - h->stat.frame.i_direct_score_SSD[1] : + i_direct_score_1 - 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' :