reconinter.c 37.1 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"
John Koleszar's avatar
John Koleszar committed
14
15
16
17
18
19
20
#include "subpixel.h"
#include "blockd.h"
#include "reconinter.h"
#if CONFIG_RUNTIME_CPU_DETECT
#include "onyxc_int.h"
#endif

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
void vp8_setup_interp_filters(MACROBLOCKD *xd,
                              INTERPOLATIONFILTERTYPE mcomp_filter_type,
                              VP8_COMMON *cm) {
  if (mcomp_filter_type == SIXTAP) {
    xd->subpixel_predict        = SUBPIX_INVOKE(
        &cm->rtcd.subpix, sixtap4x4);
    xd->subpixel_predict8x4     = SUBPIX_INVOKE(
        &cm->rtcd.subpix, sixtap8x4);
    xd->subpixel_predict8x8     = SUBPIX_INVOKE(
        &cm->rtcd.subpix, sixtap8x8);
    xd->subpixel_predict16x16   = SUBPIX_INVOKE(
        &cm->rtcd.subpix, sixtap16x16);
    xd->subpixel_predict_avg    = SUBPIX_INVOKE(
        &cm->rtcd.subpix, sixtap_avg4x4);
    xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
        &cm->rtcd.subpix, sixtap_avg8x8);
    xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
        &cm->rtcd.subpix, sixtap_avg16x16);
  }
  else if (mcomp_filter_type == EIGHTTAP
#if CONFIG_SWITCHABLE_INTERP
           ||
           mcomp_filter_type == SWITCHABLE
#endif
          ) {
    xd->subpixel_predict        = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap4x4);
    xd->subpixel_predict8x4     = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap8x4);
    xd->subpixel_predict8x8     = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap8x8);
    xd->subpixel_predict16x16   = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap16x16);
    xd->subpixel_predict_avg    = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap_avg4x4);
    xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap_avg8x8);
    xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap_avg16x16);
  } else if (mcomp_filter_type == EIGHTTAP_SHARP) {
    xd->subpixel_predict        = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap4x4_sharp);
    xd->subpixel_predict8x4     = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap8x4_sharp);
    xd->subpixel_predict8x8     = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap8x8_sharp);
    xd->subpixel_predict16x16   = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap16x16_sharp);
    xd->subpixel_predict_avg    = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap_avg4x4_sharp);
    xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap_avg8x8_sharp);
    xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
        &cm->rtcd.subpix, eighttap_avg16x16_sharp);
  }
  else {
    xd->subpixel_predict        = SUBPIX_INVOKE(
        &cm->rtcd.subpix, bilinear4x4);
    xd->subpixel_predict8x4     = SUBPIX_INVOKE(
        &cm->rtcd.subpix, bilinear8x4);
    xd->subpixel_predict8x8     = SUBPIX_INVOKE(
        &cm->rtcd.subpix, bilinear8x8);
    xd->subpixel_predict16x16   = SUBPIX_INVOKE(
        &cm->rtcd.subpix, bilinear16x16);
    xd->subpixel_predict_avg    = SUBPIX_INVOKE(
        &cm->rtcd.subpix, bilinear_avg4x4);
    xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
        &cm->rtcd.subpix, bilinear_avg8x8);
    xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
        &cm->rtcd.subpix, bilinear_avg16x16);
  }
}

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

John Koleszar's avatar
John Koleszar committed
100
  int r;
John Koleszar's avatar
John Koleszar committed
101

John Koleszar's avatar
John Koleszar committed
102
  for (r = 0; r < 16; r++) {
103
#if !(CONFIG_FAST_UNALIGNED)
John Koleszar's avatar
John Koleszar committed
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    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
120
121

#else
John Koleszar's avatar
John Koleszar committed
122
123
124
125
    ((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
126
127

#endif
John Koleszar's avatar
John Koleszar committed
128
129
    src += src_stride;
    dst += dst_stride;
John Koleszar's avatar
John Koleszar committed
130

John Koleszar's avatar
John Koleszar committed
131
  }
John Koleszar's avatar
John Koleszar committed
132
133
134

}

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

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

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

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

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

  for (r = 0; r < 8; 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
    src += src_stride;
    dst += dst_stride;
John Koleszar's avatar
John Koleszar committed
177

John Koleszar's avatar
John Koleszar committed
178
  }
John Koleszar's avatar
John Koleszar committed
179
180
181

}

182
void vp8_avg_mem8x8_c(
John Koleszar's avatar
John Koleszar committed
183
184
185
186
187
  unsigned char *src,
  int src_stride,
  unsigned char *dst,
  int dst_stride) {
  int r;
188

John Koleszar's avatar
John Koleszar committed
189
190
191
192
193
  for (r = 0; r < 8; r++) {
    int n;

    for (n = 0; n < 8; n++) {
      dst[n] = (dst[n] + src[n] + 1) >> 1;
194
    }
John Koleszar's avatar
John Koleszar committed
195
196
197
198

    src += src_stride;
    dst += dst_stride;
  }
199
200
}

