/src/libvpx/vp8/common/reconinter.c
Line | Count | Source (jump to first uncovered line) |
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 | | #include <limits.h> |
12 | | #include <string.h> |
13 | | |
14 | | #include "vpx_config.h" |
15 | | #include "vp8_rtcd.h" |
16 | | #include "vpx/vpx_integer.h" |
17 | | #include "blockd.h" |
18 | | #include "reconinter.h" |
19 | | #if CONFIG_RUNTIME_CPU_DETECT |
20 | | #include "onyxc_int.h" |
21 | | #endif |
22 | | |
23 | | void vp8_copy_mem16x16_c(unsigned char *src, int src_stride, unsigned char *dst, |
24 | 0 | int dst_stride) { |
25 | 0 | int r; |
26 | |
|
27 | 0 | for (r = 0; r < 16; ++r) { |
28 | 0 | memcpy(dst, src, 16); |
29 | |
|
30 | 0 | src += src_stride; |
31 | 0 | dst += dst_stride; |
32 | 0 | } |
33 | 0 | } |
34 | | |
35 | | void vp8_copy_mem8x8_c(unsigned char *src, int src_stride, unsigned char *dst, |
36 | 0 | int dst_stride) { |
37 | 0 | int r; |
38 | |
|
39 | 0 | for (r = 0; r < 8; ++r) { |
40 | 0 | memcpy(dst, src, 8); |
41 | |
|
42 | 0 | src += src_stride; |
43 | 0 | dst += dst_stride; |
44 | 0 | } |
45 | 0 | } |
46 | | |
47 | | void vp8_copy_mem8x4_c(unsigned char *src, int src_stride, unsigned char *dst, |
48 | 0 | int dst_stride) { |
49 | 0 | int r; |
50 | |
|
51 | 0 | for (r = 0; r < 4; ++r) { |
52 | 0 | memcpy(dst, src, 8); |
53 | |
|
54 | 0 | src += src_stride; |
55 | 0 | dst += dst_stride; |
56 | 0 | } |
57 | 0 | } |
58 | | |
59 | | void vp8_build_inter_predictors_b(BLOCKD *d, int pitch, unsigned char *base_pre, |
60 | 65.7M | int pre_stride, vp8_subpix_fn_t sppf) { |
61 | 65.7M | int r; |
62 | 65.7M | unsigned char *pred_ptr = d->predictor; |
63 | 65.7M | unsigned char *ptr; |
64 | 65.7M | ptr = base_pre + d->offset + (d->bmi.mv.as_mv.row >> 3) * pre_stride + |
65 | 65.7M | (d->bmi.mv.as_mv.col >> 3); |
66 | | |
67 | 65.7M | if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7) { |
68 | 15.6M | sppf(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, |
69 | 15.6M | pred_ptr, pitch); |
70 | 50.1M | } else { |
71 | 250M | for (r = 0; r < 4; ++r) { |
72 | 200M | pred_ptr[0] = ptr[0]; |
73 | 200M | pred_ptr[1] = ptr[1]; |
74 | 200M | pred_ptr[2] = ptr[2]; |
75 | 200M | pred_ptr[3] = ptr[3]; |
76 | 200M | pred_ptr += pitch; |
77 | 200M | ptr += pre_stride; |
78 | 200M | } |
79 | 50.1M | } |
80 | 65.7M | } |
81 | | |
82 | | static void build_inter_predictors4b(MACROBLOCKD *x, BLOCKD *d, |
83 | | unsigned char *dst, int dst_stride, |
84 | 299k | unsigned char *base_pre, int pre_stride) { |
85 | 299k | unsigned char *ptr; |
86 | 299k | ptr = base_pre + d->offset + (d->bmi.mv.as_mv.row >> 3) * pre_stride + |
87 | 299k | (d->bmi.mv.as_mv.col >> 3); |
88 | | |
89 | 299k | if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7) { |
90 | 84.7k | x->subpixel_predict8x8(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, |
91 | 84.7k | d->bmi.mv.as_mv.row & 7, dst, dst_stride); |
92 | 214k | } else { |
93 | 214k | vp8_copy_mem8x8(ptr, pre_stride, dst, dst_stride); |
94 | 214k | } |
95 | 299k | } |
96 | | |
97 | | static void build_inter_predictors2b(MACROBLOCKD *x, BLOCKD *d, |
98 | | unsigned char *dst, int dst_stride, |
99 | 1.03M | unsigned char *base_pre, int pre_stride) { |
100 | 1.03M | unsigned char *ptr; |
101 | 1.03M | ptr = base_pre + d->offset + (d->bmi.mv.as_mv.row >> 3) * pre_stride + |
102 | 1.03M | (d->bmi.mv.as_mv.col >> 3); |
103 | | |
104 | 1.03M | if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7) { |
105 | 584k | x->subpixel_predict8x4(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, |
106 | 584k | d->bmi.mv.as_mv.row & 7, dst, dst_stride); |
107 | 584k | } else { |
108 | 455k | vp8_copy_mem8x4(ptr, pre_stride, dst, dst_stride); |
109 | 455k | } |
110 | 1.03M | } |
111 | | |
112 | | static void build_inter_predictors_b(BLOCKD *d, unsigned char *dst, |
113 | | int dst_stride, unsigned char *base_pre, |
114 | 692k | int pre_stride, vp8_subpix_fn_t sppf) { |
115 | 692k | int r; |
116 | 692k | unsigned char *ptr; |
117 | 692k | ptr = base_pre + d->offset + (d->bmi.mv.as_mv.row >> 3) * pre_stride + |
118 | 692k | (d->bmi.mv.as_mv.col >> 3); |
119 | | |
120 | 692k | if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7) { |
121 | 406k | sppf(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, dst, |
122 | 406k | dst_stride); |
123 | 406k | } else { |
124 | 1.43M | for (r = 0; r < 4; ++r) { |
125 | 1.14M | dst[0] = ptr[0]; |
126 | 1.14M | dst[1] = ptr[1]; |
127 | 1.14M | dst[2] = ptr[2]; |
128 | 1.14M | dst[3] = ptr[3]; |
129 | 1.14M | dst += dst_stride; |
130 | 1.14M | ptr += pre_stride; |
131 | 1.14M | } |
132 | 286k | } |
133 | 692k | } |
134 | | |
135 | | /*encoder only*/ |
136 | 2.26M | void vp8_build_inter16x16_predictors_mbuv(MACROBLOCKD *x) { |
137 | 2.26M | unsigned char *uptr, *vptr; |
138 | 2.26M | unsigned char *upred_ptr = &x->predictor[256]; |
139 | 2.26M | unsigned char *vpred_ptr = &x->predictor[320]; |
140 | | |
141 | 2.26M | int mv_row = x->mode_info_context->mbmi.mv.as_mv.row; |
142 | 2.26M | int mv_col = x->mode_info_context->mbmi.mv.as_mv.col; |
143 | 2.26M | int offset; |
144 | 2.26M | int pre_stride = x->pre.uv_stride; |
145 | | |
146 | | /* calc uv motion vectors */ |
147 | 2.26M | mv_row += 1 | (mv_row >> (sizeof(int) * CHAR_BIT - 1)); |
148 | 2.26M | mv_col += 1 | (mv_col >> (sizeof(int) * CHAR_BIT - 1)); |
149 | 2.26M | mv_row /= 2; |
150 | 2.26M | mv_col /= 2; |
151 | 2.26M | mv_row &= x->fullpixel_mask; |
152 | 2.26M | mv_col &= x->fullpixel_mask; |
153 | | |
154 | 2.26M | offset = (mv_row >> 3) * pre_stride + (mv_col >> 3); |
155 | 2.26M | uptr = x->pre.u_buffer + offset; |
156 | 2.26M | vptr = x->pre.v_buffer + offset; |
157 | | |
158 | 2.26M | if ((mv_row | mv_col) & 7) { |
159 | 1.02M | x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, |
160 | 1.02M | 8); |
161 | 1.02M | x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, |
162 | 1.02M | 8); |
163 | 1.23M | } else { |
164 | 1.23M | vp8_copy_mem8x8(uptr, pre_stride, upred_ptr, 8); |
165 | 1.23M | vp8_copy_mem8x8(vptr, pre_stride, vpred_ptr, 8); |
166 | 1.23M | } |
167 | 2.26M | } |
168 | | |
169 | | /*encoder only*/ |
170 | 252k | void vp8_build_inter4x4_predictors_mbuv(MACROBLOCKD *x) { |
171 | 252k | int i, j; |
172 | 252k | int pre_stride = x->pre.uv_stride; |
173 | 252k | unsigned char *base_pre; |
174 | | |
175 | | /* build uv mvs */ |
176 | 758k | for (i = 0; i < 2; ++i) { |
177 | 1.51M | for (j = 0; j < 2; ++j) { |
178 | 1.01M | int yoffset = i * 8 + j * 2; |
179 | 1.01M | int uoffset = 16 + i * 2 + j; |
180 | 1.01M | int voffset = 20 + i * 2 + j; |
181 | | |
182 | 1.01M | int temp; |
183 | | |
184 | 1.01M | temp = x->block[yoffset].bmi.mv.as_mv.row + |
185 | 1.01M | x->block[yoffset + 1].bmi.mv.as_mv.row + |
186 | 1.01M | x->block[yoffset + 4].bmi.mv.as_mv.row + |
187 | 1.01M | x->block[yoffset + 5].bmi.mv.as_mv.row; |
188 | | |
189 | 1.01M | temp += 4 + ((temp >> (sizeof(temp) * CHAR_BIT - 1)) * 8); |
190 | | |
191 | 1.01M | x->block[uoffset].bmi.mv.as_mv.row = (temp / 8) & x->fullpixel_mask; |
192 | | |
193 | 1.01M | temp = x->block[yoffset].bmi.mv.as_mv.col + |
194 | 1.01M | x->block[yoffset + 1].bmi.mv.as_mv.col + |
195 | 1.01M | x->block[yoffset + 4].bmi.mv.as_mv.col + |
196 | 1.01M | x->block[yoffset + 5].bmi.mv.as_mv.col; |
197 | | |
198 | 1.01M | temp += 4 + ((temp >> (sizeof(temp) * CHAR_BIT - 1)) * 8); |
199 | | |
200 | 1.01M | x->block[uoffset].bmi.mv.as_mv.col = (temp / 8) & x->fullpixel_mask; |
201 | | |
202 | 1.01M | x->block[voffset].bmi.mv.as_int = x->block[uoffset].bmi.mv.as_int; |
203 | 1.01M | } |
204 | 505k | } |
205 | | |
206 | 252k | base_pre = x->pre.u_buffer; |
207 | 758k | for (i = 16; i < 20; i += 2) { |
208 | 505k | BLOCKD *d0 = &x->block[i]; |
209 | 505k | BLOCKD *d1 = &x->block[i + 1]; |
210 | | |
211 | 505k | if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { |
212 | 310k | build_inter_predictors2b(x, d0, d0->predictor, 8, base_pre, pre_stride); |
213 | 310k | } else { |
214 | 194k | vp8_build_inter_predictors_b(d0, 8, base_pre, pre_stride, |
215 | 194k | x->subpixel_predict); |
216 | 194k | vp8_build_inter_predictors_b(d1, 8, base_pre, pre_stride, |
217 | 194k | x->subpixel_predict); |
218 | 194k | } |
219 | 505k | } |
220 | | |
221 | 252k | base_pre = x->pre.v_buffer; |
222 | 758k | for (i = 20; i < 24; i += 2) { |
223 | 505k | BLOCKD *d0 = &x->block[i]; |
224 | 505k | BLOCKD *d1 = &x->block[i + 1]; |
225 | | |
226 | 505k | if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { |
227 | 310k | build_inter_predictors2b(x, d0, d0->predictor, 8, base_pre, pre_stride); |
228 | 310k | } else { |
229 | 194k | vp8_build_inter_predictors_b(d0, 8, base_pre, pre_stride, |
230 | 194k | x->subpixel_predict); |
231 | 194k | vp8_build_inter_predictors_b(d1, 8, base_pre, pre_stride, |
232 | 194k | x->subpixel_predict); |
233 | 194k | } |
234 | 505k | } |
235 | 252k | } |
236 | | |
237 | | /*encoder only*/ |
238 | | void vp8_build_inter16x16_predictors_mby(MACROBLOCKD *x, unsigned char *dst_y, |
239 | 2.26M | int dst_ystride) { |
240 | 2.26M | unsigned char *ptr_base; |
241 | 2.26M | unsigned char *ptr; |
242 | 2.26M | int mv_row = x->mode_info_context->mbmi.mv.as_mv.row; |
243 | 2.26M | int mv_col = x->mode_info_context->mbmi.mv.as_mv.col; |
244 | 2.26M | int pre_stride = x->pre.y_stride; |
245 | | |
246 | 2.26M | ptr_base = x->pre.y_buffer; |
247 | 2.26M | ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3); |
248 | | |
249 | 2.26M | if ((mv_row | mv_col) & 7) { |
250 | 560k | x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, dst_y, |
251 | 560k | dst_ystride); |
252 | 1.69M | } else { |
253 | 1.69M | vp8_copy_mem16x16(ptr, pre_stride, dst_y, dst_ystride); |
254 | 1.69M | } |
255 | 2.26M | } |
256 | | |
257 | 0 | static void clamp_mv_to_umv_border(MV *mv, const MACROBLOCKD *xd) { |
258 | | /* If the MV points so far into the UMV border that no visible pixels |
259 | | * are used for reconstruction, the subpel part of the MV can be |
260 | | * discarded and the MV limited to 16 pixels with equivalent results. |
261 | | * |
262 | | * This limit kicks in at 19 pixels for the top and left edges, for |
263 | | * the 16 pixels plus 3 taps right of the central pixel when subpel |
264 | | * filtering. The bottom and right edges use 16 pixels plus 2 pixels |
265 | | * left of the central pixel when filtering. |
266 | | */ |
267 | 0 | if (mv->col < (xd->mb_to_left_edge - (19 << 3))) { |
268 | 0 | mv->col = xd->mb_to_left_edge - (16 << 3); |
269 | 0 | } else if (mv->col > xd->mb_to_right_edge + (18 << 3)) { |
270 | 0 | mv->col = xd->mb_to_right_edge + (16 << 3); |
271 | 0 | } |
272 | |
|
273 | 0 | if (mv->row < (xd->mb_to_top_edge - (19 << 3))) { |
274 | 0 | mv->row = xd->mb_to_top_edge - (16 << 3); |
275 | 0 | } else if (mv->row > xd->mb_to_bottom_edge + (18 << 3)) { |
276 | 0 | mv->row = xd->mb_to_bottom_edge + (16 << 3); |
277 | 0 | } |
278 | 0 | } |
279 | | |
280 | | /* A version of the above function for chroma block MVs.*/ |
281 | 0 | static void clamp_uvmv_to_umv_border(MV *mv, const MACROBLOCKD *xd) { |
282 | 0 | mv->col = (2 * mv->col < (xd->mb_to_left_edge - (19 << 3))) |
283 | 0 | ? (xd->mb_to_left_edge - (16 << 3)) >> 1 |
284 | 0 | : mv->col; |
285 | 0 | mv->col = (2 * mv->col > xd->mb_to_right_edge + (18 << 3)) |
286 | 0 | ? (xd->mb_to_right_edge + (16 << 3)) >> 1 |
287 | 0 | : mv->col; |
288 | |
|
289 | 0 | mv->row = (2 * mv->row < (xd->mb_to_top_edge - (19 << 3))) |
290 | 0 | ? (xd->mb_to_top_edge - (16 << 3)) >> 1 |
291 | 0 | : mv->row; |
292 | 0 | mv->row = (2 * mv->row > xd->mb_to_bottom_edge + (18 << 3)) |
293 | 0 | ? (xd->mb_to_bottom_edge + (16 << 3)) >> 1 |
294 | 0 | : mv->row; |
295 | 0 | } |
296 | | |
297 | | void vp8_build_inter16x16_predictors_mb(MACROBLOCKD *x, unsigned char *dst_y, |
298 | | unsigned char *dst_u, |
299 | | unsigned char *dst_v, int dst_ystride, |
300 | 391k | int dst_uvstride) { |
301 | 391k | int offset; |
302 | 391k | unsigned char *ptr; |
303 | 391k | unsigned char *uptr, *vptr; |
304 | | |
305 | 391k | int_mv _16x16mv; |
306 | | |
307 | 391k | unsigned char *ptr_base = x->pre.y_buffer; |
308 | 391k | int pre_stride = x->pre.y_stride; |
309 | | |
310 | 391k | _16x16mv.as_int = x->mode_info_context->mbmi.mv.as_int; |
311 | | |
312 | 391k | if (x->mode_info_context->mbmi.need_to_clamp_mvs) { |
313 | 0 | clamp_mv_to_umv_border(&_16x16mv.as_mv, x); |
314 | 0 | } |
315 | | |
316 | 391k | ptr = ptr_base + (_16x16mv.as_mv.row >> 3) * pre_stride + |
317 | 391k | (_16x16mv.as_mv.col >> 3); |
318 | | |
319 | 391k | if (_16x16mv.as_int & 0x00070007) { |
320 | 148k | x->subpixel_predict16x16(ptr, pre_stride, _16x16mv.as_mv.col & 7, |
321 | 148k | _16x16mv.as_mv.row & 7, dst_y, dst_ystride); |
322 | 243k | } else { |
323 | 243k | vp8_copy_mem16x16(ptr, pre_stride, dst_y, dst_ystride); |
324 | 243k | } |
325 | | |
326 | | /* calc uv motion vectors */ |
327 | 391k | _16x16mv.as_mv.row += |
328 | 391k | 1 | (_16x16mv.as_mv.row >> (sizeof(int) * CHAR_BIT - 1)); |
329 | 391k | _16x16mv.as_mv.col += |
330 | 391k | 1 | (_16x16mv.as_mv.col >> (sizeof(int) * CHAR_BIT - 1)); |
331 | 391k | _16x16mv.as_mv.row /= 2; |
332 | 391k | _16x16mv.as_mv.col /= 2; |
333 | 391k | _16x16mv.as_mv.row &= x->fullpixel_mask; |
334 | 391k | _16x16mv.as_mv.col &= x->fullpixel_mask; |
335 | | |
336 | 391k | if (2 * _16x16mv.as_mv.col < (x->mb_to_left_edge - (19 << 3)) || |
337 | 391k | 2 * _16x16mv.as_mv.col > x->mb_to_right_edge + (18 << 3) || |
338 | 391k | 2 * _16x16mv.as_mv.row < (x->mb_to_top_edge - (19 << 3)) || |
339 | 391k | 2 * _16x16mv.as_mv.row > x->mb_to_bottom_edge + (18 << 3)) { |
340 | 863 | return; |
341 | 863 | } |
342 | | |
343 | 390k | pre_stride >>= 1; |
344 | 390k | offset = (_16x16mv.as_mv.row >> 3) * pre_stride + (_16x16mv.as_mv.col >> 3); |
345 | 390k | uptr = x->pre.u_buffer + offset; |
346 | 390k | vptr = x->pre.v_buffer + offset; |
347 | | |
348 | 390k | if (_16x16mv.as_int & 0x00070007) { |
349 | 255k | x->subpixel_predict8x8(uptr, pre_stride, _16x16mv.as_mv.col & 7, |
350 | 255k | _16x16mv.as_mv.row & 7, dst_u, dst_uvstride); |
351 | 255k | x->subpixel_predict8x8(vptr, pre_stride, _16x16mv.as_mv.col & 7, |
352 | 255k | _16x16mv.as_mv.row & 7, dst_v, dst_uvstride); |
353 | 255k | } else { |
354 | 135k | vp8_copy_mem8x8(uptr, pre_stride, dst_u, dst_uvstride); |
355 | 135k | vp8_copy_mem8x8(vptr, pre_stride, dst_v, dst_uvstride); |
356 | 135k | } |
357 | 390k | } |
358 | | |
359 | 113k | static void build_inter4x4_predictors_mb(MACROBLOCKD *x) { |
360 | 113k | int i; |
361 | 113k | unsigned char *base_dst = x->dst.y_buffer; |
362 | 113k | unsigned char *base_pre = x->pre.y_buffer; |
363 | | |
364 | 113k | if (x->mode_info_context->mbmi.partitioning < 3) { |
365 | 74.8k | BLOCKD *b; |
366 | 74.8k | int dst_stride = x->dst.y_stride; |
367 | | |
368 | 74.8k | x->block[0].bmi = x->mode_info_context->bmi[0]; |
369 | 74.8k | x->block[2].bmi = x->mode_info_context->bmi[2]; |
370 | 74.8k | x->block[8].bmi = x->mode_info_context->bmi[8]; |
371 | 74.8k | x->block[10].bmi = x->mode_info_context->bmi[10]; |
372 | 74.8k | if (x->mode_info_context->mbmi.need_to_clamp_mvs) { |
373 | 0 | clamp_mv_to_umv_border(&x->block[0].bmi.mv.as_mv, x); |
374 | 0 | clamp_mv_to_umv_border(&x->block[2].bmi.mv.as_mv, x); |
375 | 0 | clamp_mv_to_umv_border(&x->block[8].bmi.mv.as_mv, x); |
376 | 0 | clamp_mv_to_umv_border(&x->block[10].bmi.mv.as_mv, x); |
377 | 0 | } |
378 | | |
379 | 74.8k | b = &x->block[0]; |
380 | 74.8k | build_inter_predictors4b(x, b, base_dst + b->offset, dst_stride, base_pre, |
381 | 74.8k | dst_stride); |
382 | 74.8k | b = &x->block[2]; |
383 | 74.8k | build_inter_predictors4b(x, b, base_dst + b->offset, dst_stride, base_pre, |
384 | 74.8k | dst_stride); |
385 | 74.8k | b = &x->block[8]; |
386 | 74.8k | build_inter_predictors4b(x, b, base_dst + b->offset, dst_stride, base_pre, |
387 | 74.8k | dst_stride); |
388 | 74.8k | b = &x->block[10]; |
389 | 74.8k | build_inter_predictors4b(x, b, base_dst + b->offset, dst_stride, base_pre, |
390 | 74.8k | dst_stride); |
391 | 74.8k | } else { |
392 | 348k | for (i = 0; i < 16; i += 2) { |
393 | 309k | BLOCKD *d0 = &x->block[i]; |
394 | 309k | BLOCKD *d1 = &x->block[i + 1]; |
395 | 309k | int dst_stride = x->dst.y_stride; |
396 | | |
397 | 309k | x->block[i + 0].bmi = x->mode_info_context->bmi[i + 0]; |
398 | 309k | x->block[i + 1].bmi = x->mode_info_context->bmi[i + 1]; |
399 | 309k | if (x->mode_info_context->mbmi.need_to_clamp_mvs) { |
400 | 0 | clamp_mv_to_umv_border(&x->block[i + 0].bmi.mv.as_mv, x); |
401 | 0 | clamp_mv_to_umv_border(&x->block[i + 1].bmi.mv.as_mv, x); |
402 | 0 | } |
403 | | |
404 | 309k | if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { |
405 | 159k | build_inter_predictors2b(x, d0, base_dst + d0->offset, dst_stride, |
406 | 159k | base_pre, dst_stride); |
407 | 159k | } else { |
408 | 150k | build_inter_predictors_b(d0, base_dst + d0->offset, dst_stride, |
409 | 150k | base_pre, dst_stride, x->subpixel_predict); |
410 | 150k | build_inter_predictors_b(d1, base_dst + d1->offset, dst_stride, |
411 | 150k | base_pre, dst_stride, x->subpixel_predict); |
412 | 150k | } |
413 | 309k | } |
414 | 38.7k | } |
415 | 113k | base_dst = x->dst.u_buffer; |
416 | 113k | base_pre = x->pre.u_buffer; |
417 | 340k | for (i = 16; i < 20; i += 2) { |
418 | 227k | BLOCKD *d0 = &x->block[i]; |
419 | 227k | BLOCKD *d1 = &x->block[i + 1]; |
420 | 227k | int dst_stride = x->dst.uv_stride; |
421 | | |
422 | | /* Note: uv mvs already clamped in build_4x4uvmvs() */ |
423 | | |
424 | 227k | if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { |
425 | 129k | build_inter_predictors2b(x, d0, base_dst + d0->offset, dst_stride, |
426 | 129k | base_pre, dst_stride); |
427 | 129k | } else { |
428 | 97.9k | build_inter_predictors_b(d0, base_dst + d0->offset, dst_stride, base_pre, |
429 | 97.9k | dst_stride, x->subpixel_predict); |
430 | 97.9k | build_inter_predictors_b(d1, base_dst + d1->offset, dst_stride, base_pre, |
431 | 97.9k | dst_stride, x->subpixel_predict); |
432 | 97.9k | } |
433 | 227k | } |
434 | | |
435 | 113k | base_dst = x->dst.v_buffer; |
436 | 113k | base_pre = x->pre.v_buffer; |
437 | 340k | for (i = 20; i < 24; i += 2) { |
438 | 227k | BLOCKD *d0 = &x->block[i]; |
439 | 227k | BLOCKD *d1 = &x->block[i + 1]; |
440 | 227k | int dst_stride = x->dst.uv_stride; |
441 | | |
442 | | /* Note: uv mvs already clamped in build_4x4uvmvs() */ |
443 | | |
444 | 227k | if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { |
445 | 129k | build_inter_predictors2b(x, d0, base_dst + d0->offset, dst_stride, |
446 | 129k | base_pre, dst_stride); |
447 | 129k | } else { |
448 | 97.9k | build_inter_predictors_b(d0, base_dst + d0->offset, dst_stride, base_pre, |
449 | 97.9k | dst_stride, x->subpixel_predict); |
450 | 97.9k | build_inter_predictors_b(d1, base_dst + d1->offset, dst_stride, base_pre, |
451 | 97.9k | dst_stride, x->subpixel_predict); |
452 | 97.9k | } |
453 | 227k | } |
454 | 113k | } |
455 | | |
456 | 113k | static void build_4x4uvmvs(MACROBLOCKD *x) { |
457 | 113k | int i, j; |
458 | | |
459 | 340k | for (i = 0; i < 2; ++i) { |
460 | 681k | for (j = 0; j < 2; ++j) { |
461 | 454k | int yoffset = i * 8 + j * 2; |
462 | 454k | int uoffset = 16 + i * 2 + j; |
463 | 454k | int voffset = 20 + i * 2 + j; |
464 | | |
465 | 454k | int temp; |
466 | | |
467 | 454k | temp = x->mode_info_context->bmi[yoffset + 0].mv.as_mv.row + |
468 | 454k | x->mode_info_context->bmi[yoffset + 1].mv.as_mv.row + |
469 | 454k | x->mode_info_context->bmi[yoffset + 4].mv.as_mv.row + |
470 | 454k | x->mode_info_context->bmi[yoffset + 5].mv.as_mv.row; |
471 | | |
472 | 454k | temp += 4 + ((temp >> (sizeof(temp) * CHAR_BIT - 1)) * 8); |
473 | | |
474 | 454k | x->block[uoffset].bmi.mv.as_mv.row = (temp / 8) & x->fullpixel_mask; |
475 | | |
476 | 454k | temp = x->mode_info_context->bmi[yoffset + 0].mv.as_mv.col + |
477 | 454k | x->mode_info_context->bmi[yoffset + 1].mv.as_mv.col + |
478 | 454k | x->mode_info_context->bmi[yoffset + 4].mv.as_mv.col + |
479 | 454k | x->mode_info_context->bmi[yoffset + 5].mv.as_mv.col; |
480 | | |
481 | 454k | temp += 4 + ((temp >> (sizeof(temp) * CHAR_BIT - 1)) * 8); |
482 | | |
483 | 454k | x->block[uoffset].bmi.mv.as_mv.col = (temp / 8) & x->fullpixel_mask; |
484 | | |
485 | 454k | if (x->mode_info_context->mbmi.need_to_clamp_mvs) { |
486 | 0 | clamp_uvmv_to_umv_border(&x->block[uoffset].bmi.mv.as_mv, x); |
487 | 0 | } |
488 | | |
489 | 454k | x->block[voffset].bmi.mv.as_int = x->block[uoffset].bmi.mv.as_int; |
490 | 454k | } |
491 | 227k | } |
492 | 113k | } |
493 | | |
494 | 504k | void vp8_build_inter_predictors_mb(MACROBLOCKD *xd) { |
495 | 504k | if (xd->mode_info_context->mbmi.mode != SPLITMV) { |
496 | 391k | vp8_build_inter16x16_predictors_mb(xd, xd->dst.y_buffer, xd->dst.u_buffer, |
497 | 391k | xd->dst.v_buffer, xd->dst.y_stride, |
498 | 391k | xd->dst.uv_stride); |
499 | 391k | } else { |
500 | 113k | build_4x4uvmvs(xd); |
501 | 113k | build_inter4x4_predictors_mb(xd); |
502 | 113k | } |
503 | 504k | } |