From: Anton Mitrofanov Date: Mon, 10 Mar 2014 12:48:02 +0000 (+0400) Subject: mbaff: fix mb_field_decoding_flag tracking and simplify allow skip check X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8b821ec19ba9425c120b8986a57ca7c6b9f088ed;p=libx264 mbaff: fix mb_field_decoding_flag tracking and simplify allow skip check Fixes an issue with too many forced non-skips in mbaff+cavlc, as well as non-deterministic output with mbaff+cavlc+sliced-threads. --- diff --git a/common/macroblock.c b/common/macroblock.c index bf5a0e82..8437b729 100644 --- a/common/macroblock.c +++ b/common/macroblock.c @@ -1253,8 +1253,13 @@ static void ALWAYS_INLINE x264_macroblock_cache_load( x264_t *h, int mb_x, int m } } - if( b_mbaff && mb_x == 0 && !(mb_y&1) && mb_y > 0 ) - h->mb.field_decoding_flag = h->mb.field[h->mb.i_mb_xy - h->mb.i_mb_stride]; + if( b_mbaff && mb_x == 0 && !(mb_y&1) ) + { + if( h->mb.i_mb_top_xy >= h->sh.i_first_mb ) + h->mb.field_decoding_flag = h->mb.field[h->mb.i_mb_top_xy]; + else + h->mb.field_decoding_flag = 0; + } /* Check whether skip here would cause decoder to predict interlace mode incorrectly. * FIXME: It might be better to change the interlace type rather than forcing a skip to be non-skip. */ @@ -1262,26 +1267,8 @@ static void ALWAYS_INLINE x264_macroblock_cache_load( x264_t *h, int mb_x, int m if( b_mbaff ) { if( MB_INTERLACED != h->mb.field_decoding_flag && - h->mb.i_mb_prev_xy >= 0 && IS_SKIP(h->mb.type[h->mb.i_mb_prev_xy]) ) + (mb_y&1) && IS_SKIP(h->mb.type[h->mb.i_mb_xy - h->mb.i_mb_stride]) ) h->mb.b_allow_skip = 0; - if( (mb_y&1) && IS_SKIP(h->mb.type[h->mb.i_mb_xy - h->mb.i_mb_stride]) ) - { - if( h->mb.i_neighbour & MB_LEFT ) - { - if( h->mb.field[h->mb.i_mb_xy - 1] != MB_INTERLACED ) - h->mb.b_allow_skip = 0; - } - else if( h->mb.i_neighbour & MB_TOP ) - { - if( h->mb.field[h->mb.i_mb_top_xy] != MB_INTERLACED ) - h->mb.b_allow_skip = 0; - } - else // Frame mb pair is predicted - { - if( MB_INTERLACED ) - h->mb.b_allow_skip = 0; - } - } } if( h->param.b_cabac ) diff --git a/encoder/cavlc.c b/encoder/cavlc.c index b8ea8f2f..5d826fff 100644 --- a/encoder/cavlc.c +++ b/encoder/cavlc.c @@ -500,6 +500,9 @@ void x264_macroblock_write_cavlc( x264_t *h ) && (!(h->mb.i_mb_y & 1) || IS_SKIP(h->mb.type[h->mb.i_mb_xy - h->mb.i_mb_stride])) ) { bs_write1( s, MB_INTERLACED ); +#if !RDO_SKIP_BS + h->mb.field_decoding_flag = MB_INTERLACED; +#endif } #if !RDO_SKIP_BS