John Koleszar's avatar
John Koleszar committed
201
void vp8_copy_mem8x4_c(
John Koleszar's avatar
John Koleszar committed
202
203
204
205
206
207
208
  unsigned char *src,
  int src_stride,
  unsigned char *dst,
  int dst_stride) {
  int r;

  for (r = 0; r < 4; r++) {
209
#if !(CONFIG_FAST_UNALIGNED)
John Koleszar's avatar
John Koleszar committed
210
211
212
213
214
215
216
217
    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
218
#else
John Koleszar's avatar
John Koleszar committed
219
220
    ((uint32_t *)dst)[0] = ((uint32_t *)src)[0];
    ((uint32_t *)dst)[1] = ((uint32_t *)src)[1];
John Koleszar's avatar
John Koleszar committed
221
#endif
John Koleszar's avatar
John Koleszar committed
222
223
    src += src_stride;
    dst += dst_stride;
John Koleszar's avatar
John Koleszar committed
224

John Koleszar's avatar
John Koleszar committed
225
  }
John Koleszar's avatar
John Koleszar committed
226
227
228
229
230

}



John Koleszar's avatar
John Koleszar committed
231
232
233
234
235
236
void vp8_build_inter_predictors_b(BLOCKD *d, int pitch, vp8_subpix_fn_t sppf) {
  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
237

John Koleszar's avatar
John Koleszar committed
238
239
  ptr_base = *(d->base_pre);
  mv.as_int = d->bmi.as_mv.first.as_int;
John Koleszar's avatar
John Koleszar committed
240

John Koleszar's avatar
John Koleszar committed
241
242
243
244
245
246
  if (mv.as_mv.row & 7 || mv.as_mv.col & 7) {
    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);
  } else {
    ptr_base += d->pre + (mv.as_mv.row >> 3) * d->pre_stride + (mv.as_mv.col >> 3);
    ptr = ptr_base;
John Koleszar's avatar
John Koleszar committed
247

John Koleszar's avatar
John Koleszar committed
248
    for (r = 0; r < 4; r++) {
249
#if !(CONFIG_FAST_UNALIGNED)
John Koleszar's avatar
John Koleszar committed
250
251
252
253
      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
254
#else
John Koleszar's avatar
John Koleszar committed
255
      *(uint32_t *)pred_ptr = *(uint32_t *)ptr;
John Koleszar's avatar
John Koleszar committed
256
#endif
John Koleszar's avatar
John Koleszar committed
257
258
      pred_ptr     += pitch;
      ptr         += d->pre_stride;
John Koleszar's avatar
John Koleszar committed
259
    }
John Koleszar's avatar
John Koleszar committed
260
  }
John Koleszar's avatar
John Koleszar committed
261
262
}

263
264
265
266
267
268
/*
 * Similar to vp8_build_inter_predictors_b(), but instead of storing the
 * results in d->predictor, we average the contents of d->predictor (which
 * come from an earlier call to vp8_build_inter_predictors_b()) with the
 * predictor of the second reference frame / motion vector.
 */
John Koleszar's avatar
John Koleszar committed
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
void vp8_build_2nd_inter_predictors_b(BLOCKD *d, int pitch, vp8_subpix_fn_t sppf) {
  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) {
    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);
  } else {
    ptr_base += d->pre + (mv.as_mv.row >> 3) * d->pre_stride + (mv.as_mv.col >> 3);
    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;
293
    }
John Koleszar's avatar
John Koleszar committed
294
  }
295
296
}

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

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

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

316
317
318
319
320
321
/*
 * 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.
 */
Paul Wilkins's avatar
Paul Wilkins committed
322
323
static void build_2nd_inter_predictors4b(MACROBLOCKD *xd,
                                         BLOCKD *d, int pitch) {
John Koleszar's avatar
John Koleszar committed
324
325
326
327
328
329
330
  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
331
332
  ptr = ptr_base + d->pre + (mv.as_mv.row >> 3) * d->pre_stride +
        (mv.as_mv.col >> 3);
333

John Koleszar's avatar
John Koleszar committed
334
  if (mv.as_mv.row & 7 || mv.as_mv.col & 7) {
Paul Wilkins's avatar
Paul Wilkins committed
335
336
    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
337
  } else {
338
    vp8_avg_mem8x8(ptr, d->pre_stride, pred_ptr, pitch);
John Koleszar's avatar
John Koleszar committed
339
  }
340
341
}

