vp9_reconinter.c 37.7 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  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.
John Koleszar's avatar
John Koleszar committed
9 10 11 12
 */


#include "vpx_ports/config.h"
13
#include "vpx/vpx_integer.h"
14 15
#include "vp9/common/vp9_blockd.h"
#include "vp9/common/vp9_reconinter.h"
16
#include "vp9/common/vp9_reconintra.h"
John Koleszar's avatar
John Koleszar committed
17
#if CONFIG_RUNTIME_CPU_DETECT
18
#include "vp9/common/vp9_onyxc_int.h"
John Koleszar's avatar
John Koleszar committed
19 20
#endif

21
void vp9_setup_interp_filters(MACROBLOCKD *xd,
22
                              INTERPOLATIONFILTERTYPE mcomp_filter_type,
23
                              VP9_COMMON *cm) {
24
  if (mcomp_filter_type == SIXTAP) {
25 26 27 28 29 30 31
    xd->subpixel_predict        = vp9_sixtap_predict;
    xd->subpixel_predict8x4     = vp9_sixtap_predict8x4;
    xd->subpixel_predict8x8     = vp9_sixtap_predict8x8;
    xd->subpixel_predict16x16   = vp9_sixtap_predict16x16;
    xd->subpixel_predict_avg    = vp9_sixtap_predict_avg;
    xd->subpixel_predict_avg8x8 = vp9_sixtap_predict_avg8x8;
    xd->subpixel_predict_avg16x16 = vp9_sixtap_predict_avg16x16;
32
  } else if (mcomp_filter_type == EIGHTTAP || mcomp_filter_type == SWITCHABLE) {
33 34 35 36 37 38 39
    xd->subpixel_predict        = vp9_eighttap_predict;
    xd->subpixel_predict8x4     = vp9_eighttap_predict8x4;
    xd->subpixel_predict8x8     = vp9_eighttap_predict8x8;
    xd->subpixel_predict16x16   = vp9_eighttap_predict16x16;
    xd->subpixel_predict_avg    = vp9_eighttap_predict_avg4x4;
    xd->subpixel_predict_avg8x8 = vp9_eighttap_predict_avg8x8;
    xd->subpixel_predict_avg16x16 = vp9_eighttap_predict_avg16x16;
40
  } else if (mcomp_filter_type == EIGHTTAP_SHARP) {
41 42 43 44 45 46 47
    xd->subpixel_predict        = vp9_eighttap_predict_sharp;
    xd->subpixel_predict8x4     = vp9_eighttap_predict8x4_sharp;
    xd->subpixel_predict8x8     = vp9_eighttap_predict8x8_sharp;
    xd->subpixel_predict16x16   = vp9_eighttap_predict16x16_sharp;
    xd->subpixel_predict_avg    = vp9_eighttap_predict_avg4x4_sharp;
    xd->subpixel_predict_avg8x8 = vp9_eighttap_predict_avg8x8_sharp;
    xd->subpixel_predict_avg16x16 = vp9_eighttap_predict_avg16x16_sharp_c;
48 49
  }
  else {
50 51 52 53 54 55 56
    xd->subpixel_predict        = vp9_bilinear_predict4x4;
    xd->subpixel_predict8x4     = vp9_bilinear_predict8x4;
    xd->subpixel_predict8x8     = vp9_bilinear_predict8x8;
    xd->subpixel_predict16x16   = vp9_bilinear_predict16x16;
    xd->subpixel_predict_avg    = vp9_bilinear_predict_avg4x4;
    xd->subpixel_predict_avg8x8 = vp9_bilinear_predict_avg8x8;
    xd->subpixel_predict_avg16x16 = vp9_bilinear_predict_avg16x16;
57 58 59
  }
}

60 61 62 63
void vp9_copy_mem16x16_c(unsigned char *src,
                         int src_stride,
                         unsigned char *dst,
                         int dst_stride) {
John Koleszar's avatar
John Koleszar committed
64
  int r;
John Koleszar's avatar
John Koleszar committed
65

John Koleszar's avatar
John Koleszar committed
66
  for (r = 0; r < 16; r++) {
67
#if !(CONFIG_FAST_UNALIGNED)
John Koleszar's avatar
John Koleszar committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
    dst[0] = src[0];
    dst[1] = src[1];
    dst[2] = src[2];
    dst[3] = src[3];
    dst[4] = src[4];
    dst[5] = src[5];
    dst[6] = src[6];
    dst[7] = src[7];
    dst[8] = src[8];
    dst[9] = src[9];
    dst[10] = src[10];
    dst[11] = src[11];
    dst[12] = src[12];
    dst[13] = src[13];
    dst[14] = src[14];
    dst[15] = src[15];
John Koleszar's avatar
John Koleszar committed
84 85

#else
John Koleszar's avatar
John Koleszar committed
86 87 88 89
    ((uint32_t *)dst)[0] = ((uint32_t *)src)[0];
    ((uint32_t *)dst)[1] = ((uint32_t *)src)[1];
    ((uint32_t *)dst)[2] = ((uint32_t *)src)[2];
    ((uint32_t *)dst)[3] = ((uint32_t *)src)[3];
John Koleszar's avatar
John Koleszar committed
90 91

#endif
John Koleszar's avatar
John Koleszar committed
92 93 94
    src += src_stride;
    dst += dst_stride;
  }
John Koleszar's avatar
John Koleszar committed
95 96
}

97 98 99 100
void vp9_avg_mem16x16_c(unsigned char *src,
                        int src_stride,
                        unsigned char *dst,
                        int dst_stride) {
John Koleszar's avatar
John Koleszar committed
101
  int r;
102

John Koleszar's avatar
John Koleszar committed
103 104 105 106 107
  for (r = 0; r < 16; r++) {
    int n;

    for (n = 0; n < 16; n++) {
      dst[n] = (dst[n] + src[n] + 1) >> 1;
108
    }
John Koleszar's avatar
John Koleszar committed
109 110 111 112

    src += src_stride;
    dst += dst_stride;
  }
113 114
}

115 116 117 118
void vp9_copy_mem8x8_c(unsigned char *src,
                       int src_stride,
                       unsigned char *dst,
                       int dst_stride) {
John Koleszar's avatar
John Koleszar committed
119 120 121
  int r;

  for (r = 0; r < 8; r++) {
122
#if !(CONFIG_FAST_UNALIGNED)
John Koleszar's avatar
John Koleszar committed
123 124 125 126 127 128 129 130
    dst[0] = src[0];
    dst[1] = src[1];
    dst[2] = src[2];
    dst[3] = src[3];
    dst[4] = src[4];
    dst[5] = src[5];
    dst[6] = src[6];
    dst[7] = src[7];
John Koleszar's avatar
John Koleszar committed
131
#else
John Koleszar's avatar
John Koleszar committed
132 133
    ((uint32_t *)dst)[0] = ((uint32_t *)src)[0];
    ((uint32_t *)dst)[1] = ((uint32_t *)src)[1];
John Koleszar's avatar
John Koleszar committed
134
#endif
John Koleszar's avatar
John Koleszar committed
135 136 137
    src += src_stride;
    dst += dst_stride;
  }
John Koleszar's avatar
John Koleszar committed
138 139
}

