Initial WebM release
[profile/ivi/libvpx.git] / vp8 / encoder / x86 / variance_mmx.c
1 /*
2  *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license and patent
5  *  grant that can be found in the LICENSE file in the root of the source
6  *  tree. All contributing project authors may be found in the AUTHORS
7  *  file in the root of the source tree.
8  */
9
10
11 #include "variance.h"
12 #include "pragmas.h"
13 #include "vpx_ports/mem.h"
14
15 extern void filter_block1d_h6_mmx
16 (
17     unsigned char *src_ptr,
18     unsigned short *output_ptr,
19     unsigned int src_pixels_per_line,
20     unsigned int pixel_step,
21     unsigned int output_height,
22     unsigned int output_width,
23     short *vp7_filter
24 );
25 extern void filter_block1d_v6_mmx
26 (
27     short *src_ptr,
28     unsigned char *output_ptr,
29     unsigned int pixels_per_line,
30     unsigned int pixel_step,
31     unsigned int output_height,
32     unsigned int output_width,
33     short *vp7_filter
34 );
35
36 extern unsigned int vp8_get_mb_ss_mmx(short *src_ptr);
37 extern unsigned int vp8_get8x8var_mmx
38 (
39     unsigned char *src_ptr,
40     int  source_stride,
41     unsigned char *ref_ptr,
42     int  recon_stride,
43     unsigned int *SSE,
44     int *Sum
45 );
46 extern unsigned int vp8_get4x4var_mmx
47 (
48     unsigned char *src_ptr,
49     int  source_stride,
50     unsigned char *ref_ptr,
51     int  recon_stride,
52     unsigned int *SSE,
53     int *Sum
54 );
55 extern unsigned int vp8_get4x4sse_cs_mmx
56 (
57     unsigned char *src_ptr,
58     int  source_stride,
59     unsigned char *ref_ptr,
60     int  recon_stride
61 );
62 extern void vp8_filter_block2d_bil4x4_var_mmx
63 (
64     unsigned char *ref_ptr,
65     int ref_pixels_per_line,
66     unsigned char *src_ptr,
67     int src_pixels_per_line,
68     const short *HFilter,
69     const short *VFilter,
70     int *sum,
71     unsigned int *sumsquared
72 );
73 extern void vp8_filter_block2d_bil_var_mmx
74 (
75     unsigned char *ref_ptr,
76     int ref_pixels_per_line,
77     unsigned char *src_ptr,
78     int src_pixels_per_line,
79     unsigned int Height,
80     const short *HFilter,
81     const short *VFilter,
82     int *sum,
83     unsigned int *sumsquared
84 );
85 extern unsigned int vp8_get16x16pred_error_mmx
86 (
87     unsigned char *src_ptr,
88     int src_stride,
89     unsigned char *ref_ptr,
90     int ref_stride
91 );
92
93
94 void vp8_test_get_mb_ss(void)
95 {
96     short zz[] =
97     {
98         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
99         -2, -2, -2, -2, 2, 2, 2, 2, -2, -2, -2, -2, 2, 2, 2, 2,
100         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
101         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
102         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
103         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
104         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
105         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
106         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
107         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
108         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
109         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
110         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
111         -3, -3, -3, -3, 3, 3, 3, 3, -3, -3, -3, -3, 3, 3, 3, 3,
112         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
113         -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
114     };
115     int s = 0, x = vp8_get_mb_ss_mmx(zz);
116     {
117         int y;
118
119         for (y = 0; y < 256; y++)
120             s += (zz[y] * zz[y]);
121     }
122
123     x += 0;
124 }
125
126
127 unsigned int vp8_get16x16var_mmx(
128     unsigned char *src_ptr,
129     int  source_stride,
130     unsigned char *ref_ptr,
131     int  recon_stride,
132     unsigned *SSE,
133     unsigned *SUM
134 )
135 {
136     unsigned int sse0, sse1, sse2, sse3, var;
137     int sum0, sum1, sum2, sum3, avg;
138
139
140     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
141     vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
142     vp8_get8x8var_mmx(src_ptr + 8 * source_stride, source_stride, ref_ptr + 8 * recon_stride, recon_stride, &sse2, &sum2) ;
143     vp8_get8x8var_mmx(src_ptr + 8 * source_stride + 8, source_stride, ref_ptr + 8 * recon_stride + 8, recon_stride, &sse3, &sum3);
144
145     var = sse0 + sse1 + sse2 + sse3;
146     avg = sum0 + sum1 + sum2 + sum3;
147
148     *SSE = var;
149     *SUM = avg;
150     return (var - ((avg * avg) >> 8));
151
152 }
153
154
155
156
157
158 unsigned int vp8_variance4x4_mmx(
159     unsigned char *src_ptr,
160     int  source_stride,
161     unsigned char *ref_ptr,
162     int  recon_stride,
163     unsigned int *sse)
164 {
165     unsigned int var;
166     int avg;
167
168     vp8_get4x4var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &var, &avg) ;
169     *sse = var;
170     return (var - ((avg * avg) >> 4));
171
172 }
173
174 unsigned int vp8_variance8x8_mmx(
175     unsigned char *src_ptr,
176     int  source_stride,
177     unsigned char *ref_ptr,
178     int  recon_stride,
179     unsigned int *sse)
180 {
181     unsigned int var;
182     int avg;
183
184     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &var, &avg) ;
185     *sse = var;
186
187     return (var - ((avg * avg) >> 6));
188
189 }
190
191 unsigned int vp8_mse16x16_mmx(
192     unsigned char *src_ptr,
193     int  source_stride,
194     unsigned char *ref_ptr,
195     int  recon_stride,
196     unsigned int *sse)
197 {
198     unsigned int sse0, sse1, sse2, sse3, var;
199     int sum0, sum1, sum2, sum3;
200
201
202     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
203     vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
204     vp8_get8x8var_mmx(src_ptr + 8 * source_stride, source_stride, ref_ptr + 8 * recon_stride, recon_stride, &sse2, &sum2) ;
205     vp8_get8x8var_mmx(src_ptr + 8 * source_stride + 8, source_stride, ref_ptr + 8 * recon_stride + 8, recon_stride, &sse3, &sum3);
206
207     var = sse0 + sse1 + sse2 + sse3;
208     *sse = var;
209     return var;
210 }
211
212
213 unsigned int vp8_variance16x16_mmx(
214     unsigned char *src_ptr,
215     int  source_stride,
216     unsigned char *ref_ptr,
217     int  recon_stride,
218     int *sse)
219 {
220     unsigned int sse0, sse1, sse2, sse3, var;
221     int sum0, sum1, sum2, sum3, avg;
222
223
224     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
225     vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
226     vp8_get8x8var_mmx(src_ptr + 8 * source_stride, source_stride, ref_ptr + 8 * recon_stride, recon_stride, &sse2, &sum2) ;
227     vp8_get8x8var_mmx(src_ptr + 8 * source_stride + 8, source_stride, ref_ptr + 8 * recon_stride + 8, recon_stride, &sse3, &sum3);
228
229     var = sse0 + sse1 + sse2 + sse3;
230     avg = sum0 + sum1 + sum2 + sum3;
231     *sse = var;
232     return (var - ((avg * avg) >> 8));
233 }
234
235 unsigned int vp8_variance16x8_mmx(
236     unsigned char *src_ptr,
237     int  source_stride,
238     unsigned char *ref_ptr,
239     int  recon_stride,
240     unsigned int *sse)
241 {
242     unsigned int sse0, sse1, var;
243     int sum0, sum1, avg;
244
245     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
246     vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
247
248     var = sse0 + sse1;
249     avg = sum0 + sum1;
250     *sse = var;
251     return (var - ((avg * avg) >> 7));
252
253 }
254
255
256 unsigned int vp8_variance8x16_mmx(
257     unsigned char *src_ptr,
258     int  source_stride,
259     unsigned char *ref_ptr,
260     int  recon_stride,
261     unsigned int *sse)
262 {
263     unsigned int sse0, sse1, var;
264     int sum0, sum1, avg;
265
266     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
267     vp8_get8x8var_mmx(src_ptr + 8 * source_stride, source_stride, ref_ptr + 8 * recon_stride, recon_stride, &sse1, &sum1) ;
268
269     var = sse0 + sse1;
270     avg = sum0 + sum1;
271     *sse = var;
272
273     return (var - ((avg * avg) >> 7));
274
275 }
276
277
278
279
280 ///////////////////////////////////////////////////////////////////////////
281 // the mmx function that does the bilinear filtering and var calculation //
282 // int one pass                                                          //
283 ///////////////////////////////////////////////////////////////////////////
284 DECLARE_ALIGNED(16, const short, vp8_vp7_bilinear_filters_mmx[8][8]) =
285 {
286     { 128, 128, 128, 128,  0,  0,  0,  0 },
287     { 112, 112, 112, 112, 16, 16, 16, 16 },
288     {  96, 96, 96, 96, 32, 32, 32, 32 },
289     {  80, 80, 80, 80, 48, 48, 48, 48 },
290     {  64, 64, 64, 64, 64, 64, 64, 64 },
291     {  48, 48, 48, 48, 80, 80, 80, 80 },
292     {  32, 32, 32, 32, 96, 96, 96, 96 },
293     {  16, 16, 16, 16, 112, 112, 112, 112 }
294 };
295
296 unsigned int vp8_sub_pixel_variance4x4_mmx
297 (
298     unsigned char  *src_ptr,
299     int  src_pixels_per_line,
300     int  xoffset,
301     int  yoffset,
302     unsigned char *dst_ptr,
303     int dst_pixels_per_line,
304     unsigned int *sse)
305
306 {
307     int xsum;
308     unsigned int xxsum;
309     vp8_filter_block2d_bil4x4_var_mmx(
310         src_ptr, src_pixels_per_line,
311         dst_ptr, dst_pixels_per_line,
312         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
313         &xsum, &xxsum
314     );
315     *sse = xxsum;
316     return (xxsum - ((xsum * xsum) >> 4));
317 }
318
319
320 unsigned int vp8_sub_pixel_variance8x8_mmx
321 (
322     unsigned char  *src_ptr,
323     int  src_pixels_per_line,
324     int  xoffset,
325     int  yoffset,
326     unsigned char *dst_ptr,
327     int dst_pixels_per_line,
328     unsigned int *sse
329 )
330 {
331
332     int xsum;
333     unsigned int xxsum;
334     vp8_filter_block2d_bil_var_mmx(
335         src_ptr, src_pixels_per_line,
336         dst_ptr, dst_pixels_per_line, 8,
337         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
338         &xsum, &xxsum
339     );
340     *sse = xxsum;
341     return (xxsum - ((xsum * xsum) >> 6));
342 }
343
344 unsigned int vp8_sub_pixel_variance16x16_mmx
345 (
346     unsigned char  *src_ptr,
347     int  src_pixels_per_line,
348     int  xoffset,
349     int  yoffset,
350     unsigned char *dst_ptr,
351     int dst_pixels_per_line,
352     unsigned int *sse
353 )
354 {
355
356     int xsum0, xsum1;
357     unsigned int xxsum0, xxsum1;
358
359
360     vp8_filter_block2d_bil_var_mmx(
361         src_ptr, src_pixels_per_line,
362         dst_ptr, dst_pixels_per_line, 16,
363         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
364         &xsum0, &xxsum0
365     );
366
367
368     vp8_filter_block2d_bil_var_mmx(
369         src_ptr + 8, src_pixels_per_line,
370         dst_ptr + 8, dst_pixels_per_line, 16,
371         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
372         &xsum1, &xxsum1
373     );
374
375     xsum0 += xsum1;
376     xxsum0 += xxsum1;
377
378     *sse = xxsum0;
379     return (xxsum0 - ((xsum0 * xsum0) >> 8));
380
381
382 }
383
384 unsigned int vp8_sub_pixel_mse16x16_mmx(
385     unsigned char  *src_ptr,
386     int  src_pixels_per_line,
387     int  xoffset,
388     int  yoffset,
389     unsigned char *dst_ptr,
390     int dst_pixels_per_line,
391     unsigned int *sse
392 )
393 {
394     vp8_sub_pixel_variance16x16_mmx(src_ptr, src_pixels_per_line, xoffset, yoffset, dst_ptr, dst_pixels_per_line, sse);
395     return *sse;
396 }
397
398 unsigned int vp8_sub_pixel_variance16x8_mmx
399 (
400     unsigned char  *src_ptr,
401     int  src_pixels_per_line,
402     int  xoffset,
403     int  yoffset,
404     unsigned char *dst_ptr,
405     int dst_pixels_per_line,
406     unsigned int *sse
407 )
408 {
409     int xsum0, xsum1;
410     unsigned int xxsum0, xxsum1;
411
412
413     vp8_filter_block2d_bil_var_mmx(
414         src_ptr, src_pixels_per_line,
415         dst_ptr, dst_pixels_per_line, 8,
416         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
417         &xsum0, &xxsum0
418     );
419
420
421     vp8_filter_block2d_bil_var_mmx(
422         src_ptr + 8, src_pixels_per_line,
423         dst_ptr + 8, dst_pixels_per_line, 8,
424         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
425         &xsum1, &xxsum1
426     );
427
428     xsum0 += xsum1;
429     xxsum0 += xxsum1;
430
431     *sse = xxsum0;
432     return (xxsum0 - ((xsum0 * xsum0) >> 7));
433 }
434
435 unsigned int vp8_sub_pixel_variance8x16_mmx
436 (
437     unsigned char  *src_ptr,
438     int  src_pixels_per_line,
439     int  xoffset,
440     int  yoffset,
441     unsigned char *dst_ptr,
442     int dst_pixels_per_line,
443     int *sse
444 )
445 {
446     int xsum;
447     unsigned int xxsum;
448     vp8_filter_block2d_bil_var_mmx(
449         src_ptr, src_pixels_per_line,
450         dst_ptr, dst_pixels_per_line, 16,
451         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
452         &xsum, &xxsum
453     );
454     *sse = xxsum;
455     return (xxsum - ((xsum * xsum) >> 7));
456 }
457
458 unsigned int vp8_i_variance16x16_mmx(
459     unsigned char *src_ptr,
460     int  source_stride,
461     unsigned char *ref_ptr,
462     int  recon_stride,
463     unsigned int *sse)
464 {
465     unsigned int sse0, sse1, sse2, sse3, var;
466     int sum0, sum1, sum2, sum3, avg;
467
468
469     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
470     vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
471     vp8_get8x8var_mmx(src_ptr + (source_stride >> 1), source_stride, ref_ptr + (recon_stride >> 1), recon_stride, &sse2, &sum2) ;
472     vp8_get8x8var_mmx(src_ptr + (source_stride >> 1) + 8, source_stride, ref_ptr + (recon_stride >> 1) + 8, recon_stride, &sse3, &sum3);
473
474     var = sse0 + sse1 + sse2 + sse3;
475     avg = sum0 + sum1 + sum2 + sum3;
476     *sse = var;
477     return (var - ((avg * avg) >> 8));
478
479 }
480
481 unsigned int vp8_i_variance8x16_mmx(
482     unsigned char *src_ptr,
483     int  source_stride,
484     unsigned char *ref_ptr,
485     int  recon_stride,
486     unsigned int *sse)
487 {
488     unsigned int sse0, sse1, var;
489     int sum0, sum1, avg;
490     vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
491     vp8_get8x8var_mmx(src_ptr + (source_stride >> 1), source_stride, ref_ptr + (recon_stride >> 1), recon_stride, &sse1, &sum1) ;
492
493     var = sse0 + sse1;
494     avg = sum0 + sum1;
495
496     *sse = var;
497     return (var - ((avg * avg) >> 7));
498
499 }
500
501 unsigned int vp8_i_sub_pixel_variance16x16_mmx
502 (
503     unsigned char  *src_ptr,
504     int  src_pixels_per_line,
505     int  xoffset,
506     int  yoffset,
507     unsigned char *dst_ptr,
508     int dst_pixels_per_line,
509     unsigned int *sse
510 )
511 {
512     int xsum0, xsum1;
513     unsigned int xxsum0, xxsum1;
514     int f2soffset = (src_pixels_per_line >> 1);
515     int f2doffset = (dst_pixels_per_line >> 1);
516
517
518     vp8_filter_block2d_bil_var_mmx(
519         src_ptr, src_pixels_per_line,
520         dst_ptr, dst_pixels_per_line, 8,
521         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
522         &xsum0, &xxsum0
523     );
524
525
526     vp8_filter_block2d_bil_var_mmx(
527         src_ptr + 8, src_pixels_per_line,
528         dst_ptr + 8, dst_pixels_per_line, 8,
529         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
530         &xsum1, &xxsum1
531     );
532
533     xsum0 += xsum1;
534     xxsum0 += xxsum1;
535
536     vp8_filter_block2d_bil_var_mmx(
537         src_ptr + f2soffset, src_pixels_per_line,
538         dst_ptr + f2doffset, dst_pixels_per_line, 8,
539         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
540         &xsum1, &xxsum1
541     );
542
543     xsum0 += xsum1;
544     xxsum0 += xxsum1;
545
546     vp8_filter_block2d_bil_var_mmx(
547         src_ptr + f2soffset + 8, src_pixels_per_line,
548         dst_ptr + f2doffset + 8, dst_pixels_per_line, 8,
549         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
550         &xsum1, &xxsum1
551     );
552
553     xsum0 += xsum1;
554     xxsum0 += xxsum1;
555     *sse = xxsum0;
556     return (xxsum0 - ((xsum0 * xsum0) >> 8));
557 }
558
559
560 unsigned int vp8_i_sub_pixel_variance8x16_mmx
561 (
562     unsigned char  *src_ptr,
563     int  src_pixels_per_line,
564     int  xoffset,
565     int  yoffset,
566     unsigned char *dst_ptr,
567     int dst_pixels_per_line,
568     unsigned int *sse
569 )
570 {
571     int xsum0, xsum1;
572     unsigned int xxsum0, xxsum1;
573     int f2soffset = (src_pixels_per_line >> 1);
574     int f2doffset = (dst_pixels_per_line >> 1);
575
576
577     vp8_filter_block2d_bil_var_mmx(
578         src_ptr, src_pixels_per_line,
579         dst_ptr, dst_pixels_per_line, 8,
580         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
581         &xsum0, &xxsum0
582     );
583
584
585     vp8_filter_block2d_bil_var_mmx(
586         src_ptr + f2soffset, src_pixels_per_line,
587         dst_ptr + f2doffset, dst_pixels_per_line, 8,
588         vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
589         &xsum1, &xxsum1
590     );
591
592     xsum0 += xsum1;
593     xxsum0 += xxsum1;
594     *sse = xxsum0;
595     return (xxsum0 - ((xsum0 * xsum0) >> 7));
596 }