Merge "Skip computation of distortion in vp8_pick_inter_mode if active_map is used"
[libvpx.git] / vp8 / common / reconinter.c
blob064a8355ce3c47b61135a6b1fbb62676fb45abff
1 /*
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
12 #include "vpx_ports/config.h"
13 #include "vpx/vpx_integer.h"
14 #include "recon.h"
15 #include "subpixel.h"
16 #include "blockd.h"
17 #include "reconinter.h"
18 #if CONFIG_RUNTIME_CPU_DETECT
19 #include "onyxc_int.h"
20 #endif
22 void vp8_copy_mem16x16_c(
23 unsigned char *src,
24 int src_stride,
25 unsigned char *dst,
26 int dst_stride)
29 int r;
31 for (r = 0; r < 16; r++)
33 #if !(CONFIG_FAST_UNALIGNED)
34 dst[0] = src[0];
35 dst[1] = src[1];
36 dst[2] = src[2];
37 dst[3] = src[3];
38 dst[4] = src[4];
39 dst[5] = src[5];
40 dst[6] = src[6];
41 dst[7] = src[7];
42 dst[8] = src[8];
43 dst[9] = src[9];
44 dst[10] = src[10];
45 dst[11] = src[11];
46 dst[12] = src[12];
47 dst[13] = src[13];
48 dst[14] = src[14];
49 dst[15] = src[15];
51 #else
52 ((uint32_t *)dst)[0] = ((uint32_t *)src)[0] ;
53 ((uint32_t *)dst)[1] = ((uint32_t *)src)[1] ;
54 ((uint32_t *)dst)[2] = ((uint32_t *)src)[2] ;
55 ((uint32_t *)dst)[3] = ((uint32_t *)src)[3] ;
57 #endif
58 src += src_stride;
59 dst += dst_stride;
65 void vp8_copy_mem8x8_c(
66 unsigned char *src,
67 int src_stride,
68 unsigned char *dst,
69 int dst_stride)
71 int r;
73 for (r = 0; r < 8; r++)
75 #if !(CONFIG_FAST_UNALIGNED)
76 dst[0] = src[0];
77 dst[1] = src[1];
78 dst[2] = src[2];
79 dst[3] = src[3];
80 dst[4] = src[4];
81 dst[5] = src[5];
82 dst[6] = src[6];
83 dst[7] = src[7];
84 #else
85 ((uint32_t *)dst)[0] = ((uint32_t *)src)[0] ;
86 ((uint32_t *)dst)[1] = ((uint32_t *)src)[1] ;
87 #endif
88 src += src_stride;
89 dst += dst_stride;
95 void vp8_copy_mem8x4_c(
96 unsigned char *src,
97 int src_stride,
98 unsigned char *dst,
99 int dst_stride)
101 int r;
103 for (r = 0; r < 4; r++)
105 #if !(CONFIG_FAST_UNALIGNED)
106 dst[0] = src[0];
107 dst[1] = src[1];
108 dst[2] = src[2];
109 dst[3] = src[3];
110 dst[4] = src[4];
111 dst[5] = src[5];
112 dst[6] = src[6];
113 dst[7] = src[7];
114 #else
115 ((uint32_t *)dst)[0] = ((uint32_t *)src)[0] ;
116 ((uint32_t *)dst)[1] = ((uint32_t *)src)[1] ;
117 #endif
118 src += src_stride;
119 dst += dst_stride;
127 void vp8_build_inter_predictors_b(BLOCKD *d, int pitch, vp8_subpix_fn_t sppf)
129 int r;
130 unsigned char *ptr_base;
131 unsigned char *ptr;
132 unsigned char *pred_ptr = d->predictor;
134 ptr_base = *(d->base_pre);
136 if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
138 ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
139 sppf(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
141 else
143 ptr_base += d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
144 ptr = ptr_base;
146 for (r = 0; r < 4; r++)
148 #if !(CONFIG_FAST_UNALIGNED)
149 pred_ptr[0] = ptr[0];
150 pred_ptr[1] = ptr[1];
151 pred_ptr[2] = ptr[2];
152 pred_ptr[3] = ptr[3];
153 #else
154 *(uint32_t *)pred_ptr = *(uint32_t *)ptr ;
155 #endif
156 pred_ptr += pitch;
157 ptr += d->pre_stride;
162 static void build_inter_predictors4b(MACROBLOCKD *x, BLOCKD *d, int pitch)
164 unsigned char *ptr_base;
165 unsigned char *ptr;
166 unsigned char *pred_ptr = d->predictor;
168 ptr_base = *(d->base_pre);
169 ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
171 if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
173 x->subpixel_predict8x8(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
175 else
177 RECON_INVOKE(&x->rtcd->recon, copy8x8)(ptr, d->pre_stride, pred_ptr, pitch);
181 static void build_inter_predictors2b(MACROBLOCKD *x, BLOCKD *d, int pitch)
183 unsigned char *ptr_base;
184 unsigned char *ptr;
185 unsigned char *pred_ptr = d->predictor;
187 ptr_base = *(d->base_pre);
188 ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
190 if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
192 x->subpixel_predict8x4(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
194 else
196 RECON_INVOKE(&x->rtcd->recon, copy8x4)(ptr, d->pre_stride, pred_ptr, pitch);
201 /*encoder only*/
202 void vp8_build_inter16x16_predictors_mbuv(MACROBLOCKD *x)
204 unsigned char *uptr, *vptr;
205 unsigned char *upred_ptr = &x->predictor[256];
206 unsigned char *vpred_ptr = &x->predictor[320];
208 int mv_row = x->mode_info_context->mbmi.mv.as_mv.row;
209 int mv_col = x->mode_info_context->mbmi.mv.as_mv.col;
210 int offset;
211 int pre_stride = x->block[16].pre_stride;
213 /* calc uv motion vectors */
214 if (mv_row < 0)
215 mv_row -= 1;
216 else
217 mv_row += 1;
219 if (mv_col < 0)
220 mv_col -= 1;
221 else
222 mv_col += 1;
224 mv_row /= 2;
225 mv_col /= 2;
227 mv_row &= x->fullpixel_mask;
228 mv_col &= x->fullpixel_mask;
230 offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
231 uptr = x->pre.u_buffer + offset;
232 vptr = x->pre.v_buffer + offset;
234 if ((mv_row | mv_col) & 7)
236 x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, 8);
237 x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, 8);
239 else
241 RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, upred_ptr, 8);
242 RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, pre_stride, vpred_ptr, 8);
246 /*encoder only*/
247 void vp8_build_inter4x4_predictors_mbuv(MACROBLOCKD *x)
249 int i, j;
251 /* build uv mvs */
252 for (i = 0; i < 2; i++)
254 for (j = 0; j < 2; j++)
256 int yoffset = i * 8 + j * 2;
257 int uoffset = 16 + i * 2 + j;
258 int voffset = 20 + i * 2 + j;
260 int temp;
262 temp = x->block[yoffset ].bmi.mv.as_mv.row
263 + x->block[yoffset+1].bmi.mv.as_mv.row
264 + x->block[yoffset+4].bmi.mv.as_mv.row
265 + x->block[yoffset+5].bmi.mv.as_mv.row;
267 if (temp < 0) temp -= 4;
268 else temp += 4;
270 x->block[uoffset].bmi.mv.as_mv.row = (temp / 8) & x->fullpixel_mask;
272 temp = x->block[yoffset ].bmi.mv.as_mv.col
273 + x->block[yoffset+1].bmi.mv.as_mv.col
274 + x->block[yoffset+4].bmi.mv.as_mv.col
275 + x->block[yoffset+5].bmi.mv.as_mv.col;
277 if (temp < 0) temp -= 4;
278 else temp += 4;
280 x->block[uoffset].bmi.mv.as_mv.col = (temp / 8) & x->fullpixel_mask;
282 x->block[voffset].bmi.mv.as_mv.row =
283 x->block[uoffset].bmi.mv.as_mv.row ;
284 x->block[voffset].bmi.mv.as_mv.col =
285 x->block[uoffset].bmi.mv.as_mv.col ;
289 for (i = 16; i < 24; i += 2)
291 BLOCKD *d0 = &x->block[i];
292 BLOCKD *d1 = &x->block[i+1];
294 if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
295 build_inter_predictors2b(x, d0, 8);
296 else
298 vp8_build_inter_predictors_b(d0, 8, x->subpixel_predict);
299 vp8_build_inter_predictors_b(d1, 8, x->subpixel_predict);
305 /*encoder only*/
306 void vp8_build_inter16x16_predictors_mby(MACROBLOCKD *x)
308 unsigned char *ptr_base;
309 unsigned char *ptr;
310 unsigned char *pred_ptr = x->predictor;
311 int mv_row = x->mode_info_context->mbmi.mv.as_mv.row;
312 int mv_col = x->mode_info_context->mbmi.mv.as_mv.col;
313 int pre_stride = x->block[0].pre_stride;
315 ptr_base = x->pre.y_buffer;
316 ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
318 if ((mv_row | mv_col) & 7)
320 x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, pred_ptr, 16);
322 else
324 RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, pred_ptr, 16);
328 void vp8_build_inter16x16_predictors_mb(MACROBLOCKD *x,
329 unsigned char *dst_y,
330 unsigned char *dst_u,
331 unsigned char *dst_v,
332 int dst_ystride,
333 int dst_uvstride)
335 int offset;
336 unsigned char *ptr;
337 unsigned char *uptr, *vptr;
339 int mv_row = x->mode_info_context->mbmi.mv.as_mv.row;
340 int mv_col = x->mode_info_context->mbmi.mv.as_mv.col;
342 unsigned char *ptr_base = x->pre.y_buffer;
343 int pre_stride = x->block[0].pre_stride;
345 ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
347 if ((mv_row | mv_col) & 7)
349 x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, dst_y, dst_ystride);
351 else
353 RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, dst_y, dst_ystride);
356 /* calc uv motion vectors */
357 if (mv_row < 0)
358 mv_row -= 1;
359 else
360 mv_row += 1;
362 if (mv_col < 0)
363 mv_col -= 1;
364 else
365 mv_col += 1;
367 mv_row /= 2;
368 mv_col /= 2;
370 mv_row &= x->fullpixel_mask;
371 mv_col &= x->fullpixel_mask;
373 pre_stride >>= 1;
374 offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
375 uptr = x->pre.u_buffer + offset;
376 vptr = x->pre.v_buffer + offset;
378 if ((mv_row | mv_col) & 7)
380 x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, dst_u, dst_uvstride);
381 x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, dst_v, dst_uvstride);
383 else
385 RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, dst_u, dst_uvstride);
386 RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, pre_stride, dst_v, dst_uvstride);
391 static void build_inter4x4_predictors_mb(MACROBLOCKD *x)
393 int i;
395 if (x->mode_info_context->mbmi.partitioning < 3)
397 x->block[ 0].bmi = x->mode_info_context->bmi[ 0];
398 x->block[ 2].bmi = x->mode_info_context->bmi[ 2];
399 x->block[ 8].bmi = x->mode_info_context->bmi[ 8];
400 x->block[10].bmi = x->mode_info_context->bmi[10];
402 build_inter_predictors4b(x, &x->block[ 0], 16);
403 build_inter_predictors4b(x, &x->block[ 2], 16);
404 build_inter_predictors4b(x, &x->block[ 8], 16);
405 build_inter_predictors4b(x, &x->block[10], 16);
407 else
409 for (i = 0; i < 16; i += 2)
411 BLOCKD *d0 = &x->block[i];
412 BLOCKD *d1 = &x->block[i+1];
414 x->block[i+0].bmi = x->mode_info_context->bmi[i+0];
415 x->block[i+1].bmi = x->mode_info_context->bmi[i+1];
417 if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
418 build_inter_predictors2b(x, d0, 16);
419 else
421 vp8_build_inter_predictors_b(d0, 16, x->subpixel_predict);
422 vp8_build_inter_predictors_b(d1, 16, x->subpixel_predict);
429 for (i = 16; i < 24; i += 2)
431 BLOCKD *d0 = &x->block[i];
432 BLOCKD *d1 = &x->block[i+1];
434 if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
435 build_inter_predictors2b(x, d0, 8);
436 else
438 vp8_build_inter_predictors_b(d0, 8, x->subpixel_predict);
439 vp8_build_inter_predictors_b(d1, 8, x->subpixel_predict);
444 static
445 void build_4x4uvmvs(MACROBLOCKD *x)
447 int i, j;
449 for (i = 0; i < 2; i++)
451 for (j = 0; j < 2; j++)
453 int yoffset = i * 8 + j * 2;
454 int uoffset = 16 + i * 2 + j;
455 int voffset = 20 + i * 2 + j;
457 int temp;
459 temp = x->mode_info_context->bmi[yoffset + 0].mv.as_mv.row
460 + x->mode_info_context->bmi[yoffset + 1].mv.as_mv.row
461 + x->mode_info_context->bmi[yoffset + 4].mv.as_mv.row
462 + x->mode_info_context->bmi[yoffset + 5].mv.as_mv.row;
464 if (temp < 0) temp -= 4;
465 else temp += 4;
467 x->block[uoffset].bmi.mv.as_mv.row = (temp / 8) & x->fullpixel_mask;
469 temp = x->mode_info_context->bmi[yoffset + 0].mv.as_mv.col
470 + x->mode_info_context->bmi[yoffset + 1].mv.as_mv.col
471 + x->mode_info_context->bmi[yoffset + 4].mv.as_mv.col
472 + x->mode_info_context->bmi[yoffset + 5].mv.as_mv.col;
474 if (temp < 0) temp -= 4;
475 else temp += 4;
477 x->block[uoffset].bmi.mv.as_mv.col = (temp / 8) & x->fullpixel_mask;
479 x->block[voffset].bmi.mv.as_mv.row =
480 x->block[uoffset].bmi.mv.as_mv.row ;
481 x->block[voffset].bmi.mv.as_mv.col =
482 x->block[uoffset].bmi.mv.as_mv.col ;
487 void vp8_build_inter_predictors_mb(MACROBLOCKD *x)
489 if (x->mode_info_context->mbmi.mode != SPLITMV)
491 vp8_build_inter16x16_predictors_mb(x, x->predictor, &x->predictor[256],
492 &x->predictor[320], 16, 8);
494 else
496 build_4x4uvmvs(x);
497 build_inter4x4_predictors_mb(x);