vp9_reconinter.c 37.8 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_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

18
void vp9_setup_interp_filters(MACROBLOCKD *xd,
19
                              INTERPOLATIONFILTERTYPE mcomp_filter_type,
20
                              VP9_COMMON *cm) {
21
  if (mcomp_filter_type == SIXTAP) {
22
23
24
25
26
27
28
    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;
29
  } else if (mcomp_filter_type == EIGHTTAP || mcomp_filter_type == SWITCHABLE) {
30
31
32
33
34
35
36
    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;
37
  } else if (mcomp_filter_type == EIGHTTAP_SHARP) {
38
39
40
41
42
43
44
    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;
45
46
  }
  else {
47
48
49
50
51
52
53
    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;
54
55
56
  }
}

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

John Koleszar's avatar
John Koleszar committed
63
  for (r = 0; r < 16; r++) {
64
#if !(CONFIG_FAST_UNALIGNED)
John Koleszar's avatar
John Koleszar committed
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    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
81
82

#else
John Koleszar's avatar
John Koleszar committed
83
84
85
86
    ((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
87
88

#endif
John Koleszar's avatar
John Koleszar committed
89
90
91
    src += src_stride;
    dst += dst_stride;
  }
John Koleszar's avatar
John Koleszar committed
92
93
}

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

John Koleszar's avatar
John Koleszar committed
100
101
102
103
104
  for (r = 0; r < 16; r++) {
    int n;

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

    src += src_stride;
    dst += dst_stride;
  }
110
111
}

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

  for (r = 0; r < 8; r++) {
119
#if !(CONFIG_FAST_UNALIGNED)
John Koleszar's avatar
John Koleszar committed
120
121
122
123
124
125
126
127
    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
128
#else
John Koleszar's avatar
John Koleszar committed
129
130
    ((uint32_t *)dst)[0] = ((uint32_t *)src)[0];
    ((uint32_t *)dst)[1] = ((uint32_t *)src)[1];
John Koleszar's avatar
John Koleszar committed
131
#endif
John Koleszar's avatar
John Koleszar committed
132
133
134
    src += src_stride;
    dst += dst_stride;
  }
John Koleszar's avatar
John Koleszar committed
135
136
}

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

John Koleszar's avatar
John Koleszar committed
143
144
145
146
147
  for (r = 0; r < 8; r++) {
    int n;

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

    src += src_stride;
    dst += dst_stride;
  }
153
154
}

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

  for (r = 0; r < 4; r++) {
162
#if !(CONFIG_FAST_UNALIGNED)
John Koleszar's avatar
John Koleszar committed
163
164
165
166
167
168
169
170
    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
171
#else
John Koleszar's avatar
John Koleszar committed
172
173
    ((uint32_t *)dst)[0] = ((uint32_t *)src)[0];
    ((uint32_t *)dst)[1] = ((uint32_t *)src)[1];
John Koleszar's avatar
John Koleszar committed
174
#endif
John Koleszar's avatar
John Koleszar committed
175
176
177
    src += src_stride;
    dst += dst_stride;
  }
John Koleszar's avatar
John Koleszar committed
178
179
}

180
void vp9_build_inter_predictors_b(BLOCKD *d, int pitch, vp9_subpix_fn_t sppf) {
John Koleszar's avatar
John Koleszar committed
181
182
183
184
185
  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
186

John Koleszar's avatar
John Koleszar committed
187
188
  ptr_base = *(d->base_pre);
  mv.as_int = d->bmi.as_mv.first.as_int;
John Koleszar's avatar
John Koleszar committed
189

John Koleszar's avatar
John Koleszar committed
190
  if (mv.as_mv.row & 7 || mv.as_mv.col & 7) {
191
192
193
194
    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
195
  } else {
196
197
    ptr_base += d->pre + (mv.as_mv.row >> 3) * d->pre_stride +
                (mv.as_mv.col >> 3);
John Koleszar's avatar
John Koleszar committed
198
    ptr = ptr_base;
John Koleszar's avatar
John Koleszar committed
199

John Koleszar's avatar
John Koleszar committed
200
    for (r = 0; r < 4; r++) {
201
#if !(CONFIG_FAST_UNALIGNED)
John Koleszar's avatar
John Koleszar committed
202
203
204
205
      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
206
#else
John Koleszar's avatar
John Koleszar committed
207
      *(uint32_t *)pred_ptr = *(uint32_t *)ptr;
John Koleszar's avatar
John Koleszar committed
208
#endif
John Koleszar's avatar
John Koleszar committed
209
210
      pred_ptr     += pitch;
      ptr         += d->pre_stride;
John Koleszar's avatar
John Koleszar committed
211
    }
John Koleszar's avatar
John Koleszar committed
212
  }
John Koleszar's avatar
John Koleszar committed
213
214
}