140 141 142 143
void vp9_avg_mem8x8_c(unsigned char *src,
                      int src_stride,
                      unsigned char *dst,
                      int dst_stride) {
John Koleszar's avatar
John Koleszar committed
144
  int r;
145

John Koleszar's avatar
John Koleszar committed
146 147 148 149 150
  for (r = 0; r < 8; r++) {
    int n;

    for (n = 0; n < 8; n++) {
      dst[n] = (dst[n] + src[n] + 1) >> 1;
151
    }
John Koleszar's avatar
John Koleszar committed
152 153 154 155

    src += src_stride;
    dst += dst_stride;
  }
156 157
}

158 159 160 161
void vp9_copy_mem8x4_c(unsigned char *src,
                       int src_stride,
                       unsigned char *dst,
                       int dst_stride) {
John Koleszar's avatar
John Koleszar committed
162 163 164
  int r;

  for (r = 0; r < 4; r++) {
165
#if !(CONFIG_FAST_UNALIGNED)
John Koleszar's avatar
John Koleszar committed
166 167 168 169 170 171 172 173
    dst[0] = src[0];
    dst[1] = src[1];
    dst[2] = src[2];
    dst[3] = src[3];
    dst[4] = src[4];
    dst[5] = src[5];
    dst[6] = src[6];
    dst[7] = src[7];
John Koleszar's avatar
John Koleszar committed
174
#else
John Koleszar's avatar
John Koleszar committed
175 176
    ((uint32_t *)dst)[0] = ((uint32_t *)src)[0];
    ((uint32_t *)dst)[1] = ((uint32_t *)src)[1];
John Koleszar's avatar
John Koleszar committed
177
#endif
John Koleszar's avatar
John Koleszar committed
178 179 180
    src += src_stride;
    dst += dst_stride;
  }
John Koleszar's avatar
John Koleszar committed
181 182
}

183
void vp9_build_inter_predictors_b(BLOCKD *d, int pitch, vp9_subpix_fn_t sppf) {
John Koleszar's avatar
John Koleszar committed
184 185 186 187 188
  int r;
  unsigned char *ptr_base;
  unsigned char *ptr;
  unsigned char *pred_ptr = d->predictor;
  int_mv mv;
John Koleszar's avatar
John Koleszar committed
189

John Koleszar's avatar
John Koleszar committed
190 191
  ptr_base = *(d->base_pre);
  mv.as_int = d->bmi.as_mv.first.as_int;
John Koleszar's avatar
John Koleszar committed
192

John Koleszar's avatar
John Koleszar committed
193
  if (mv.as_mv.row & 7 || mv.as_mv.col & 7) {
194 195 196 197
    ptr = ptr_base + d->pre + (mv.as_mv.row >> 3) * d->pre_stride +
          (mv.as_mv.col >> 3);
    sppf(ptr, d->pre_stride, (mv.as_mv.col & 7) << 1, (mv.as_mv.row & 7) << 1,
         pred_ptr, pitch);
John Koleszar's avatar
John Koleszar committed
198
  } else {
199 200
    ptr_base += d->pre + (mv.as_mv.row >> 3) * d->pre_stride +
                (mv.as_mv.col >> 3);
John Koleszar's avatar
John Koleszar committed
201
    ptr = ptr_base;
John Koleszar's avatar
John Koleszar committed
202

John Koleszar's avatar
John Koleszar committed
203
    for (r = 0; r < 4; r++) {
204
#if !(CONFIG_FAST_UNALIGNED)
John Koleszar's avatar
John Koleszar committed
205 206 207 208
      pred_ptr[0]  = ptr[0];
      pred_ptr[1]  = ptr[1];
      pred_ptr[2]  = ptr[2];
      pred_ptr[3]  = ptr[3];
John Koleszar's avatar
John Koleszar committed
209
#else
John Koleszar's avatar
John Koleszar committed
210
      *(uint32_t *)pred_ptr = *(uint32_t *)ptr;
John Koleszar's avatar
John Koleszar committed
211
#endif
John Koleszar's avatar
John Koleszar committed
212 213
      pred_ptr     += pitch;
      ptr         += d->pre_stride;
John Koleszar's avatar
John Koleszar committed
214
    }
John Koleszar's avatar
John Koleszar committed
215
  }
John Koleszar's avatar
John Koleszar committed
216 217
}

218
/*
219
 * Similar to vp9_build_inter_predictors_b(), but instead of storing the
220
 * results in d->predictor, we average the contents of d->predictor (which
221
 * come from an earlier call to vp9_build_inter_predictors_b()) with the
222 223
 * predictor of the second reference frame / motion vector.
 */
224 225
void vp9_build_2nd_inter_predictors_b(BLOCKD *d, int pitch,
                                      vp9_subpix_fn_t sppf) {
John Koleszar's avatar
John Koleszar committed
226 227 228 229 230 231 232 233 234 235
  int r;
  unsigned char *ptr_base;
  unsigned char *ptr;
  unsigned char *pred_ptr = d->predictor;
  int_mv mv;

  ptr_base = *(d->base_second_pre);
  mv.as_int = d->bmi.as_mv.second.as_int;

  if (mv.as_mv.row & 7 || mv.as_mv.col & 7) {
236 237 238 239
    ptr = ptr_base + d->pre + (mv.as_mv.row >> 3) * d->pre_stride +
          (mv.as_mv.col >> 3);
    sppf(ptr, d->pre_stride, (mv.as_mv.col & 7) << 1, (mv.as_mv.row & 7) << 1,
         pred_ptr, pitch);
John Koleszar's avatar
John Koleszar committed
240
  } else {
241 242
    ptr_base += d->pre + (mv.as_mv.row >> 3) * d->pre_stride +
                (mv.as_mv.col >> 3);
John Koleszar's avatar
John Koleszar committed
243 244 245 246 247 248 249 250 251
    ptr = ptr_base;

    for (r = 0; r < 4; r++) {
      pred_ptr[0]  = (pred_ptr[0] + ptr[0] + 1) >> 1;
      pred_ptr[1]  = (pred_ptr[1] + ptr[1] + 1) >> 1;
      pred_ptr[2]  = (pred_ptr[2] + ptr[2] + 1) >> 1;
      pred_ptr[3]  = (pred_ptr[3] + ptr[3] + 1) >> 1;
      pred_ptr    += pitch;
      ptr         += d->pre_stride;
252
    }
John Koleszar's avatar
John Koleszar committed
253
  }
254 255
}

