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.
12 #include "vpx_ports/config.h"
13 #include "vpx/vpx_integer.h"
17 #include "reconinter.h"
18 #if CONFIG_RUNTIME_CPU_DETECT
19 #include "onyxc_int.h"
22 void vp8_copy_mem16x16_c(
31 for (r
= 0; r
< 16; r
++)
33 #if !(CONFIG_FAST_UNALIGNED)
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] ;
65 void vp8_copy_mem8x8_c(
73 for (r
= 0; r
< 8; r
++)
75 #if !(CONFIG_FAST_UNALIGNED)
85 ((uint32_t *)dst
)[0] = ((uint32_t *)src
)[0] ;
86 ((uint32_t *)dst
)[1] = ((uint32_t *)src
)[1] ;
95 void vp8_copy_mem8x4_c(
103 for (r
= 0; r
< 4; r
++)
105 #if !(CONFIG_FAST_UNALIGNED)
115 ((uint32_t *)dst
)[0] = ((uint32_t *)src
)[0] ;
116 ((uint32_t *)dst
)[1] = ((uint32_t *)src
)[1] ;
127 void vp8_build_inter_predictors_b(BLOCKD
*d
, int pitch
, vp8_subpix_fn_t sppf
)
130 unsigned char *ptr_base
;
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
);
143 ptr_base
+= d
->pre
+ (d
->bmi
.mv
.as_mv
.row
>> 3) * d
->pre_stride
+ (d
->bmi
.mv
.as_mv
.col
>> 3);
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];
154 *(uint32_t *)pred_ptr
= *(uint32_t *)ptr
;
157 ptr
+= d
->pre_stride
;
162 static void build_inter_predictors4b(MACROBLOCKD
*x
, BLOCKD
*d
, int pitch
)
164 unsigned char *ptr_base
;
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
);
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
;
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
);
196 RECON_INVOKE(&x
->rtcd
->recon
, copy8x4
)(ptr
, d
->pre_stride
, pred_ptr
, pitch
);
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
;
211 int pre_stride
= x
->block
[16].pre_stride
;
213 /* calc uv motion vectors */
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);
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);
247 void vp8_build_inter4x4_predictors_mbuv(MACROBLOCKD
*x
)
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
;
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;
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;
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);
298 vp8_build_inter_predictors_b(d0
, 8, x
->subpixel_predict
);
299 vp8_build_inter_predictors_b(d1
, 8, x
->subpixel_predict
);
306 void vp8_build_inter16x16_predictors_mby(MACROBLOCKD
*x
)
308 unsigned char *ptr_base
;
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);
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
,
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
);
353 RECON_INVOKE(&x
->rtcd
->recon
, copy16x16
)(ptr
, pre_stride
, dst_y
, dst_ystride
);
356 /* calc uv motion vectors */
370 mv_row
&= x
->fullpixel_mask
;
371 mv_col
&= x
->fullpixel_mask
;
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
);
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
)
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);
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);
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);
438 vp8_build_inter_predictors_b(d0
, 8, x
->subpixel_predict
);
439 vp8_build_inter_predictors_b(d1
, 8, x
->subpixel_predict
);
445 void build_4x4uvmvs(MACROBLOCKD
*x
)
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
;
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;
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;
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);
497 build_inter4x4_predictors_mb(x
);