]> granicus.if.org Git - libx264/commitdiff
avoid a division in x264_mb_predict_mv_ref16x16.
authorLoren Merritt <pengvado@videolan.org>
Sat, 1 Dec 2007 15:17:19 +0000 (15:17 +0000)
committerLoren Merritt <pengvado@videolan.org>
Sat, 1 Dec 2007 15:17:19 +0000 (15:17 +0000)
patch by Fiona Glaser.

git-svn-id: svn://svn.videolan.org/x264/trunk@704 df754926-b1dd-0310-bc7b-ec298dee348c

common/frame.h
common/macroblock.c

index 13678848cfcda0df32c9345066f280d075b0578e..0e698fd4c3460e98ec584970fc97dfcc3874284d 100644 (file)
@@ -64,6 +64,7 @@ typedef struct
     int8_t  *ref[2];
     int     i_ref[2];
     int     ref_poc[2][16];
+    int     inv_ref_poc[16]; // inverse values (list0 only) to avoid divisions in MB encoding
 
     /* for adaptive B-frame decision.
      * contains the SATD cost of the lowres frame encoded in various modes
index fb2f0cc051654d283f248725fc8fae46dfa91cc4..a8056de5ea3a96902cb3adc1202183595ed84dea 100644 (file)
@@ -506,6 +506,8 @@ void x264_mb_load_mv_direct8x8( x264_t *h, int idx )
     }
 }
 
+#define FIXED_SCALE 256
+
 /* This just improves encoder performance, it's not part of the spec */
 void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int mvc[8][2], int *i_mvc )
 {
@@ -551,23 +553,17 @@ void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int mvc[8][2
     if( h->fref0[0]->i_ref[0] > 0 && !h->sh.b_mbaff )
     {
         x264_frame_t *l0 = h->fref0[0];
-        int ref_col_cur, ref_col_prev = -1;
-        int scale = 0;
 
 #define SET_TMVP(dx, dy) { \
             int i_b4 = h->mb.i_b4_xy + dx*4 + dy*4*h->mb.i_b4_stride; \
             int i_b8 = h->mb.i_b8_xy + dx*2 + dy*2*h->mb.i_b8_stride; \
-            ref_col_cur = l0->ref[0][i_b8]; \
-            if( ref_col_cur >= 0 ) \
+            int ref_col = l0->ref[0][i_b8]; \
+            if( ref_col >= 0 ) \
             { \
-                /* TODO: calc once per frame and tablize? */\
-                if( ref_col_cur != ref_col_prev ) \
-                    scale = 256 * (h->fenc->i_poc - h->fref0[i_ref]->i_poc) \
-                                / (l0->i_poc - l0->ref_poc[0][ref_col_cur]); \
-                mvc[i][0] = l0->mv[0][i_b4][0] * scale / 256; \
-                mvc[i][1] = l0->mv[0][i_b4][1] * scale / 256; \
+                int scale = (h->fdec->i_poc - h->fdec->ref_poc[0][i_ref]) * l0->inv_ref_poc[ref_col];\
+                mvc[i][0] = l0->mv[0][i_b4][0] * scale / FIXED_SCALE; \
+                mvc[i][1] = l0->mv[0][i_b4][1] * scale / FIXED_SCALE; \
                 i++; \
-                ref_col_prev = ref_col_cur; \
             } \
         }
 
@@ -582,6 +578,17 @@ void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int mvc[8][2
     *i_mvc = i;
 }
 
+/* Set up a lookup table for delta pocs to reduce an IDIV to an IMUL */
+static void setup_inverse_delta_pocs( x264_t *h )
+{
+    int i;
+    for( i = 0; i < h->i_ref0; i++ )
+    {
+        int delta = h->fdec->i_poc - h->fref0[i]->i_poc;
+        h->fdec->inv_ref_poc[i] = (FIXED_SCALE + delta/2) / delta;
+    }
+}
+
 static inline void x264_mb_mc_0xywh( x264_t *h, int x, int y, int width, int height )
 {
     const int i8 = x264_scan8[0]+x+8*y;
@@ -965,6 +972,8 @@ void x264_macroblock_slice_init( x264_t *h )
     }
     if( h->sh.i_type == SLICE_TYPE_P )
         memset( h->mb.cache.skip, 0, X264_SCAN8_SIZE * sizeof( int8_t ) );
+
+    setup_inverse_delta_pocs( h );
 }
 
 void x264_prefetch_fenc( x264_t *h, x264_frame_t *fenc, int i_mb_x, int i_mb_y )