shithub: libvpx

Download patch

ref: 117fcb207e2e655cd334b6a8522af7d713b1fcee
parent: b9f98a52c8c63b6d49ce4aee03ac4a00c50fe28d
parent: d75eb7365357ec45626452756308d4327fa66911
author: John Koleszar <jkoleszar@google.com>
date: Tue May 24 20:05:14 EDT 2011

Merge remote branch 'origin/master' into experimental

Change-Id: I9e5c28f898d92091e39f62193f6329b593968819

--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -165,14 +165,16 @@
     unsigned char segment_id;                  /* Which set of segmentation parameters should be used for this MB */
 } MB_MODE_INFO;
 
-
 typedef struct
 {
     MB_MODE_INFO mbmi;
-    B_MODE_INFO bmi[16];
+    union
+    {
+        B_PREDICTION_MODE as_mode;
+        int_mv mv;
+    } bmi[16];
 } MODE_INFO;
 
-
 typedef struct
 {
     short *qcoeff;
@@ -195,7 +197,6 @@
     int eob;
 
     B_MODE_INFO bmi;
-
 } BLOCKD;
 
 typedef struct
@@ -278,5 +279,25 @@
 
 extern void vp8_build_block_doffsets(MACROBLOCKD *x);
 extern void vp8_setup_block_dptrs(MACROBLOCKD *x);
+
+static void update_blockd_bmi(MACROBLOCKD *xd)
+{
+    int i;
+    if (xd->mode_info_context->mbmi.mode == SPLITMV)
+    {
+        for (i = 0; i < 16; i++)
+        {
+            BLOCKD *d = &xd->block[i];
+            d->bmi.mv.as_int = xd->mode_info_context->bmi[i].mv.as_int;
+        }
+    }else if (xd->mode_info_context->mbmi.mode == B_PRED)
+    {
+        for (i = 0; i < 16; i++)
+        {
+            BLOCKD *d = &xd->block[i];
+            d->bmi.mode = xd->mode_info_context->bmi[i].as_mode;
+        }
+    }
+}
 
 #endif  /* __INC_BLOCKD_H */
--- a/vp8/common/debugmodes.c
+++ b/vp8/common/debugmodes.c
@@ -97,7 +97,7 @@
                 bindex = (b_row & 3) * 4 + (b_col & 3);
 
                 if (mi[mb_index].mbmi.mode == B_PRED)
-                    fprintf(mvs, "%2d ", mi[mb_index].bmi[bindex].mode);
+                    fprintf(mvs, "%2d ", mi[mb_index].bmi[bindex].as_mode);
                 else
                     fprintf(mvs, "xx ");
 
--- a/vp8/common/findnearmv.c
+++ b/vp8/common/findnearmv.c
@@ -153,26 +153,3 @@
     return p;
 }
 
-const B_MODE_INFO *vp8_left_bmi(const MODE_INFO *cur_mb, int b)
-{
-    if (!(b & 3))
-    {
-        /* On L edge, get from MB to left of us */
-        --cur_mb;
-        b += 4;
-    }
-
-    return cur_mb->bmi + b - 1;
-}
-
-const B_MODE_INFO *vp8_above_bmi(const MODE_INFO *cur_mb, int b, int mi_stride)
-{
-    if (!(b >> 2))
-    {
-        /* On top edge, get from MB above us */
-        cur_mb -= mi_stride;
-        b += 16;
-    }
-
-    return cur_mb->bmi + b - 4;
-}
--- a/vp8/common/findnearmv.h
+++ b/vp8/common/findnearmv.h
@@ -85,10 +85,60 @@
     vp8_prob p[VP8_MVREFS-1], const int near_mv_ref_ct[4]
 );
 
-const B_MODE_INFO *vp8_left_bmi(const MODE_INFO *cur_mb, int b);
+extern const unsigned char vp8_mbsplit_offset[4][16];
 
-const B_MODE_INFO *vp8_above_bmi(const MODE_INFO *cur_mb, int b, int mi_stride);
 