215
/*
216
 * Similar to vp9_build_inter_predictors_b(), but instead of storing the
217
 * results in d->predictor, we average the contents of d->predictor (which
218
 * come from an earlier call to vp9_build_inter_predictors_b()) with the
219
220
 * predictor of the second reference frame / motion vector.
 */
221
222
void vp9_build_2nd_inter_predictors_b(BLOCKD *d, int pitch,
                                      vp9_subpix_fn_t sppf) {
John Koleszar's avatar
John Koleszar committed
223
224
225
226
227
228
229
230
231
232
  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) {
233
234
235
236
    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
237
  } else {
238
239
    ptr_base += d->pre + (mv.as_mv.row >> 3) * d->pre_stride +
                (mv.as_mv.col >> 3);
John Koleszar's avatar
John Koleszar committed
240
241
242
243
244
245
246
247
248
    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;
249
    }
John Koleszar's avatar
John Koleszar committed
250
  }
251
252
}

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

John Koleszar's avatar
John Koleszar committed
259
260
  ptr_base = *(d->base_pre);
  mv.as_int = d->bmi.as_mv.first.as_int;
Paul Wilkins's avatar
Paul Wilkins committed
261
262
  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
263

John Koleszar's avatar
John Koleszar committed
264
  if (mv.as_mv.row & 7 || mv.as_mv.col & 7) {
Paul Wilkins's avatar
Paul Wilkins committed
265
266
    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
267
  } else {
268
    vp9_copy_mem8x8(ptr, d->pre_stride, pred_ptr, pitch);
John Koleszar's avatar
John Koleszar committed
269
  }
John Koleszar's avatar
John Koleszar committed
270
271
}

272
273
274
275
276
277
/*
 * 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.
 */
278
void vp9_build_2nd_inter_predictors4b(MACROBLOCKD *xd,
279
                                      BLOCKD *d, int pitch) {
John Koleszar's avatar
John Koleszar committed
280
281
282
283
284
285
286
  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
287
288
  ptr = ptr_base + d->pre + (mv.as_mv.row >> 3) * d->pre_stride +
        (mv.as_mv.col >> 3);
289

John Koleszar's avatar
John Koleszar committed
290
  if (mv.as_mv.row & 7 || mv.as_mv.col & 7) {
Paul Wilkins's avatar
Paul Wilkins committed
291
292
    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
293
  } else {
294
    vp9_avg_mem8x8(ptr, d->pre_stride, pred_ptr, pitch);
John Koleszar's avatar
John Koleszar committed
295
  }
296
297
}

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

John Koleszar's avatar
John Koleszar committed
304
305
  ptr_base = *(d->base_pre);
  mv.as_int = d->bmi.as_mv.first.as_int;
Paul Wilkins's avatar
Paul Wilkins committed
306
307
  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
308

John Koleszar's avatar
John Koleszar committed
309
  if (mv.as_mv.row & 7 || mv.as_mv.col & 7) {
Paul Wilkins's avatar
Paul Wilkins committed
310
311
    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
312
  } else {
313
    vp9_copy_mem8x4(ptr, d->pre_stride, pred_ptr, pitch);
John Koleszar's avatar
John Koleszar committed
314
  }
John Koleszar's avatar
John Koleszar committed
315
316
317
}