256
void vp9_build_inter_predictors4b(MACROBLOCKD *xd, BLOCKD *d, int pitch) {
John Koleszar's avatar
John Koleszar committed
257 258 259 260
  unsigned char *ptr_base;
  unsigned char *ptr;
  unsigned char *pred_ptr = d->predictor;
  int_mv mv;
John Koleszar's avatar
John Koleszar committed
261

John Koleszar's avatar
John Koleszar committed
262 263
  ptr_base = *(d->base_pre);
  mv.as_int = d->bmi.as_mv.first.as_int;
Paul Wilkins's avatar
Paul Wilkins committed
264 265
  ptr = ptr_base + d->pre + (mv.as_mv.row >> 3) * d->pre_stride +
        (mv.as_mv.col >> 3);
John Koleszar's avatar
John Koleszar committed
266

John Koleszar's avatar
John Koleszar committed
267
  if (mv.as_mv.row & 7 || mv.as_mv.col & 7) {
Paul Wilkins's avatar
Paul Wilkins committed
268 269
    xd->subpixel_predict8x8(ptr, d->pre_stride, (mv.as_mv.col & 7) << 1,
                            (mv.as_mv.row & 7) << 1, pred_ptr, pitch);
John Koleszar's avatar
John Koleszar committed
270
  } else {
271
    vp9_copy_mem8x8(ptr, d->pre_stride, pred_ptr, pitch);
John Koleszar's avatar
John Koleszar committed
272
  }
John Koleszar's avatar
John Koleszar committed
273 274
}

275 276 277 278 279 280
/*
 * Similar to build_inter_predictors_4b(), but instead of storing the
 * results in d->predictor, we average the contents of d->predictor (which
 * come from an earlier call to build_inter_predictors_4b()) with the
 * predictor of the second reference frame / motion vector.
 */
281
void vp9_build_2nd_inter_predictors4b(MACROBLOCKD *xd,
282
                                      BLOCKD *d, int pitch) {
John Koleszar's avatar
John Koleszar committed
283 284 285 286 287 288 289
  unsigned char *ptr_base;
  unsigned char *ptr;
  unsigned char *pred_ptr = d->predictor;
  int_mv mv;

  ptr_base = *(d->base_second_pre);
  mv.as_int = d->bmi.as_mv.second.as_int;
Paul Wilkins's avatar
Paul Wilkins committed
290 291
  ptr = ptr_base + d->pre + (mv.as_mv.row >> 3) * d->pre_stride +
        (mv.as_mv.col >> 3);
292

John Koleszar's avatar
John Koleszar committed
293
  if (mv.as_mv.row & 7 || mv.as_mv.col & 7) {
Paul Wilkins's avatar
Paul Wilkins committed
294 295
    xd->subpixel_predict_avg8x8(ptr, d->pre_stride, (mv.as_mv.col & 7) << 1,
                               (mv.as_mv.row & 7) << 1, pred_ptr, pitch);
John Koleszar's avatar
John Koleszar committed
296
  } else {
297
    vp9_avg_mem8x8(ptr, d->pre_stride, pred_ptr, pitch);
John Koleszar's avatar
John Koleszar committed
298
  }
299 300
}

Paul Wilkins's avatar
Paul Wilkins committed
301
static void build_inter_predictors2b(MACROBLOCKD *xd, BLOCKD *d, int pitch) {
John Koleszar's avatar
John Koleszar committed
302 303 304 305
  unsigned char *ptr_base;
  unsigned char *ptr;
  unsigned char *pred_ptr = d->predictor;
  int_mv mv;
John Koleszar's avatar
John Koleszar committed
306

John Koleszar's avatar
John Koleszar committed
307 308
  ptr_base = *(d->base_pre);
  mv.as_int = d->bmi.as_mv.first.as_int;
Paul Wilkins's avatar
Paul Wilkins committed
309 310
  ptr = ptr_base + d->pre + (mv.as_mv.row >> 3) * d->pre_stride +
        (mv.as_mv.col >> 3);
John Koleszar's avatar
John Koleszar committed
311

John Koleszar's avatar
John Koleszar committed
312
  if (mv.as_mv.row & 7 || mv.as_mv.col & 7) {
Paul Wilkins's avatar
Paul Wilkins committed
313 314
    xd->subpixel_predict8x4(ptr, d->pre_stride, (mv.as_mv.col & 7) << 1,
                           (mv.as_mv.row & 7) << 1, pred_ptr, pitch);
John Koleszar's avatar
John Koleszar committed
315
  } else {
316
    vp9_copy_mem8x4(ptr, d->pre_stride, pred_ptr, pitch);
John Koleszar's avatar
John Koleszar committed
317
  }
John Koleszar's avatar
John Koleszar committed
318 319 320
}


321
/*encoder only*/
322 323 324 325 326 327 328 329 330 331 332 333 334 335
#if CONFIG_PRED_FILTER

// Select the thresholded or non-thresholded filter
#define USE_THRESH_FILTER 0

#define PRED_FILT_LEN 5

static const int filt_shift = 4;
static const int pred_filter[PRED_FILT_LEN] = {1, 2, 10, 2, 1};
// Alternative filter {1, 1, 4, 1, 1}

