1 : /*
2 : * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 :
12 : #include "vpx_ports/config.h"
13 : #include "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
21 :
22 : static const int bbb[4] = {0, 2, 8, 10};
23 :
24 :
25 :
26 0 : void vp8_copy_mem16x16_c(
27 : unsigned char *src,
28 : int src_stride,
29 : unsigned char *dst,
30 : int dst_stride)
31 : {
32 :
33 : int r;
34 :
35 0 : for (r = 0; r < 16; r++)
36 : {
37 : #if !(CONFIG_FAST_UNALIGNED)
38 : dst[0] = src[0];
39 : dst[1] = src[1];
40 : dst[2] = src[2];
41 : dst[3] = src[3];
42 : dst[4] = src[4];
43 : dst[5] = src[5];
44 : dst[6] = src[6];
45 : dst[7] = src[7];
46 : dst[8] = src[8];
47 : dst[9] = src[9];
48 : dst[10] = src[10];
49 : dst[11] = src[11];
50 : dst[12] = src[12];
51 : dst[13] = src[13];
52 : dst[14] = src[14];
53 : dst[15] = src[15];
54 :
55 : #else
56 0 : ((uint32_t *)dst)[0] = ((uint32_t *)src)[0] ;
57 0 : ((uint32_t *)dst)[1] = ((uint32_t *)src)[1] ;
58 0 : ((uint32_t *)dst)[2] = ((uint32_t *)src)[2] ;
59 0 : ((uint32_t *)dst)[3] = ((uint32_t *)src)[3] ;
60 :
61 : #endif
62 0 : src += src_stride;
63 0 : dst += dst_stride;
64 :
65 : }
66 :
67 0 : }
68 :
69 0 : void vp8_copy_mem8x8_c(
70 : unsigned char *src,
71 : int src_stride,
72 : unsigned char *dst,
73 : int dst_stride)
74 : {
75 : int r;
76 :
77 0 : for (r = 0; r < 8; r++)
78 : {
79 : #if !(CONFIG_FAST_UNALIGNED)
80 : dst[0] = src[0];
81 : dst[1] = src[1];
82 : dst[2] = src[2];
83 : dst[3] = src[3];
84 : dst[4] = src[4];
85 : dst[5] = src[5];
86 : dst[6] = src[6];
87 : dst[7] = src[7];
88 : #else
89 0 : ((uint32_t *)dst)[0] = ((uint32_t *)src)[0] ;
90 0 : ((uint32_t *)dst)[1] = ((uint32_t *)src)[1] ;
91 : #endif
92 0 : src += src_stride;
93 0 : dst += dst_stride;
94 :
95 : }
96 :
97 0 : }
98 :
99 0 : void vp8_copy_mem8x4_c(
100 : unsigned char *src,
101 : int src_stride,
102 : unsigned char *dst,
103 : int dst_stride)
104 : {
105 : int r;
106 :
107 0 : for (r = 0; r < 4; r++)
108 : {
109 : #if !(CONFIG_FAST_UNALIGNED)
110 : dst[0] = src[0];
111 : dst[1] = src[1];
112 : dst[2] = src[2];
113 : dst[3] = src[3];
114 : dst[4] = src[4];
115 : dst[5] = src[5];
116 : dst[6] = src[6];
117 : dst[7] = src[7];
118 : #else
119 0 : ((uint32_t *)dst)[0] = ((uint32_t *)src)[0] ;
120 0 : ((uint32_t *)dst)[1] = ((uint32_t *)src)[1] ;
121 : #endif
122 0 : src += src_stride;
123 0 : dst += dst_stride;
124 :
125 : }
126 :
127 0 : }
128 :
129 :
130 :
131 0 : void vp8_build_inter_predictors_b(BLOCKD *d, int pitch, vp8_subpix_fn_t sppf)
132 : {
133 : int r;
134 : unsigned char *ptr_base;
135 : unsigned char *ptr;
136 0 : unsigned char *pred_ptr = d->predictor;
137 :
138 0 : ptr_base = *(d->base_pre);
139 :
140 0 : if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
141 : {
142 0 : ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
143 0 : sppf(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
144 : }
145 : else
146 : {
147 0 : ptr_base += d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
148 0 : ptr = ptr_base;
149 :
150 0 : for (r = 0; r < 4; r++)
151 : {
152 : #if !(CONFIG_FAST_UNALIGNED)
153 : pred_ptr[0] = ptr[0];
154 : pred_ptr[1] = ptr[1];
155 : pred_ptr[2] = ptr[2];
156 : pred_ptr[3] = ptr[3];
157 : #else
158 0 : *(uint32_t *)pred_ptr = *(uint32_t *)ptr ;
159 : #endif
160 0 : pred_ptr += pitch;
161 0 : ptr += d->pre_stride;
162 : }
163 : }
164 0 : }
165 :
166 0 : static void build_inter_predictors4b(MACROBLOCKD *x, BLOCKD *d, int pitch)
167 : {
168 : unsigned char *ptr_base;
169 : unsigned char *ptr;
170 0 : unsigned char *pred_ptr = d->predictor;
171 :
172 0 : ptr_base = *(d->base_pre);
173 0 : ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
174 :
175 0 : if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
176 : {
177 0 : x->subpixel_predict8x8(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
178 : }
179 : else
180 : {
181 0 : RECON_INVOKE(&x->rtcd->recon, copy8x8)(ptr, d->pre_stride, pred_ptr, pitch);
182 : }
183 0 : }
184 :
185 0 : static void build_inter_predictors2b(MACROBLOCKD *x, BLOCKD *d, int pitch)
186 : {
187 : unsigned char *ptr_base;
188 : unsigned char *ptr;
189 0 : unsigned char *pred_ptr = d->predictor;
190 :
191 0 : ptr_base = *(d->base_pre);
192 0 : ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
193 :
194 0 : if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
195 : {
196 0 : x->subpixel_predict8x4(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
197 : }
198 : else
199 : {
200 0 : RECON_INVOKE(&x->rtcd->recon, copy8x4)(ptr, d->pre_stride, pred_ptr, pitch);
201 : }
202 0 : }
203 :
204 :
205 : /*encoder only*/
206 0 : void vp8_build_inter_predictors_mbuv(MACROBLOCKD *x)
207 : {
208 : int i;
209 :
210 0 : if (x->mode_info_context->mbmi.mode != SPLITMV)
211 : {
212 : unsigned char *uptr, *vptr;
213 0 : unsigned char *upred_ptr = &x->predictor[256];
214 0 : unsigned char *vpred_ptr = &x->predictor[320];
215 :
216 0 : int mv_row = x->block[16].bmi.mv.as_mv.row;
217 0 : int mv_col = x->block[16].bmi.mv.as_mv.col;
218 : int offset;
219 0 : int pre_stride = x->block[16].pre_stride;
220 :
221 0 : offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
222 0 : uptr = x->pre.u_buffer + offset;
223 0 : vptr = x->pre.v_buffer + offset;
224 :
225 0 : if ((mv_row | mv_col) & 7)
226 : {
227 0 : x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, 8);
228 0 : x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, 8);
229 : }
230 : else
231 : {
232 0 : RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, upred_ptr, 8);
233 0 : RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, pre_stride, vpred_ptr, 8);
234 : }
235 : }
236 : else
237 : {
238 0 : for (i = 16; i < 24; i += 2)
239 : {
240 0 : BLOCKD *d0 = &x->block[i];
241 0 : BLOCKD *d1 = &x->block[i+1];
242 :
243 0 : if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
244 0 : build_inter_predictors2b(x, d0, 8);
245 : else
246 : {
247 0 : vp8_build_inter_predictors_b(d0, 8, x->subpixel_predict);
248 0 : vp8_build_inter_predictors_b(d1, 8, x->subpixel_predict);
249 : }
250 : }
251 : }
252 0 : }
253 :
254 : /*encoder only*/
255 0 : void vp8_build_inter16x16_predictors_mby(MACROBLOCKD *x)
256 : {
257 : unsigned char *ptr_base;
258 : unsigned char *ptr;
259 0 : unsigned char *pred_ptr = x->predictor;
260 0 : int mv_row = x->mode_info_context->mbmi.mv.as_mv.row;
261 0 : int mv_col = x->mode_info_context->mbmi.mv.as_mv.col;
262 0 : int pre_stride = x->block[0].pre_stride;
263 :
264 0 : ptr_base = x->pre.y_buffer;
265 0 : ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
266 :
267 0 : if ((mv_row | mv_col) & 7)
268 : {
269 0 : x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, pred_ptr, 16);
270 : }
271 : else
272 : {
273 0 : RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, pred_ptr, 16);
274 : }
275 0 : }
276 :
277 0 : void vp8_build_inter16x16_predictors_mb(MACROBLOCKD *x,
278 : unsigned char *dst_y,
279 : unsigned char *dst_u,
280 : unsigned char *dst_v,
281 : int dst_ystride,
282 : int dst_uvstride)
283 : {
284 : int offset;
285 : unsigned char *ptr;
286 : unsigned char *uptr, *vptr;
287 :
288 0 : int mv_row = x->mode_info_context->mbmi.mv.as_mv.row;
289 0 : int mv_col = x->mode_info_context->mbmi.mv.as_mv.col;
290 :
291 0 : unsigned char *ptr_base = x->pre.y_buffer;
292 0 : int pre_stride = x->block[0].pre_stride;
293 :
294 0 : ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
295 :
296 0 : if ((mv_row | mv_col) & 7)
297 : {
298 0 : x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, dst_y, dst_ystride);
299 : }
300 : else
301 : {
302 0 : RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, dst_y, dst_ystride);
303 : }
304 :
305 0 : mv_row = x->block[16].bmi.mv.as_mv.row;
306 0 : mv_col = x->block[16].bmi.mv.as_mv.col;
307 0 : pre_stride >>= 1;
308 0 : offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
309 0 : uptr = x->pre.u_buffer + offset;
310 0 : vptr = x->pre.v_buffer + offset;
311 :
312 0 : if ((mv_row | mv_col) & 7)
313 : {
314 0 : x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, dst_u, dst_uvstride);
315 0 : x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, dst_v, dst_uvstride);
316 : }
317 : else
318 : {
319 0 : RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, dst_u, dst_uvstride);
320 0 : RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, pre_stride, dst_v, dst_uvstride);
321 : }
322 :
323 0 : }
324 :
325 0 : void vp8_build_inter4x4_predictors_mb(MACROBLOCKD *x)
326 : {
327 : int i;
328 :
329 0 : if (x->mode_info_context->mbmi.partitioning < 3)
330 : {
331 0 : for (i = 0; i < 4; i++)
332 : {
333 0 : BLOCKD *d = &x->block[bbb[i]];
334 0 : build_inter_predictors4b(x, d, 16);
335 : }
336 : }
337 : else
338 : {
339 0 : for (i = 0; i < 16; i += 2)
340 : {
341 0 : BLOCKD *d0 = &x->block[i];
342 0 : BLOCKD *d1 = &x->block[i+1];
343 :
344 0 : if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
345 0 : build_inter_predictors2b(x, d0, 16);
346 : else
347 : {
348 0 : vp8_build_inter_predictors_b(d0, 16, x->subpixel_predict);
349 0 : vp8_build_inter_predictors_b(d1, 16, x->subpixel_predict);
350 : }
351 :
352 : }
353 :
354 : }
355 :
356 0 : for (i = 16; i < 24; i += 2)
357 : {
358 0 : BLOCKD *d0 = &x->block[i];
359 0 : BLOCKD *d1 = &x->block[i+1];
360 :
361 0 : if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
362 0 : build_inter_predictors2b(x, d0, 8);
363 : else
364 : {
365 0 : vp8_build_inter_predictors_b(d0, 8, x->subpixel_predict);
366 0 : vp8_build_inter_predictors_b(d1, 8, x->subpixel_predict);
367 : }
368 : }
369 0 : }
370 :
371 0 : void vp8_build_inter_predictors_mb(MACROBLOCKD *x)
372 : {
373 0 : if (x->mode_info_context->mbmi.mode != SPLITMV)
374 : {
375 0 : vp8_build_inter16x16_predictors_mb(x, x->predictor, &x->predictor[256],
376 : &x->predictor[320], 16, 8);
377 : }
378 : else
379 : {
380 0 : vp8_build_inter4x4_predictors_mb(x);
381 : }
382 0 : }
383 :
384 0 : void vp8_build_uvmvs(MACROBLOCKD *x, int fullpixel)
385 : {
386 : int i, j;
387 :
388 0 : if (x->mode_info_context->mbmi.mode == SPLITMV)
389 : {
390 0 : for (i = 0; i < 2; i++)
391 : {
392 0 : for (j = 0; j < 2; j++)
393 : {
394 0 : int yoffset = i * 8 + j * 2;
395 0 : int uoffset = 16 + i * 2 + j;
396 0 : int voffset = 20 + i * 2 + j;
397 :
398 : int temp;
399 :
400 0 : temp = x->block[yoffset ].bmi.mv.as_mv.row
401 0 : + x->block[yoffset+1].bmi.mv.as_mv.row
402 0 : + x->block[yoffset+4].bmi.mv.as_mv.row
403 0 : + x->block[yoffset+5].bmi.mv.as_mv.row;
404 :
405 0 : if (temp < 0) temp -= 4;
406 0 : else temp += 4;
407 :
408 0 : x->block[uoffset].bmi.mv.as_mv.row = temp / 8;
409 :
410 0 : if (fullpixel)
411 0 : x->block[uoffset].bmi.mv.as_mv.row = (temp / 8) & 0xfffffff8;
412 :
413 0 : temp = x->block[yoffset ].bmi.mv.as_mv.col
414 0 : + x->block[yoffset+1].bmi.mv.as_mv.col
415 0 : + x->block[yoffset+4].bmi.mv.as_mv.col
416 0 : + x->block[yoffset+5].bmi.mv.as_mv.col;
417 :
418 0 : if (temp < 0) temp -= 4;
419 0 : else temp += 4;
420 :
421 0 : x->block[uoffset].bmi.mv.as_mv.col = temp / 8;
422 :
423 0 : if (fullpixel)
424 0 : x->block[uoffset].bmi.mv.as_mv.col = (temp / 8) & 0xfffffff8;
425 :
426 0 : x->block[voffset].bmi.mv.as_mv.row = x->block[uoffset].bmi.mv.as_mv.row ;
427 0 : x->block[voffset].bmi.mv.as_mv.col = x->block[uoffset].bmi.mv.as_mv.col ;
428 : }
429 : }
430 : }
431 : else
432 : {
433 0 : int mvrow = x->mode_info_context->mbmi.mv.as_mv.row;
434 0 : int mvcol = x->mode_info_context->mbmi.mv.as_mv.col;
435 :
436 0 : if (mvrow < 0)
437 0 : mvrow -= 1;
438 : else
439 0 : mvrow += 1;
440 :
441 0 : if (mvcol < 0)
442 0 : mvcol -= 1;
443 : else
444 0 : mvcol += 1;
445 :
446 0 : mvrow /= 2;
447 0 : mvcol /= 2;
448 :
449 0 : for (i = 0; i < 8; i++)
450 : {
451 0 : x->block[ 16 + i].bmi.mv.as_mv.row = mvrow;
452 0 : x->block[ 16 + i].bmi.mv.as_mv.col = mvcol;
453 :
454 0 : if (fullpixel)
455 : {
456 0 : x->block[ 16 + i].bmi.mv.as_mv.row = mvrow & 0xfffffff8;
457 0 : x->block[ 16 + i].bmi.mv.as_mv.col = mvcol & 0xfffffff8;
458 : }
459 : }
460 : }
461 0 : }
462 :
463 :
464 :
465 :
|