/src/libvpx/vp8/common/reconinter.c
Line | Count | Source |
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 | 94.3M | int pre_stride, vp8_subpix_fn_t sppf) { |
61 | 94.3M | int r; |
62 | 94.3M | unsigned char *pred_ptr = d->predictor; |
63 | 94.3M | unsigned char *ptr; |
64 | 94.3M | ptr = base_pre + d->offset + (d->bmi.mv.as_mv.row >> 3) * pre_stride + |
65 | 94.3M | (d->bmi.mv.as_mv.col >> 3); |
66 | | |
67 | 94.3M | if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7) { |
68 | 24.1M | sppf(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, |
69 | 24.1M | pred_ptr, pitch); |
70 | 70.2M | } else { |
71 | 351M | for (r = 0; r < 4; ++r) { |
72 | 280M | pred_ptr[0] = ptr[0]; |
73 | 280M | pred_ptr[1] = ptr[1]; |
74 | 280M | pred_ptr[2] = ptr[2]; |
75 | 280M | pred_ptr[3] = ptr[3]; |
76 | 280M | pred_ptr += pitch; |
77 | 280M | ptr += pre_stride; |
78 | 280M | } |
79 | 70.2M | } |
80 | 94.3M | } |
81 | | |
82 | | static void build_inter_predictors4b(MACROBLOCKD *x, BLOCKD *d, |
83 | | unsigned char *dst, int dst_stride, |
84 | 1.94M | unsigned char *base_pre, int pre_stride) { |
85 | 1.94M | unsigned char *ptr; |
86 | 1.94M | ptr = base_pre + d->offset + (d->bmi.mv.as_mv.row >> 3) * pre_stride + |
87 | 1.94M | (d->bmi.mv.as_mv.col >> 3); |
88 | | |
89 | 1.94M | if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7) { |
90 | 896k | x->subpixel_predict8x8(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, |
91 | 896k | d->bmi.mv.as_mv.row & 7, dst, dst_stride); |
92 | 1.04M | } else { |
93 | 1.04M | vp8_copy_mem8x8(ptr, pre_stride, dst, dst_stride); |
94 | 1.04M | } |
95 | 1.94M | } |
96 | | |
97 | | static void build_inter_predictors2b(MACROBLOCKD *x, BLOCKD *d, |
98 | | unsigned char *dst, int dst_stride, |
99 | 4.65M | unsigned char *base_pre, int pre_stride) { |
100 | 4.65M | unsigned char *ptr; |
101 | 4.65M | ptr = base_pre + d->offset + (d->bmi.mv.as_mv.row >> 3) * pre_stride + |
102 | 4.65M | (d->bmi.mv.as_mv.col >> 3); |
103 | | |
104 | 4.65M | if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7) { |
105 | 1.94M | x->subpixel_predict8x4(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, |
106 | 1.94M | d->bmi.mv.as_mv.row & 7, dst, dst_stride); |
107 | 2.71M | } else { |
108 | 2.71M | vp8_copy_mem8x4(ptr, pre_stride, dst, dst_stride); |
109 | 2.71M | } |
110 | 4.65M | } |
111 | | |
112 | | static void build_inter_predictors_b(BLOCKD *d, unsigned char *dst, |
113 | | int dst_stride, unsigned char *base_pre, |
114 | 4.82M | int pre_stride, vp8_subpix_fn_t sppf) { |
115 | 4.82M | int r; |
116 | 4.82M | unsigned char *ptr; |
117 | 4.82M | ptr = base_pre + d->offset + (d->bmi.mv.as_mv.row >> 3) * pre_stride + |
118 | 4.82M | (d->bmi.mv.as_mv.col >> 3); |
119 | | |
120 | 4.82M | if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7) { |
121 | 2.03M | sppf(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, dst, |
122 | 2.03M | dst_stride); |
123 | 2.78M | } else { |
124 | 13.9M | for (r = 0; r < 4; ++r) { |
125 | 11.1M | dst[0] = ptr[0]; |
126 | 11.1M | dst[1] = ptr[1]; |
127 | 11.1M | dst[2] = ptr[2]; |
128 | 11.1M | dst[3] = ptr[3]; |
129 | 11.1M | dst += dst_stride; |
130 | 11.1M | ptr += pre_stride; |
131 | 11.1M | } |
132 | 2.78M | } |
133 | 4.82M | } |
134 | | |
135 | | /*encoder only*/ |
136 | 2.84M | void vp8_build_inter16x16_predictors_mbuv(MACROBLOCKD *x) { |
137 | 2.84M | unsigned char *uptr, *vptr; |
138 | 2.84M | unsigned char *upred_ptr = &x->predictor[256]; |
139 | 2.84M | unsigned char *vpred_ptr = &x->predictor[320]; |
140 | | |
141 | 2.84M | int mv_row = x->mode_info_context->mbmi.mv.as_mv.row; |
142 | 2.84M | int mv_col = x->mode_info_context->mbmi.mv.as_mv.col; |
143 | 2.84M | int offset; |
144 | 2.84M | int pre_stride = x->pre.uv_stride; |
145 | | |
146 | | /* calc uv motion vectors */ |
147 | 2.84M | mv_row += 1 | (mv_row >> (sizeof(int) * CHAR_BIT - 1)); |
148 | 2.84M | mv_col += 1 | (mv_col >> (sizeof(int) * CHAR_BIT - 1)); |
149 | 2.84M | mv_row /= 2; |
150 | 2.84M | mv_col /= 2; |
151 | 2.84M | mv_row &= x->fullpixel_mask; |
152 | 2.84M | mv_col &= x->fullpixel_mask; |
153 | | |
154 | 2.84M | offset = (mv_row >> 3) * pre_stride + (mv_col >> 3); |
155 | 2.84M | uptr = x->pre.u_buffer + offset; |
156 | 2.84M | vptr = x->pre.v_buffer + offset; |
157 | | |
158 | 2.84M | if ((mv_row | mv_col) & 7) { |
159 | 1.31M | x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, |
160 | 1.31M | 8); |
161 | 1.31M | x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, |
162 | 1.31M | 8); |
163 | 1.52M | } else { |
164 | 1.52M | vp8_copy_mem8x8(uptr, pre_stride, upred_ptr, 8); |
165 | 1.52M | vp8_copy_mem8x8(vptr, pre_stride, vpred_ptr, 8); |
166 | 1.52M | } |
167 | 2.84M | } |
168 | | |
169 | | /*encoder only*/ |
170 | 386k | void vp8_build_inter4x4_predictors_mbuv(MACROBLOCKD *x) { |
171 | 386k | int i, j; |
172 | 386k | int pre_stride = x->pre.uv_stride; |
173 | 386k | unsigned char *base_pre; |
174 | | |
175 | | /* build uv mvs */ |
176 | 1.15M | for (i = 0; i < 2; ++i) { |
177 | 2.31M | for (j = 0; j < 2; ++j) { |
178 | 1.54M | int yoffset = i * 8 + j * 2; |
179 | 1.54M | int uoffset = 16 + i * 2 + j; |
180 | 1.54M | int voffset = 20 + i * 2 + j; |
181 | | |
182 | 1.54M | int temp; |
183 | | |
184 | 1.54M | temp = x->block[yoffset].bmi.mv.as_mv.row + |
185 | 1.54M | x->block[yoffset + 1].bmi.mv.as_mv.row + |
186 | 1.54M | x->block[yoffset + 4].bmi.mv.as_mv.row + |
187 | 1.54M | x->block[yoffset + 5].bmi.mv.as_mv.row; |
188 | | |
189 | 1.54M | temp += 4 + ((temp >> (sizeof(temp) * CHAR_BIT - 1)) * 8); |
190 | | |
191 | 1.54M | x->block[uoffset].bmi.mv.as_mv.row = (temp / 8) & x->fullpixel_mask; |
192 | | |
193 | 1.54M | temp = x->block[yoffset].bmi.mv.as_mv.col + |
194 | 1.54M | x->block[yoffset + 1].bmi.mv.as_mv.col + |
195 | 1.54M | x->block[yoffset + 4].bmi.mv.as_mv.col + |
196 | 1.54M | x->block[yoffset + 5].bmi.mv.as_mv.col; |
197 | | |
198 | 1.54M | temp += 4 + ((temp >> (sizeof(temp) * CHAR_BIT - 1)) * 8); |
199 | | |
200 | 1.54M | x->block[uoffset].bmi.mv.as_mv.col = (temp / 8) & x->fullpixel_mask; |
201 | | |
202 | 1.54M | x->block[voffset].bmi.mv.as_int = x->block[uoffset].bmi.mv.as_int; |
203 | 1.54M | } |
204 | 773k | } |
205 | | |
206 | 386k | base_pre = x->pre.u_buffer; |
207 | 1.15M | for (i = 16; i < 20; i += 2) { |
208 | 773k | BLOCKD *d0 = &x->block[i]; |
209 | 773k | BLOCKD *d1 = &x->block[i + 1]; |
210 | | |
211 | 773k | if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { |
212 | 440k | build_inter_predictors2b(x, d0, d0->predictor, 8, base_pre, pre_stride); |
213 | 440k | } else { |
214 | 332k | vp8_build_inter_predictors_b(d0, 8, base_pre, pre_stride, |
215 | 332k | x->subpixel_predict); |
216 | 332k | vp8_build_inter_predictors_b(d1, 8, base_pre, pre_stride, |
217 | 332k | x->subpixel_predict); |
218 | 332k | } |
219 | 773k | } |
220 | | |
221 | 386k | base_pre = x->pre.v_buffer; |
222 | 1.15M | for (i = 20; i < 24; i += 2) { |
223 | 773k | BLOCKD *d0 = &x->block[i]; |
224 | 773k | BLOCKD *d1 = &x->block[i + 1]; |
225 | | |
226 | 773k | if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { |
227 | 440k | build_inter_predictors2b(x, d0, d0->predictor, 8, base_pre, pre_stride); |
228 | 440k | } else { |
229 | 332k | vp8_build_inter_predictors_b(d0, 8, base_pre, pre_stride, |
230 | 332k | x->subpixel_predict); |
231 | 332k | vp8_build_inter_predictors_b(d1, 8, base_pre, pre_stride, |
232 | 332k | x->subpixel_predict); |
233 | 332k | } |
234 | 773k | } |
235 | 386k | } |
236 | | |
237 | | /*encoder only*/ |
238 | | void vp8_build_inter16x16_predictors_mby(MACROBLOCKD *x, unsigned char *dst_y, |
239 | 2.84M | int dst_ystride) { |
240 | 2.84M | unsigned char *ptr_base; |
241 | 2.84M | unsigned char *ptr; |
242 | 2.84M | int mv_row = x->mode_info_context->mbmi.mv.as_mv.row; |
243 | 2.84M | int mv_col = x->mode_info_context->mbmi.mv.as_mv.col; |
244 | 2.84M | int pre_stride = x->pre.y_stride; |
245 | | |
246 | 2.84M | ptr_base = x->pre.y_buffer; |
247 | 2.84M | ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3); |
248 | | |
249 | 2.84M | if ((mv_row | mv_col) & 7) { |
250 | 713k | x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, dst_y, |
251 | 713k | dst_ystride); |
252 | 2.13M | } else { |
253 | 2.13M | vp8_copy_mem16x16(ptr, pre_stride, dst_y, dst_ystride); |
254 | 2.13M | } |
255 | 2.84M | } |
256 | | |
257 | 2.64M | 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 | 2.64M | if (mv->col < (xd->mb_to_left_edge - (19 << 3))) { |
268 | 217k | mv->col = xd->mb_to_left_edge - (16 << 3); |
269 | 2.43M | } else if (mv->col > xd->mb_to_right_edge + (18 << 3)) { |
270 | 214k | mv->col = xd->mb_to_right_edge + (16 << 3); |
271 | 214k | } |
272 | | |
273 | 2.64M | if (mv->row < (xd->mb_to_top_edge - (19 << 3))) { |
274 | 440k | mv->row = xd->mb_to_top_edge - (16 << 3); |
275 | 2.20M | } else if (mv->row > xd->mb_to_bottom_edge + (18 << 3)) { |
276 | 152k | mv->row = xd->mb_to_bottom_edge + (16 << 3); |
277 | 152k | } |
278 | 2.64M | } |
279 | | |
280 | | /* A version of the above function for chroma block MVs.*/ |
281 | 2.67M | static void clamp_uvmv_to_umv_border(MV *mv, const MACROBLOCKD *xd) { |
282 | 2.67M | mv->col = (2 * mv->col < (xd->mb_to_left_edge - (19 << 3))) |
283 | 2.67M | ? (xd->mb_to_left_edge - (16 << 3)) >> 1 |
284 | 2.67M | : mv->col; |
285 | 2.67M | mv->col = (2 * mv->col > xd->mb_to_right_edge + (18 << 3)) |
286 | 2.67M | ? (xd->mb_to_right_edge + (16 << 3)) >> 1 |
287 | 2.67M | : mv->col; |
288 | | |
289 | 2.67M | mv->row = (2 * mv->row < (xd->mb_to_top_edge - (19 << 3))) |
290 | 2.67M | ? (xd->mb_to_top_edge - (16 << 3)) >> 1 |
291 | 2.67M | : mv->row; |
292 | 2.67M | mv->row = (2 * mv->row > xd->mb_to_bottom_edge + (18 << 3)) |
293 | 2.67M | ? (xd->mb_to_bottom_edge + (16 << 3)) >> 1 |
294 | 2.67M | : mv->row; |
295 | 2.67M | } |
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 | 1.76M | int dst_uvstride) { |
301 | 1.76M | int offset; |
302 | 1.76M | unsigned char *ptr; |
303 | 1.76M | unsigned char *uptr, *vptr; |
304 | | |
305 | 1.76M | int_mv _16x16mv; |
306 | | |
307 | 1.76M | unsigned char *ptr_base = x->pre.y_buffer; |
308 | 1.76M | int pre_stride = x->pre.y_stride; |
309 | | |
310 | 1.76M | _16x16mv.as_int = x->mode_info_context->mbmi.mv.as_int; |
311 | | |
312 | 1.76M | if (x->mode_info_context->mbmi.need_to_clamp_mvs) { |
313 | 147k | clamp_mv_to_umv_border(&_16x16mv.as_mv, x); |
314 | 147k | } |
315 | | |
316 | 1.76M | ptr = ptr_base + (_16x16mv.as_mv.row >> 3) * pre_stride + |
317 | 1.76M | (_16x16mv.as_mv.col >> 3); |
318 | | |
319 | 1.76M | if (_16x16mv.as_int & 0x00070007) { |
320 | 979k | x->subpixel_predict16x16(ptr, pre_stride, _16x16mv.as_mv.col & 7, |
321 | 979k | _16x16mv.as_mv.row & 7, dst_y, dst_ystride); |
322 | 979k | } else { |
323 | 786k | vp8_copy_mem16x16(ptr, pre_stride, dst_y, dst_ystride); |
324 | 786k | } |
325 | | |
326 | | /* calc uv motion vectors */ |
327 | 1.76M | _16x16mv.as_mv.row += |
328 | 1.76M | 1 | (_16x16mv.as_mv.row >> (sizeof(int) * CHAR_BIT - 1)); |
329 | 1.76M | _16x16mv.as_mv.col += |
330 | 1.76M | 1 | (_16x16mv.as_mv.col >> (sizeof(int) * CHAR_BIT - 1)); |
331 | 1.76M | _16x16mv.as_mv.row /= 2; |
332 | 1.76M | _16x16mv.as_mv.col /= 2; |
333 | 1.76M | _16x16mv.as_mv.row &= x->fullpixel_mask; |
334 | 1.76M | _16x16mv.as_mv.col &= x->fullpixel_mask; |
335 | | |
336 | | /* Rounding to full-pel can move the chroma MV outside the border tap |
337 | | * window even though the luma MV was already clamped, so clamp again to |
338 | | * keep the reference read in bounds and ensure dst_u/dst_v are written. */ |
339 | 1.76M | clamp_uvmv_to_umv_border(&_16x16mv.as_mv, x); |
340 | | |
341 | 1.76M | pre_stride >>= 1; |
342 | 1.76M | offset = (_16x16mv.as_mv.row >> 3) * pre_stride + (_16x16mv.as_mv.col >> 3); |
343 | 1.76M | uptr = x->pre.u_buffer + offset; |
344 | 1.76M | vptr = x->pre.v_buffer + offset; |
345 | | |
346 | 1.76M | if (_16x16mv.as_int & 0x00070007) { |
347 | 502k | x->subpixel_predict8x8(uptr, pre_stride, _16x16mv.as_mv.col & 7, |
348 | 502k | _16x16mv.as_mv.row & 7, dst_u, dst_uvstride); |
349 | 502k | x->subpixel_predict8x8(vptr, pre_stride, _16x16mv.as_mv.col & 7, |
350 | 502k | _16x16mv.as_mv.row & 7, dst_v, dst_uvstride); |
351 | 1.26M | } else { |
352 | 1.26M | vp8_copy_mem8x8(uptr, pre_stride, dst_u, dst_uvstride); |
353 | 1.26M | vp8_copy_mem8x8(vptr, pre_stride, dst_v, dst_uvstride); |
354 | 1.26M | } |
355 | 1.76M | } |
356 | | |
357 | 840k | static void build_inter4x4_predictors_mb(MACROBLOCKD *x) { |
358 | 840k | int i; |
359 | 840k | unsigned char *base_dst = x->dst.y_buffer; |
360 | 840k | unsigned char *base_pre = x->pre.y_buffer; |
361 | | |
362 | 840k | if (x->mode_info_context->mbmi.partitioning < 3) { |
363 | 486k | BLOCKD *b; |
364 | 486k | int dst_stride = x->dst.y_stride; |
365 | | |
366 | 486k | x->block[0].bmi = x->mode_info_context->bmi[0]; |
367 | 486k | x->block[2].bmi = x->mode_info_context->bmi[2]; |
368 | 486k | x->block[8].bmi = x->mode_info_context->bmi[8]; |
369 | 486k | x->block[10].bmi = x->mode_info_context->bmi[10]; |
370 | 486k | if (x->mode_info_context->mbmi.need_to_clamp_mvs) { |
371 | 95.9k | clamp_mv_to_umv_border(&x->block[0].bmi.mv.as_mv, x); |
372 | 95.9k | clamp_mv_to_umv_border(&x->block[2].bmi.mv.as_mv, x); |
373 | 95.9k | clamp_mv_to_umv_border(&x->block[8].bmi.mv.as_mv, x); |
374 | 95.9k | clamp_mv_to_umv_border(&x->block[10].bmi.mv.as_mv, x); |
375 | 95.9k | } |
376 | | |
377 | 486k | b = &x->block[0]; |
378 | 486k | build_inter_predictors4b(x, b, base_dst + b->offset, dst_stride, base_pre, |
379 | 486k | dst_stride); |
380 | 486k | b = &x->block[2]; |
381 | 486k | build_inter_predictors4b(x, b, base_dst + b->offset, dst_stride, base_pre, |
382 | 486k | dst_stride); |
383 | 486k | b = &x->block[8]; |
384 | 486k | build_inter_predictors4b(x, b, base_dst + b->offset, dst_stride, base_pre, |
385 | 486k | dst_stride); |
386 | 486k | b = &x->block[10]; |
387 | 486k | build_inter_predictors4b(x, b, base_dst + b->offset, dst_stride, base_pre, |
388 | 486k | dst_stride); |
389 | 486k | } else { |
390 | 3.18M | for (i = 0; i < 16; i += 2) { |
391 | 2.82M | BLOCKD *d0 = &x->block[i]; |
392 | 2.82M | BLOCKD *d1 = &x->block[i + 1]; |
393 | 2.82M | int dst_stride = x->dst.y_stride; |
394 | | |
395 | 2.82M | x->block[i + 0].bmi = x->mode_info_context->bmi[i + 0]; |
396 | 2.82M | x->block[i + 1].bmi = x->mode_info_context->bmi[i + 1]; |
397 | 2.82M | if (x->mode_info_context->mbmi.need_to_clamp_mvs) { |
398 | 1.05M | clamp_mv_to_umv_border(&x->block[i + 0].bmi.mv.as_mv, x); |
399 | 1.05M | clamp_mv_to_umv_border(&x->block[i + 1].bmi.mv.as_mv, x); |
400 | 1.05M | } |
401 | | |
402 | 2.82M | if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { |
403 | 1.84M | build_inter_predictors2b(x, d0, base_dst + d0->offset, dst_stride, |
404 | 1.84M | base_pre, dst_stride); |
405 | 1.84M | } else { |
406 | 981k | build_inter_predictors_b(d0, base_dst + d0->offset, dst_stride, |
407 | 981k | base_pre, dst_stride, x->subpixel_predict); |
408 | 981k | build_inter_predictors_b(d1, base_dst + d1->offset, dst_stride, |
409 | 981k | base_pre, dst_stride, x->subpixel_predict); |
410 | 981k | } |
411 | 2.82M | } |
412 | 353k | } |
413 | 840k | base_dst = x->dst.u_buffer; |
414 | 840k | base_pre = x->pre.u_buffer; |
415 | 2.52M | for (i = 16; i < 20; i += 2) { |
416 | 1.68M | BLOCKD *d0 = &x->block[i]; |
417 | 1.68M | BLOCKD *d1 = &x->block[i + 1]; |
418 | 1.68M | int dst_stride = x->dst.uv_stride; |
419 | | |
420 | | /* Note: uv mvs already clamped in build_4x4uvmvs() */ |
421 | | |
422 | 1.68M | if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { |
423 | 964k | build_inter_predictors2b(x, d0, base_dst + d0->offset, dst_stride, |
424 | 964k | base_pre, dst_stride); |
425 | 964k | } else { |
426 | 715k | build_inter_predictors_b(d0, base_dst + d0->offset, dst_stride, base_pre, |
427 | 715k | dst_stride, x->subpixel_predict); |
428 | 715k | build_inter_predictors_b(d1, base_dst + d1->offset, dst_stride, base_pre, |
429 | 715k | dst_stride, x->subpixel_predict); |
430 | 715k | } |
431 | 1.68M | } |
432 | | |
433 | 840k | base_dst = x->dst.v_buffer; |
434 | 840k | base_pre = x->pre.v_buffer; |
435 | 2.52M | for (i = 20; i < 24; i += 2) { |
436 | 1.68M | BLOCKD *d0 = &x->block[i]; |
437 | 1.68M | BLOCKD *d1 = &x->block[i + 1]; |
438 | 1.68M | int dst_stride = x->dst.uv_stride; |
439 | | |
440 | | /* Note: uv mvs already clamped in build_4x4uvmvs() */ |
441 | | |
442 | 1.68M | if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { |
443 | 964k | build_inter_predictors2b(x, d0, base_dst + d0->offset, dst_stride, |
444 | 964k | base_pre, dst_stride); |
445 | 964k | } else { |
446 | 715k | build_inter_predictors_b(d0, base_dst + d0->offset, dst_stride, base_pre, |
447 | 715k | dst_stride, x->subpixel_predict); |
448 | 715k | build_inter_predictors_b(d1, base_dst + d1->offset, dst_stride, base_pre, |
449 | 715k | dst_stride, x->subpixel_predict); |
450 | 715k | } |
451 | 1.68M | } |
452 | 840k | } |
453 | | |
454 | 840k | static void build_4x4uvmvs(MACROBLOCKD *x) { |
455 | 840k | int i, j; |
456 | | |
457 | 2.52M | for (i = 0; i < 2; ++i) { |
458 | 5.04M | for (j = 0; j < 2; ++j) { |
459 | 3.36M | int yoffset = i * 8 + j * 2; |
460 | 3.36M | int uoffset = 16 + i * 2 + j; |
461 | 3.36M | int voffset = 20 + i * 2 + j; |
462 | | |
463 | 3.36M | int temp; |
464 | | |
465 | 3.36M | temp = x->mode_info_context->bmi[yoffset + 0].mv.as_mv.row + |
466 | 3.36M | x->mode_info_context->bmi[yoffset + 1].mv.as_mv.row + |
467 | 3.36M | x->mode_info_context->bmi[yoffset + 4].mv.as_mv.row + |
468 | 3.36M | x->mode_info_context->bmi[yoffset + 5].mv.as_mv.row; |
469 | | |
470 | 3.36M | temp += 4 + ((temp >> (sizeof(temp) * CHAR_BIT - 1)) * 8); |
471 | | |
472 | 3.36M | x->block[uoffset].bmi.mv.as_mv.row = (temp / 8) & x->fullpixel_mask; |
473 | | |
474 | 3.36M | temp = x->mode_info_context->bmi[yoffset + 0].mv.as_mv.col + |
475 | 3.36M | x->mode_info_context->bmi[yoffset + 1].mv.as_mv.col + |
476 | 3.36M | x->mode_info_context->bmi[yoffset + 4].mv.as_mv.col + |
477 | 3.36M | x->mode_info_context->bmi[yoffset + 5].mv.as_mv.col; |
478 | | |
479 | 3.36M | temp += 4 + ((temp >> (sizeof(temp) * CHAR_BIT - 1)) * 8); |
480 | | |
481 | 3.36M | x->block[uoffset].bmi.mv.as_mv.col = (temp / 8) & x->fullpixel_mask; |
482 | | |
483 | 3.36M | if (x->mode_info_context->mbmi.need_to_clamp_mvs) { |
484 | 912k | clamp_uvmv_to_umv_border(&x->block[uoffset].bmi.mv.as_mv, x); |
485 | 912k | } |
486 | | |
487 | 3.36M | x->block[voffset].bmi.mv.as_int = x->block[uoffset].bmi.mv.as_int; |
488 | 3.36M | } |
489 | 1.68M | } |
490 | 840k | } |
491 | | |
492 | 2.60M | void vp8_build_inter_predictors_mb(MACROBLOCKD *xd) { |
493 | 2.60M | if (xd->mode_info_context->mbmi.mode != SPLITMV) { |
494 | 1.76M | vp8_build_inter16x16_predictors_mb(xd, xd->dst.y_buffer, xd->dst.u_buffer, |
495 | 1.76M | xd->dst.v_buffer, xd->dst.y_stride, |
496 | 1.76M | xd->dst.uv_stride); |
497 | 1.76M | } else { |
498 | 840k | build_4x4uvmvs(xd); |
499 | 840k | build_inter4x4_predictors_mb(xd); |
500 | 840k | } |
501 | 2.60M | } |