#if !USE_THRESH_FILTER
void filter_mb(unsigned char *src, int src_stride,
               unsigned char *dst, int dst_stride,
John Koleszar's avatar
John Koleszar committed
336 337 338 339 340 341 342 343 344 345 346 347 348
               int width, int height) {
  int i, j, k;
  unsigned int Temp[32 * 32];
  unsigned int  *pTmp = Temp;
  unsigned char *pSrc = src - (1 + src_stride) * (PRED_FILT_LEN / 2);

  // Horizontal
  for (i = 0; i < height + PRED_FILT_LEN - 1; i++) {
    for (j = 0; j < width; j++) {
      int sum = 0;
      for (k = 0; k < PRED_FILT_LEN; k++)
        sum += pSrc[j + k] * pred_filter[k];
      pTmp[j] = sum;
349 350
    }

John Koleszar's avatar
John Koleszar committed
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
    pSrc += src_stride;
    pTmp += width;
  }

  // Vertical
  pTmp = Temp;
  for (i = 0; i < width; i++) {
    unsigned char *pDst = dst + i;
    for (j = 0; j < height; j++) {
      int sum = 0;
      for (k = 0; k < PRED_FILT_LEN; k++)
        sum += pTmp[(j + k) * width] * pred_filter[k];
      // Round
      sum = (sum + ((1 << (filt_shift << 1)) >> 1)) >> (filt_shift << 1);
      pDst[j * dst_stride] = (sum < 0 ? 0 : sum > 255 ? 255 : sum);
366
    }
John Koleszar's avatar
John Koleszar committed
367 368
    ++pTmp;
  }
369 370
}
#else
371
// Based on vp9_post_proc_down_and_across_c (vp9_postproc.c)
372 373
void filter_mb(unsigned char *src, int src_stride,
               unsigned char *dst, int dst_stride,
John Koleszar's avatar
John Koleszar committed
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404
               int width, int height) {
  unsigned char *pSrc, *pDst;
  int row;
  int col;
  int i;
  int v;
  unsigned char d[8];

  /* TODO flimit should be linked to the quantizer value */
  int flimit = 7;

  for (row = 0; row < height; row++) {
    /* post_proc_down for one row */
    pSrc = src;
    pDst = dst;

    for (col = 0; col < width; col++) {
      int kernel = (1 << (filt_shift - 1));
      int v = pSrc[col];

      for (i = -2; i <= 2; i++) {
        if (abs(v - pSrc[col + i * src_stride]) > flimit)
          goto down_skip_convolve;

        kernel += pred_filter[2 + i] * pSrc[col + i * src_stride];
      }

      v = (kernel >> filt_shift);
    down_skip_convolve:
      pDst[col] = v;
    }
405

John Koleszar's avatar
John Koleszar committed
406 407 408
    /* now post_proc_across */
    pSrc = dst;
    pDst = dst;
409

John Koleszar's avatar
John Koleszar committed
410 411
    for (i = 0; i < 8; i++)
      d[i] = pSrc[i];
412

John Koleszar's avatar
John Koleszar committed
413 414 415
    for (col = 0; col < width; col++) {
      int kernel = (1 << (filt_shift - 1));
      v = pSrc[col];
416

John Koleszar's avatar
John Koleszar committed
417
      d[col & 7] = v;
418

John Koleszar's avatar
John Koleszar committed
419 420 421
      for (i = -2; i <= 2; i++) {
        if (abs(v - pSrc[col + i]) > flimit)
          goto across_skip_convolve;
422

John Koleszar's avatar
John Koleszar committed
423 424
        kernel += pred_filter[2 + i] * pSrc[col + i];
      }
425

John Koleszar's avatar
John Koleszar committed
426 427
      d[col & 7] = (kernel >> filt_shift);
    across_skip_convolve:
428

John Koleszar's avatar
John Koleszar committed
429 430 431
      if (col >= 2)
        pDst[col - 2] = d[(col - 2) & 7];
    }
432

John Koleszar's avatar
John Koleszar committed
433 434 435
    /* handle the last two pixels */
    pDst[col - 2] = d[(col - 2) & 7];
    pDst[col - 1] = d[(col - 1) & 7];
436

John Koleszar's avatar
John Koleszar committed
437 438 439 440
    /* next row */
    src += src_stride;
    dst += dst_stride;
  }
441 442 443 444 445
}
#endif  // !USE_THRESH_FILTER

#endif  // CONFIG_PRED_FILTER

446
/*encoder only*/
447
void vp9_build_inter4x4_predictors_mbuv(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
448
  int i, j;
Paul Wilkins's avatar
Paul Wilkins committed
449
  BLOCKD *blockd = xd->block;
John Koleszar's avatar
John Koleszar committed
450 451 452 453 454 455 456 457 458

  /* build uv mvs */
  for (i = 0; i < 2; i++) {
    for (j = 0; j < 2; j++) {
      int yoffset = i * 8 + j * 2;
      int uoffset = 16 + i * 2 + j;
      int voffset = 20 + i * 2 + j;
      int temp;

Paul Wilkins's avatar
Paul Wilkins committed
459 460 461 462
      temp = blockd[yoffset  ].bmi.as_mv.first.as_mv.row
             + blockd[yoffset + 1].bmi.as_mv.first.as_mv.row
             + blockd[yoffset + 4].bmi.as_mv.first.as_mv.row
             + blockd[yoffset + 5].bmi.as_mv.first.as_mv.row;
John Koleszar's avatar
John Koleszar committed
463 464 465 466

      if (temp < 0) temp -= 4;
      else temp += 4;

Paul Wilkins's avatar
Paul Wilkins committed
467 468
      xd->block[uoffset].bmi.as_mv.first.as_mv.row = (temp / 8) &
        xd->fullpixel_mask;
John Koleszar's avatar
John Koleszar committed
469

Paul Wilkins's avatar
Paul Wilkins committed
470 471 472 473
      temp = blockd[yoffset  ].bmi.as_mv.first.as_mv.col
             + blockd[yoffset + 1].bmi.as_mv.first.as_mv.col
             + blockd[yoffset + 4].bmi.as_mv.first.as_mv.col
             + blockd[yoffset + 5].bmi.as_mv.first.as_mv.col;
John Koleszar's avatar
John Koleszar committed
474 475 476 477

      if (temp < 0) temp -= 4;
      else temp += 4;

Paul Wilkins's avatar
Paul Wilkins committed
478 479
      blockd[uoffset].bmi.as_mv.first.as_mv.col = (temp / 8) &
        xd->fullpixel_mask;
John Koleszar's avatar
John Koleszar committed
480

Paul Wilkins's avatar
Paul Wilkins committed
481 482 483 484
      blockd[voffset].bmi.as_mv.first.as_mv.row =
        blockd[uoffset].bmi.as_mv.first.as_mv.row;
      blockd[voffset].bmi.as_mv.first.as_mv.col =
        blockd[uoffset].bmi.as_mv.first.as_mv.col;
John Koleszar's avatar
John Koleszar committed
485

486
      if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
Paul Wilkins's avatar
Paul Wilkins committed
487 488 489 490
        temp = blockd[yoffset  ].bmi.as_mv.second.as_mv.row
               + blockd[yoffset + 1].bmi.as_mv.second.as_mv.row
               + blockd[yoffset + 4].bmi.as_mv.second.as_mv.row
               + blockd[yoffset + 5].bmi.as_mv.second.as_mv.row;
John Koleszar's avatar
John Koleszar committed
491 492 493 494 495

        if (temp < 0) {
          temp -= 4;
        } else {
          temp += 4;
496 497
        }

Paul Wilkins's avatar
Paul Wilkins committed
498 499
        blockd[uoffset].bmi.as_mv.second.as_mv.row = (temp / 8) &
          xd->fullpixel_mask;
500

Paul Wilkins's avatar
Paul Wilkins committed
501 502 503 504
        temp = blockd[yoffset  ].bmi.as_mv.second.as_mv.col
               + blockd[yoffset + 1].bmi.as_mv.second.as_mv.col
               + blockd[yoffset + 4].bmi.as_mv.second.as_mv.col
               + blockd[yoffset + 5].bmi.as_mv.second.as_mv.col;
John Koleszar's avatar
John Koleszar committed
505 506 507 508 509

        if (temp < 0) {
          temp -= 4;
        } else {
          temp += 4;
510
        }
John Koleszar's avatar
John Koleszar committed
511

Paul Wilkins's avatar
Paul Wilkins committed
512 513
        blockd[uoffset].bmi.as_mv.second.as_mv.col = (temp / 8) &
          xd->fullpixel_mask;
John Koleszar's avatar
John Koleszar committed
514

Paul Wilkins's avatar
Paul Wilkins committed
515 516 517 518
        blockd[voffset].bmi.as_mv.second.as_mv.row =
          blockd[uoffset].bmi.as_mv.second.as_mv.row;
        blockd[voffset].bmi.as_mv.second.as_mv.col =
          blockd[uoffset].bmi.as_mv.second.as_mv.col;
John Koleszar's avatar
John Koleszar committed
519
      }
John Koleszar's avatar
John Koleszar committed
520
    }
John Koleszar's avatar
John Koleszar committed
521 522 523
  }

  for (i = 16; i < 24; i += 2) {
Paul Wilkins's avatar
Paul Wilkins committed
524 525
    BLOCKD *d0 = &blockd[i];
    BLOCKD *d1 = &blockd[i + 1];
John Koleszar's avatar
John Koleszar committed
526 527

    if (d0->bmi.as_mv.first.as_int == d1->bmi.as_mv.first.as_int)
Paul Wilkins's avatar
Paul Wilkins committed
528
      build_inter_predictors2b(xd, d0, 8);
John Koleszar's avatar
John Koleszar committed
529
    else {
530 531
      vp9_build_inter_predictors_b(d0, 8, xd->subpixel_predict);
      vp9_build_inter_predictors_b(d1, 8, xd->subpixel_predict);
John Koleszar's avatar
John Koleszar committed
532 533
    }

534
    if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
535 536
      vp9_build_2nd_inter_predictors_b(d0, 8, xd->subpixel_predict_avg);
      vp9_build_2nd_inter_predictors_b(d1, 8, xd->subpixel_predict_avg);
John Koleszar's avatar
John Koleszar committed
537 538
    }
  }
