]> git.sesse.net Git - ffmpeg/blob - tests/checkasm/llviddsp.c
Merge commit '40d5df67d2c4e1f0dd1e902435567eb5edad6a9a'
[ffmpeg] / tests / checkasm / llviddsp.c
1 /*
2  * Copyright (c) 2016 Alexandra Hájková
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 #include <string.h>
22
23 #include "libavutil/common.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/mem.h"
26
27 #include "libavcodec/lossless_videodsp.h"
28
29 #include "checkasm.h"
30
31 #define randomize_buffers(buf, size)     \
32     do {                                 \
33         int j;                           \
34         uint8_t *tmp_buf = (uint8_t *)buf;\
35         for (j = 0; j < size; j++)       \
36             tmp_buf[j] = rnd() & 0xFF;       \
37     } while (0)
38
39 #define init_buffer(a0, a1, type, width)\
40     if (!a0 || !a1)\
41         fail();\
42     randomize_buffers(a0, width * sizeof(type));\
43     memcpy(a1, a0, width*sizeof(type));\
44
45 static void check_add_bytes(LLVidDSPContext c, int width)
46 {
47     uint8_t *dst0 = av_mallocz(width);
48     uint8_t *dst1 = av_mallocz(width);
49     uint8_t *src0 = av_mallocz_array(width, sizeof(uint8_t));
50     uint8_t *src1 = av_mallocz_array(width, sizeof(uint8_t));
51     declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, uint8_t *src, ptrdiff_t w);
52
53     init_buffer(src0, src1, uint8_t, width);
54
55     if (!dst0 || !dst1)
56         fail();
57
58
59     if (check_func(c.add_bytes, "add_bytes")) {
60         call_ref(dst0, src0, width);
61         call_new(dst1, src1, width);
62         if (memcmp(dst0, dst1, width))
63             fail();
64         bench_new(dst1, src1, width);
65     }
66
67     av_free(src0);
68     av_free(src1);
69     av_free(dst0);
70     av_free(dst1);
71 }
72
73 static void check_add_median_pred(LLVidDSPContext c, int width) {
74     int A0, A1, B0, B1;
75     uint8_t *dst0 = av_mallocz(width);
76     uint8_t *dst1 = av_mallocz(width);
77     uint8_t *src0 = av_mallocz_array(width, sizeof(uint8_t));
78     uint8_t *src1 = av_mallocz_array(width, sizeof(uint8_t));
79     uint8_t *diff0 = av_mallocz_array(width, sizeof(uint8_t));
80     uint8_t *diff1 = av_mallocz_array(width, sizeof(uint8_t));
81     declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, const uint8_t *src1,
82                       const uint8_t *diff, ptrdiff_t w,
83                       int *left, int *left_top);
84
85     init_buffer(src0, src1, uint8_t, width);
86     init_buffer(diff0, diff1, uint8_t, width);
87
88     A0 = rnd() & 0xFF;
89     B0 = rnd() & 0xFF;
90     A1 = A0;
91     B1 = B0;
92
93
94     if (check_func(c.add_median_pred, "add_median_pred")) {
95         call_ref(dst0, src0, diff0, width, &A0, &B0);
96         call_new(dst1, src1, diff1, width, &A1, &B1);
97         if (memcmp(dst0, dst1, width) || (A0 != A1) || (B0 != B1))
98             fail();
99         bench_new(dst1, src1, diff1, width, &A1, &B1);
100     }
101
102     av_free(src0);
103     av_free(src1);
104     av_free(diff0);
105     av_free(diff1);
106     av_free(dst0);
107     av_free(dst1);
108 }
109
110 static void check_add_left_pred(LLVidDSPContext c, int width, int acc, const char * report)
111 {
112     uint8_t *dst0 = av_mallocz(width);
113     uint8_t *dst1 = av_mallocz(width);
114     uint8_t *src0 = av_mallocz_array(width, sizeof(uint8_t));
115     uint8_t *src1 = av_mallocz_array(width, sizeof(uint8_t));
116     declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, uint8_t *src, ptrdiff_t w, int acc);
117
118     init_buffer(src0, src1, uint8_t, width);
119
120     if (!dst0 || !dst1)
121         fail();
122
123     if (check_func(c.add_left_pred, "%s", report)) {
124         call_ref(dst0, src0, width, acc);
125         call_new(dst1, src1, width, acc);
126         if (memcmp(dst0, dst1, width))
127             fail();
128         bench_new(dst1, src1, width, acc);
129     }
130
131     av_free(src0);
132     av_free(src1);
133     av_free(dst0);
134     av_free(dst1);
135 }
136
137 static void check_add_left_pred_16(LLVidDSPContext c, unsigned mask, int width, unsigned acc, const char * report)
138 {
139     uint16_t *dst0 = av_mallocz_array(width, sizeof(uint16_t));
140     uint16_t *dst1 = av_mallocz_array(width, sizeof(uint16_t));
141     uint16_t *src0 = av_mallocz_array(width, sizeof(uint16_t));
142     uint16_t *src1 = av_mallocz_array(width, sizeof(uint16_t));
143     declare_func_emms(AV_CPU_FLAG_MMX, void, uint16_t *dst, uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc);
144
145     init_buffer(src0, src1, uint16_t, width);
146
147     if (!dst0 || !dst1)
148         fail();
149
150     if (check_func(c.add_left_pred_int16, "%s", report)) {
151         call_ref(dst0, src0, mask, width, acc);
152         call_new(dst1, src1, mask, width, acc);
153         if (memcmp(dst0, dst1, width))
154             fail();
155         bench_new(dst1, src1, mask, width, acc);
156     }
157
158     av_free(src0);
159     av_free(src1);
160     av_free(dst0);
161     av_free(dst1);
162 }
163
164 void checkasm_check_llviddsp(void)
165 {
166     LLVidDSPContext c;
167     int width = 16 * av_clip(rnd(), 16, 128);
168     int accRnd = rnd() & 0xFF;
169
170     ff_llviddsp_init(&c);
171
172     check_add_bytes(c, width);
173     report("add_bytes");
174
175     check_add_median_pred(c, width);
176     report("add_median_pred");
177
178     check_add_left_pred(c, width, 0, "add_left_pred_zero");
179     report("add_left_pred_zero");
180
181     check_add_left_pred(c, width, accRnd, "add_left_pred_rnd_acc");
182     report("add_left_pred_rnd_acc");
183
184     check_add_left_pred_16(c, 255, width, accRnd, "add_left_pred_int16");
185     report("add_left_pred_int16");
186 }