-extern const unsigned char vp8_mbsplit_offset[4][16];
+static int left_block_mv(const MODE_INFO *cur_mb, int b)
+{
+    if (!(b & 3))
+    {
+        /* On L edge, get from MB to left of us */
+        --cur_mb;
+
+        if(cur_mb->mbmi.mode != SPLITMV)
+            return cur_mb->mbmi.mv.as_int;
+        b += 4;
+    }
+
+    return (cur_mb->bmi + b - 1)->mv.as_int;
+}
+
+static int above_block_mv(const MODE_INFO *cur_mb, int b, int mi_stride)
+{
+    if (!(b >> 2))
+    {
+        /* On top edge, get from MB above us */
+        cur_mb -= mi_stride;
+
+        if(cur_mb->mbmi.mode != SPLITMV)
+            return cur_mb->mbmi.mv.as_int;
+        b += 16;
+    }
+
+    return (cur_mb->bmi + b - 4)->mv.as_int;
+}
+static B_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mb, int b)
+{
+    if (!(b & 3))
+    {
+        /* On L edge, get from MB to left of us */
+        --cur_mb;
+        b += 4;
+    }
+
+    return (cur_mb->bmi + b - 1)->as_mode;
+}
+
+static B_PREDICTION_MODE above_block_mode(const MODE_INFO *cur_mb, int b, int mi_stride)
+{
+    if (!(b >> 2))
+    {
+        /* On top edge, get from MB above us */
+        cur_mb -= mi_stride;
+        b += 16;
+    }
+
+    return (cur_mb->bmi + b - 4)->as_mode;
+}
 
 #endif
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -94,10 +94,10 @@
 
                 do
                 {
-                    const B_PREDICTION_MODE A = vp8_above_bmi(m, i, mis)->mode;
-                    const B_PREDICTION_MODE L = vp8_left_bmi(m, i)->mode;
+                    const B_PREDICTION_MODE A = above_block_mode(m, i, mis);
+                    const B_PREDICTION_MODE L = left_block_mode(m, i);
 
-                    m->bmi[i].mode = (B_PREDICTION_MODE) vp8_read_bmode(bc, pbi->common.kf_bmode_prob [A] [L]);
+                    m->bmi[i].as_mode = (B_PREDICTION_MODE) vp8_read_bmode(bc, pbi->common.kf_bmode_prob [A] [L]);
                 }
                 while (++i < 16);
             }
@@ -127,7 +127,7 @@
 
                 do
                 {
-                    m->bmi[i].mode = (B_PREDICTION_MODE)BMode;
+                    m->bmi[i].as_mode = (B_PREDICTION_MODE)BMode;
                 }
                 while (++i < 16);
             }
