Home | History | Annotate | Download | only in common
      1 /*
      2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 
     12 #include "vpx_ports/config.h"
     13 #include "recon.h"
     14 #include "subpixel.h"
     15 #include "blockd.h"
     16 #include "reconinter.h"
     17 #if CONFIG_RUNTIME_CPU_DETECT
     18 #include "onyxc_int.h"
     19 #endif
     20 
     21 /* use this define on systems where unaligned int reads and writes are
     22  * not allowed, i.e. ARM architectures
     23  */
     24 /*#define MUST_BE_ALIGNED*/
     25 
     26 
     27 static const int bbb[4] = {0, 2, 8, 10};
     28 
     29 
     30 
     31 void vp8_copy_mem16x16_c(
     32     unsigned char *src,
     33     int src_stride,
     34     unsigned char *dst,
     35     int dst_stride)
     36 {
     37 
     38     int r;
     39 
     40     for (r = 0; r < 16; r++)
     41     {
     42 #ifdef MUST_BE_ALIGNED
     43         dst[0] = src[0];
     44         dst[1] = src[1];
     45         dst[2] = src[2];
     46         dst[3] = src[3];
     47         dst[4] = src[4];
     48         dst[5] = src[5];
     49         dst[6] = src[6];
     50         dst[7] = src[7];
     51         dst[8] = src[8];
     52         dst[9] = src[9];
     53         dst[10] = src[10];
     54         dst[11] = src[11];
     55         dst[12] = src[12];
     56         dst[13] = src[13];
     57         dst[14] = src[14];
     58         dst[15] = src[15];
     59 
     60 #else
     61         ((int *)dst)[0] = ((int *)src)[0] ;
     62         ((int *)dst)[1] = ((int *)src)[1] ;
     63         ((int *)dst)[2] = ((int *)src)[2] ;
     64         ((int *)dst)[3] = ((int *)src)[3] ;
     65 
     66 #endif
     67         src += src_stride;
     68         dst += dst_stride;
     69 
     70     }
     71 
     72 }
     73 
     74 void vp8_copy_mem8x8_c(
     75     unsigned char *src,
     76     int src_stride,
     77     unsigned char *dst,
     78     int dst_stride)
     79 {
     80     int r;
     81 
     82     for (r = 0; r < 8; r++)
     83     {
     84 #ifdef MUST_BE_ALIGNED
     85         dst[0] = src[0];
     86         dst[1] = src[1];
     87         dst[2] = src[2];
     88         dst[3] = src[3];
     89         dst[4] = src[4];
     90         dst[5] = src[5];
     91         dst[6] = src[6];
     92         dst[7] = src[7];
     93 #else
     94         ((int *)dst)[0] = ((int *)src)[0] ;
     95         ((int *)dst)[1] = ((int *)src)[1] ;
     96 #endif
     97         src += src_stride;
     98         dst += dst_stride;
     99 
    100     }
    101 
    102 }
    103 
    104 void vp8_copy_mem8x4_c(
    105     unsigned char *src,
    106     int src_stride,
    107     unsigned char *dst,
    108     int dst_stride)
    109 {
    110     int r;
    111 
    112     for (r = 0; r < 4; r++)
    113     {
    114 #ifdef MUST_BE_ALIGNED
    115         dst[0] = src[0];
    116         dst[1] = src[1];
    117         dst[2] = src[2];
    118         dst[3] = src[3];
    119         dst[4] = src[4];
    120         dst[5] = src[5];
    121         dst[6] = src[6];
    122         dst[7] = src[7];
    123 #else
    124         ((int *)dst)[0] = ((int *)src)[0] ;
    125         ((int *)dst)[1] = ((int *)src)[1] ;
    126 #endif
    127         src += src_stride;
    128         dst += dst_stride;
    129 
    130     }
    131 
    132 }
    133 
    134 
    135 
    136 void vp8_build_inter_predictors_b(BLOCKD *d, int pitch, vp8_subpix_fn_t sppf)
    137 {
    138     int r;
    139     unsigned char *ptr_base;
    140     unsigned char *ptr;
    141     unsigned char *pred_ptr = d->predictor;
    142 
    143     ptr_base = *(d->base_pre);
    144 
    145     if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
    146     {
    147         ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
    148         sppf(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
    149     }
    150     else
    151     {
    152         ptr_base += d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
    153         ptr = ptr_base;
    154 
    155         for (r = 0; r < 4; r++)
    156         {
    157 #ifdef MUST_BE_ALIGNED
    158             pred_ptr[0]  = ptr[0];
    159             pred_ptr[1]  = ptr[1];
    160             pred_ptr[2]  = ptr[2];
    161             pred_ptr[3]  = ptr[3];
    162 #else
    163             *(int *)pred_ptr = *(int *)ptr ;
    164 #endif
    165             pred_ptr     += pitch;
    166             ptr         += d->pre_stride;
    167         }
    168     }
    169 }
    170 
    171 static void build_inter_predictors4b(MACROBLOCKD *x, BLOCKD *d, int pitch)
    172 {
    173     unsigned char *ptr_base;
    174     unsigned char *ptr;
    175     unsigned char *pred_ptr = d->predictor;
    176 
    177     ptr_base = *(d->base_pre);
    178     ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
    179 
    180     if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
    181     {
    182         x->subpixel_predict8x8(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
    183     }
    184     else
    185     {
    186         RECON_INVOKE(&x->rtcd->recon, copy8x8)(ptr, d->pre_stride, pred_ptr, pitch);
    187     }
    188 }
    189 
    190 static void build_inter_predictors2b(MACROBLOCKD *x, BLOCKD *d, int pitch)
    191 {
    192     unsigned char *ptr_base;
    193     unsigned char *ptr;
    194     unsigned char *pred_ptr = d->predictor;
    195 
    196     ptr_base = *(d->base_pre);
    197     ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
    198 
    199     if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
    200     {
    201         x->subpixel_predict8x4(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
    202     }
    203     else
    204     {
    205         RECON_INVOKE(&x->rtcd->recon, copy8x4)(ptr, d->pre_stride, pred_ptr, pitch);
    206     }
    207 }
    208 
    209 
    210 void vp8_build_inter_predictors_mbuv(MACROBLOCKD *x)
    211 {
    212     int i;
    213 
    214     if (x->mode_info_context->mbmi.ref_frame != INTRA_FRAME &&
    215         x->mode_info_context->mbmi.mode != SPLITMV)
    216     {
    217         unsigned char *uptr, *vptr;
    218         unsigned char *upred_ptr = &x->predictor[256];
    219         unsigned char *vpred_ptr = &x->predictor[320];
    220 
    221         int mv_row = x->block[16].bmi.mv.as_mv.row;
    222         int mv_col = x->block[16].bmi.mv.as_mv.col;
    223         int offset;
    224         int pre_stride = x->block[16].pre_stride;
    225 
    226         offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
    227         uptr = x->pre.u_buffer + offset;
    228         vptr = x->pre.v_buffer + offset;
    229 
    230         if ((mv_row | mv_col) & 7)
    231         {
    232             x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, 8);
    233             x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, 8);
    234         }
    235         else
    236         {
    237             RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, upred_ptr, 8);
    238             RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, pre_stride, vpred_ptr, 8);
    239         }
    240     }
    241     else
    242     {
    243         for (i = 16; i < 24; i += 2)
    244         {
    245             BLOCKD *d0 = &x->block[i];
    246             BLOCKD *d1 = &x->block[i+1];
    247 
    248             if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
    249                 build_inter_predictors2b(x, d0, 8);
    250             else
    251             {
    252                 vp8_build_inter_predictors_b(d0, 8, x->subpixel_predict);
    253                 vp8_build_inter_predictors_b(d1, 8, x->subpixel_predict);
    254             }
    255         }
    256     }
    257 }
    258 
    259 /*encoder only*/
    260 void vp8_build_inter_predictors_mby(MACROBLOCKD *x)
    261 {
    262 
    263   if (x->mode_info_context->mbmi.ref_frame != INTRA_FRAME &&
    264       x->mode_info_context->mbmi.mode != SPLITMV)
    265     {
    266         unsigned char *ptr_base;
    267         unsigned char *ptr;
    268         unsigned char *pred_ptr = x->predictor;
    269         int mv_row = x->mode_info_context->mbmi.mv.as_mv.row;
    270         int mv_col = x->mode_info_context->mbmi.mv.as_mv.col;
    271         int pre_stride = x->block[0].pre_stride;
    272 
    273         ptr_base = x->pre.y_buffer;
    274         ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
    275 
    276         if ((mv_row | mv_col) & 7)
    277         {
    278             x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, pred_ptr, 16);
    279         }
    280         else
    281         {
    282             RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, pred_ptr, 16);
    283         }
    284     }
    285     else
    286     {
    287         int i;
    288 
    289         if (x->mode_info_context->mbmi.partitioning < 3)
    290         {
    291             for (i = 0; i < 4; i++)
    292             {
    293                 BLOCKD *d = &x->block[bbb[i]];
    294                 build_inter_predictors4b(x, d, 16);
    295             }
    296 
    297         }
    298         else
    299         {
    300             for (i = 0; i < 16; i += 2)
    301             {
    302                 BLOCKD *d0 = &x->block[i];
    303                 BLOCKD *d1 = &x->block[i+1];
    304 
    305                 if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
    306                     build_inter_predictors2b(x, d0, 16);
    307                 else
    308                 {
    309                     vp8_build_inter_predictors_b(d0, 16, x->subpixel_predict);
    310                     vp8_build_inter_predictors_b(d1, 16, x->subpixel_predict);
    311                 }
    312 
    313             }
    314         }
    315     }
    316 }
    317 
    318 void vp8_build_inter_predictors_mb(MACROBLOCKD *x)
    319 {
    320 
    321     if (x->mode_info_context->mbmi.ref_frame != INTRA_FRAME &&
    322         x->mode_info_context->mbmi.mode != SPLITMV)
    323     {
    324         int offset;
    325         unsigned char *ptr_base;
    326         unsigned char *ptr;
    327         unsigned char *uptr, *vptr;
    328         unsigned char *pred_ptr = x->predictor;
    329         unsigned char *upred_ptr = &x->predictor[256];
    330         unsigned char *vpred_ptr = &x->predictor[320];
    331 
    332         int mv_row = x->mode_info_context->mbmi.mv.as_mv.row;
    333         int mv_col = x->mode_info_context->mbmi.mv.as_mv.col;
    334         int pre_stride = x->block[0].pre_stride;
    335 
    336         ptr_base = x->pre.y_buffer;
    337         ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
    338 
    339         if ((mv_row | mv_col) & 7)
    340         {
    341             x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, pred_ptr, 16);
    342         }
    343         else
    344         {
    345             RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, pred_ptr, 16);
    346         }
    347 
    348         mv_row = x->block[16].bmi.mv.as_mv.row;
    349         mv_col = x->block[16].bmi.mv.as_mv.col;
    350         pre_stride >>= 1;
    351         offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
    352         uptr = x->pre.u_buffer + offset;
    353         vptr = x->pre.v_buffer + offset;
    354 
    355         if ((mv_row | mv_col) & 7)
    356         {
    357             x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, 8);
    358             x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, 8);
    359         }
    360         else
    361         {
    362             RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, upred_ptr, 8);
    363             RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, pre_stride, vpred_ptr, 8);
    364         }
    365     }
    366     else
    367     {
    368         int i;
    369 
    370         if (x->mode_info_context->mbmi.partitioning < 3)
    371         {
    372             for (i = 0; i < 4; i++)
    373             {
    374                 BLOCKD *d = &x->block[bbb[i]];
    375                 build_inter_predictors4b(x, d, 16);
    376             }
    377         }
    378         else
    379         {
    380             for (i = 0; i < 16; i += 2)
    381             {
    382                 BLOCKD *d0 = &x->block[i];
    383                 BLOCKD *d1 = &x->block[i+1];
    384 
    385                 if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
    386                     build_inter_predictors2b(x, d0, 16);
    387                 else
    388                 {
    389                     vp8_build_inter_predictors_b(d0, 16, x->subpixel_predict);
    390                     vp8_build_inter_predictors_b(d1, 16, x->subpixel_predict);
    391                 }
    392 
    393             }
    394 
    395         }
    396 
    397         for (i = 16; i < 24; i += 2)
    398         {
    399             BLOCKD *d0 = &x->block[i];
    400             BLOCKD *d1 = &x->block[i+1];
    401 
    402             if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
    403                 build_inter_predictors2b(x, d0, 8);
    404             else
    405             {
    406                 vp8_build_inter_predictors_b(d0, 8, x->subpixel_predict);
    407                 vp8_build_inter_predictors_b(d1, 8, x->subpixel_predict);
    408             }
    409 
    410         }
    411 
    412     }
    413 }
    414 
    415 void vp8_build_uvmvs(MACROBLOCKD *x, int fullpixel)
    416 {
    417     int i, j;
    418 
    419     if (x->mode_info_context->mbmi.mode == SPLITMV)
    420     {
    421         for (i = 0; i < 2; i++)
    422         {
    423             for (j = 0; j < 2; j++)
    424             {
    425                 int yoffset = i * 8 + j * 2;
    426                 int uoffset = 16 + i * 2 + j;
    427                 int voffset = 20 + i * 2 + j;
    428 
    429                 int temp;
    430 
    431                 temp = x->block[yoffset  ].bmi.mv.as_mv.row
    432                        + x->block[yoffset+1].bmi.mv.as_mv.row
    433                        + x->block[yoffset+4].bmi.mv.as_mv.row
    434                        + x->block[yoffset+5].bmi.mv.as_mv.row;
    435 
    436                 if (temp < 0) temp -= 4;
    437                 else temp += 4;
    438 
    439                 x->block[uoffset].bmi.mv.as_mv.row = temp / 8;
    440 
    441                 if (fullpixel)
    442                     x->block[uoffset].bmi.mv.as_mv.row = (temp / 8) & 0xfffffff8;
    443 
    444                 temp = x->block[yoffset  ].bmi.mv.as_mv.col
    445                        + x->block[yoffset+1].bmi.mv.as_mv.col
    446                        + x->block[yoffset+4].bmi.mv.as_mv.col
    447                        + x->block[yoffset+5].bmi.mv.as_mv.col;
    448 
    449                 if (temp < 0) temp -= 4;
    450                 else temp += 4;
    451 
    452                 x->block[uoffset].bmi.mv.as_mv.col = temp / 8;
    453 
    454                 if (fullpixel)
    455                     x->block[uoffset].bmi.mv.as_mv.col = (temp / 8) & 0xfffffff8;
    456 
    457                 x->block[voffset].bmi.mv.as_mv.row = x->block[uoffset].bmi.mv.as_mv.row ;
    458                 x->block[voffset].bmi.mv.as_mv.col = x->block[uoffset].bmi.mv.as_mv.col ;
    459             }
    460         }
    461     }
    462     else
    463     {
    464         int mvrow = x->mode_info_context->mbmi.mv.as_mv.row;
    465         int mvcol = x->mode_info_context->mbmi.mv.as_mv.col;
    466 
    467         if (mvrow < 0)
    468             mvrow -= 1;
    469         else
    470             mvrow += 1;
    471 
    472         if (mvcol < 0)
    473             mvcol -= 1;
    474         else
    475             mvcol += 1;
    476 
    477         mvrow /= 2;
    478         mvcol /= 2;
    479 
    480         for (i = 0; i < 8; i++)
    481         {
    482             x->block[ 16 + i].bmi.mv.as_mv.row = mvrow;
    483             x->block[ 16 + i].bmi.mv.as_mv.col = mvcol;
    484 
    485             if (fullpixel)
    486             {
    487                 x->block[ 16 + i].bmi.mv.as_mv.row = mvrow & 0xfffffff8;
    488                 x->block[ 16 + i].bmi.mv.as_mv.col = mvcol & 0xfffffff8;
    489             }
    490         }
    491     }
    492 }
    493 
    494 
    495 /* The following functions are wriiten for skip_recon_mb() to call. Since there is no recon in this
    496  * situation, we can write the result directly to dst buffer instead of writing it to predictor
    497  * buffer and then copying it to dst buffer.
    498  */
    499 static void vp8_build_inter_predictors_b_s(BLOCKD *d, unsigned char *dst_ptr, vp8_subpix_fn_t sppf)
    500 {
    501     int r;
    502     unsigned char *ptr_base;
    503     unsigned char *ptr;
    504     /*unsigned char *pred_ptr = d->predictor;*/
    505     int dst_stride = d->dst_stride;
    506     int pre_stride = d->pre_stride;
    507 
    508     ptr_base = *(d->base_pre);
    509 
    510     if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
    511     {
    512         ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
    513         sppf(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, dst_ptr, dst_stride);
    514     }
    515     else
    516     {
    517         ptr_base += d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
    518         ptr = ptr_base;
    519 
    520         for (r = 0; r < 4; r++)
    521         {
    522 #ifdef MUST_BE_ALIGNED
    523             dst_ptr[0]   = ptr[0];
    524             dst_ptr[1]   = ptr[1];
    525             dst_ptr[2]   = ptr[2];
    526             dst_ptr[3]   = ptr[3];
    527 #else
    528             *(int *)dst_ptr = *(int *)ptr ;
    529 #endif
    530             dst_ptr      += dst_stride;
    531             ptr         += pre_stride;
    532         }
    533     }
    534 }
    535 
    536 
    537 
    538 void vp8_build_inter_predictors_mb_s(MACROBLOCKD *x)
    539 {
    540     /*unsigned char *pred_ptr = x->block[0].predictor;
    541     unsigned char *dst_ptr = *(x->block[0].base_dst) + x->block[0].dst;*/
    542     unsigned char *pred_ptr = x->predictor;
    543     unsigned char *dst_ptr = x->dst.y_buffer;
    544 
    545     if (x->mode_info_context->mbmi.mode != SPLITMV)
    546     {
    547         int offset;
    548         unsigned char *ptr_base;
    549         unsigned char *ptr;
    550         unsigned char *uptr, *vptr;
    551         /*unsigned char *pred_ptr = x->predictor;
    552         unsigned char *upred_ptr = &x->predictor[256];
    553         unsigned char *vpred_ptr = &x->predictor[320];*/
    554         unsigned char *udst_ptr = x->dst.u_buffer;
    555         unsigned char *vdst_ptr = x->dst.v_buffer;
    556 
    557         int mv_row = x->mode_info_context->mbmi.mv.as_mv.row;
    558         int mv_col = x->mode_info_context->mbmi.mv.as_mv.col;
    559         int pre_stride = x->dst.y_stride; /*x->block[0].pre_stride;*/
    560 
    561         ptr_base = x->pre.y_buffer;
    562         ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
    563 
    564         if ((mv_row | mv_col) & 7)
    565         {
    566             x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, dst_ptr, x->dst.y_stride); /*x->block[0].dst_stride);*/
    567         }
    568         else
    569         {
    570             RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, dst_ptr, x->dst.y_stride); /*x->block[0].dst_stride);*/
    571         }
    572 
    573         mv_row = x->block[16].bmi.mv.as_mv.row;
    574         mv_col = x->block[16].bmi.mv.as_mv.col;
    575         pre_stride >>= 1;
    576         offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
    577         uptr = x->pre.u_buffer + offset;
    578         vptr = x->pre.v_buffer + offset;
    579 
    580         if ((mv_row | mv_col) & 7)
    581         {
    582             x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, udst_ptr, x->dst.uv_stride);
    583             x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vdst_ptr, x->dst.uv_stride);
    584         }
    585         else
    586         {
    587             RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, udst_ptr, x->dst.uv_stride);
    588             RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, pre_stride, vdst_ptr, x->dst.uv_stride);
    589         }
    590     }
    591     else
    592     {
    593         /* note: this whole ELSE part is not executed at all. So, no way to test the correctness of my modification. Later,
    594          * if sth is wrong, go back to what it is in build_inter_predictors_mb.
    595          */
    596         int i;
    597 
    598         if (x->mode_info_context->mbmi.partitioning < 3)
    599         {
    600             for (i = 0; i < 4; i++)
    601             {
    602                 BLOCKD *d = &x->block[bbb[i]];
    603                 /*build_inter_predictors4b(x, d, 16);*/
    604 
    605                 {
    606                     unsigned char *ptr_base;
    607                     unsigned char *ptr;
    608                     unsigned char *pred_ptr = d->predictor;
    609 
    610                     ptr_base = *(d->base_pre);
    611                     ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
    612 
    613                     if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
    614                     {
    615                         x->subpixel_predict8x8(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, dst_ptr, x->dst.y_stride); /*x->block[0].dst_stride);*/
    616                     }
    617                     else
    618                     {
    619                         RECON_INVOKE(&x->rtcd->recon, copy8x8)(ptr, d->pre_stride, dst_ptr, x->dst.y_stride); /*x->block[0].dst_stride);*/
    620                     }
    621                 }
    622             }
    623         }
    624         else
    625         {
    626             for (i = 0; i < 16; i += 2)
    627             {
    628                 BLOCKD *d0 = &x->block[i];
    629                 BLOCKD *d1 = &x->block[i+1];
    630 
    631                 if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
    632                 {
    633                     /*build_inter_predictors2b(x, d0, 16);*/
    634                     unsigned char *ptr_base;
    635                     unsigned char *ptr;
    636                     unsigned char *pred_ptr = d0->predictor;
    637 
    638                     ptr_base = *(d0->base_pre);
    639                     ptr = ptr_base + d0->pre + (d0->bmi.mv.as_mv.row >> 3) * d0->pre_stride + (d0->bmi.mv.as_mv.col >> 3);
    640 
    641                     if (d0->bmi.mv.as_mv.row & 7 || d0->bmi.mv.as_mv.col & 7)
    642                     {
    643                         x->subpixel_predict8x4(ptr, d0->pre_stride, d0->bmi.mv.as_mv.col & 7, d0->bmi.mv.as_mv.row & 7, dst_ptr, x->dst.y_stride);
    644                     }
    645                     else
    646                     {
    647                         RECON_INVOKE(&x->rtcd->recon, copy8x4)(ptr, d0->pre_stride, dst_ptr, x->dst.y_stride);
    648                     }
    649                 }
    650                 else
    651                 {
    652                     vp8_build_inter_predictors_b_s(d0, dst_ptr, x->subpixel_predict);
    653                     vp8_build_inter_predictors_b_s(d1, dst_ptr, x->subpixel_predict);
    654                 }
    655             }
    656         }
    657 
    658         for (i = 16; i < 24; i += 2)
    659         {
    660             BLOCKD *d0 = &x->block[i];
    661             BLOCKD *d1 = &x->block[i+1];
    662 
    663             if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
    664             {
    665                 /*build_inter_predictors2b(x, d0, 8);*/
    666                 unsigned char *ptr_base;
    667                 unsigned char *ptr;
    668                 unsigned char *pred_ptr = d0->predictor;
    669 
    670                 ptr_base = *(d0->base_pre);
    671                 ptr = ptr_base + d0->pre + (d0->bmi.mv.as_mv.row >> 3) * d0->pre_stride + (d0->bmi.mv.as_mv.col >> 3);
    672 
    673                 if (d0->bmi.mv.as_mv.row & 7 || d0->bmi.mv.as_mv.col & 7)
    674                 {
    675                     x->subpixel_predict8x4(ptr, d0->pre_stride,
    676                         d0->bmi.mv.as_mv.col & 7,
    677                         d0->bmi.mv.as_mv.row & 7,
    678                         dst_ptr, x->dst.uv_stride);
    679                 }
    680                 else
    681                 {
    682                     RECON_INVOKE(&x->rtcd->recon, copy8x4)(ptr,
    683                         d0->pre_stride, dst_ptr, x->dst.uv_stride);
    684                 }
    685             }
    686             else
    687             {
    688                 vp8_build_inter_predictors_b_s(d0, dst_ptr, x->subpixel_predict);
    689                 vp8_build_inter_predictors_b_s(d1, dst_ptr, x->subpixel_predict);
    690             }
    691         }
    692     }
    693 }
    694