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.
13 #include "vp8/common/filter.h"
16 unsigned int vp8_get_mb_ss_c
21 unsigned int i
= 0, sum
= 0;
25 sum
+= (src_ptr
[i
] * src_ptr
[i
]);
35 const unsigned char *src_ptr
,
37 const unsigned char *ref_ptr
,
50 for (i
= 0; i
< h
; i
++)
52 for (j
= 0; j
< w
; j
++)
54 diff
= src_ptr
[j
] - ref_ptr
[j
];
59 src_ptr
+= source_stride
;
60 ref_ptr
+= recon_stride
;
67 const unsigned char *src_ptr
,
69 const unsigned char *ref_ptr
,
76 variance(src_ptr
, source_stride
, ref_ptr
, recon_stride
, 8, 8, SSE
, Sum
);
77 return (*SSE
- (((*Sum
) * (*Sum
)) >> 6));
83 const unsigned char *src_ptr
,
85 const unsigned char *ref_ptr
,
92 variance(src_ptr
, source_stride
, ref_ptr
, recon_stride
, 16, 16, SSE
, Sum
);
93 return (*SSE
- (((*Sum
) * (*Sum
)) >> 8));
99 unsigned int vp8_variance16x16_c(
100 const unsigned char *src_ptr
,
102 const unsigned char *ref_ptr
,
110 variance(src_ptr
, source_stride
, ref_ptr
, recon_stride
, 16, 16, &var
, &avg
);
112 return (var
- ((avg
* avg
) >> 8));
115 unsigned int vp8_variance8x16_c(
116 const unsigned char *src_ptr
,
118 const unsigned char *ref_ptr
,
126 variance(src_ptr
, source_stride
, ref_ptr
, recon_stride
, 8, 16, &var
, &avg
);
128 return (var
- ((avg
* avg
) >> 7));
131 unsigned int vp8_variance16x8_c(
132 const unsigned char *src_ptr
,
134 const unsigned char *ref_ptr
,
142 variance(src_ptr
, source_stride
, ref_ptr
, recon_stride
, 16, 8, &var
, &avg
);
144 return (var
- ((avg
* avg
) >> 7));
148 unsigned int vp8_variance8x8_c(
149 const unsigned char *src_ptr
,
151 const unsigned char *ref_ptr
,
159 variance(src_ptr
, source_stride
, ref_ptr
, recon_stride
, 8, 8, &var
, &avg
);
161 return (var
- ((avg
* avg
) >> 6));
164 unsigned int vp8_variance4x4_c(
165 const unsigned char *src_ptr
,
167 const unsigned char *ref_ptr
,
175 variance(src_ptr
, source_stride
, ref_ptr
, recon_stride
, 4, 4, &var
, &avg
);
177 return (var
- ((avg
* avg
) >> 4));
181 unsigned int vp8_mse16x16_c(
182 const unsigned char *src_ptr
,
184 const unsigned char *ref_ptr
,
191 variance(src_ptr
, source_stride
, ref_ptr
, recon_stride
, 16, 16, &var
, &avg
);
197 /****************************************************************************
199 * ROUTINE : filter_block2d_bil_first_pass
201 * INPUTS : UINT8 *src_ptr : Pointer to source block.
202 * UINT32 src_pixels_per_line : Stride of input block.
203 * UINT32 pixel_step : Offset between filter input samples (see notes).
204 * UINT32 output_height : Input block height.
205 * UINT32 output_width : Input block width.
206 * INT32 *vp8_filter : Array of 2 bi-linear filter taps.
208 * OUTPUTS : INT32 *output_ptr : Pointer to filtered block.
212 * FUNCTION : Applies a 1-D 2-tap bi-linear filter to the source block in
213 * either horizontal or vertical direction to produce the
214 * filtered output block. Used to implement first-pass
215 * of 2-D separable filter.
217 * SPECIAL NOTES : Produces INT32 output to retain precision for next pass.
218 * Two filter taps should sum to VP8_FILTER_WEIGHT.
219 * pixel_step defines whether the filter is applied
220 * horizontally (pixel_step=1) or vertically (pixel_step=stride).
221 * It defines the offset required to move from one input
224 ****************************************************************************/
225 static void var_filter_block2d_bil_first_pass
227 const unsigned char *src_ptr
,
228 unsigned short *output_ptr
,
229 unsigned int src_pixels_per_line
,
231 unsigned int output_height
,
232 unsigned int output_width
,
233 const short *vp8_filter
238 for (i
= 0; i
< output_height
; i
++)
240 for (j
= 0; j
< output_width
; j
++)
242 // Apply bilinear filter
243 output_ptr
[j
] = (((int)src_ptr
[0] * vp8_filter
[0]) +
244 ((int)src_ptr
[pixel_step
] * vp8_filter
[1]) +
245 (VP8_FILTER_WEIGHT
/ 2)) >> VP8_FILTER_SHIFT
;
250 src_ptr
+= src_pixels_per_line
- output_width
;
251 output_ptr
+= output_width
;
255 /****************************************************************************
257 * ROUTINE : filter_block2d_bil_second_pass
259 * INPUTS : INT32 *src_ptr : Pointer to source block.
260 * UINT32 src_pixels_per_line : Stride of input block.
261 * UINT32 pixel_step : Offset between filter input samples (see notes).
262 * UINT32 output_height : Input block height.
263 * UINT32 output_width : Input block width.
264 * INT32 *vp8_filter : Array of 2 bi-linear filter taps.
266 * OUTPUTS : UINT16 *output_ptr : Pointer to filtered block.
270 * FUNCTION : Applies a 1-D 2-tap bi-linear filter to the source block in
271 * either horizontal or vertical direction to produce the
272 * filtered output block. Used to implement second-pass
273 * of 2-D separable filter.
275 * SPECIAL NOTES : Requires 32-bit input as produced by filter_block2d_bil_first_pass.
276 * Two filter taps should sum to VP8_FILTER_WEIGHT.
277 * pixel_step defines whether the filter is applied
278 * horizontally (pixel_step=1) or vertically (pixel_step=stride).
279 * It defines the offset required to move from one input
282 ****************************************************************************/
283 static void var_filter_block2d_bil_second_pass
285 const unsigned short *src_ptr
,
286 unsigned char *output_ptr
,
287 unsigned int src_pixels_per_line
,
288 unsigned int pixel_step
,
289 unsigned int output_height
,
290 unsigned int output_width
,
291 const short *vp8_filter
297 for (i
= 0; i
< output_height
; i
++)
299 for (j
= 0; j
< output_width
; j
++)
302 Temp
= ((int)src_ptr
[0] * vp8_filter
[0]) +
303 ((int)src_ptr
[pixel_step
] * vp8_filter
[1]) +
304 (VP8_FILTER_WEIGHT
/ 2);
305 output_ptr
[j
] = (unsigned int)(Temp
>> VP8_FILTER_SHIFT
);
310 src_ptr
+= src_pixels_per_line
- output_width
;
311 output_ptr
+= output_width
;
316 unsigned int vp8_sub_pixel_variance4x4_c
318 const unsigned char *src_ptr
,
319 int src_pixels_per_line
,
322 const unsigned char *dst_ptr
,
323 int dst_pixels_per_line
,
327 unsigned char temp2
[20*16];
328 const short *HFilter
, *VFilter
;
329 unsigned short FData3
[5*4]; // Temp data bufffer used in filtering
331 HFilter
= vp8_bilinear_filters
[xoffset
];
332 VFilter
= vp8_bilinear_filters
[yoffset
];
334 // First filter 1d Horizontal
335 var_filter_block2d_bil_first_pass(src_ptr
, FData3
, src_pixels_per_line
, 1, 5, 4, HFilter
);
337 // Now filter Verticaly
338 var_filter_block2d_bil_second_pass(FData3
, temp2
, 4, 4, 4, 4, VFilter
);
340 return vp8_variance4x4_c(temp2
, 4, dst_ptr
, dst_pixels_per_line
, sse
);
344 unsigned int vp8_sub_pixel_variance8x8_c
346 const unsigned char *src_ptr
,
347 int src_pixels_per_line
,
350 const unsigned char *dst_ptr
,
351 int dst_pixels_per_line
,
355 unsigned short FData3
[9*8]; // Temp data bufffer used in filtering
356 unsigned char temp2
[20*16];
357 const short *HFilter
, *VFilter
;
359 HFilter
= vp8_bilinear_filters
[xoffset
];
360 VFilter
= vp8_bilinear_filters
[yoffset
];
362 var_filter_block2d_bil_first_pass(src_ptr
, FData3
, src_pixels_per_line
, 1, 9, 8, HFilter
);
363 var_filter_block2d_bil_second_pass(FData3
, temp2
, 8, 8, 8, 8, VFilter
);
365 return vp8_variance8x8_c(temp2
, 8, dst_ptr
, dst_pixels_per_line
, sse
);
368 unsigned int vp8_sub_pixel_variance16x16_c
370 const unsigned char *src_ptr
,
371 int src_pixels_per_line
,
374 const unsigned char *dst_ptr
,
375 int dst_pixels_per_line
,
379 unsigned short FData3
[17*16]; // Temp data bufffer used in filtering
380 unsigned char temp2
[20*16];
381 const short *HFilter
, *VFilter
;
383 HFilter
= vp8_bilinear_filters
[xoffset
];
384 VFilter
= vp8_bilinear_filters
[yoffset
];
386 var_filter_block2d_bil_first_pass(src_ptr
, FData3
, src_pixels_per_line
, 1, 17, 16, HFilter
);
387 var_filter_block2d_bil_second_pass(FData3
, temp2
, 16, 16, 16, 16, VFilter
);
389 return vp8_variance16x16_c(temp2
, 16, dst_ptr
, dst_pixels_per_line
, sse
);
393 unsigned int vp8_variance_halfpixvar16x16_h_c(
394 const unsigned char *src_ptr
,
396 const unsigned char *ref_ptr
,
400 return vp8_sub_pixel_variance16x16_c(src_ptr
, source_stride
, 4, 0,
401 ref_ptr
, recon_stride
, sse
);
405 unsigned int vp8_variance_halfpixvar16x16_v_c(
406 const unsigned char *src_ptr
,
408 const unsigned char *ref_ptr
,
412 return vp8_sub_pixel_variance16x16_c(src_ptr
, source_stride
, 0, 4,
413 ref_ptr
, recon_stride
, sse
);
417 unsigned int vp8_variance_halfpixvar16x16_hv_c(
418 const unsigned char *src_ptr
,
420 const unsigned char *ref_ptr
,
424 return vp8_sub_pixel_variance16x16_c(src_ptr
, source_stride
, 4, 4,
425 ref_ptr
, recon_stride
, sse
);
429 unsigned int vp8_sub_pixel_mse16x16_c
431 const unsigned char *src_ptr
,
432 int src_pixels_per_line
,
435 const unsigned char *dst_ptr
,
436 int dst_pixels_per_line
,
440 vp8_sub_pixel_variance16x16_c(src_ptr
, src_pixels_per_line
, xoffset
, yoffset
, dst_ptr
, dst_pixels_per_line
, sse
);
444 unsigned int vp8_sub_pixel_variance16x8_c
446 const unsigned char *src_ptr
,
447 int src_pixels_per_line
,
450 const unsigned char *dst_ptr
,
451 int dst_pixels_per_line
,
455 unsigned short FData3
[16*9]; // Temp data bufffer used in filtering
456 unsigned char temp2
[20*16];
457 const short *HFilter
, *VFilter
;
459 HFilter
= vp8_bilinear_filters
[xoffset
];
460 VFilter
= vp8_bilinear_filters
[yoffset
];
462 var_filter_block2d_bil_first_pass(src_ptr
, FData3
, src_pixels_per_line
, 1, 9, 16, HFilter
);
463 var_filter_block2d_bil_second_pass(FData3
, temp2
, 16, 16, 8, 16, VFilter
);
465 return vp8_variance16x8_c(temp2
, 16, dst_ptr
, dst_pixels_per_line
, sse
);
468 unsigned int vp8_sub_pixel_variance8x16_c
470 const unsigned char *src_ptr
,
471 int src_pixels_per_line
,
474 const unsigned char *dst_ptr
,
475 int dst_pixels_per_line
,
479 unsigned short FData3
[9*16]; // Temp data bufffer used in filtering
480 unsigned char temp2
[20*16];
481 const short *HFilter
, *VFilter
;
484 HFilter
= vp8_bilinear_filters
[xoffset
];
485 VFilter
= vp8_bilinear_filters
[yoffset
];
488 var_filter_block2d_bil_first_pass(src_ptr
, FData3
, src_pixels_per_line
, 1, 17, 8, HFilter
);
489 var_filter_block2d_bil_second_pass(FData3
, temp2
, 8, 8, 16, 8, VFilter
);
491 return vp8_variance8x16_c(temp2
, 8, dst_ptr
, dst_pixels_per_line
, sse
);