@@ -354,12 +354,15 @@
 
             do  /* for each subset j */
             {
+                int_mv leftmv, abovemv;
                 B_MODE_INFO bmi;
                 int k;  /* first block in subset j */
                 int mv_contz;
                 k = vp8_mbsplit_offset[s][j];
 
-                mv_contz = vp8_mv_cont(&(vp8_left_bmi(mi, k)->mv.as_mv), &(vp8_above_bmi(mi, k, mis)->mv.as_mv));
+                leftmv.as_int = left_block_mv(mi, k);
+                abovemv.as_int = above_block_mv(mi, k, mis);
+                mv_contz = vp8_mv_cont(&(leftmv.as_mv), &(abovemv.as_mv));
 
                 switch (bmi.mode = (B_PREDICTION_MODE) sub_mv_ref(bc, vp8_sub_mv_ref_prob2 [mv_contz])) /*pc->fc.sub_mv_ref_prob))*/
                 {
@@ -372,13 +375,13 @@
   #endif
                     break;
                 case LEFT4X4:
-                    bmi.mv.as_int = vp8_left_bmi(mi, k)->mv.as_int;
+                    bmi.mv.as_int = leftmv.as_int;
   #ifdef VPX_MODE_COUNT
                     vp8_mv_cont_count[mv_contz][0]++;
   #endif
                     break;
                 case ABOVE4X4:
-                    bmi.mv.as_int = vp8_above_bmi(mi, k, mis)->mv.as_int;
+                    bmi.mv.as_int = abovemv.as_int;
   #ifdef VPX_MODE_COUNT
                     vp8_mv_cont_count[mv_contz][1]++;
   #endif
@@ -409,9 +412,8 @@
                     fill_offset = &mbsplit_fill_offset[s][(unsigned char)j * mbsplit_fill_count[s]];
 
                     do {
-                        mi->bmi[ *fill_offset] = bmi;
+                        mi->bmi[ *fill_offset].mv.as_int = bmi.mv.as_int;
                         fill_offset++;
-
                     }while (--fill_count);
                 }
 
@@ -485,20 +487,16 @@
     }
     else
     {
-        /* MB is intra coded */
-        int j = 0;
-        do
-        {
-            mi->bmi[j].mv.as_int = 0;
-        }
-        while (++j < 16);
+        /* required for left and above block mv */
+        mbmi->mv.as_int = 0;
 
+        /* MB is intra coded */
         if ((mbmi->mode = (MB_PREDICTION_MODE) vp8_read_ymode(bc, pbi->common.fc.ymode_prob)) == B_PRED)
         {
-            j = 0;
+            int j = 0;
             do
             {
-                mi->bmi[j].mode = (B_PREDICTION_MODE)vp8_read_bmode(bc, pbi->common.fc.bmode_prob);
+                mi->bmi[j].as_mode = (B_PREDICTION_MODE)vp8_read_bmode(bc, pbi->common.fc.bmode_prob);
             }
             while (++j < 16);
         }
@@ -531,7 +529,9 @@
 
         while (++mb_col < pbi->common.mb_cols)
         {
+#if CONFIG_ERROR_CONCEALMENT
             int mb_num = mb_row * pbi->common.mb_cols + mb_col;
+#endif
             /*read_mb_modes_mv(pbi, xd->mode_info_context, &xd->mode_info_context->mbmi, mb_row, mb_col);*/
             if(pbi->common.frame_type == KEY_FRAME)
                 vp8_kfread_modes(pbi, mi, mb_row, mb_col);
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -350,8 +350,6 @@
 static void
 decode_mb_row(VP8D_COMP *pbi, VP8_COMMON *pc, int mb_row, MACROBLOCKD *xd)
 {
-
-    int i;
     int recon_yoffset, recon_uvoffset;
     int mb_col;
     int ref_fb_idx = pc->lst_fb_idx;
@@ -399,14 +397,7 @@
         }
 #endif
 
-        if (xd->mode_info_context->mbmi.mode == SPLITMV || xd->mode_info_context->mbmi.mode == B_PRED)
-        {
-            for (i = 0; i < 16; i++)
-            {
-                BLOCKD *d = &xd->block[i];
-                vpx_memcpy(&d->bmi, &xd->mode_info_context->bmi[i], sizeof(B_MODE_INFO));
-            }
-        }
+        update_blockd_bmi(xd);
 
         xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
         xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -39,6 +39,8 @@
 
 extern void vp8_init_loop_filter(VP8_COMMON *cm);
 extern void vp8cx_init_de_quantizer(VP8D_COMP *pbi);
+static int get_free_fb (VP8_COMMON *cm);
+static void ref_cnt_fb (int *buf, int *idx, int new_idx);
 
 
 void vp8dx_initialize()
@@ -155,18 +157,24 @@
 {
     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
     VP8_COMMON *cm = &pbi->common;
-    int ref_fb_idx;
+    int *ref_fb_ptr = NULL;
+    int free_fb;
 
     if (ref_frame_flag == VP8_LAST_FLAG)
-        ref_fb_idx = cm->lst_fb_idx;
+        *ref_fb_ptr = cm->lst_fb_idx;
     else if (ref_frame_flag == VP8_GOLD_FLAG)
-        ref_fb_idx = cm->gld_fb_idx;
+        *ref_fb_ptr = cm->gld_fb_idx;
     else if (ref_frame_flag == VP8_ALT_FLAG)
-        ref_fb_idx = cm->alt_fb_idx;
+        *ref_fb_ptr = cm->alt_fb_idx;
     else
         return -1;
 
-    vp8_yv12_copy_frame_ptr(sd, &cm->yv12_fb[ref_fb_idx]);
+    /* Find an empty frame buffer. */
+    free_fb = get_free_fb(cm);
+
+    /* Manage the reference counters and copy image. */
+    ref_cnt_fb (cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
+    vp8_yv12_copy_frame_ptr(sd, &cm->yv12_fb[*ref_fb_ptr]);
 
     return 0;
 }
--- a/vp8/decoder/threading.c
+++ b/vp8/decoder/threading.c
@@ -187,7 +187,6 @@
         {
             BLOCKD *b = &xd->block[i];
             vp8mt_predict_intra4x4(pbi, xd, b->bmi.mode, b->predictor, mb_row, mb_col, i);
-
             if (xd->eobs[i] > 1)
             {
                 DEQUANT_INVOKE(&pbi->dequant, idct_add)
@@ -288,14 +287,7 @@
                             }
                         }
 
-                        if (xd->mode_info_context->mbmi.mode == SPLITMV || xd->mode_info_context->mbmi.mode == B_PRED)
-                        {
-                            for (i = 0; i < 16; i++)
-                            {
-                                BLOCKD *d = &xd->block[i];
-                                vpx_memcpy(&d->bmi, &xd->mode_info_context->bmi[i], sizeof(B_MODE_INFO));
-                            }
-                        }
+                        update_blockd_bmi(xd);
 
                         /* Distance of Mb to the various image edges.
                          * These are specified to 8th pel as they are always compared to values that are in 1/8th pel units
@@ -776,14 +768,7 @@
                     }
                 }
 
-                if (xd->mode_info_context->mbmi.mode == SPLITMV || xd->mode_info_context->mbmi.mode == B_PRED)
-                {
-                    for (i = 0; i < 16; i++)
-                    {
-                        BLOCKD *d = &xd->block[i];
-                        vpx_memcpy(&d->bmi, &xd->mode_info_context->bmi[i], sizeof(B_MODE_INFO));
-                    }
-                }
+                update_blockd_bmi(xd);
 
                 /* Distance of Mb to the various image edges.
                  * These are specified to 8th pel as they are always compared to values that are in 1/8th pel units
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -948,8 +948,7 @@
                     int j = 0;
 
                     do
-                        write_bmode(w, m->bmi[j].mode, pc->fc.bmode_prob);
-
+                        write_bmode(w, m->bmi[j].as_mode, pc->fc.bmode_prob);
                     while (++j < 16);
                 }
 
@@ -1016,14 +1015,16 @@
                         const int *const  L = vp8_mbsplits [mi->partitioning];
                         int k = -1;  /* first block in subset j */
                         int mv_contz;
+                        int_mv leftmv, abovemv;
 
+
                         while (j != L[++k])
                             if (k >= 16)
                                 assert(0);
+                        leftmv.as_int = left_block_mv(m, k);
+                        abovemv.as_int = above_block_mv(m, k, mis);
+                        mv_contz = vp8_mv_cont(&(leftmv.as_mv), &(abovemv.as_mv));
 
-                        mv_contz = vp8_mv_cont
-                                   (&(vp8_left_bmi(m, k)->mv.as_mv),
-                                    &(vp8_above_bmi(m, k, mis)->mv.as_mv));
                         write_sub_mv_ref(w, b->mode, vp8_sub_mv_ref_prob2 [mv_contz]); //pc->fc.sub_mv_ref_prob);
 
                         if (b->mode == NEW4X4)
@@ -1099,9 +1100,9 @@
 
                 do
                 {
-                    const B_PREDICTION_MODE A = vp8_above_bmi(m, i, mis)->mode;
-                    const B_PREDICTION_MODE L = vp8_left_bmi(m, i)->mode;
-                    const int bm = m->bmi[i].mode;
+                    const B_PREDICTION_MODE A = above_block_mode(m, i, mis);
+                    const B_PREDICTION_MODE L = left_block_mode(m, i);
+                    const int bm = m->bmi[i].as_mode;
 
 #ifdef ENTROPY_STATS
                     ++intra_mode_stats [A] [L] [bm];
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -477,8 +477,24 @@
         x->mb_activity_ptr++;
         x->mb_norm_activity_ptr++;
 
-        for (i = 0; i < 16; i++)
-            vpx_memcpy(&xd->mode_info_context->bmi[i], &xd->block[i].bmi, sizeof(xd->block[i].bmi));
+        if(cm->frame_type != INTRA_FRAME)
+        {
+            if (xd->mode_info_context->mbmi.mode != B_PRED)
+            {
+                for (i = 0; i < 16; i++)
+                    xd->mode_info_context->bmi[i].mv.as_int = xd->block[i].bmi.mv.as_int;
+            }else
+            {
+                for (i = 0; i < 16; i++)
+                    xd->mode_info_context->bmi[i].as_mode = xd->block[i].bmi.mode;
+            }
+        }
+        else
+        {
+            if(xd->mode_info_context->mbmi.mode != B_PRED)
+                for (i = 0; i < 16; i++)
+                    xd->mode_info_context->bmi[i].as_mode = xd->block[i].bmi.mode;
+        }
 
         // adjust to the next column of macroblocks
         x->src.y_buffer += 16;
--- a/vp8/encoder/encodeintra.c
+++ b/vp8/encoder/encodeintra.c
@@ -88,7 +88,6 @@
 
         switch (x->e_mbd.mode_info_context->mbmi.mode)
         {
-
         case DC_PRED:
             d->bmi.mode = B_DC_PRED;
             break;
@@ -104,7 +103,6 @@
         default:
             d->bmi.mode = B_DC_PRED;
             break;
-
         }
     }
 }
--- a/vp8/encoder/ethreading.c
+++ b/vp8/encoder/ethreading.c
@@ -120,8 +120,6 @@
                 // for each macroblock col in image
                 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
                 {
-                    int seg_map_index = (mb_row * cm->mb_cols);
-
                     if ((mb_col & (nsync - 1)) == 0)
                     {
                         while (mb_col > (*last_row_current_mb_col - nsync) && *last_row_current_mb_col != cm->mb_cols - 1)
@@ -234,8 +232,23 @@
                     x->mb_activity_ptr++;
                     x->mb_norm_activity_ptr++;
 
-                    for (i = 0; i < 16; i++)
-                        vpx_memcpy(&xd->mode_info_context->bmi[i], &xd->block[i].bmi, sizeof(xd->block[i].bmi));
+                    if(cm->frame_type != INTRA_FRAME)
+                    {
+                        if (xd->mode_info_context->mbmi.mode != B_PRED)
+                        {
+                            for (i = 0; i < 16; i++)
+                                xd->mode_info_context->bmi[i].mv.as_int = xd->block[i].bmi.mv.as_int;
+                        }else
+                        {
+                            for (i = 0; i < 16; i++)
+                                xd->mode_info_context->bmi[i].as_mode = xd->block[i].bmi.mode;
+                        }
+                    }
+                    else {
+                        if(xd->mode_info_context->mbmi.mode != B_PRED)
+                            for (i = 0; i < 16; i++)
+                                xd->mode_info_context->bmi[i].as_mode = xd->block[i].bmi.mode;
+                    }
 
                     // adjust to the next column of macroblocks
                     x->src.y_buffer += 16;
--- a/vp8/encoder/mcomp.c
+++ b/vp8/encoder/mcomp.c
@@ -793,12 +793,36 @@
     return bestmse;
 }
 
+#define CHECK_BOUNDS(range) \
+{\
+    all_in = 1;\
+    all_in &= ((br-range) >= x->mv_row_min);\
+    all_in &= ((br+range) <= x->mv_row_max);\
+    all_in &= ((bc-range) >= x->mv_col_min);\
+    all_in &= ((bc+range) <= x->mv_col_max);\
+}
 
-#define MVC(r,c) (((mvsadcost[0][r-rr] + mvsadcost[1][c-rc]) * error_per_bit + 128 )>>8 ) // estimated cost of a motion vector (r,c)
-#define PRE(r,c) (*(d->base_pre) + d->pre + (r) * d->pre_stride + (c)) // pointer to predictor base of a motionvector
-#define DIST(r,c,v) vfp->sdf( src,src_stride,PRE(r,c),d->pre_stride, v) // returns sad error score.
-#define ERR(r,c,v) (MVC(r,c)+DIST(r,c,v)) // returns distortion + motion vector cost
-#define CHECK_BETTER(v,r,c) if ((v = ERR(r,c,besterr)) < besterr) { besterr = v; br=r; bc=c; } // checks if (r,c) has better score than previous best
+#define CHECK_POINT \
+{\
+    if (this_mv.as_mv.col < x->mv_col_min) continue;\
+    if (this_mv.as_mv.col > x->mv_col_max) continue;\
+    if (this_mv.as_mv.row < x->mv_row_min) continue;\
+    if (this_mv.as_mv.row > x->mv_row_max) continue;\
+}
+
+#define CHECK_BETTER \
+{\
+    if (thissad < bestsad)\
+    {\
+        thissad += mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, error_per_bit);\
+        if (thissad < bestsad)\
+        {\
+            bestsad = thissad;\
+            best_site = i;\
+        }\
+    }\
+}
+
 static const MV next_chkpts[6][3] =
 {
     {{ -2, 0}, { -1, -2}, {1, -2}},
@@ -808,6 +832,7 @@
     {{1, 2}, { -1, 2}, { -2, 0}},
     {{ -1, 2}, { -2, 0}, { -1, -2}}
 };
+
 int vp8_hex_search
 (
     MACROBLOCK *x,
@@ -825,134 +850,159 @@
 )
 {
     MV hex[6] = { { -1, -2}, {1, -2}, {2, 0}, {1, 2}, { -1, 2}, { -2, 0} } ;
-    //MV neighbors[8] = { { -1, -1}, {0, -1}, {1, -1}, { -1, 0}, {1, 0}, { -1, 1}, {0, 1}, {1, 1} } ;
     MV neighbors[4] = {{0, -1}, { -1, 0}, {1, 0}, {0, 1}} ;
-
     int i, j;
-    unsigned char *src = (*(b->base_src) + b->src);
-    int src_stride = b->src_stride;
-    int rr = center_mv->as_mv.row, rc = center_mv->as_mv.col;
-    int br = ref_mv->as_mv.row >> 3, bc = ref_mv->as_mv.col >> 3, tr, tc;
-    unsigned int besterr, thiserr = 0x7fffffff;
-    int k = -1, tk;
 
-    if (bc < x->mv_col_min) bc = x->mv_col_min;
+    unsigned char *what = (*(b->base_src) + b->src);
+    int what_stride = b->src_stride;
+    int in_what_stride = d->pre_stride;
+    int br = ref_mv->as_mv.row >> 3, bc = ref_mv->as_mv.col >> 3;
+    int_mv this_mv;
+    unsigned int bestsad = 0x7fffffff;
+    unsigned int thissad;
+    unsigned char *base_offset;
+    unsigned char *this_offset;
+    int k = -1;
+    int all_in;
+    int best_site = -1;
 
-    if (bc > x->mv_col_max) bc = x->mv_col_max;
+    int_mv fcenter_mv;
+    fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
+    fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
 
-    if (br < x->mv_row_min) br = x->mv_row_min;
+    // Work out the start point for the search
+    base_offset = (unsigned char *)(*(d->base_pre) + d->pre);
+    this_offset = base_offset + (br * (d->pre_stride)) + bc;
+    this_mv.as_mv.row = br;
+    this_mv.as_mv.col = bc;
+    bestsad = vfp->sdf( what, what_stride, this_offset, in_what_stride, 0x7fffffff) + mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, error_per_bit);
 
-    if (br > x->mv_row_max) br = x->mv_row_max;
-
-    rr >>= 3;
-    rc >>= 3;
-
-    besterr = ERR(br, bc, thiserr);
-
     // hex search
     //j=0
-    tr = br;
-    tc = bc;
+    CHECK_BOUNDS(2)
 
-    for (i = 0; i < 6; i++)
+    if(all_in)
     {
-        int nr = tr + hex[i].row, nc = tc + hex[i].col;
-
-        if (nc < x->mv_col_min) continue;
-
-        if (nc > x->mv_col_max) continue;
-
-        if (nr < x->mv_row_min) continue;
-
-        if (nr > x->mv_row_max) continue;
-
-        //CHECK_BETTER(thiserr,nr,nc);
-        if ((thiserr = ERR(nr, nc, besterr)) < besterr)
+        for (i = 0; i < 6; i++)
         {
-            besterr = thiserr;
-            br = nr;
-            bc = nc;
-            k = i;
+            this_mv.as_mv.row = br + hex[i].row;
+            this_mv.as_mv.col = bc + hex[i].col;
+            this_offset = base_offset + (this_mv.as_mv.row * in_what_stride) + this_mv.as_mv.col;
+            thissad=vfp->sdf( what, what_stride, this_offset, in_what_stride, bestsad);
+            CHECK_BETTER
         }
+    }else
+    {
+        for (i = 0; i < 6; i++)
+        {
+            this_mv.as_mv.row = br + hex[i].row;
+            this_mv.as_mv.col = bc + hex[i].col;
+            CHECK_POINT
+            this_offset = base_offset + (this_mv.as_mv.row * in_what_stride) + this_mv.as_mv.col;
+            thissad=vfp->sdf( what, what_stride, this_offset, in_what_stride, bestsad);
+            CHECK_BETTER
+        }
     }
 
-    if (tr == br && tc == bc)
+    if (best_site == -1)
         goto cal_neighbors;
+    else
+    {
+        br += hex[best_site].row;
+        bc += hex[best_site].col;
+        k = best_site;
+    }
 
     for (j = 1; j < 127; j++)
     {
-        tr = br;
-        tc = bc;
-        tk = k;
+        best_site = -1;
+        CHECK_BOUNDS(2)
 
-        for (i = 0; i < 3; i++)
+        if(all_in)
         {
-            int nr = tr + next_chkpts[tk][i].row, nc = tc + next_chkpts[tk][i].col;
-
-            if (nc < x->mv_col_min) continue;
-
-            if (nc > x->mv_col_max) continue;
-
-            if (nr < x->mv_row_min) continue;
-
-            if (nr > x->mv_row_max) continue;
-
-            //CHECK_BETTER(thiserr,nr,nc);
-            if ((thiserr = ERR(nr, nc, besterr)) < besterr)
+            for (i = 0; i < 3; i++)
             {
-                besterr = thiserr;
-                br = nr;
-                bc = nc; //k=(tk+5+i)%6;}
-                k = tk + 5 + i;
-
-                if (k >= 12) k -= 12;
-                else if (k >= 6) k -= 6;
+                this_mv.as_mv.row = br + next_chkpts[k][i].row;
+                this_mv.as_mv.col = bc + next_chkpts[k][i].col;
+                this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) + this_mv.as_mv.col;
+                thissad = vfp->sdf( what, what_stride, this_offset, in_what_stride, bestsad);
+                CHECK_BETTER
             }
+        }else
+        {
+            for (i = 0; i < 3; i++)
+            {
+                this_mv.as_mv.row = br + next_chkpts[k][i].row;
+                this_mv.as_mv.col = bc + next_chkpts[k][i].col;
+                CHECK_POINT
+                this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) + this_mv.as_mv.col;
+                thissad = vfp->sdf( what, what_stride, this_offset, in_what_stride, bestsad);
+                CHECK_BETTER
+            }
         }
 
-        if (tr == br && tc == bc)
+        if (best_site == -1)
             break;
+        else
+        {
+            br += next_chkpts[k][best_site].row;
+            bc += next_chkpts[k][best_site].col;
+            k += 5 + best_site;
+            if (k >= 12) k -= 12;
+            else if (k >= 6) k -= 6;
+        }
     }
 
     // check 4 1-away neighbors
 cal_neighbors:
