• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "variance.h"
13 #include "vp8/common/filter.h"
14 
15 
vp8_get_mb_ss_c(const short * src_ptr)16 unsigned int vp8_get_mb_ss_c
17 (
18     const short *src_ptr
19 )
20 {
21     unsigned int i = 0, sum = 0;
22 
23     do
24     {
25         sum += (src_ptr[i] * src_ptr[i]);
26         i++;
27     }
28     while (i < 256);
29 
30     return sum;
31 }
32 
33 
variance(const unsigned char * src_ptr,int source_stride,const unsigned char * ref_ptr,int recon_stride,int w,int h,unsigned int * sse,int * sum)34 static void variance(
35     const unsigned char *src_ptr,
36     int  source_stride,
37     const unsigned char *ref_ptr,
38     int  recon_stride,
39     int  w,
40     int  h,
41     unsigned int *sse,
42     int *sum)
43 {
44     int i, j;
45     int diff;
46 
47     *sum = 0;
48     *sse = 0;
49 
50     for (i = 0; i < h; i++)
51     {
52         for (j = 0; j < w; j++)
53         {
54             diff = src_ptr[j] - ref_ptr[j];
55             *sum += diff;
56             *sse += diff * diff;
57         }
58 
59         src_ptr += source_stride;
60         ref_ptr += recon_stride;
61     }
62 }
63 
64 unsigned int
vp8_get8x8var_c(const unsigned char * src_ptr,int source_stride,const unsigned char * ref_ptr,int recon_stride,unsigned int * SSE,int * Sum)65 vp8_get8x8var_c
66 (
67     const unsigned char *src_ptr,
68     int  source_stride,
69     const unsigned char *ref_ptr,
70     int  recon_stride,
71     unsigned int *SSE,
72     int *Sum
73 )
74 {
75 
76     variance(src_ptr, source_stride, ref_ptr, recon_stride, 8, 8, SSE, Sum);
77     return (*SSE - (((*Sum) * (*Sum)) >> 6));
78 }
79 
80 unsigned int
vp8_get16x16var_c(const unsigned char * src_ptr,int source_stride,const unsigned char * ref_ptr,int recon_stride,unsigned int * SSE,int * Sum)81 vp8_get16x16var_c
82 (
83     const unsigned char *src_ptr,
84     int  source_stride,
85     const unsigned char *ref_ptr,
86     int  recon_stride,
87     unsigned int *SSE,
88     int *Sum
89 )
90 {
91 
92     variance(src_ptr, source_stride, ref_ptr, recon_stride, 16, 16, SSE, Sum);
93     return (*SSE - (((*Sum) * (*Sum)) >> 8));
94 
95 }
96 
97 
98 
vp8_variance16x16_c(const unsigned char * src_ptr,int source_stride,const unsigned char * ref_ptr,int recon_stride,unsigned int * sse)99 unsigned int vp8_variance16x16_c(
100     const unsigned char *src_ptr,
101     int  source_stride,
102     const unsigned char *ref_ptr,
103     int  recon_stride,
104     unsigned int *sse)
105 {
106     unsigned int var;
107     int avg;
108 
109 
110     variance(src_ptr, source_stride, ref_ptr, recon_stride, 16, 16, &var, &avg);
111     *sse = var;
112     return (var - ((avg * avg) >> 8));
113 }
114 
vp8_variance8x16_c(const unsigned char * src_ptr,int source_stride,const unsigned char * ref_ptr,int recon_stride,unsigned int * sse)115 unsigned int vp8_variance8x16_c(
116     const unsigned char *src_ptr,
117     int  source_stride,
118     const unsigned char *ref_ptr,
119     int  recon_stride,
120     unsigned int *sse)
121 {
122     unsigned int var;
123     int avg;
124 
125 
126     variance(src_ptr, source_stride, ref_ptr, recon_stride, 8, 16, &var, &avg);
127     *sse = var;
128     return (var - ((avg * avg) >> 7));
129 }
130 
vp8_variance16x8_c(const unsigned char * src_ptr,int source_stride,const unsigned char * ref_ptr,int recon_stride,unsigned int * sse)131 unsigned int vp8_variance16x8_c(
132     const unsigned char *src_ptr,
133     int  source_stride,
134     const unsigned char *ref_ptr,
135     int  recon_stride,
136     unsigned int *sse)
137 {
138     unsigned int var;
139     int avg;
140 
141 
142     variance(src_ptr, source_stride, ref_ptr, recon_stride, 16, 8, &var, &avg);
143     *sse = var;
144     return (var - ((avg * avg) >> 7));
145 }
146 
147 
vp8_variance8x8_c(const unsigned char * src_ptr,int source_stride,const unsigned char * ref_ptr,int recon_stride,unsigned int * sse)148 unsigned int vp8_variance8x8_c(
149     const unsigned char *src_ptr,
150     int  source_stride,
151     const unsigned char *ref_ptr,
152     int  recon_stride,
153     unsigned int *sse)
154 {
155     unsigned int var;
156     int avg;
157 
158 
159     variance(src_ptr, source_stride, ref_ptr, recon_stride, 8, 8, &var, &avg);
160     *sse = var;
161     return (var - ((avg * avg) >> 6));
162 }
163 
vp8_variance4x4_c(const unsigned char * src_ptr,int source_stride,const unsigned char * ref_ptr,int recon_stride,unsigned int * sse)164 unsigned int vp8_variance4x4_c(
165     const unsigned char *src_ptr,
166     int  source_stride,
167     const unsigned char *ref_ptr,
168     int  recon_stride,
169     unsigned int *sse)
170 {
171     unsigned int var;
172     int avg;
173 
174 
175     variance(src_ptr, source_stride, ref_ptr, recon_stride, 4, 4, &var, &avg);
176     *sse = var;
177     return (var - ((avg * avg) >> 4));
178 }
179 
180 
vp8_mse16x16_c(const unsigned char * src_ptr,int source_stride,const unsigned char * ref_ptr,int recon_stride,unsigned int * sse)181 unsigned int vp8_mse16x16_c(
182     const unsigned char *src_ptr,
183     int  source_stride,
184     const unsigned char *ref_ptr,
185     int  recon_stride,
186     unsigned int *sse)
187 {
188     unsigned int var;
189     int avg;
190 
191     variance(src_ptr, source_stride, ref_ptr, recon_stride, 16, 16, &var, &avg);
192     *sse = var;
193     return var;
194 }
195 
196 
197 /****************************************************************************
198  *
199  *  ROUTINE       : filter_block2d_bil_first_pass
200  *
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.
207  *
208  *  OUTPUTS       : INT32 *output_ptr        : Pointer to filtered block.
209  *
210  *  RETURNS       : void
211  *
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.
216  *
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
222  *                  to the next.
223  *
224  ****************************************************************************/
var_filter_block2d_bil_first_pass(const unsigned char * src_ptr,unsigned short * output_ptr,unsigned int src_pixels_per_line,int pixel_step,unsigned int output_height,unsigned int output_width,const short * vp8_filter)225 static void var_filter_block2d_bil_first_pass
226 (
227     const unsigned char *src_ptr,
228     unsigned short *output_ptr,
229     unsigned int src_pixels_per_line,
230     int pixel_step,
231     unsigned int output_height,
232     unsigned int output_width,
233     const short *vp8_filter
234 )
235 {
236     unsigned int i, j;
237 
238     for (i = 0; i < output_height; i++)
239     {
240         for (j = 0; j < output_width; j++)
241         {
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;
246             src_ptr++;
247         }
248 
249         // Next row...
250         src_ptr    += src_pixels_per_line - output_width;
251         output_ptr += output_width;
252     }
253 }
254 
255 /****************************************************************************
256  *
257  *  ROUTINE       : filter_block2d_bil_second_pass
258  *
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.
265  *
266  *  OUTPUTS       : UINT16 *output_ptr       : Pointer to filtered block.
267  *
268  *  RETURNS       : void
269  *
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.
274  *
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
280  *                  to the next.
281  *
282  ****************************************************************************/
var_filter_block2d_bil_second_pass(const unsigned short * src_ptr,unsigned char * output_ptr,unsigned int src_pixels_per_line,unsigned int pixel_step,unsigned int output_height,unsigned int output_width,const short * vp8_filter)283 static void var_filter_block2d_bil_second_pass
284 (
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
292 )
293 {
294     unsigned int  i, j;
295     int  Temp;
296 
297     for (i = 0; i < output_height; i++)
298     {
299         for (j = 0; j < output_width; j++)
300         {
301             // Apply filter
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);
306             src_ptr++;
307         }
308 
309         // Next row...
310         src_ptr    += src_pixels_per_line - output_width;
311         output_ptr += output_width;
312     }
313 }
314 
315 
vp8_sub_pixel_variance4x4_c(const unsigned char * src_ptr,int src_pixels_per_line,int xoffset,int yoffset,const unsigned char * dst_ptr,int dst_pixels_per_line,unsigned int * sse)316 unsigned int vp8_sub_pixel_variance4x4_c
317 (
318     const unsigned char  *src_ptr,
319     int  src_pixels_per_line,
320     int  xoffset,
321     int  yoffset,
322     const unsigned char *dst_ptr,
323     int dst_pixels_per_line,
324     unsigned int *sse
325 )
326 {
327     unsigned char  temp2[20*16];
328     const short *HFilter, *VFilter;
329     unsigned short FData3[5*4]; // Temp data bufffer used in filtering
330 
331     HFilter = vp8_bilinear_filters[xoffset];
332     VFilter = vp8_bilinear_filters[yoffset];
333 
334     // First filter 1d Horizontal
335     var_filter_block2d_bil_first_pass(src_ptr, FData3, src_pixels_per_line, 1, 5, 4, HFilter);
336 
337     // Now filter Verticaly
338     var_filter_block2d_bil_second_pass(FData3, temp2, 4,  4,  4,  4, VFilter);
339 
340     return vp8_variance4x4_c(temp2, 4, dst_ptr, dst_pixels_per_line, sse);
341 }
342 
343 
vp8_sub_pixel_variance8x8_c(const unsigned char * src_ptr,int src_pixels_per_line,int xoffset,int yoffset,const unsigned char * dst_ptr,int dst_pixels_per_line,unsigned int * sse)344 unsigned int vp8_sub_pixel_variance8x8_c
345 (
346     const unsigned char  *src_ptr,
347     int  src_pixels_per_line,
348     int  xoffset,
349     int  yoffset,
350     const unsigned char *dst_ptr,
351     int dst_pixels_per_line,
352     unsigned int *sse
353 )
354 {
355     unsigned short FData3[9*8]; // Temp data bufffer used in filtering
356     unsigned char  temp2[20*16];
357     const short *HFilter, *VFilter;
358 
359     HFilter = vp8_bilinear_filters[xoffset];
360     VFilter = vp8_bilinear_filters[yoffset];
361 
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);
364 
365     return vp8_variance8x8_c(temp2, 8, dst_ptr, dst_pixels_per_line, sse);
366 }
367 
vp8_sub_pixel_variance16x16_c(const unsigned char * src_ptr,int src_pixels_per_line,int xoffset,int yoffset,const unsigned char * dst_ptr,int dst_pixels_per_line,unsigned int * sse)368 unsigned int vp8_sub_pixel_variance16x16_c
369 (
370     const unsigned char  *src_ptr,
371     int  src_pixels_per_line,
372     int  xoffset,
373     int  yoffset,
374     const unsigned char *dst_ptr,
375     int dst_pixels_per_line,
376     unsigned int *sse
377 )
378 {
379     unsigned short FData3[17*16];   // Temp data bufffer used in filtering
380     unsigned char  temp2[20*16];
381     const short *HFilter, *VFilter;
382 
383     HFilter = vp8_bilinear_filters[xoffset];
384     VFilter = vp8_bilinear_filters[yoffset];
385 
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);
388 
389     return vp8_variance16x16_c(temp2, 16, dst_ptr, dst_pixels_per_line, sse);
390 }
391 
392 
vp8_variance_halfpixvar16x16_h_c(const unsigned char * src_ptr,int source_stride,const unsigned char * ref_ptr,int recon_stride,unsigned int * sse)393 unsigned int vp8_variance_halfpixvar16x16_h_c(
394     const unsigned char *src_ptr,
395     int  source_stride,
396     const unsigned char *ref_ptr,
397     int  recon_stride,
398     unsigned int *sse)
399 {
400     return vp8_sub_pixel_variance16x16_c(src_ptr, source_stride, 4, 0,
401                                          ref_ptr, recon_stride, sse);
402 }
403 
404 
vp8_variance_halfpixvar16x16_v_c(const unsigned char * src_ptr,int source_stride,const unsigned char * ref_ptr,int recon_stride,unsigned int * sse)405 unsigned int vp8_variance_halfpixvar16x16_v_c(
406     const unsigned char *src_ptr,
407     int  source_stride,
408     const unsigned char *ref_ptr,
409     int  recon_stride,
410     unsigned int *sse)
411 {
412     return vp8_sub_pixel_variance16x16_c(src_ptr, source_stride, 0, 4,
413                                          ref_ptr, recon_stride, sse);
414 }
415 
416 
vp8_variance_halfpixvar16x16_hv_c(const unsigned char * src_ptr,int source_stride,const unsigned char * ref_ptr,int recon_stride,unsigned int * sse)417 unsigned int vp8_variance_halfpixvar16x16_hv_c(
418     const unsigned char *src_ptr,
419     int  source_stride,
420     const unsigned char *ref_ptr,
421     int  recon_stride,
422     unsigned int *sse)
423 {
424     return vp8_sub_pixel_variance16x16_c(src_ptr, source_stride, 4, 4,
425                                          ref_ptr, recon_stride, sse);
426 }
427 
428 
vp8_sub_pixel_mse16x16_c(const unsigned char * src_ptr,int src_pixels_per_line,int xoffset,int yoffset,const unsigned char * dst_ptr,int dst_pixels_per_line,unsigned int * sse)429 unsigned int vp8_sub_pixel_mse16x16_c
430 (
431     const unsigned char  *src_ptr,
432     int  src_pixels_per_line,
433     int  xoffset,
434     int  yoffset,
435     const unsigned char *dst_ptr,
436     int dst_pixels_per_line,
437     unsigned int *sse
438 )
439 {
440     vp8_sub_pixel_variance16x16_c(src_ptr, src_pixels_per_line, xoffset, yoffset, dst_ptr, dst_pixels_per_line, sse);
441     return *sse;
442 }
443 
vp8_sub_pixel_variance16x8_c(const unsigned char * src_ptr,int src_pixels_per_line,int xoffset,int yoffset,const unsigned char * dst_ptr,int dst_pixels_per_line,unsigned int * sse)444 unsigned int vp8_sub_pixel_variance16x8_c
445 (
446     const unsigned char  *src_ptr,
447     int  src_pixels_per_line,
448     int  xoffset,
449     int  yoffset,
450     const unsigned char *dst_ptr,
451     int dst_pixels_per_line,
452     unsigned int *sse
453 )
454 {
455     unsigned short FData3[16*9];    // Temp data bufffer used in filtering
456     unsigned char  temp2[20*16];
457     const short *HFilter, *VFilter;
458 
459     HFilter = vp8_bilinear_filters[xoffset];
460     VFilter = vp8_bilinear_filters[yoffset];
461 
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);
464 
465     return vp8_variance16x8_c(temp2, 16, dst_ptr, dst_pixels_per_line, sse);
466 }
467 
vp8_sub_pixel_variance8x16_c(const unsigned char * src_ptr,int src_pixels_per_line,int xoffset,int yoffset,const unsigned char * dst_ptr,int dst_pixels_per_line,unsigned int * sse)468 unsigned int vp8_sub_pixel_variance8x16_c
469 (
470     const unsigned char  *src_ptr,
471     int  src_pixels_per_line,
472     int  xoffset,
473     int  yoffset,
474     const unsigned char *dst_ptr,
475     int dst_pixels_per_line,
476     unsigned int *sse
477 )
478 {
479     unsigned short FData3[9*16];    // Temp data bufffer used in filtering
480     unsigned char  temp2[20*16];
481     const short *HFilter, *VFilter;
482 
483 
484     HFilter = vp8_bilinear_filters[xoffset];
485     VFilter = vp8_bilinear_filters[yoffset];
486 
487 
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);
490 
491     return vp8_variance8x16_c(temp2, 8, dst_ptr, dst_pixels_per_line, sse);
492 }
493