Paul Wilkins's avatar
Paul Wilkins committed
342
static void build_inter_predictors2b(MACROBLOCKD *xd, BLOCKD *d, int pitch) {
John Koleszar's avatar
John Koleszar committed
343
344
345
346
  unsigned char *ptr_base;
  unsigned char *ptr;
  unsigned char *pred_ptr = d->predictor;
  int_mv mv;
John Koleszar's avatar
John Koleszar committed
347

John Koleszar's avatar
John Koleszar committed
348
349
  ptr_base = *(d->base_pre);
  mv.as_int = d->bmi.as_mv.first.as_int;
Paul Wilkins's avatar
Paul Wilkins committed
350
351
  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
352

John Koleszar's avatar
John Koleszar committed
353
  if (mv.as_mv.row & 7 || mv.as_mv.col & 7) {
Paul Wilkins's avatar
Paul Wilkins committed
354
355
    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
356
  } else {
357
    vp8_copy_mem8x4(ptr, d->pre_stride, pred_ptr, pitch);
John Koleszar's avatar
John Koleszar committed
358
  }
John Koleszar's avatar
John Koleszar committed
359
360
361
}


362
/*encoder only*/
363
364
365
366
367
368
369
370
371
372
373
374
375
376
#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
377
378
379
380
381
382
383
384
385
386
387
388
389
               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;
390
391
    }

John Koleszar's avatar
John Koleszar committed
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
    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);
407
    }
John Koleszar's avatar
John Koleszar committed
408
409
    ++pTmp;
  }
410
411
412
413
414
}
#else
// Based on vp8_post_proc_down_and_across_c (postproc.c)
void filter_mb(unsigned char *src, int src_stride,
               unsigned char *dst, int dst_stride,
John Koleszar's avatar
John Koleszar committed
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
               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;
    }
446

John Koleszar's avatar
John Koleszar committed
447
448
449
    /* now post_proc_across */
    pSrc = dst;
    pDst = dst;
450

John Koleszar's avatar
John Koleszar committed
451
452
    for (i = 0; i < 8; i++)
      d[i] = pSrc[i];
453

John Koleszar's avatar
John Koleszar committed
454
455
456
    for (col = 0; col < width; col++) {
      int kernel = (1 << (filt_shift - 1));
      v = pSrc[col];
457

John Koleszar's avatar
John Koleszar committed
458
      d[col & 7] = v;
459

John Koleszar's avatar
John Koleszar committed
460
461
462
      for (i = -2; i <= 2; i++) {
        if (abs(v - pSrc[col + i]) > flimit)
          goto across_skip_convolve;
463

John Koleszar's avatar
John Koleszar committed
464
465
        kernel += pred_filter[2 + i] * pSrc[col + i];
      }
466

John Koleszar's avatar
John Koleszar committed
467
468
      d[col & 7] = (kernel >> filt_shift);
    across_skip_convolve:
469

John Koleszar's avatar
John Koleszar committed
470
471
472
      if (col >= 2)
        pDst[col - 2] = d[(col - 2) & 7];
    }
473

John Koleszar's avatar
John Koleszar committed
474
475
476
    /* handle the last two pixels */
    pDst[col - 2] = d[(col - 2) & 7];
    pDst[col - 1] = d[(col - 1) & 7];
477

John Koleszar's avatar
John Koleszar committed
478
479
480
481
    /* next row */
    src += src_stride;
    dst += dst_stride;
  }
482
483
484
485
486
}
#endif  // !USE_THRESH_FILTER

#endif  // CONFIG_PRED_FILTER

487
/*encoder only*/
Paul Wilkins's avatar
Paul Wilkins committed
488
void vp8_build_inter4x4_predictors_mbuv(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
489
  int i, j;
Paul Wilkins's avatar
Paul Wilkins committed
490
  BLOCKD *blockd = xd->block;
John Koleszar's avatar
John Koleszar committed
491
492
493
494
495
496
497
498
499

  /* 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
500
501
502
503
      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
504
505
506
507

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

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

Paul Wilkins's avatar
Paul Wilkins committed
511
512
513
514
      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
515
516
517
518

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

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

Paul Wilkins's avatar
Paul Wilkins committed
522
523
524
525
      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
526

Paul Wilkins's avatar
Paul Wilkins committed
527
528
529
530
531
      if (xd->mode_info_context->mbmi.second_ref_frame) {
        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
532
533
534
535
536

        if (temp < 0) {
          temp -= 4;
        } else {
          temp += 4;
537
538
        }

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

Paul Wilkins's avatar
Paul Wilkins committed
542
543
544
545
        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
546
547
548
549
550

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

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

Paul Wilkins's avatar
Paul Wilkins committed
556
557
558
559
        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
560
      }
John Koleszar's avatar
John Koleszar committed
561
    }
John Koleszar's avatar
John Koleszar committed
562
563
564
  }

  for (i = 16; i < 24; i += 2) {
Paul Wilkins's avatar
Paul Wilkins committed
565
566
    BLOCKD *d0 = &blockd[i];
    BLOCKD *d1 = &blockd[i + 1];
John Koleszar's avatar
John Koleszar committed
567
568

    if (d0->bmi.as_mv.first.as_int == d1->bmi.as_mv.first.as_int)
Paul Wilkins's avatar
Paul Wilkins committed
569
      build_inter_predictors2b(xd, d0, 8);
John Koleszar's avatar
John Koleszar committed
570
    else {
Paul Wilkins's avatar
Paul Wilkins committed
571
572
      vp8_build_inter_predictors_b(d0, 8, xd->subpixel_predict);
      vp8_build_inter_predictors_b(d1, 8, xd->subpixel_predict);
John Koleszar's avatar
John Koleszar committed
573
574
    }

Paul Wilkins's avatar
Paul Wilkins committed
575
576
577
    if (xd->mode_info_context->mbmi.second_ref_frame) {
      vp8_build_2nd_inter_predictors_b(d0, 8, xd->subpixel_predict_avg);
      vp8_build_2nd_inter_predictors_b(d1, 8, xd->subpixel_predict_avg);
John Koleszar's avatar
John Koleszar committed
578
579
    }
  }
John Koleszar's avatar
John Koleszar committed
580
581
}

John Koleszar's avatar
John Koleszar committed
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
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.
   */
  if (mv->col < (xd->mb_to_left_edge - ((16 + INTERP_EXTEND) << 3)))
    mv->col = xd->mb_to_left_edge - (16 << 3);
  else if (mv->col > xd->mb_to_right_edge + ((15 + INTERP_EXTEND) << 3))
    mv->col = xd->mb_to_right_edge + (16 << 3);

  if (mv->row < (xd->mb_to_top_edge - ((16 + INTERP_EXTEND) << 3)))
    mv->row = xd->mb_to_top_edge - (16 << 3);
  else if (mv->row > xd->mb_to_bottom_edge + ((15 + INTERP_EXTEND) << 3))
    mv->row = xd->mb_to_bottom_edge + (16 << 3);
601
602
603
}