-
     for (j = 0; j < 32; j++)
     {
-        tr = br;
-        tc = bc;
+        best_site = -1;
+        CHECK_BOUNDS(1)
 
-        for (i = 0; i < 4; i++)
+        if(all_in)
         {
-            int nr = tr + neighbors[i].row, nc = tc + neighbors[i].col;
-
-            if (nc < x->mv_col_min) continue;
-
-            if (nc > x->mv_col_max) continue;
-
-            if (nr < x->mv_row_min) continue;
-
-            if (nr > x->mv_row_max) continue;
-
-            CHECK_BETTER(thiserr, nr, nc);
+            for (i = 0; i < 4; i++)
+            {
+                this_mv.as_mv.row = br + neighbors[i].row;
+                this_mv.as_mv.col = bc + neighbors[i].col;
+                this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) + this_mv.as_mv.col;
+                thissad = vfp->sdf( what, what_stride, this_offset, in_what_stride, bestsad);
+                CHECK_BETTER
+            }
+        }else
+        {
+            for (i = 0; i < 4; i++)
+            {
+                this_mv.as_mv.row = br + neighbors[i].row;
+                this_mv.as_mv.col = bc + neighbors[i].col;
+                CHECK_POINT
+                this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) + this_mv.as_mv.col;
+                thissad = vfp->sdf( what, what_stride, this_offset, in_what_stride, bestsad);
+                CHECK_BETTER
+            }
         }
 