John Koleszar's avatar
John Koleszar committed
539 540
}

John Koleszar's avatar
John Koleszar committed
541 542 543 544 545 546 547 548 549 550
static void clamp_mv_to_umv_border(MV *mv, const MACROBLOCKD *xd) {
  /* If the MV points so far into the UMV border that no visible pixels
   * are used for reconstruction, the subpel part of the MV can be
   * discarded and the MV limited to 16 pixels with equivalent results.
   *
   * This limit kicks in at 19 pixels for the top and left edges, for
   * the 16 pixels plus 3 taps right of the central pixel when subpel
   * filtering. The bottom and right edges use 16 pixels plus 2 pixels
   * left of the central pixel when filtering.
   */
John Koleszar's avatar
John Koleszar committed
551
  if (mv->col < (xd->mb_to_left_edge - ((16 + VP9_INTERP_EXTEND) << 3)))
John Koleszar's avatar
John Koleszar committed
552
    mv->col = xd->mb_to_left_edge - (16 << 3);
John Koleszar's avatar
John Koleszar committed
553
  else if (mv->col > xd->mb_to_right_edge + ((15 + VP9_INTERP_EXTEND) << 3))
John Koleszar's avatar
John Koleszar committed
554 555
    mv->col = xd->mb_to_right_edge + (16 << 3);

John Koleszar's avatar
John Koleszar committed
556
  if (mv->row < (xd->mb_to_top_edge - ((16 + VP9_INTERP_EXTEND) << 3)))
John Koleszar's avatar
John Koleszar committed
557
    mv->row = xd->mb_to_top_edge - (16 << 3);
John Koleszar's avatar
John Koleszar committed
558
  else if (mv->row > xd->mb_to_bottom_edge + ((15 + VP9_INTERP_EXTEND) << 3))
John Koleszar's avatar
John Koleszar committed
559
    mv->row = xd->mb_to_bottom_edge + (16 << 3);
560 561 562
}

/* A version of the above function for chroma block MVs.*/
John Koleszar's avatar
John Koleszar committed
563
static void clamp_uvmv_to_umv_border(MV *mv, const MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
564 565 566
  const int extend = VP9_INTERP_EXTEND;

  mv->col = (2 * mv->col < (xd->mb_to_left_edge - ((16 + extend) << 3))) ?
John Koleszar's avatar
John Koleszar committed
567
            (xd->mb_to_left_edge - (16 << 3)) >> 1 : mv->col;
John Koleszar's avatar
John Koleszar committed
568
  mv->col = (2 * mv->col > xd->mb_to_right_edge + ((15 + extend) << 3)) ?
John Koleszar's avatar
John Koleszar committed
569 570
            (xd->mb_to_right_edge + (16 << 3)) >> 1 : mv->col;

John Koleszar's avatar
John Koleszar committed
571
  mv->row = (2 * mv->row < (xd->mb_to_top_edge - ((16 + extend) << 3))) ?
John Koleszar's avatar
John Koleszar committed
572
            (xd->mb_to_top_edge - (16 << 3)) >> 1 : mv->row;
John Koleszar's avatar
John Koleszar committed
573
  mv->row = (2 * mv->row > xd->mb_to_bottom_edge + ((15 + extend) << 3)) ?
John Koleszar's avatar
John Koleszar committed
574
            (xd->mb_to_bottom_edge + (16 << 3)) >> 1 : mv->row;
575 576
}