/* A version of the above function for chroma block MVs.*/
John Koleszar's avatar
John Koleszar committed
604
605
606
607
608
609
610
611
612
613
static void clamp_uvmv_to_umv_border(MV *mv, const MACROBLOCKD *xd) {
  mv->col = (2 * mv->col < (xd->mb_to_left_edge - ((16 + INTERP_EXTEND) << 3))) ?
            (xd->mb_to_left_edge - (16 << 3)) >> 1 : mv->col;
  mv->col = (2 * mv->col > xd->mb_to_right_edge + ((15 + INTERP_EXTEND) << 3)) ?
            (xd->mb_to_right_edge + (16 << 3)) >> 1 : mv->col;

  mv->row = (2 * mv->row < (xd->mb_to_top_edge - ((16 + INTERP_EXTEND) << 3))) ?
            (xd->mb_to_top_edge - (16 << 3)) >> 1 : mv->row;
  mv->row = (2 * mv->row > xd->mb_to_bottom_edge + ((15 + INTERP_EXTEND) << 3)) ?
            (xd->mb_to_bottom_edge + (16 << 3)) >> 1 : mv->row;
614
615
}

616
617
618
/*encoder only*/
void vp8_build_1st_inter16x16_predictors_mby(MACROBLOCKD *xd,
                                             unsigned char *dst_y,
619
620
                                             int dst_ystride,
                                             int clamp_mvs) {
621
  unsigned char *ptr_base = xd->pre.y_buffer;
John Koleszar's avatar
John Koleszar committed
622
  unsigned char *ptr;
623
624
  int pre_stride = xd->block[0].pre_stride;
  int_mv ymv;
John Koleszar's avatar
John Koleszar committed
625

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

628
  if (clamp_mvs)
629
    clamp_mv_to_umv_border(&ymv.as_mv, xd);
630

631
  ptr = ptr_base + (ymv.as_mv.row >> 3) * pre_stride + (ymv.as_mv.col >> 3);
632
633

#if CONFIG_PRED_FILTER
634
635
  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
636
      // Sub-pel filter needs extended input
637
      int len = 15 + (INTERP_EXTEND << 1);
638
      unsigned char Temp[32 * 32]; // Data required by sub-pel filter
639
      unsigned char *pTemp = Temp + (INTERP_EXTEND - 1) * (len + 1);
640

John Koleszar's avatar
John Koleszar committed
641
      // Copy extended MB into Temp array, applying the spatial filter
642
      filter_mb(ptr - (INTERP_EXTEND - 1) * (pre_stride + 1), pre_stride,
John Koleszar's avatar
John Koleszar committed
643
                Temp, len, len, len);
644

645
646
647
648
649
      // 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
650
651
652
    } else {
      // Apply spatial filter to create the prediction directly
      filter_mb(ptr, pre_stride, dst_y, dst_ystride, 16, 16);
653
    }
John Koleszar's avatar
John Koleszar committed
654
  } else
655
#endif
656
657
658
659
660
    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
661
    } else {
Jim Bankoski's avatar
Jim Bankoski committed
662
      vp8_copy_mem16x16(ptr, pre_stride, dst_y, dst_ystride);
663
    }
664
665
}