318
/*encoder only*/
319
320
321
322
323
324
325
326
327
328
329
330
331
332
#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
333
334
335
336
337
338
339
340
341
342
343
344
345
               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;
346
347
    }

John Koleszar's avatar
John Koleszar committed
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
    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);
363
    }
John Koleszar's avatar
John Koleszar committed
364
365
    ++pTmp;
  }
366
367
}
#else
368
// Based on vp9_post_proc_down_and_across_c (vp9_postproc.c)
369
370
void filter_mb(unsigned char *src, int src_stride,
               unsigned char *dst, int dst_stride,
John Koleszar's avatar
John Koleszar committed
371
372
373
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
               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;
    }
402

John Koleszar's avatar
John Koleszar committed
403
404
405
    /* now post_proc_across */
    pSrc = dst;
    pDst = dst;
406

John Koleszar's avatar
John Koleszar committed
407
408
    for (i = 0; i < 8; i++)
      d[i] = pSrc[i];
409

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

John Koleszar's avatar
John Koleszar committed
414
      d[col & 7] = v;
415

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

John Koleszar's avatar
John Koleszar committed
420
421
        kernel += pred_filter[2 + i] * pSrc[col + i];
      }
422

John Koleszar's avatar
John Koleszar committed
423
424
      d[col & 7] = (kernel >> filt_shift);
    across_skip_convolve:
425

John Koleszar's avatar
John Koleszar committed
426
427
428
      if (col >= 2)
        pDst[col - 2] = d[(col - 2) & 7];
    }
429

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

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

#endif  // CONFIG_PRED_FILTER

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

  /* 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
456
457
458
459
      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
460
461
462
463

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

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

Paul Wilkins's avatar
Paul Wilkins committed
467
468
469
470
      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
471
472
473
474

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

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

Paul Wilkins's avatar
Paul Wilkins committed
478
479
480
481
      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
482

483
      if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
Paul Wilkins's avatar
Paul Wilkins committed
484
485
486
487
        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
488
489
490
491
492

        if (temp < 0) {
          temp -= 4;
        } else {
          temp += 4;
493
494
        }

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

Paul Wilkins's avatar
Paul Wilkins committed
498
499
500
501
        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
502
503
504
505
506

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

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

Paul Wilkins's avatar
Paul Wilkins committed
512
513
514
515
        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
516
      }
John Koleszar's avatar
John Koleszar committed
517
    }
John Koleszar's avatar
John Koleszar committed
518
519
520
  }

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

    if (d0->bmi.as_mv.first.as_int == d1->bmi.as_mv.first.as_int)
Paul Wilkins's avatar
Paul Wilkins committed
525
      build_inter_predictors2b(xd, d0, 8);
John Koleszar's avatar
John Koleszar committed
526
    else {
527
528
      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
529
530
    }

531
    if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
532
533
      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
534
535
    }
  }
John Koleszar's avatar
John Koleszar committed
536
537
}

John Koleszar's avatar
John Koleszar committed
538
539
540
541
542
543
544
545
546
547
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
548
  if (mv->col < (xd->mb_to_left_edge - ((16 + VP9_INTERP_EXTEND) << 3)))
John Koleszar's avatar
John Koleszar committed
549
    mv->col = xd->mb_to_left_edge - (16 << 3);
John Koleszar's avatar
John Koleszar committed
550
  else if (mv->col > xd->mb_to_right_edge + ((15 + VP9_INTERP_EXTEND) << 3))
John Koleszar's avatar
John Koleszar committed
551
552
    mv->col = xd->mb_to_right_edge + (16 << 3);

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

/* A version of the above function for chroma block MVs.*/
John Koleszar's avatar
John Koleszar committed
560
static void clamp_uvmv_to_umv_border(MV *mv, const MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
561
562
563
  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
564
            (xd->mb_to_left_edge - (16 << 3)) >> 1 : mv->col;
John Koleszar's avatar
John Koleszar committed
565
  mv->col = (2 * mv->col > xd->mb_to_right_edge + ((15 + extend) << 3)) ?
John Koleszar's avatar
John Koleszar committed
566
567
            (xd->mb_to_right_edge + (16 << 3)) >> 1 : mv->col;

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

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

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

586
  if (clamp_mvs)
587
    clamp_mv_to_umv_border(&ymv.as_mv, xd);
588

589
  ptr = ptr_base + (ymv.as_mv.row >> 3) * pre_stride + (ymv.as_mv.col >> 3);
590
591

#if CONFIG_PRED_FILTER
592
593
  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
594
      // Sub-pel filter needs extended input
John Koleszar's avatar
John Koleszar committed
595
      int len = 15 + (VP9_INTERP_EXTEND << 1);
596
      unsigned char Temp[32 * 32]; // Data required by sub-pel filter
John Koleszar's avatar
John Koleszar committed
597
      unsigned char *pTemp = Temp + (VP9_INTERP_EXTEND - 1) * (len + 1);
598

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

603
604
605
606
607
      // 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
608
609
610
    } else {
      // Apply spatial filter to create the prediction directly
      filter_mb(ptr, pre_stride, dst_y, dst_ystride, 16, 16);
611
    }