577
/*encoder only*/
578
void vp9_build_1st_inter16x16_predictors_mby(MACROBLOCKD *xd,
579
                                             unsigned char *dst_y,
580 581
                                             int dst_ystride,
                                             int clamp_mvs) {
582
  unsigned char *ptr_base = xd->pre.y_buffer;
John Koleszar's avatar
John Koleszar committed
583
  unsigned char *ptr;
584 585
  int pre_stride = xd->block[0].pre_stride;
  int_mv ymv;
John Koleszar's avatar
John Koleszar committed
586

587
  ymv.as_int = xd->mode_info_context->mbmi.mv[0].as_int;
John Koleszar's avatar
John Koleszar committed
588

589
  if (clamp_mvs)
590
    clamp_mv_to_umv_border(&ymv.as_mv, xd);
591

592
  ptr = ptr_base + (ymv.as_mv.row >> 3) * pre_stride + (ymv.as_mv.col >> 3);
593 594

#if CONFIG_PRED_FILTER
595 596
  if (xd->mode_info_context->mbmi.pred_filter_enabled) {
    if ((ymv.as_mv.row | ymv.as_mv.col) & 7) {
John Koleszar's avatar
John Koleszar committed
597
      // Sub-pel filter needs extended input
John Koleszar's avatar
John Koleszar committed
598
      int len = 15 + (VP9_INTERP_EXTEND << 1);
599
      unsigned char Temp[32 * 32]; // Data required by sub-pel filter
John Koleszar's avatar
John Koleszar committed
600
      unsigned char *pTemp = Temp + (VP9_INTERP_EXTEND - 1) * (len + 1);
601

John Koleszar's avatar
John Koleszar committed
602
      // Copy extended MB into Temp array, applying the spatial filter
John Koleszar's avatar
John Koleszar committed
603
      filter_mb(ptr - (VP9_INTERP_EXTEND - 1) * (pre_stride + 1), pre_stride,
John Koleszar's avatar
John Koleszar committed
604
                Temp, len, len, len);
605

606 607 608 609 610
      // Sub-pel interpolation
      xd->subpixel_predict16x16(pTemp, len,
                                (ymv.as_mv.col & 7) << 1,
                                (ymv.as_mv.row & 7) << 1,
                                dst_y, dst_ystride);
John Koleszar's avatar
John Koleszar committed
611 612 613
    } else {
      // Apply spatial filter to create the prediction directly
      filter_mb(ptr, pre_stride, dst_y, dst_ystride, 16, 16);
614
    }
John Koleszar's avatar
John Koleszar committed
615
  } else
616
#endif
617 618 619 620 621
    if ((ymv.as_mv.row | ymv.as_mv.col) & 7) {
      xd->subpixel_predict16x16(ptr, pre_stride,
                                (ymv.as_mv.col & 7) << 1,
                                (ymv.as_mv.row & 7) << 1,
                                dst_y, dst_ystride);
John Koleszar's avatar
John Koleszar committed
622
    } else {
623
      vp9_copy_mem16x16(ptr, pre_stride, dst_y, dst_ystride);
624
    }
625 626
}

627
void vp9_build_1st_inter16x16_predictors_mbuv(MACROBLOCKD *xd,
628 629 630 631 632
                                              unsigned char *dst_u,
                                              unsigned char *dst_v,
                                              int dst_uvstride) {
  int offset;
  unsigned char *uptr, *vptr;
Paul Wilkins's avatar
Paul Wilkins committed
633
  int pre_stride = xd->block[0].pre_stride;
634 635 636
  int_mv _o16x16mv;
  int_mv _16x16mv;

Paul Wilkins's avatar
Paul Wilkins committed
637
  _16x16mv.as_int = xd->mode_info_context->mbmi.mv[0].as_int;
638

Paul Wilkins's avatar
Paul Wilkins committed
639 640
  if (xd->mode_info_context->mbmi.need_to_clamp_mvs)
    clamp_mv_to_umv_border(&_16x16mv.as_mv, xd);
John Koleszar's avatar
John Koleszar committed
641

John Koleszar's avatar
John Koleszar committed
642 643 644 645 646 647
  _o16x16mv = _16x16mv;
  /* calc uv motion vectors */
  if (_16x16mv.as_mv.row < 0)
    _16x16mv.as_mv.row -= 1;
  else
    _16x16mv.as_mv.row += 1;
648

John Koleszar's avatar
John Koleszar committed
649 650 651 652
  if (_16x16mv.as_mv.col < 0)
    _16x16mv.as_mv.col -= 1;
  else
    _16x16mv.as_mv.col += 1;
653

John Koleszar's avatar
John Koleszar committed
654 655
  _16x16mv.as_mv.row /= 2;
  _16x16mv.as_mv.col /= 2;
656

Paul Wilkins's avatar
Paul Wilkins committed
657 658
  _16x16mv.as_mv.row &= xd->fullpixel_mask;
  _16x16mv.as_mv.col &= xd->fullpixel_mask;
659

John Koleszar's avatar
John Koleszar committed
660 661
  pre_stride >>= 1;
  offset = (_16x16mv.as_mv.row >> 3) * pre_stride + (_16x16mv.as_mv.col >> 3);
Paul Wilkins's avatar
Paul Wilkins committed
662 663
  uptr = xd->pre.u_buffer + offset;
  vptr = xd->pre.v_buffer + offset;
John Koleszar's avatar
John Koleszar committed
664

665
#if CONFIG_PRED_FILTER
Paul Wilkins's avatar
Paul Wilkins committed
666
  if (xd->mode_info_context->mbmi.pred_filter_enabled) {
John Koleszar's avatar
John Koleszar committed
667 668 669
    int i;
    unsigned char *pSrc = uptr;
    unsigned char *pDst = dst_u;
John Koleszar's avatar
John Koleszar committed
670
    int len = 7 + (VP9_INTERP_EXTEND << 1);
John Koleszar's avatar
John Koleszar committed
671
    unsigned char Temp[32 * 32]; // Data required by the sub-pel filter
John Koleszar's avatar
John Koleszar committed
672
    unsigned char *pTemp = Temp + (VP9_INTERP_EXTEND - 1) * (len + 1);
673

John Koleszar's avatar
John Koleszar committed
674 675 676 677
    // U & V
    for (i = 0; i < 2; i++) {
      if (_o16x16mv.as_int & 0x000f000f) {
        // Copy extended MB into Temp array, applying the spatial filter
John Koleszar's avatar
John Koleszar committed
678
        filter_mb(pSrc - (VP9_INTERP_EXTEND - 1) * (pre_stride + 1), pre_stride,
John Koleszar's avatar
John Koleszar committed
679 680 681
                  Temp, len, len, len);

        // Sub-pel filter
Deb Mukherjee's avatar
Deb Mukherjee committed
682
        xd->subpixel_predict8x8(pTemp, len,
683 684 685
                                _o16x16mv.as_mv.col & 15,
                                _o16x16mv.as_mv.row & 15,
                                pDst, dst_uvstride);
686
      } else {
John Koleszar's avatar
John Koleszar committed
687 688 689 690 691 692
        filter_mb(pSrc, pre_stride, pDst, dst_uvstride, 8, 8);
      }

      // V
      pSrc = vptr;
      pDst = dst_v;
693
    }
John Koleszar's avatar
John Koleszar committed
694
  } else
695
#endif
John Koleszar's avatar
John Koleszar committed
696
    if (_o16x16mv.as_int & 0x000f000f) {
Paul Wilkins's avatar
Paul Wilkins committed
697 698 699 700
      xd->subpixel_predict8x8(uptr, pre_stride, _o16x16mv.as_mv.col & 15,
                              _o16x16mv.as_mv.row & 15, dst_u, dst_uvstride);
      xd->subpixel_predict8x8(vptr, pre_stride, _o16x16mv.as_mv.col & 15,
                              _o16x16mv.as_mv.row & 15, dst_v, dst_uvstride);
701
    } else {
702 703
      vp9_copy_mem8x8(uptr, pre_stride, dst_u, dst_uvstride);
      vp9_copy_mem8x8(vptr, pre_stride, dst_v, dst_uvstride);
704
    }
705 706 707
}