Paul Wilkins's avatar
Paul Wilkins committed
666
void vp8_build_1st_inter16x16_predictors_mbuv(MACROBLOCKD *xd,
667
668
669
670
671
                                              unsigned char *dst_u,
                                              unsigned char *dst_v,
                                              int dst_uvstride) {
  int offset;
  unsigned char *uptr, *vptr;
Paul Wilkins's avatar
Paul Wilkins committed
672
  int pre_stride = xd->block[0].pre_stride;
673
674
675
  int_mv _o16x16mv;
  int_mv _16x16mv;

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

Paul Wilkins's avatar
Paul Wilkins committed
678
679
  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
680

John Koleszar's avatar
John Koleszar committed
681
682
683
684
685
686
  _o16x16mv = _16x16mv;
  /* calc uv motion vectors */
  if (_16x16mv.as_mv.row < 0)
    _16x16mv.as_mv.row -= 1;
  else
    _16x16mv.as_mv.row += 1;
687

John Koleszar's avatar
John Koleszar committed
688
689
690
691
  if (_16x16mv.as_mv.col < 0)
    _16x16mv.as_mv.col -= 1;
  else
    _16x16mv.as_mv.col += 1;
692

John Koleszar's avatar
John Koleszar committed
693
694
  _16x16mv.as_mv.row /= 2;
  _16x16mv.as_mv.col /= 2;
695

Paul Wilkins's avatar
Paul Wilkins committed
696
697
  _16x16mv.as_mv.row &= xd->fullpixel_mask;
  _16x16mv.as_mv.col &= xd->fullpixel_mask;
698

John Koleszar's avatar
John Koleszar committed
699
700
  pre_stride >>= 1;
  offset = (_16x16mv.as_mv.row >> 3) * pre_stride + (_16x16mv.as_mv.col >> 3);
Paul Wilkins's avatar
Paul Wilkins committed
701
702
  uptr = xd->pre.u_buffer + offset;
  vptr = xd->pre.v_buffer + offset;
John Koleszar's avatar
John Koleszar committed
703

704
#if CONFIG_PRED_FILTER
Paul Wilkins's avatar
Paul Wilkins committed
705
  if (xd->mode_info_context->mbmi.pred_filter_enabled) {
John Koleszar's avatar
John Koleszar committed
706
707
708
    int i;
    unsigned char *pSrc = uptr;
    unsigned char *pDst = dst_u;
709
    int len = 7 + (INTERP_EXTEND << 1);
John Koleszar's avatar
John Koleszar committed
710
    unsigned char Temp[32 * 32]; // Data required by the sub-pel filter
711
    unsigned char *pTemp = Temp + (INTERP_EXTEND - 1) * (len + 1);
712

John Koleszar's avatar
John Koleszar committed
713
714
715
716
    // U & V
    for (i = 0; i < 2; i++) {
      if (_o16x16mv.as_int & 0x000f000f) {
        // Copy extended MB into Temp array, applying the spatial filter
717
        filter_mb(pSrc - (INTERP_EXTEND - 1) * (pre_stride + 1), pre_stride,
John Koleszar's avatar
John Koleszar committed
718
719
720
                  Temp, len, len, len);

        // Sub-pel filter
Deb Mukherjee's avatar
Deb Mukherjee committed
721
        xd->subpixel_predict8x8(pTemp, len,
722
723
724
                                _o16x16mv.as_mv.col & 15,
                                _o16x16mv.as_mv.row & 15,
                                pDst, dst_uvstride);
725
      } else {
John Koleszar's avatar
John Koleszar committed
726
727
728
729
730
731
        filter_mb(pSrc, pre_stride, pDst, dst_uvstride, 8, 8);
      }

      // V
      pSrc = vptr;
      pDst = dst_v;
732
    }
John Koleszar's avatar
John Koleszar committed
733
  } else
734
#endif
John Koleszar's avatar
John Koleszar committed
735
    if (_o16x16mv.as_int & 0x000f000f) {
Paul Wilkins's avatar
Paul Wilkins committed
736
737
738
739
      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);
740
    } else {
741
742
      vp8_copy_mem8x8(uptr, pre_stride, dst_u, dst_uvstride);
      vp8_copy_mem8x8(vptr, pre_stride, dst_v, dst_uvstride);
743
    }
744
745
746
}


Paul Wilkins's avatar
Paul Wilkins committed
747
void vp8_build_1st_inter16x16_predictors_mb(MACROBLOCKD *xd,
748
749
750
751
                                            unsigned char *dst_y,
                                            unsigned char *dst_u,
                                            unsigned char *dst_v,
                                            int dst_ystride, int dst_uvstride) {
752
753
  vp8_build_1st_inter16x16_predictors_mby(xd, dst_y, dst_ystride,
      xd->mode_info_context->mbmi.need_to_clamp_mvs);
Paul Wilkins's avatar
Paul Wilkins committed
754
  vp8_build_1st_inter16x16_predictors_mbuv(xd, dst_u, dst_v, dst_uvstride);
755
}
John Koleszar's avatar
John Koleszar committed
756

