[x264-devel] Enhance mb_info: add mb_info_update

Jason Garrett-Glaser git at videolan.org
Wed Sep 5 21:07:22 CEST 2012


x264 | branch: master | Jason Garrett-Glaser <jason at x264.com> | Thu Aug 16 13:40:32 2012 -0700| [198a7ea13ccb727d4ea24b29f5da9b0292387309] | committer: Jason Garrett-Glaser

Enhance mb_info: add mb_info_update
This feature lets the callee know which decoded macroblocks have changed.

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

 encoder/analyse.c |   70 +++++++++++++++++++++++++++++------------------------
 x264.h            |   20 ++++++++++++---
 2 files changed, 55 insertions(+), 35 deletions(-)

diff --git a/encoder/analyse.c b/encoder/analyse.c
index d396cc4..0577b7a 100644
--- a/encoder/analyse.c
+++ b/encoder/analyse.c
@@ -3047,43 +3047,49 @@ intra_analysis:
         else
         {
             /* Special fast-skip logic using information from mb_info. */
-            if( h->fdec->mb_info && !SLICE_MBAFF && (h->fdec->mb_info[h->mb.i_mb_xy]&X264_MBINFO_CONSTANT) &&
-                 (h->fdec->i_frame - h->fref[0][0]->i_frame) == 1 && !h->sh.b_weighted_pred &&
-                h->fref[0][0]->effective_qp[h->mb.i_mb_xy] <= h->mb.i_qp )
-            {
-                /* Use the P-SKIP MV if we can... */
-                if( !M32(h->mb.cache.pskip_mv) )
-                    b_skip = 1;
-                /* Otherwise, just force a 16x16 block. */
-                else
+            if( h->fdec->mb_info && (h->fdec->mb_info[h->mb.i_mb_xy]&X264_MBINFO_CONSTANT) )
+            {
+                if( !SLICE_MBAFF && (h->fdec->i_frame - h->fref[0][0]->i_frame) == 1 && !h->sh.b_weighted_pred &&
+                    h->fref[0][0]->effective_qp[h->mb.i_mb_xy] <= h->mb.i_qp )
                 {
-                    h->mb.i_type = P_L0;
                     h->mb.i_partition = D_16x16;
-                    analysis.l0.me16x16.i_ref = 0;
-                    M32( analysis.l0.me16x16.mv ) = 0;
+                    /* Use the P-SKIP MV if we can... */
+                    if( !M32(h->mb.cache.pskip_mv) )
+                    {
+                        b_skip = 1;
+                        h->mb.i_type = P_SKIP;
+                    }
+                    /* Otherwise, just force a 16x16 block. */
+                    else
+                    {
+                        h->mb.i_type = P_L0;
+                        analysis.l0.me16x16.i_ref = 0;
+                        M32( analysis.l0.me16x16.mv ) = 0;
+                    }
                     goto skip_analysis;
                 }
+                /* Reset the information accordingly */
+                else if( h->param.analyse.b_mb_info_update )
+                    h->fdec->mb_info[h->mb.i_mb_xy] &= ~X264_MBINFO_CONSTANT;
             }
-            else
-            {
-                int skip_invalid = h->i_thread_frames > 1 && h->mb.cache.pskip_mv[1] > h->mb.mv_max_spel[1];
-                /* If the current macroblock is off the frame, just skip it. */
-                if( HAVE_INTERLACED && !MB_INTERLACED && h->mb.i_mb_y * 16 >= h->param.i_height && !skip_invalid )
-                    b_skip = 1;
-                /* Fast P_SKIP detection */
-                else if( h->param.analyse.b_fast_pskip )
-                {
-                    if( skip_invalid )
-                        // FIXME don't need to check this if the reference frame is done
-                        {}
-                    else if( h->param.analyse.i_subpel_refine >= 3 )
-                        analysis.b_try_skip = 1;
-                    else if( h->mb.i_mb_type_left[0] == P_SKIP ||
-                             h->mb.i_mb_type_top == P_SKIP ||
-                             h->mb.i_mb_type_topleft == P_SKIP ||
-                             h->mb.i_mb_type_topright == P_SKIP )
-                        b_skip = x264_macroblock_probe_pskip( h );
-                }
+
+            int skip_invalid = h->i_thread_frames > 1 && h->mb.cache.pskip_mv[1] > h->mb.mv_max_spel[1];
+            /* If the current macroblock is off the frame, just skip it. */
+            if( HAVE_INTERLACED && !MB_INTERLACED && h->mb.i_mb_y * 16 >= h->param.i_height && !skip_invalid )
+                b_skip = 1;
+            /* Fast P_SKIP detection */
+            else if( h->param.analyse.b_fast_pskip )
+            {
+                if( skip_invalid )
+                    // FIXME don't need to check this if the reference frame is done
+                    {}
+                else if( h->param.analyse.i_subpel_refine >= 3 )
+                    analysis.b_try_skip = 1;
+                else if( h->mb.i_mb_type_left[0] == P_SKIP ||
+                         h->mb.i_mb_type_top == P_SKIP ||
+                         h->mb.i_mb_type_topleft == P_SKIP ||
+                         h->mb.i_mb_type_topright == P_SKIP )
+                    b_skip = x264_macroblock_probe_pskip( h );
             }
         }
 
diff --git a/x264.h b/x264.h
index 7648c96..8e96b7c 100644
--- a/x264.h
+++ b/x264.h
@@ -41,7 +41,7 @@
 
 #include "x264_config.h"
 
-#define X264_BUILD 127
+#define X264_BUILD 128
 
 /* Application developers planning to link against a shared library version of
  * libx264 from a Microsoft Visual Studio or similar development environment
@@ -365,7 +365,8 @@ typedef struct x264_param_t
         float        f_psy_trellis; /* Psy trellis strength */
         int          b_psy; /* Toggle all psy optimizations */
 
-        int          b_mb_info; /* Use input mb_info data in x264_picture_t */
+        int          b_mb_info;            /* Use input mb_info data in x264_picture_t */
+        int          b_mb_info_update; /* Update the values in mb_info according to the results of encoding. */
 
         /* the deadzone size that will be used in luma quantization */
         int          i_luma_deadzone[2]; /* {inter, intra} */
@@ -718,7 +719,20 @@ typedef struct
      *     Allows specifying additional information for the encoder such as which macroblocks
      *     remain unchanged.  Usable flags are listed below.
      *     x264_param_t.analyse.b_mb_info must be set to use this, since x264 needs to track
-     *     extra data internally to make full use of this information. */
+     *     extra data internally to make full use of this information.
+     *
+     * Out: if b_mb_info_update is set, x264 will update this array as a result of encoding.
+     *
+     *      For "MBINFO_CONSTANT", it will remove this flag on any macroblock whose decoded
+     *      pixels have changed.  This can be useful for e.g. noting which areas of the
+     *      frame need to actually be blitted. Note: this intentionally ignores the effects
+     *      of deblocking for the current frame, which should be fine unless one needs exact
+     *      pixel-perfect accuracy.
+     *
+     *      Results for MBINFO_CONSTANT are currently only set for P-frames, and are not
+     *      guaranteed to enumerate all blocks which haven't changed.  (There may be false
+     *      negatives, but no false positives.)
+     */
     uint8_t *mb_info;
     /* In: optional callback to free mb_info when used. */
     void (*mb_info_free)( void* );



More information about the x264-devel mailing list