e107cb19d0c71064fc1a448ce682220e5c4785d7
[profile/ivi/libvpx.git] / vp8 / encoder / x86 / variance_mmx.c
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 "vp8/encoder/variance.h"
13 #include "vp8/common/pragmas.h"
14 #include "vpx_ports/mem.h"
15
16 extern void filter_block1d_h6_mmx
17 (
18     const unsigned char *src_ptr,
19     unsigned short *output_ptr,
20     unsigned int src_pixels_per_line,
21     unsigned int pixel_step,
22     unsigned int output_height,
23     unsigned int output_width,
24     short *vp7_filter
25 );
26 extern void filter_block1d_v6_mmx
27 (
28     const short *src_ptr,
29     unsigned char *output_ptr,
30     unsigned int pixels_per_line,
31     unsigned int pixel_step,
32     unsigned int output_height,
33     unsigned int output_width,
34     short *vp7_filter
35 );
36
37 extern unsigned int vp8_get_mb_ss_mmx(short *src_ptr);
38 extern unsigned int vp8_get8x8var_mmx
39 (
40     const unsigned char *src_ptr,
41     int  source_stride,
42     const unsigned char *ref_ptr,
43     int  recon_stride,
44     unsigned int *SSE,
45     int *Sum
46 );
47 extern unsigned int vp8_get4x4var_mmx
48 (
49     const unsigned char *src_ptr,
50     int  source_stride,
51     const unsigned char *ref_ptr,
52     int  recon_stride,
53     unsigned int *SSE,
54     int *Sum
55 );
56 extern unsigned int vp8_get4x4sse_cs_mmx
57 (
58     const unsigned char *src_ptr,
59     int  source_stride,
60     const unsigned char *ref_ptr,
61     int  recon_stride
62 );
63 extern void vp8_filter_block2d_bil4x4_var_mmx
64 (
65     const unsigned char *ref_ptr,
66     int ref_pixels_per_line,
67     const unsigned char *src_ptr,
68     int src_pixels_per_line,
69     const short *HFilter,
70     const short *VFilter,
71     int *sum,
72     unsigned int *sumsquared
73 );
74 extern void vp8_filter_block2d_bil_var_mmx
75 (
76     const unsigned char *ref_ptr,
77     int ref_pixels_per_line,
78     const unsigned char *src_ptr,
79     int src_pixels_per_line,
80     unsigned int Height,
81     const short *HFilter,
82     const short *VFilter,
83     int *sum,
84     unsigned int *sumsquared
85 );
86 extern unsigned int vp8_get16x16pred_error_mmx
87 (
88     unsigned char *src_ptr,
89     int src_stride,
90     unsigned char *ref_ptr,
91     int ref_stride
92 );
93
94
95 unsigned int vp8_get16x16var_mmx(
96     const unsigned char *src_ptr,
97     int  source_stride,
98     const unsigned char *ref_ptr,
99     int  recon_stride,
100     unsigned *SSE,
101     unsigned *SUM
102 )
103 {
104     unsigned int sse0, sse1, sse2, sse3, var;
105     int sum0, sum1, sum2, sum3, avg;
106
107
108     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
109     vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
110     vp8_get8x8var_mmx(src_ptr + 8 * source_stride, source_stride, ref_ptr + 8 * recon_stride, recon_stride, &sse2, &sum2) ;
111     vp8_get8x8var_mmx(src_ptr + 8 * source_stride + 8, source_stride, ref_ptr + 8 * recon_stride + 8, recon_stride, &sse3, &sum3);
112
113     var = sse0 + sse1 + sse2 + sse3;
114     avg = sum0 + sum1 + sum2 + sum3;
115
116     *SSE = var;
117     *SUM = avg;
118     return (var - ((avg * avg) >> 8));
119
120 }
121
122
123
124
125
126 unsigned int vp8_variance4x4_mmx(
127     const unsigned char *src_ptr,
128     int  source_stride,
129     const unsigned char *ref_ptr,
130     int  recon_stride,
131     unsigned int *sse)
132 {
133     unsigned int var;
134     int avg;
135
136     vp8_get4x4var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &var, &avg) ;
137     *sse = var;
138     return (var - ((avg * avg) >> 4));
139
140 }
141
142 unsigned int vp8_variance8x8_mmx(
143     const unsigned char *src_ptr,
144     int  source_stride,
145     const unsigned char *ref_ptr,
146     int  recon_stride,
147     unsigned int *sse)
148 {
149     unsigned int var;
150     int avg;
151
152     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &var, &avg) ;
153     *sse = var;
154
155     return (var - ((avg * avg) >> 6));
156
157 }
158
159 unsigned int vp8_mse16x16_mmx(
160     const unsigned char *src_ptr,
161     int  source_stride,
162     const unsigned char *ref_ptr,
163     int  recon_stride,
164     unsigned int *sse)
165 {
166     unsigned int sse0, sse1, sse2, sse3, var;
167     int sum0, sum1, sum2, sum3;
168
169
170     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
171     vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
172     vp8_get8x8var_mmx(src_ptr + 8 * source_stride, source_stride, ref_ptr + 8 * recon_stride, recon_stride, &sse2, &sum2) ;
173     vp8_get8x8var_mmx(src_ptr + 8 * source_stride + 8, source_stride, ref_ptr + 8 * recon_stride + 8, recon_stride, &sse3, &sum3);
174
175     var = sse0 + sse1 + sse2 + sse3;
176     *sse = var;
177     return var;
178 }
179
180
181 unsigned int vp8_variance16x16_mmx(
182     const unsigned char *src_ptr,
183     int  source_stride,
184     const unsigned char *ref_ptr,
185     int  recon_stride,
186     int *sse)
187 {
188     unsigned int sse0, sse1, sse2, sse3, var;
189     int sum0, sum1, sum2, sum3, avg;
190
191
192     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
193     vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
194     vp8_get8x8var_mmx(src_ptr + 8 * source_stride, source_stride, ref_ptr + 8 * recon_stride, recon_stride, &sse2, &sum2) ;
195     vp8_get8x8var_mmx(src_ptr + 8 * source_stride + 8, source_stride, ref_ptr + 8 * recon_stride + 8, recon_stride, &sse3, &sum3);
196
197     var = sse0 + sse1 + sse2 + sse3;
198     avg = sum0 + sum1 + sum2 + sum3;
199     *sse = var;
200     return (var - ((avg * avg) >> 8));
201 }
202
203 unsigned int vp8_variance16x8_mmx(
204     const unsigned char *src_ptr,
205     int  source_stride,
206     const unsigned char *ref_ptr,
207     int  recon_stride,
208     unsigned int *sse)
209 {
210     unsigned int sse0, sse1, var;
211     int sum0, sum1, avg;
212
213     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
214     vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
215
216     var = sse0 + sse1;
217     avg = sum0 + sum1;
218     *sse = var;
219     return (var - ((avg * avg) >> 7));
220
221 }
222
223
224 unsigned int vp8_variance8x16_mmx(
225     const unsigned char *src_ptr,
226     int  source_stride,
227     const unsigned char *ref_ptr,
228     int  recon_stride,
229     unsigned int *sse)
230 {
231     unsigned int sse0, sse1, var;
232     int sum0, sum1, avg;
233
234     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
235     vp8_get8x8var_mmx(src_ptr + 8 * source_stride, source_stride, ref_ptr + 8 * recon_stride, recon_stride, &sse1, &sum1) ;
236
237     var = sse0 + sse1;
238     avg = sum0 + sum1;
239     *sse = var;
240
241     return (var - ((avg * avg) >> 7));
242
243 }
244
245
246
247
248 ///////////////////////////////////////////////////////////////////////////
249 // the mmx function that does the bilinear filtering and var calculation //
250 // int one pass                                                          //
251 ///////////////////////////////////////////////////////////////////////////
252 DECLARE_ALIGNED(16, const short, vp8_vp7_bilinear_filters_mmx[8][8]) =
253 {
254     { 128, 128, 128, 128,  0,  0,  0,  0 },
255     { 112, 112, 112, 112, 16, 16, 16, 16 },
256     {  96, 96, 96, 96, 32, 32, 32, 32 },
257     {  80, 80, 80, 80, 48, 48, 48, 48 },
258     {  64, 64, 64, 64, 64, 64, 64, 64 },
259     {  48, 48, 48, 48, 80, 80, 80, 80 },
260     {  32, 32, 32, 32, 96, 96, 96, 96 },
261     {  16, 16, 16, 16, 112, 112, 112, 112 }
262 };
263
264 unsigned int vp8_sub_pixel_variance4x4_mmx
265 (
266     const unsigned char  *src_ptr,
267     int  src_pixels_per_line,
268     int  xoffset,
269     int  yoffset,
270     const unsigned char *dst_ptr,
271     int dst_pixels_per_line,
272     unsigned int *sse)
273
274 {
275     int xsum;
276     unsigned int xxsum;
277     vp8_filter_block2d_bil4x4_var_mmx(
278         src_ptr, src_pixels_per_line,
279         dst_ptr, dst_pixels_per_line,
280         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
281         &xsum, &xxsum
282     );
283     *sse = xxsum;
284     return (xxsum - ((xsum * xsum) >> 4));
285 }
286
287
288 unsigned int vp8_sub_pixel_variance8x8_mmx
289 (
290     const unsigned char  *src_ptr,
291     int  src_pixels_per_line,
292     int  xoffset,
293     int  yoffset,
294     const unsigned char *dst_ptr,
295     int dst_pixels_per_line,
296     unsigned int *sse
297 )
298 {
299
300     int xsum;
301     unsigned int xxsum;
302     vp8_filter_block2d_bil_var_mmx(
303         src_ptr, src_pixels_per_line,
304         dst_ptr, dst_pixels_per_line, 8,
305         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
306         &xsum, &xxsum
307     );
308     *sse = xxsum;
309     return (xxsum - ((xsum * xsum) >> 6));
310 }
311
312 unsigned int vp8_sub_pixel_variance16x16_mmx
313 (
314     const unsigned char  *src_ptr,
315     int  src_pixels_per_line,
316     int  xoffset,
317     int  yoffset,
318     const unsigned char *dst_ptr,
319     int dst_pixels_per_line,
320     unsigned int *sse
321 )
322 {
323
324     int xsum0, xsum1;
325     unsigned int xxsum0, xxsum1;
326
327
328     vp8_filter_block2d_bil_var_mmx(
329         src_ptr, src_pixels_per_line,
330         dst_ptr, dst_pixels_per_line, 16,
331         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
332         &xsum0, &xxsum0
333     );
334
335
336     vp8_filter_block2d_bil_var_mmx(
337         src_ptr + 8, src_pixels_per_line,
338         dst_ptr + 8, dst_pixels_per_line, 16,
339         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
340         &xsum1, &xxsum1
341     );
342
343     xsum0 += xsum1;
344     xxsum0 += xxsum1;
345
346     *sse = xxsum0;
347     return (xxsum0 - ((xsum0 * xsum0) >> 8));
348
349
350 }
351
352 unsigned int vp8_sub_pixel_mse16x16_mmx(
353     const unsigned char  *src_ptr,
354     int  src_pixels_per_line,
355     int  xoffset,
356     int  yoffset,
357     const unsigned char *dst_ptr,
358     int dst_pixels_per_line,
359     unsigned int *sse
360 )
361 {
362     vp8_sub_pixel_variance16x16_mmx(src_ptr, src_pixels_per_line, xoffset, yoffset, dst_ptr, dst_pixels_per_line, sse);
363     return *sse;
364 }
365
366 unsigned int vp8_sub_pixel_variance16x8_mmx
367 (
368     const unsigned char  *src_ptr,
369     int  src_pixels_per_line,
370     int  xoffset,
371     int  yoffset,
372     const unsigned char *dst_ptr,
373     int dst_pixels_per_line,
374     unsigned int *sse
375 )
376 {
377     int xsum0, xsum1;
378     unsigned int xxsum0, xxsum1;
379
380
381     vp8_filter_block2d_bil_var_mmx(
382         src_ptr, src_pixels_per_line,
383         dst_ptr, dst_pixels_per_line, 8,
384         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
385         &xsum0, &xxsum0
386     );
387
388
389     vp8_filter_block2d_bil_var_mmx(
390         src_ptr + 8, src_pixels_per_line,
391         dst_ptr + 8, dst_pixels_per_line, 8,
392         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
393         &xsum1, &xxsum1
394     );
395
396     xsum0 += xsum1;
397     xxsum0 += xxsum1;
398
399     *sse = xxsum0;
400     return (xxsum0 - ((xsum0 * xsum0) >> 7));
401 }
402
403 unsigned int vp8_sub_pixel_variance8x16_mmx
404 (
405     const unsigned char  *src_ptr,
406     int  src_pixels_per_line,
407     int  xoffset,
408     int  yoffset,
409     const unsigned char *dst_ptr,
410     int dst_pixels_per_line,
411     int *sse
412 )
413 {
414     int xsum;
415     unsigned int xxsum;
416     vp8_filter_block2d_bil_var_mmx(
417         src_ptr, src_pixels_per_line,
418         dst_ptr, dst_pixels_per_line, 16,
419         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
420         &xsum, &xxsum
421     );
422     *sse = xxsum;
423     return (xxsum - ((xsum * xsum) >> 7));
424 }
425
426
427 unsigned int vp8_variance_halfpixvar16x16_h_mmx(
428     const unsigned char *src_ptr,
429     int  source_stride,
430     const unsigned char *ref_ptr,
431     int  recon_stride,
432     unsigned int *sse)
433 {
434     return vp8_sub_pixel_variance16x16_mmx(src_ptr, source_stride, 4, 0,
435                                            ref_ptr, recon_stride, sse);
436 }
437
438
439 unsigned int vp8_variance_halfpixvar16x16_v_mmx(
440     const unsigned char *src_ptr,
441     int  source_stride,
442     const unsigned char *ref_ptr,
443     int  recon_stride,
444     unsigned int *sse)
445 {
446     return vp8_sub_pixel_variance16x16_mmx(src_ptr, source_stride, 0, 4,
447                                            ref_ptr, recon_stride, sse);
448 }
449
450
451 unsigned int vp8_variance_halfpixvar16x16_hv_mmx(
452     const unsigned char *src_ptr,
453     int  source_stride,
454     const unsigned char *ref_ptr,
455     int  recon_stride,
456     unsigned int *sse)
457 {
458     return vp8_sub_pixel_variance16x16_mmx(src_ptr, source_stride, 4, 4,
459                                            ref_ptr, recon_stride, sse);
460 }