708
void vp9_build_1st_inter16x16_predictors_mb(MACROBLOCKD *xd,
709 710 711 712
                                            unsigned char *dst_y,
                                            unsigned char *dst_u,
                                            unsigned char *dst_v,
                                            int dst_ystride, int dst_uvstride) {
713
  vp9_build_1st_inter16x16_predictors_mby(xd, dst_y, dst_ystride,
714
      xd->mode_info_context->mbmi.need_to_clamp_mvs);
715
  vp9_build_1st_inter16x16_predictors_mbuv(xd, dst_u, dst_v, dst_uvstride);
716
}
John Koleszar's avatar
John Koleszar committed
717

Ronald S. Bultje's avatar
Ronald S. Bultje committed
718
#if CONFIG_SUPERBLOCKS
719
void vp9_build_inter32x32_predictors_sb(MACROBLOCKD *x,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
720 721 722 723 724 725 726 727
                                        unsigned char *dst_y,
                                        unsigned char *dst_u,
                                        unsigned char *dst_v,
                                        int dst_ystride,
                                        int dst_uvstride) {
  uint8_t *y1 = x->pre.y_buffer, *u1 = x->pre.u_buffer, *v1 = x->pre.v_buffer;
  uint8_t *y2 = x->second_pre.y_buffer, *u2 = x->second_pre.u_buffer,
          *v2 = x->second_pre.v_buffer;
728
  int edge[4], n;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
729

730 731 732 733 734 735
  edge[0] = x->mb_to_top_edge;
  edge[1] = x->mb_to_bottom_edge;
  edge[2] = x->mb_to_left_edge;
  edge[3] = x->mb_to_right_edge;

  for (n = 0; n < 4; n++) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
736 737
    const int x_idx = n & 1, y_idx = n >> 1;

738 739 740 741 742
    x->mb_to_top_edge    = edge[0] -      ((y_idx  * 16) << 3);
    x->mb_to_bottom_edge = edge[1] + (((1 - y_idx) * 16) << 3);
    x->mb_to_left_edge   = edge[2] -      ((x_idx  * 16) << 3);
    x->mb_to_right_edge  = edge[3] + (((1 - x_idx) * 16) << 3);

Ronald S. Bultje's avatar
Ronald S. Bultje committed
743 744 745 746
    x->pre.y_buffer = y1 + y_idx * 16 * x->pre.y_stride  + x_idx * 16;
    x->pre.u_buffer = u1 + y_idx *  8 * x->pre.uv_stride + x_idx *  8;
    x->pre.v_buffer = v1 + y_idx *  8 * x->pre.uv_stride + x_idx *  8;

747
    vp9_build_1st_inter16x16_predictors_mb(x,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
748 749 750 751
      dst_y + y_idx * 16 * dst_ystride  + x_idx * 16,
      dst_u + y_idx *  8 * dst_uvstride + x_idx *  8,
      dst_v + y_idx *  8 * dst_uvstride + x_idx *  8,
      dst_ystride, dst_uvstride);
752
    if (x->mode_info_context->mbmi.second_ref_frame > 0) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
753 754 755 756
      x->second_pre.y_buffer = y2 + y_idx * 16 * x->pre.y_stride  + x_idx * 16;
      x->second_pre.u_buffer = u2 + y_idx *  8 * x->pre.uv_stride + x_idx *  8;
      x->second_pre.v_buffer = v2 + y_idx *  8 * x->pre.uv_stride + x_idx *  8;

757
      vp9_build_2nd_inter16x16_predictors_mb(x,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
758 759 760 761 762 763 764
        dst_y + y_idx * 16 * dst_ystride  + x_idx * 16,
        dst_u + y_idx *  8 * dst_uvstride + x_idx *  8,
        dst_v + y_idx *  8 * dst_uvstride + x_idx *  8,
        dst_ystride, dst_uvstride);
    }
  }

765 766 767 768 769
  x->mb_to_top_edge    = edge[0];
  x->mb_to_bottom_edge = edge[1];
  x->mb_to_left_edge   = edge[2];
  x->mb_to_right_edge  = edge[3];

Ronald S. Bultje's avatar
Ronald S. Bultje committed
770 771 772 773
  x->pre.y_buffer = y1;
  x->pre.u_buffer = u1;
  x->pre.v_buffer = v1;

774
  if (x->mode_info_context->mbmi.second_ref_frame > 0) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
775 776 777 778 779 780 781
    x->second_pre.y_buffer = y2;
    x->second_pre.u_buffer = u2;
    x->second_pre.v_buffer = v2;
  }
}
#endif

782
/*
783
 * The following functions should be called after an initial
784
 * call to vp9_build_1st_inter16x16_predictors_mb() or _mby()/_mbuv().
785 786 787 788 789 790 791 792 793 794 795
 * It will run a second sixtap filter on a (different) ref
 * frame and average the result with the output of the
 * first sixtap filter. The second reference frame is stored
 * in x->second_pre (the reference frame index is in
 * x->mode_info_context->mbmi.second_ref_frame). The second
 * motion vector is x->mode_info_context->mbmi.second_mv.
 *
 * This allows blending prediction from two reference frames
 * which sometimes leads to better prediction than from a
 * single reference framer.
 */