John Koleszar's avatar
John Koleszar committed
612
  } else
613
#endif
614
615
616
617
618
    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
619
    } else {
620
      vp9_copy_mem16x16(ptr, pre_stride, dst_y, dst_ystride);
621
    }
622
623
}

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

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

Paul Wilkins's avatar
Paul Wilkins committed
636
637
  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
638

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

John Koleszar's avatar
John Koleszar committed
646
647
648
649
  if (_16x16mv.as_mv.col < 0)
    _16x16mv.as_mv.col -= 1;
  else
    _16x16mv.as_mv.col += 1;
650

John Koleszar's avatar
John Koleszar committed
651
652
  _16x16mv.as_mv.row /= 2;
  _16x16mv.as_mv.col /= 2;
653

Paul Wilkins's avatar
Paul Wilkins committed
654
655
  _16x16mv.as_mv.row &= xd->fullpixel_mask;
  _16x16mv.as_mv.col &= xd->fullpixel_mask;
656

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

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

John Koleszar's avatar
John Koleszar committed
671
672
673
674
    // 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
675
        filter_mb(pSrc - (VP9_INTERP_EXTEND - 1) * (pre_stride + 1), pre_stride,
John Koleszar's avatar
John Koleszar committed
676
677
678
                  Temp, len, len, len);

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

      // V
      pSrc = vptr;
      pDst = dst_v;
690
    }
John Koleszar's avatar
John Koleszar committed
691
  } else
692
#endif
John Koleszar's avatar
John Koleszar committed
693
    if (_o16x16mv.as_int & 0x000f000f) {
Paul Wilkins's avatar
Paul Wilkins committed
694
695
696
697
      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);
698
    } else {
699
700
      vp9_copy_mem8x8(uptr, pre_stride, dst_u, dst_uvstride);
      vp9_copy_mem8x8(vptr, pre_stride, dst_v, dst_uvstride);
701
    }
702
703
704
}


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

Ronald S. Bultje's avatar
Ronald S. Bultje committed
715
#if CONFIG_SUPERBLOCKS
716
void vp9_build_inter32x32_predictors_sb(MACROBLOCKD *x,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
717
718
719
720
721
722
723
724
                                        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;
725
  int edge[4], n;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
726

727
728
729
730
731
732
  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
733
734
    const int x_idx = n & 1, y_idx = n >> 1;

735
736
737
738
739
    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
740
741
742
743
    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;

744
    vp9_build_1st_inter16x16_predictors_mb(x,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
745
746
747
748
      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);
749
    if (x->mode_info_context->mbmi.second_ref_frame > 0) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
750
751
752
753
      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;

754
      vp9_build_2nd_inter16x16_predictors_mb(x,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
755
756
757
758
759
760
761
        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);
    }
  }

762
763
764
765
766
  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
767
768
769
770
  x->pre.y_buffer = y1;
  x->pre.u_buffer = u1;
  x->pre.v_buffer = v1;

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

