[x264-devel] mbaff: fix mb_field_decoding_flag tracking and simplify allow skip check

Anton Mitrofanov git at videolan.org
Thu Mar 13 21:23:51 CET 2014


x264 | branch: master | Anton Mitrofanov <BugMaster at narod.ru> | Mon Mar 10 16:48:02 2014 +0400| [1adf1023fff7887df15ef459a8f85b5a036338be] | committer: Jason Garrett-Glaser

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.

> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=1adf1023fff7887df15ef459a8f85b5a036338be
---

 common/macroblock.c |   29 ++++++++---------------------
 encoder/cavlc.c     |    3 +++
 2 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/common/macroblock.c b/common/macroblock.c
index a47dbe5..2b455fd 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 3f13361..1863956 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



More information about the x264-devel mailing list