Ronald S. Bultje's avatar
Ronald S. Bultje committed
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
#if CONFIG_SUPERBLOCKS
void vp8_build_inter32x32_predictors_sb(MACROBLOCKD *x,
                                        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;
  int n;

  for (n = 0; n < 4; n++)
  {
    const int x_idx = n & 1, y_idx = n >> 1;

    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;

    vp8_build_1st_inter16x16_predictors_mb(x,
      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);
    if (x->mode_info_context->mbmi.second_ref_frame) {
      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;

      vp8_build_2nd_inter16x16_predictors_mb(x,
        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);
    }
  }

  x->pre.y_buffer = y1;
  x->pre.u_buffer = u1;
  x->pre.v_buffer = v1;

  if (x->mode_info_context->mbmi.second_ref_frame) {
    x->second_pre.y_buffer = y2;
    x->second_pre.u_buffer = u2;
    x->second_pre.v_buffer = v2;
  }
}
#endif

807
/*
808
809
 * The following functions should be called after an initial
 * call to vp8_build_inter16x16_predictors_mb() or _mby()/_mbuv().
810
811
812
813
814
815
816
817
818
819
820
 * 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.
 */
Paul Wilkins's avatar
Paul Wilkins committed
821
void vp8_build_2nd_inter16x16_predictors_mby(MACROBLOCKD *xd,
822
823
                                             unsigned char *dst_y,
                                             int dst_ystride) {
John Koleszar's avatar
John Koleszar committed
824
  unsigned char *ptr;
825

John Koleszar's avatar
John Koleszar committed
826
827
828
  int_mv _16x16mv;
  int mv_row;
  int mv_col;
Yaowu Xu's avatar
Yaowu Xu committed
829

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

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

Paul Wilkins's avatar
Paul Wilkins committed
835
836
  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
837

John Koleszar's avatar
John Koleszar committed
838
839
  mv_row = _16x16mv.as_mv.row;
  mv_col = _16x16mv.as_mv.col;
Yaowu Xu's avatar
Yaowu Xu committed
840

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

843
#if CONFIG_PRED_FILTER
Paul Wilkins's avatar
Paul Wilkins committed
844
  if (xd->mode_info_context->mbmi.pred_filter_enabled) {
John Koleszar's avatar
John Koleszar committed
845
846
    if ((mv_row | mv_col) & 7) {
      // Sub-pel filter needs extended input
847
      int len = 15 + (INTERP_EXTEND << 1);
John Koleszar's avatar
John Koleszar committed
848
      unsigned char Temp[32 * 32]; // Data required by sub-pel filter
849
      unsigned char *pTemp = Temp + (INTERP_EXTEND - 1) * (len + 1);
850

John Koleszar's avatar
John Koleszar committed
851
      // Copy extended MB into Temp array, applying the spatial filter
852
      filter_mb(ptr - (INTERP_EXTEND - 1) * (pre_stride + 1), pre_stride,
John Koleszar's avatar
John Koleszar committed
853
                Temp, len, len, len);
854

John Koleszar's avatar
John Koleszar committed
855
      // Sub-pel filter
Paul Wilkins's avatar
Paul Wilkins committed
856
857
      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
858
859
860
    } else {
      // TODO Needs to AVERAGE with the dst_y
      // For now, do not apply the prediction filter in these cases!
861
      vp8_avg_mem16x16(ptr, pre_stride, dst_y, dst_ystride);
862
    }
John Koleszar's avatar
John Koleszar committed
863
  } else
864
#endif  // CONFIG_PRED_FILTER
John Koleszar's avatar
John Koleszar committed
865
866
  {
    if ((mv_row | mv_col) & 7) {
Paul Wilkins's avatar
Paul Wilkins committed
867
868
      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
869
    } else {
870
      vp8_avg_mem16x16(ptr, pre_stride, dst_y, dst_ystride);
871
    }
John Koleszar's avatar
John Koleszar committed
872
  }
873
874
}