-        if (tr == br && tc == bc)
+        if (best_site == -1)
             break;
+        else
+        {
+            br += neighbors[best_site].row;
+            bc += neighbors[best_site].col;
+        }
     }
 
     best_mv->as_mv.row = br;
     best_mv->as_mv.col = bc;
+    this_mv.as_mv.row = br<<3;
+    this_mv.as_mv.col = bc<<3;
 
-    return vfp->vf(src, src_stride, PRE(br, bc), d->pre_stride, &thiserr) + mv_err_cost(best_mv, center_mv, mvcost, error_per_bit) ;
+    this_offset = (unsigned char *)(*(d->base_pre) + d->pre + (br * (in_what_stride)) + bc);
+    return vfp->vf(what, what_stride, this_offset, in_what_stride, &bestsad) + mv_err_cost(&this_mv, center_mv, mvcost, error_per_bit) ;
 }
-#undef MVC
-#undef PRE
-#undef SP
-#undef DIST
-#undef ERR
+#undef CHECK_BOUNDS
+#undef CHECK_POINT
 #undef CHECK_BETTER
-
 
 int vp8_diamond_search_sad
 (
--- a/vp8/encoder/pickinter.c
+++ b/vp8/encoder/pickinter.c
@@ -214,7 +214,6 @@
             *best_mode = mode;
         }
     }