796
void vp9_build_2nd_inter16x16_predictors_mby(MACROBLOCKD *xd,
797 798
                                             unsigned char *dst_y,
                                             int dst_ystride) {
John Koleszar's avatar
John Koleszar committed
799
  unsigned char *ptr;
800

John Koleszar's avatar
John Koleszar committed
801 802 803
  int_mv _16x16mv;
  int mv_row;
  int mv_col;
Yaowu Xu's avatar
Yaowu Xu committed
804

Paul Wilkins's avatar
Paul Wilkins committed
805 806
  unsigned char *ptr_base = xd->second_pre.y_buffer;
  int pre_stride = xd->block[0].pre_stride;
807

Paul Wilkins's avatar
Paul Wilkins committed
808
  _16x16mv.as_int = xd->mode_info_context->mbmi.mv[1].as_int;
Yaowu Xu's avatar
Yaowu Xu committed
809

Paul Wilkins's avatar
Paul Wilkins committed
810 811
  if (xd->mode_info_context->mbmi.need_to_clamp_secondmv)
    clamp_mv_to_umv_border(&_16x16mv.as_mv, xd);
Yaowu Xu's avatar
Yaowu Xu committed
812

John Koleszar's avatar
John Koleszar committed
813 814
  mv_row = _16x16mv.as_mv.row;
  mv_col = _16x16mv.as_mv.col;
Yaowu Xu's avatar
Yaowu Xu committed
815

John Koleszar's avatar
John Koleszar committed
816
  ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
817

818
#if CONFIG_PRED_FILTER
Paul Wilkins's avatar
Paul Wilkins committed
819
  if (xd->mode_info_context->mbmi.pred_filter_enabled) {
John Koleszar's avatar
John Koleszar committed
820 821
    if ((mv_row | mv_col) & 7) {
      // Sub-pel filter needs extended input
John Koleszar's avatar
John Koleszar committed
822
      int len = 15 + (VP9_INTERP_EXTEND << 1);
John Koleszar's avatar
John Koleszar committed
823
      unsigned char Temp[32 * 32]; // Data required by sub-pel filter
John Koleszar's avatar
John Koleszar committed
824
      unsigned char *pTemp = Temp + (VP9_INTERP_EXTEND - 1) * (len + 1);
825

John Koleszar's avatar
John Koleszar committed
826
      // Copy extended MB into Temp array, applying the spatial filter
John Koleszar's avatar
John Koleszar committed
827
      filter_mb(ptr - (VP9_INTERP_EXTEND - 1) * (pre_stride + 1), pre_stride,
John Koleszar's avatar
John Koleszar committed
828
                Temp, len, len, len);
829

John Koleszar's avatar
John Koleszar committed
830
      // Sub-pel filter
Paul Wilkins's avatar
Paul Wilkins committed
831 832
      xd->subpixel_predict_avg16x16(pTemp, len, (mv_col & 7) << 1,
                                    (mv_row & 7) << 1, dst_y, dst_ystride);
John Koleszar's avatar
John Koleszar committed
833 834 835
    } else {
      // TODO Needs to AVERAGE with the dst_y
      // For now, do not apply the prediction filter in these cases!
836
      vp9_avg_mem16x16(ptr, pre_stride, dst_y, dst_ystride);
837
    }
John Koleszar's avatar
John Koleszar committed
838
  } else
839
#endif  // CONFIG_PRED_FILTER
John Koleszar's avatar
John Koleszar committed
840 841
  {
    if ((mv_row | mv_col) & 7) {
Paul Wilkins's avatar
Paul Wilkins committed
842 843
      xd->subpixel_predict_avg16x16(ptr, pre_stride, (mv_col & 7) << 1,
                                    (mv_row & 7) << 1, dst_y, dst_ystride);
John Koleszar's avatar
John Koleszar committed
844
    } else {
845
      vp9_avg_mem16x16(ptr, pre_stride, dst_y, dst_ystride);
846
    }
John Koleszar's avatar
John Koleszar committed
847
  }
848 849
}

850
void vp9_build_2nd_inter16x16_predictors_mbuv(MACROBLOCKD *xd,
851 852 853 854 855 856 857 858 859 860 861
                                              unsigned char *dst_u,
                                              unsigned char *dst_v,
                                              int dst_uvstride) {
  int offset;
  unsigned char *uptr, *vptr;

  int_mv _16x16mv;
  int mv_row;
  int mv_col;
  int omv_row, omv_col;

Paul Wilkins's avatar
Paul Wilkins committed
862
  int pre_stride = xd->block[0].pre_stride;
863

Paul Wilkins's avatar
Paul Wilkins committed
864
  _16x16mv.as_int = xd->mode_info_context->mbmi.mv[1].as_int;
865

Paul Wilkins's avatar
Paul Wilkins committed
866 867
  if (xd->mode_info_context->mbmi.need_to_clamp_secondmv)
    clamp_mv_to_umv_border(&_16x16mv.as_mv, xd);
868 869 870

  mv_row = _16x16mv.as_mv.row;
  mv_col = _16x16mv.as_mv.col;
871

John Koleszar's avatar
John Koleszar committed
872 873 874 875 876
  /* calc uv motion vectors */
  omv_row = mv_row;
  omv_col = mv_col;
  mv_row = (mv_row + (mv_row > 0)) >> 1;
  mv_col = (mv_col + (mv_col > 0)) >> 1;
877

Paul Wilkins's avatar
Paul Wilkins committed
878 879
  mv_row &= xd->fullpixel_mask;
  mv_col &= xd->fullpixel_mask;
880

John Koleszar's avatar
John Koleszar committed
881 882
  pre_stride >>= 1;
  offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
Paul Wilkins's avatar
Paul Wilkins committed
883 884
  uptr = xd->second_pre.u_buffer + offset;
  vptr = xd->second_pre.v_buffer + offset;
885

886
#if CONFIG_PRED_FILTER
Paul Wilkins's avatar
Paul Wilkins committed
887
  if (xd->mode_info_context->mbmi.pred_filter_enabled) {
John Koleszar's avatar
John Koleszar committed
888
    int i;
John Koleszar's avatar
John Koleszar committed
889
    int len = 7 + (VP9_INTERP_EXTEND << 1);
John Koleszar's avatar
John Koleszar committed
890
    unsigned char Temp[32 * 32]; // Data required by sub-pel filter
John Koleszar's avatar
John Koleszar committed
891
    unsigned char *pTemp = Temp + (VP9_INTERP_EXTEND - 1) * (len + 1);
John Koleszar's avatar
John Koleszar committed
892 893 894 895 896 897 898
    unsigned char *pSrc = uptr;
    unsigned char *pDst = dst_u;

    // U & V
    for (i = 0; i < 2; i++) {
      if ((omv_row | omv_col) & 15) {
        // Copy extended MB into Temp array, applying the spatial filter
John Koleszar's avatar
John Koleszar committed
899
        filter_mb(pSrc - (VP9_INTERP_EXTEND - 1) * (pre_stride + 1), pre_stride,
John Koleszar's avatar
John Koleszar committed
900 901 902
                  Temp, len, len, len);

        // Sub-pel filter
Paul Wilkins's avatar
Paul Wilkins committed
903 904
        xd->subpixel_predict_avg8x8(pTemp, len, omv_col & 15,
                                    omv_row & 15, pDst, dst_uvstride);
905
      } else {
John Koleszar's avatar
John Koleszar committed