Imported Upstream version 6.1
[platform/upstream/ffmpeg.git] / 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_calloc(width, sizeof(*src0));
50     uint8_t *src1 = av_calloc(width, sizeof(*src1));
51     declare_func(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_calloc(width, sizeof(*src0));
78     uint8_t *src1  = av_calloc(width, sizeof(*src1));
79     uint8_t *diff0 = av_calloc(width, sizeof(*diff0));
80     uint8_t *diff1 = av_calloc(width, sizeof(*diff1));
81     declare_func(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     int res0, res1;
113     uint8_t *dst0 = av_mallocz(width);
114     uint8_t *dst1 = av_mallocz(width);
115     uint8_t *src0 = av_calloc(width, sizeof(*src0));
116     uint8_t *src1 = av_calloc(width, sizeof(*src1));
117     declare_func(int, uint8_t *dst, uint8_t *src, ptrdiff_t w, int acc);
118
119     init_buffer(src0, src1, uint8_t, width);
120
121     if (!dst0 || !dst1)
122         fail();
123
124     if (check_func(c->add_left_pred, "%s", report)) {
125         res0 = call_ref(dst0, src0, width, acc);
126         res1 = call_new(dst1, src1, width, acc);
127         if ((res0 & 0xFF) != (res1 & 0xFF)||\
128             memcmp(dst0, dst1, width))
129             fail();
130         bench_new(dst1, src1, width, acc);
131     }
132
133     av_free(src0);
134     av_free(src1);
135     av_free(dst0);
136     av_free(dst1);
137 }
138
139 static void check_add_left_pred_16(LLVidDSPContext *c, unsigned mask, int width, unsigned acc, const char * report)
140 {
141     int res0, res1;
142     uint16_t *dst0 = av_calloc(width, sizeof(*dst0));
143     uint16_t *dst1 = av_calloc(width, sizeof(*dst1));
144     uint16_t *src0 = av_calloc(width, sizeof(*src0));
145     uint16_t *src1 = av_calloc(width, sizeof(*src1));
146     declare_func(int, uint16_t *dst, uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc);
147
148     init_buffer(src0, src1, uint16_t, width);
149
150     if (!dst0 || !dst1)
151         fail();
152
153     if (check_func(c->add_left_pred_int16, "%s", report)) {
154         res0 = call_ref(dst0, src0, mask, width, acc);
155         res1 = call_new(dst1, src1, mask, width, acc);
156         if ((res0 &0xFFFF) != (res1 &0xFFFF)||\
157             memcmp(dst0, dst1, width))
158             fail();
159         bench_new(dst1, src1, mask, width, acc);
160     }
161
162     av_free(src0);
163     av_free(src1);
164     av_free(dst0);
165     av_free(dst1);
166 }
167
168 static void check_add_gradient_pred(LLVidDSPContext *c, int w) {
169     int src_size, stride;
170     uint8_t *src0, *src1;
171     declare_func(void, uint8_t *src, const ptrdiff_t stride,
172                  const ptrdiff_t width);
173
174     stride = w + 32;
175     src_size = (stride + 32) * 2; /* dsp need previous line, and ignore the start of the line */
176     src0 = av_mallocz(src_size);
177     src1 = av_mallocz(src_size);
178
179     init_buffer(src0, src1, uint8_t, src_size);
180
181     if (check_func(c->add_gradient_pred, "add_gradient_pred")) {
182         call_ref(src0 + stride + 32, stride, w);
183         call_new(src1 + stride + 32, stride, w);
184         if (memcmp(src0, src1, stride)||/* previous line doesn't change */
185             memcmp(src0+stride, src1 + stride, w + 32)) {
186             fail();
187         }
188         bench_new(src1 + stride + 32, stride, w);
189     }
190
191     av_free(src0);
192     av_free(src1);
193 }
194
195 void checkasm_check_llviddsp(void)
196 {
197     LLVidDSPContext c;
198     int width = 16 * av_clip(rnd(), 16, 128);
199     int accRnd = rnd() & 0xFF;
200
201     ff_llviddsp_init(&c);
202
203     check_add_bytes(&c, width);
204     report("add_bytes");
205
206     check_add_median_pred(&c, width);
207     report("add_median_pred");
208
209     check_add_left_pred(&c, width, 0, "add_left_pred_zero");
210     report("add_left_pred_zero");
211
212     check_add_left_pred(&c, width, accRnd, "add_left_pred_rnd_acc");
213     report("add_left_pred_rnd_acc");
214
215     check_add_left_pred_16(&c, 255, width, accRnd, "add_left_pred_int16");
216     report("add_left_pred_int16");
217
218     check_add_gradient_pred(&c, width);
219     report("add_gradient_pred");
220 }