-
     b->bmi.mode = (B_PREDICTION_MODE)(*best_mode);
     vp8_encode_intra4x4block(rtcd, x, ib);
     return best_rd;
@@ -241,8 +240,9 @@
     {
         MODE_INFO *const mic = xd->mode_info_context;
         const int mis = xd->mode_info_stride;
-        const B_PREDICTION_MODE A = vp8_above_bmi(mic, i, mis)->mode;
-        const B_PREDICTION_MODE L = vp8_left_bmi(mic, i)->mode;
+        const B_PREDICTION_MODE A = above_block_mode(mic, i, mis);
+        const B_PREDICTION_MODE L = left_block_mode(mic, i);
+
         B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);
         int UNINITIALIZED_IS_SAFE(r), UNINITIALIZED_IS_SAFE(d);
 
@@ -250,9 +250,8 @@
 
         cost += r;
         distortion += d;
+        mic->bmi[i].as_mode = xd->block[i].bmi.mode = best_mode;
 
-        mic->bmi[i].mode = xd->block[i].bmi.mode = best_mode;
-
         // Break out case where we have already exceeded best so far value
         // that was passed in
         if (distortion > *best_dist)
@@ -272,9 +271,6 @@
         error = INT_MAX;
     }
 
-    for (i = 0; i < 16; i++)
-        xd->block[i].bmi.mv.as_int = 0;
-
     return error;
 }
 