#if CONFIG_COMP_INTERINTRA_PRED
  if (x->mode_info_context->mbmi.second_ref_frame == INTRA_FRAME) {
    vp9_build_interintra_32x32_predictors_sb(
        x, dst_y, dst_u, dst_v, dst_ystride, dst_uvstride);
  }
#endif
Ronald S. Bultje's avatar
Ronald S. Bultje committed
783
784
785
}
#endif

786
/*
787
 * The following functions should be called after an initial
788
 * call to vp9_build_1st_inter16x16_predictors_mb() or _mby()/_mbuv().
789
790
791
792
793
794
795
796
797
798
799
 * 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.
 */
800
void vp9_build_2nd_inter16x16_predictors_mby(MACROBLOCKD *xd,
801
802
                                             unsigned char *dst_y,
                                             int dst_ystride) {
John Koleszar's avatar
John Koleszar committed
803
  unsigned char *ptr;
804

John Koleszar's avatar
John Koleszar committed
805
806
807
  int_mv _16x16mv;
  int mv_row;
  int mv_col;
Yaowu Xu's avatar
Yaowu Xu committed
808

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

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

Paul Wilkins's avatar
Paul Wilkins committed
814
815
  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
816

John Koleszar's avatar
John Koleszar committed
817
818
  mv_row = _16x16mv.as_mv.row;
  mv_col = _16x16mv.as_mv.col;
Yaowu Xu's avatar
Yaowu Xu committed
819

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

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

John Koleszar's avatar
John Koleszar committed
830
      // Copy extended MB into Temp array, applying the spatial filter
John Koleszar's avatar
John Koleszar committed
831
      filter_mb(ptr - (VP9_INTERP_EXTEND - 1) * (pre_stride + 1), pre_stride,
John Koleszar's avatar
John Koleszar committed
832
                Temp, len, len, len);
833

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

854
void vp9_build_2nd_inter16x16_predictors_mbuv(MACROBLOCKD *xd,
855
856
857
858
859
860
861
862
863
864
865
                                              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
866
  int pre_stride = xd->block[0].pre_stride;
867

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

Paul Wilkins's avatar
Paul Wilkins committed
870
871
  if (xd->mode_info_context->mbmi.need_to_clamp_secondmv)
    clamp_mv_to_umv_border(&_16x16mv.as_mv, xd);
872
873
874

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

John Koleszar's avatar
John Koleszar committed
876
877
878
879
880
  /* 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;
881

Paul Wilkins's avatar
Paul Wilkins committed
882
883
  mv_row &= xd->fullpixel_mask;
  mv_col &= xd->fullpixel_mask;
884

John Koleszar's avatar
John Koleszar committed
885
886
  pre_stride >>= 1;
  offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
Paul Wilkins's avatar
Paul Wilkins committed
887
888
  uptr = xd->second_pre.u_buffer + offset;
  vptr = xd->second_pre.v_buffer + offset;
889

890
#if CONFIG_PRED_FILTER
Paul Wilkins's avatar
Paul Wilkins committed
891
  if (xd->mode_info_context->mbmi.pred_filter_enabled) {
John Koleszar's avatar
John Koleszar committed
892
    int i;
John Koleszar's avatar
John Koleszar committed
893
    int len = 7 + (VP9_INTERP_EXTEND << 1);
John Koleszar's avatar
John Koleszar committed
894
    unsigned char Temp[32 * 32]; // Data required by sub-pel filter
John Koleszar's avatar
John Koleszar committed
895
    unsigned char *pTemp = Temp + (VP9_INTERP_EXTEND - 1) * (len + 1);
John Koleszar's avatar
John Koleszar committed
896
897
898
899
900
901
902
    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
903
        filter_mb(pSrc - (VP9_INTERP_EXTEND - 1) * (pre_stride + 1), pre_stride,
John Koleszar's avatar
John Koleszar committed
904
905
906
                  Temp, len, len, len);

        // Sub-pel filter
Paul Wilkins's avatar
Paul Wilkins committed
907
908
        xd->subpixel_predict_avg8x8(pTemp, len, omv_col & 15,
                                    omv_row & 15, pDst, dst_uvstride);
909
      } else {
John Koleszar's avatar
John Koleszar committed
910
911
        // TODO Needs to AVERAGE with the dst_[u|v]
        // For now, do not apply the prediction filter here!
912
        vp9_avg_mem8x8(pSrc, pre_stride, pDst, dst_uvstride);
John Koleszar's avatar
John Koleszar committed
913
914
915
916
917
      }

      // V
      pSrc = vptr;
      pDst = dst_v;
918
    }
John Koleszar's avatar
John Koleszar committed
919
  } else
920
#endif  // CONFIG_PRED_FILTER
John Koleszar's avatar
John Koleszar committed
921
    if ((omv_row | omv_col) & 15) {
Paul Wilkins's avatar
Paul Wilkins committed
922
923
924
925
      xd->subpixel_predict_avg8x8(uptr, pre_stride, omv_col & 15,
                                  omv_row & 15, dst_u, dst_uvstride);
      xd->subpixel_predict_avg8x8(vptr, pre_stride, omv_col & 15,
                                  omv_row & 15, dst_v, dst_uvstride);
926
    } else {
927
928
      vp9_avg_mem8x8(uptr, pre_stride, dst_u, dst_uvstride);
      vp9_avg_mem8x8(vptr, pre_stride, dst_v, dst_uvstride);
929
930
931
    }
}

932
void vp9_build_2nd_inter16x16_predictors_mb(MACROBLOCKD *xd,
933
934
935
936
937
                                            unsigned char *dst_y,
                                            unsigned char *dst_u,
                                            unsigned char *dst_v,
                                            int dst_ystride,
                                            int dst_uvstride) {
938
939
  vp9_build_2nd_inter16x16_predictors_mby(xd, dst_y, dst_ystride);
  vp9_build_2nd_inter16x16_predictors_mbuv(xd, dst_u, dst_v, dst_uvstride);
940
941
}

Paul Wilkins's avatar
Paul Wilkins committed
942
static void build_inter4x4_predictors_mb(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
943
  int i;
Paul Wilkins's avatar
Paul Wilkins committed
944
945
946
  MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
  BLOCKD *blockd = xd->block;

947
  if (xd->mode_info_context->mbmi.partitioning != PARTITIONING_4X4) {
Paul Wilkins's avatar
Paul Wilkins committed
948
949
950
951
952
953
954
955
956
957
    blockd[ 0].bmi = xd->mode_info_context->bmi[ 0];
    blockd[ 2].bmi = xd->mode_info_context->bmi[ 2];
    blockd[ 8].bmi = xd->mode_info_context->bmi[ 8];
    blockd[10].bmi = xd->mode_info_context->bmi[10];

    if (mbmi->need_to_clamp_mvs) {
      clamp_mv_to_umv_border(&blockd[ 0].bmi.as_mv.first.as_mv, xd);
      clamp_mv_to_umv_border(&blockd[ 2].bmi.as_mv.first.as_mv, xd);
      clamp_mv_to_umv_border(&blockd[ 8].bmi.as_mv.first.as_mv, xd);
      clamp_mv_to_umv_border(&blockd[10].bmi.as_mv.first.as_mv, xd);
958
      if (mbmi->second_ref_frame > 0) {
Paul Wilkins's avatar
Paul Wilkins committed
959
960
961
962
        clamp_mv_to_umv_border(&blockd[ 0].bmi.as_mv.second.as_mv, xd);
        clamp_mv_to_umv_border(&blockd[ 2].bmi.as_mv.second.as_mv, xd);
        clamp_mv_to_umv_border(&blockd[ 8].bmi.as_mv.second.as_mv, xd);
        clamp_mv_to_umv_border(&blockd[10].bmi.as_mv.second.as_mv, xd);
John Koleszar's avatar
John Koleszar committed
963
964
      }
    }
965

966

967
968
969
970