Paul Wilkins's avatar
Paul Wilkins committed
875
void vp8_build_2nd_inter16x16_predictors_mbuv(MACROBLOCKD *xd,
876
877
878
879
880
881
882
883
884
885
886
                                              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
887
  int pre_stride = xd->block[0].pre_stride;
888

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

Paul Wilkins's avatar
Paul Wilkins committed
891
892
  if (xd->mode_info_context->mbmi.need_to_clamp_secondmv)
    clamp_mv_to_umv_border(&_16x16mv.as_mv, xd);
893
894
895

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

John Koleszar's avatar
John Koleszar committed
897
898
899
900
901
  /* 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;
902

Paul Wilkins's avatar
Paul Wilkins committed
903
904
  mv_row &= xd->fullpixel_mask;
  mv_col &= xd->fullpixel_mask;
905

John Koleszar's avatar
John Koleszar committed
906
907
  pre_stride >>= 1;
  offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
Paul Wilkins's avatar
Paul Wilkins committed
908
909
  uptr = xd->second_pre.u_buffer + offset;
  vptr = xd->second_pre.v_buffer + offset;
910

911
#if CONFIG_PRED_FILTER
Paul Wilkins's avatar
Paul Wilkins committed
912
  if (xd->mode_info_context->mbmi.pred_filter_enabled) {
John Koleszar's avatar
John Koleszar committed
913
    int i;
914
    int len = 7 + (INTERP_EXTEND << 1);
John Koleszar's avatar
John Koleszar committed
915
    unsigned char Temp[32 * 32]; // Data required by sub-pel filter
916
    unsigned char *pTemp = Temp + (INTERP_EXTEND - 1) * (len + 1);
John Koleszar's avatar
John Koleszar committed
917
918
919
920
921
922
923
    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
924
        filter_mb(pSrc - (INTERP_EXTEND - 1) * (pre_stride + 1), pre_stride,
John Koleszar's avatar
John Koleszar committed
925
926
927
                  Temp, len, len, len);

        // Sub-pel filter
Paul Wilkins's avatar
Paul Wilkins committed
928
929
        xd->subpixel_predict_avg8x8(pTemp, len, omv_col & 15,
                                    omv_row & 15, pDst, dst_uvstride);
930
      } else {
John Koleszar's avatar
John Koleszar committed
931
932
        // TODO Needs to AVERAGE with the dst_[u|v]
        // For now, do not apply the prediction filter here!
933
        vp8_avg_mem8x8(pSrc, pre_stride, pDst, dst_uvstride);
John Koleszar's avatar
John Koleszar committed
934
935
936
937
938
      }

      // V
      pSrc = vptr;
      pDst = dst_v;
939
    }
John Koleszar's avatar
John Koleszar committed
940
  } else
941
#endif  // CONFIG_PRED_FILTER
John Koleszar's avatar
John Koleszar committed
942
    if ((omv_row | omv_col) & 15) {
Paul Wilkins's avatar
Paul Wilkins committed
943
944
945
946
      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);
947
    } else {
948
949
      vp8_avg_mem8x8(uptr, pre_stride, dst_u, dst_uvstride);
      vp8_avg_mem8x8(vptr, pre_stride, dst_v, dst_uvstride);
950
951
952
    }
}

Paul Wilkins's avatar
Paul Wilkins committed
953
void vp8_build_2nd_inter16x16_predictors_mb(MACROBLOCKD *xd,
954
955
956
957
958
                                            unsigned char *dst_y,
                                            unsigned char *dst_u,
                                            unsigned char *dst_v,
                                            int dst_ystride,
                                            int dst_uvstride) {
Paul Wilkins's avatar
Paul Wilkins committed
959
960
  vp8_build_2nd_inter16x16_predictors_mby(xd, dst_y, dst_ystride);
  vp8_build_2nd_inter16x16_predictors_mbuv(xd, dst_u, dst_v, dst_uvstride);
961
962
}

Paul Wilkins's avatar
Paul Wilkins committed
963
static void build_inter4x4_predictors_mb(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
964
  int i;
Paul Wilkins's avatar
Paul Wilkins committed
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
  MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
  BLOCKD *blockd = xd->block;

  if (xd->mode_info_context->mbmi.partitioning < 3) {
    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);
      if (mbmi->second_ref_frame) {
        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
984
985
      }
    }
986

987

Paul Wilkins's avatar
Paul Wilkins committed
988
989
990
991
    build_inter_predictors4b(xd, &blockd[ 0], 16);
    build_inter_predictors4b(xd, &blockd[ 2], 16);
    build_inter_predictors4b(xd, &blockd[ 8], 16);
    build_inter_predictors4b(xd, &blockd[10], 16);
992

Paul Wilkins's avatar
Paul Wilkins committed
993
994
995
996
997
    if (mbmi->second_ref_frame) {
      build_2nd_inter_predictors4b(xd, &blockd[ 0], 16);
      build_2nd_inter_predictors4b(xd, &blockd[ 2], 16);
      build_2nd_inter_predictors4b(xd, &blockd[ 8], 16);
      build_2nd_inter_predictors4b(xd, &blockd[10], 16);
998
    }
John Koleszar's avatar
John Koleszar committed
999
1000
  } else {
    for (i = 0; i < 16; i += 2) {
Paul Wilkins's avatar
Paul Wilkins committed
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
      BLOCKD *d0 = &blockd[i];
      BLOCKD *d1 = &blockd[i + 1];

      blockd[i + 0].bmi = xd->mode_info_context->bmi[i + 0];
      blockd[i + 1].bmi = xd->mode_info_context->bmi[i + 1];

      if (mbmi->need_to_clamp_mvs) {
        clamp_mv_to_umv_border(&blockd[i + 0].bmi.as_mv.first.as_mv, xd);
        clamp_mv_to_umv_border(&blockd[i + 1].bmi.as_mv.first.as_mv, xd);
        if (mbmi->second_ref_frame) {
          clamp_mv_to_umv_border(&blockd[i + 0].bmi.as_mv.second.as_mv, xd);
          clamp_mv_to_umv_border(&blockd[i + 1].bmi.as_mv.second.as_mv, xd);
John Koleszar's avatar
John Koleszar committed
1013
        }
John Koleszar's avatar
John Koleszar committed
1014
1015
1016
      }

      if (d0->bmi.as_mv.first.as_int == d1->bmi.as_mv.first.as_int)
Paul Wilkins's avatar
Paul Wilkins committed
1017
        build_inter_predictors2b(xd, d0, 16);
John Koleszar's avatar
John Koleszar committed
1018
      else {
Paul Wilkins's avatar
Paul Wilkins committed
1019
1020
        vp8_build_inter_predictors_b(d0, 16, xd->subpixel_predict);
        vp8_build_inter_predictors_b(d1, 16, xd->subpixel_predict);
John Koleszar's avatar
John Koleszar committed
1021
1022
      }

Paul Wilkins's avatar
Paul Wilkins committed
1023
1024
1025
      if (mbmi->second_ref_frame) {
        vp8_build_2nd_inter_predictors_b(d0, 16, xd->subpixel_predict_avg);
        vp8_build_2nd_inter_predictors_b(d1, 16, xd->subpixel_predict_avg);
John Koleszar's avatar
John Koleszar committed
1026
      }
John Koleszar's avatar
John Koleszar committed
1027
    }
John Koleszar's avatar
John Koleszar committed
1028
  }
1029

John Koleszar's avatar
John Koleszar committed
1030
  for (i = 16; i < 24; i += 2) {
Paul Wilkins's avatar
Paul Wilkins committed
1031
1032
    BLOCKD *d0 = &blockd[i];
    BLOCKD *d1 = &blockd[i + 1];
1033

John Koleszar's avatar
John Koleszar committed
1034
    if (d0->bmi.as_mv.first.as_int == d1->bmi.as_mv.first.as_int)
Paul Wilkins's avatar
Paul Wilkins committed
1035
      build_inter_predictors2b(xd, d0, 8);
John Koleszar's avatar
John Koleszar committed
1036
    else {
Paul Wilkins's avatar
Paul Wilkins committed
1037
1038
      vp8_build_inter_predictors_b(d0, 8, xd->subpixel_predict);
      vp8_build_inter_predictors_b(d1, 8, xd->subpixel_predict);
1039
    }
John Koleszar's avatar
John Koleszar committed
1040

Paul Wilkins's avatar
Paul Wilkins committed
1041
1042
1043
    if (mbmi->second_ref_frame) {
      vp8_build_2nd_inter_predictors_b(d0, 8, xd->subpixel_predict_avg);
      vp8_build_2nd_inter_predictors_b(d1, 8, xd->subpixel_predict_avg);
John Koleszar's avatar
John Koleszar committed
1044
1045
    }
  }
1046
1047
}

1048
static
Paul Wilkins's avatar
Paul Wilkins committed
1049
void build_4x4uvmvs(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
1050
  int i, j;
Paul Wilkins's avatar
Paul Wilkins committed
1051
  BLOCKD *blockd = xd->block;
John Koleszar's avatar
John Koleszar committed
1052
1053
1054
1055
1056
1057
1058
1059
1060

  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
1061
1062
1063
1064
      temp = xd->mode_info_context->bmi[yoffset + 0].as_mv.first.as_mv.row
             + xd->mode_info_context->bmi[yoffset + 1].as_mv.first.as_mv.row
             + xd->mode_info_context->bmi[yoffset + 4].as_mv.first.as_mv.row
             + xd->mode_info_context->bmi[yoffset + 5].as_mv.first.as_mv.row;
John Koleszar's avatar
John Koleszar committed
1065
1066
1067
1068

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

Paul Wilkins's avatar
Paul Wilkins committed
1069
1070
      blockd[uoffset].bmi.as_mv.first.as_mv.row = (temp / 8) &
                                                  xd->fullpixel_mask;
John Koleszar's avatar
John Koleszar committed
1071

Paul Wilkins's avatar
Paul Wilkins committed
1072
1073
1074
1075
      temp = xd->mode_info_context->bmi[yoffset + 0].as_mv.first.as_mv.col
             + xd->mode_info_context->bmi[yoffset + 1].as_mv.first.as_mv.col
             + xd->mode_info_context->bmi[yoffset + 4].as_mv.first.as_mv.col
             + xd->mode_info_context->bmi[yoffset + 5].as_mv.first.as_mv.col;
John Koleszar's avatar
John Koleszar committed
1076
1077
1078
1079

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

Paul Wilkins's avatar
Paul Wilkins committed
1080
1081
      blockd[uoffset].bmi.as_mv.first.as_mv.col = (temp / 8) &
        xd->fullpixel_mask;