@@ -432,9 +428,9 @@
      * therefore, only need to modify MVcount in NEWMV mode. */
     if (xd->mode_info_context->mbmi.mode == NEWMV)
     {
-        cpi->MVcount[0][mv_max+((xd->block[0].bmi.mv.as_mv.row -
+        cpi->MVcount[0][mv_max+((xd->mode_info_context->mbmi.mv.as_mv.row -
                                       best_ref_mv->as_mv.row) >> 1)]++;
-        cpi->MVcount[1][mv_max+((xd->block[0].bmi.mv.as_mv.col -
+        cpi->MVcount[1][mv_max+((xd->mode_info_context->mbmi.mv.as_mv.col -
                                       best_ref_mv->as_mv.col) >> 1)]++;
     }
 }
@@ -844,7 +840,7 @@
             x->e_mbd.block[0].bmi.mode = this_mode;
             x->e_mbd.block[0].bmi.mv.as_int = x->e_mbd.mode_info_context->mbmi.mv.as_int;
 
-            if((this_mode != NEWMV) || !(have_subp_search))
+            if((this_mode != NEWMV) || !(have_subp_search) || cpi->common.full_pixel==1)
                 distortion2 = get_inter_mbpred_error(x, &cpi->fn_ptr[BLOCK_16X16], &sse);
 
             this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
@@ -966,11 +962,11 @@
     // macroblock modes
     vpx_memcpy(&x->e_mbd.mode_info_context->mbmi, &best_mbmode, sizeof(MB_MODE_INFO));
 
-    if (x->e_mbd.mode_info_context->mbmi.mode == B_PRED)
+
+    if (x->e_mbd.mode_info_context->mbmi.mode <= B_PRED)
         for (i = 0; i < 16; i++)
         {
-            vpx_memcpy(&x->e_mbd.block[i].bmi, &best_bmodes[i], sizeof(B_MODE_INFO));
-
+            x->e_mbd.block[i].bmi.mode = best_bmodes[i].mode;
         }
     else
     {
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -712,7 +712,6 @@
             vpx_memcpy(best_dqcoeff, b->dqcoeff, 32);
         }
     }
-
     b->bmi.mode = (B_PREDICTION_MODE)(*best_mode);
 
     IDCT_INVOKE(IF_RTCD(&cpi->rtcd.common->idct), idct16)(best_dqcoeff, b->diff, 32);
@@ -754,8 +753,8 @@
 
         if (mb->e_mbd.frame_type == KEY_FRAME)
         {
-            const B_PREDICTION_MODE A = vp8_above_bmi(mic, i, mis)->mode;
-            const B_PREDICTION_MODE L = vp8_left_bmi(mic, i)->mode;
+            const B_PREDICTION_MODE A = above_block_mode(mic, i, mis);
+            const B_PREDICTION_MODE L = left_block_mode(mic, i);
 
             bmode_costs  = mb->bmode_costs[A][L];
         }
@@ -768,8 +767,9 @@
         cost += r;
         distortion += d;
         tot_rate_y += ry;
-        mic->bmi[i].mode = xd->block[i].bmi.mode = best_mode;
 
+        mic->bmi[i].as_mode = best_mode;
+
         if(total_rd >= (long long)best_rd)
             break;
     }
@@ -916,17 +916,8 @@
 
 void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv)
 {
-    int i;
-
     x->e_mbd.mode_info_context->mbmi.mode = mb;
     x->e_mbd.mode_info_context->mbmi.mv.as_int = mv->as_int;
-
-    for (i = 0; i < 16; i++)
-    {
-        B_MODE_INFO *bmi = &x->e_mbd.block[i].bmi;
-        bmi->mode = (B_PREDICTION_MODE) mb;
-        bmi->mv.as_int = mv->as_int;
-    }
 }
 
 static int labels2mode(
@@ -974,10 +965,10 @@
                 thismvcost  = vp8_mv_bit_cost(this_mv, best_ref_mv, mvcost, 102);
                 break;
             case LEFT4X4:
-                this_mv->as_int = col ? d[-1].bmi.mv.as_int : vp8_left_bmi(mic, i)->mv.as_int;
+                this_mv->as_int = col ? d[-1].bmi.mv.as_int : left_block_mv(mic, i);
                 break;
             case ABOVE4X4:
-                this_mv->as_int = row ? d[-4].bmi.mv.as_int : vp8_above_bmi(mic, i, mis)->mv.as_int;
+                this_mv->as_int = row ? d[-4].bmi.mv.as_int : above_block_mv(mic, i, mis);
                 break;
             case ZERO4X4:
                 this_mv->as_int = 0;
@@ -989,8 +980,9 @@
             if (m == ABOVE4X4)  // replace above with left if same
             {
                 int_mv left_mv;
+
                 left_mv.as_int = col ? d[-1].bmi.mv.as_int :
-                                        vp8_left_bmi(mic, i)->mv.as_int;
+                                        left_block_mv(mic, i);
 
                 if (left_mv.as_int == this_mv->as_int)
                     m = LEFT4X4;
@@ -1478,6 +1470,7 @@
         BLOCKD *bd = &x->e_mbd.block[i];
 
         bd->bmi.mv.as_mv = bsi.mvs[i].as_mv;
+        bd->bmi.mode = bsi.modes[i];
         bd->eob = bsi.eobs[i];
     }
 
@@ -2387,6 +2380,8 @@
             if (this_mode <= B_PRED)
             {
                 x->e_mbd.mode_info_context->mbmi.uv_mode = uv_intra_mode;
+                /* required for left and above block mv */
+                x->e_mbd.mode_info_context->mbmi.mv.as_int = 0;
             }
 
             other_cost += ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
@@ -2478,27 +2473,22 @@
         return;
     }
 
-
-    if(best_mbmode.mode <= B_PRED)
-    {
-        int i;
-        for (i = 0; i < 16; i++)
-        {
-            best_bmodes[i].mv.as_int = 0;
-        }
-    }
-
     // macroblock modes
     vpx_memcpy(&x->e_mbd.mode_info_context->mbmi, &best_mbmode, sizeof(MB_MODE_INFO));
 
-    for (i = 0; i < 16; i++)
+    if (best_mbmode.mode == B_PRED)
     {
-        vpx_memcpy(&x->e_mbd.block[i].bmi, &best_bmodes[i], sizeof(B_MODE_INFO));
+        for (i = 0; i < 16; i++)
+          x->e_mbd.block[i].bmi.mode = best_bmodes[i].mode;
     }
 
     if (best_mbmode.mode == SPLITMV)
     {
+        for (i = 0; i < 16; i++)
+            x->e_mbd.block[i].bmi.mv.as_int = best_bmodes[i].mv.as_int;
+
         vpx_memcpy(x->partition_info, &best_partition, sizeof(PARTITION_INFO));
+
         x->e_mbd.mode_info_context->mbmi.mv.as_int =
                                       x->partition_info->bmi[15].mv.as_int;
     }