[x264-devel] commit: Don't even try direct temporal when it would give junk MVs ( Jason Garrett-Glaser )
git version control
git at videolan.org
Mon Feb 15 10:07:49 CET 2010
x264 | branch: master | Jason Garrett-Glaser <darkshikari at gmail.com> | Sat Feb 13 11:19:38 2010 -0800| [d2277586a7bce99caa448b3d461f6f42e8a20e6d] | committer: Jason Garrett-Glaser
Don't even try direct temporal when it would give junk MVs
In PbBbP pyramid structure, the last "b" cannot use temporal because L0Ref0(L1Ref0) != L0Ref0.
Don't even bother analyzing it, just use spatial.
Should improve speed and direct auto effectiveness in CRF and 1-pass modes when b-pyramid is used.
Also makes --direct temporal useful with --b-pyramid, since it will fall back to spatial for frames where temporal is broken.
> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=d2277586a7bce99caa448b3d461f6f42e8a20e6d
---
common/frame.h | 1 +
encoder/encoder.c | 30 +++++++++++++++++++++---------
2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/common/frame.h b/common/frame.h
index b1852b3..7c8e2ff 100644
--- a/common/frame.h
+++ b/common/frame.h
@@ -48,6 +48,7 @@ typedef struct x264_frame
uint8_t i_bframes; /* number of bframes following this nonb in coded order */
float f_qp_avg_rc; /* QPs as decided by ratecontrol */
float f_qp_avg_aq; /* QPs as decided by AQ in addition to ratecontrol */
+ int i_poc_l0ref0; /* poc of first refframe in L0, used to check if direct temporal is possible */
/* YUV buffer */
int i_plane;
diff --git a/encoder/encoder.c b/encoder/encoder.c
index cca9c45..df62389 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -108,12 +108,24 @@ static void x264_slice_header_init( x264_t *h, x264_slice_header_t *sh,
sh->i_redundant_pic_cnt = 0;
- if( !h->mb.b_direct_auto_read )
+ h->mb.b_direct_auto_write = h->param.analyse.i_direct_mv_pred == X264_DIRECT_PRED_AUTO
+ && h->param.i_bframe
+ && ( h->param.rc.b_stat_write || !h->param.rc.b_stat_read );
+
+ if( !h->mb.b_direct_auto_read && sh->i_type == SLICE_TYPE_B )
{
- if( h->mb.b_direct_auto_write )
- sh->b_direct_spatial_mv_pred = ( h->stat.i_direct_score[1] > h->stat.i_direct_score[0] );
+ if( h->fref1[0]->i_poc_l0ref0 == h->fref0[0]->i_poc )
+ {
+ if( h->mb.b_direct_auto_write )
+ sh->b_direct_spatial_mv_pred = ( h->stat.i_direct_score[1] > h->stat.i_direct_score[0] );
+ else
+ sh->b_direct_spatial_mv_pred = ( param->analyse.i_direct_mv_pred == X264_DIRECT_PRED_SPATIAL );
+ }
else
- sh->b_direct_spatial_mv_pred = ( param->analyse.i_direct_mv_pred == X264_DIRECT_PRED_SPATIAL );
+ {
+ h->mb.b_direct_auto_write = 0;
+ sh->b_direct_spatial_mv_pred = 1;
+ }
}
/* else b_direct_spatial_mv_pred was read from the 2pass statsfile */
@@ -623,10 +635,6 @@ static int x264_validate_parameters( x264_t *h )
h->param.i_sync_lookahead = 0;
#endif
- h->mb.b_direct_auto_write = h->param.analyse.i_direct_mv_pred == X264_DIRECT_PRED_AUTO
- && h->param.i_bframe
- && ( h->param.rc.b_stat_write || !h->param.rc.b_stat_read );
-
h->param.i_deblocking_filter_alphac0 = x264_clip3( h->param.i_deblocking_filter_alphac0, -6, 6 );
h->param.i_deblocking_filter_beta = x264_clip3( h->param.i_deblocking_filter_beta, -6, 6 );
h->param.analyse.i_luma_deadzone[0] = x264_clip3( h->param.analyse.i_luma_deadzone[0], 0, 32 );
@@ -2371,6 +2379,9 @@ int x264_encoder_encode( x264_t *h,
x264_reference_check_reorder( h );
}
+ if( h->i_ref0 )
+ h->fdec->i_poc_l0ref0 = h->fref0[0]->i_poc;
+
if( h->sh.i_type == SLICE_TYPE_B )
x264_macroblock_bipred_init( h );
@@ -2806,7 +2817,8 @@ void x264_encoder_close ( x264_t *h )
x264_log( h, X264_LOG_INFO, "8x8 transform intra:%.1f%%%s\n", 100. * i_i8x8 / i_intra, buf );
}
- if( h->param.analyse.i_direct_mv_pred == X264_DIRECT_PRED_AUTO
+ if( (h->param.analyse.i_direct_mv_pred == X264_DIRECT_PRED_AUTO ||
+ (h->stat.i_direct_frames[0] && h->stat.i_direct_frames[1]))
&& h->stat.i_frame_count[SLICE_TYPE_B] )
{
x264_log( h, X264_LOG_INFO, "direct mvs spatial:%.1f%% temporal:%.1f%%\n",
More information about the x264-devel
mailing list