1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * This file is part of FFmpeg.
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
8cabdff1aSopenharmony_ci *
9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12cabdff1aSopenharmony_ci * Lesser General Public License for more details.
13cabdff1aSopenharmony_ci *
14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17cabdff1aSopenharmony_ci */
18cabdff1aSopenharmony_ci
19cabdff1aSopenharmony_ci#include <stdio.h>
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci#include "libavutil/internal.h"
22cabdff1aSopenharmony_ci#include "libavutil/mem.h"
23cabdff1aSopenharmony_ci#include "libavutil/pixelutils.c"
24cabdff1aSopenharmony_ci
25cabdff1aSopenharmony_ci#define W1 320
26cabdff1aSopenharmony_ci#define H1 240
27cabdff1aSopenharmony_ci#define W2 640
28cabdff1aSopenharmony_ci#define H2 480
29cabdff1aSopenharmony_ci
30cabdff1aSopenharmony_cistatic int run_single_test(const char *test,
31cabdff1aSopenharmony_ci                           const uint8_t *block1, ptrdiff_t stride1,
32cabdff1aSopenharmony_ci                           const uint8_t *block2, ptrdiff_t stride2,
33cabdff1aSopenharmony_ci                           int align, int n)
34cabdff1aSopenharmony_ci{
35cabdff1aSopenharmony_ci    int out, ref;
36cabdff1aSopenharmony_ci    av_pixelutils_sad_fn f_ref = sad_c[n - 1];
37cabdff1aSopenharmony_ci    av_pixelutils_sad_fn f_out = av_pixelutils_get_sad_fn(n, n, align, NULL);
38cabdff1aSopenharmony_ci
39cabdff1aSopenharmony_ci    switch (align) {
40cabdff1aSopenharmony_ci    case 0: block1++; block2++; break;
41cabdff1aSopenharmony_ci    case 1:           block2++; break;
42cabdff1aSopenharmony_ci    case 2:                     break;
43cabdff1aSopenharmony_ci    }
44cabdff1aSopenharmony_ci
45cabdff1aSopenharmony_ci    out = f_out(block1, stride1, block2, stride2);
46cabdff1aSopenharmony_ci    ref = f_ref(block1, stride1, block2, stride2);
47cabdff1aSopenharmony_ci    printf("[%s] [%c%c] SAD [%s] %dx%d=%d ref=%d\n",
48cabdff1aSopenharmony_ci           out == ref ? "OK" : "FAIL",
49cabdff1aSopenharmony_ci           align ? 'A' : 'U', align == 2 ? 'A' : 'U',
50cabdff1aSopenharmony_ci           test, 1<<n, 1<<n, out, ref);
51cabdff1aSopenharmony_ci    return out != ref;
52cabdff1aSopenharmony_ci}
53cabdff1aSopenharmony_ci
54cabdff1aSopenharmony_cistatic int run_test(const char *test,
55cabdff1aSopenharmony_ci                    const uint8_t *b1, const uint8_t *b2)
56cabdff1aSopenharmony_ci{
57cabdff1aSopenharmony_ci    int i, a, ret = 0;
58cabdff1aSopenharmony_ci
59cabdff1aSopenharmony_ci    for (a = 0; a < 3; a++) {
60cabdff1aSopenharmony_ci        const uint8_t *block1 = b1;
61cabdff1aSopenharmony_ci        const uint8_t *block2 = b2;
62cabdff1aSopenharmony_ci
63cabdff1aSopenharmony_ci        switch (a) {
64cabdff1aSopenharmony_ci        case 0: block1++; block2++; break;
65cabdff1aSopenharmony_ci        case 1:           block2++; break;
66cabdff1aSopenharmony_ci        case 2:                     break;
67cabdff1aSopenharmony_ci        }
68cabdff1aSopenharmony_ci        for (i = 1; i <= FF_ARRAY_ELEMS(sad_c); i++) {
69cabdff1aSopenharmony_ci            int r = run_single_test(test, b1, W1, b2, W2, a, i);
70cabdff1aSopenharmony_ci            if (r)
71cabdff1aSopenharmony_ci                ret = r;
72cabdff1aSopenharmony_ci        }
73cabdff1aSopenharmony_ci    }
74cabdff1aSopenharmony_ci    return ret;
75cabdff1aSopenharmony_ci}
76cabdff1aSopenharmony_ci
77cabdff1aSopenharmony_ciint main(void)
78cabdff1aSopenharmony_ci{
79cabdff1aSopenharmony_ci    int i, align, ret;
80cabdff1aSopenharmony_ci    uint8_t *buf1 = av_malloc(W1*H1);
81cabdff1aSopenharmony_ci    uint8_t *buf2 = av_malloc(W2*H2);
82cabdff1aSopenharmony_ci    uint32_t state = 0;
83cabdff1aSopenharmony_ci
84cabdff1aSopenharmony_ci    if (!buf1 || !buf2) {
85cabdff1aSopenharmony_ci        fprintf(stderr, "malloc failure\n");
86cabdff1aSopenharmony_ci        ret = 1;
87cabdff1aSopenharmony_ci        goto end;
88cabdff1aSopenharmony_ci    }
89cabdff1aSopenharmony_ci
90cabdff1aSopenharmony_ci    ff_check_pixfmt_descriptors();
91cabdff1aSopenharmony_ci
92cabdff1aSopenharmony_ci#define RANDOM_INIT(buf, size) do {             \
93cabdff1aSopenharmony_ci    int k;                                      \
94cabdff1aSopenharmony_ci    for (k = 0; k < size; k++) {                \
95cabdff1aSopenharmony_ci        state = state * 1664525 + 1013904223;   \
96cabdff1aSopenharmony_ci        buf[k] = state>>24;                     \
97cabdff1aSopenharmony_ci    }                                           \
98cabdff1aSopenharmony_ci} while (0)
99cabdff1aSopenharmony_ci
100cabdff1aSopenharmony_ci    /* Normal test with different strides */
101cabdff1aSopenharmony_ci    RANDOM_INIT(buf1, W1*H1);
102cabdff1aSopenharmony_ci    RANDOM_INIT(buf2, W2*H2);
103cabdff1aSopenharmony_ci    ret = run_test("random", buf1, buf2);
104cabdff1aSopenharmony_ci    if (ret < 0)
105cabdff1aSopenharmony_ci        goto end;
106cabdff1aSopenharmony_ci
107cabdff1aSopenharmony_ci    /* Check for maximum SAD */
108cabdff1aSopenharmony_ci    memset(buf1, 0xff, W1*H1);
109cabdff1aSopenharmony_ci    memset(buf2, 0x00, W2*H2);
110cabdff1aSopenharmony_ci    ret = run_test("max", buf1, buf2);
111cabdff1aSopenharmony_ci    if (ret < 0)
112cabdff1aSopenharmony_ci        goto end;
113cabdff1aSopenharmony_ci
114cabdff1aSopenharmony_ci    /* Check for minimum SAD */
115cabdff1aSopenharmony_ci    memset(buf1, 0x90, W1*H1);
116cabdff1aSopenharmony_ci    memset(buf2, 0x90, W2*H2);
117cabdff1aSopenharmony_ci    ret = run_test("min", buf1, buf2);
118cabdff1aSopenharmony_ci    if (ret < 0)
119cabdff1aSopenharmony_ci        goto end;
120cabdff1aSopenharmony_ci
121cabdff1aSopenharmony_ci    /* Exact buffer sizes, to check for overreads */
122cabdff1aSopenharmony_ci    for (i = 1; i <= 5; i++) {
123cabdff1aSopenharmony_ci        for (align = 0; align < 3; align++) {
124cabdff1aSopenharmony_ci            int size1, size2;
125cabdff1aSopenharmony_ci
126cabdff1aSopenharmony_ci            av_freep(&buf1);
127cabdff1aSopenharmony_ci            av_freep(&buf2);
128cabdff1aSopenharmony_ci
129cabdff1aSopenharmony_ci            size1 = size2 = 1 << (i << 1);
130cabdff1aSopenharmony_ci
131cabdff1aSopenharmony_ci            switch (align) {
132cabdff1aSopenharmony_ci            case 0: size1++; size2++; break;
133cabdff1aSopenharmony_ci            case 1:          size2++; break;
134cabdff1aSopenharmony_ci            case 2:                   break;
135cabdff1aSopenharmony_ci            }
136cabdff1aSopenharmony_ci
137cabdff1aSopenharmony_ci            buf1 = av_malloc(size1);
138cabdff1aSopenharmony_ci            buf2 = av_malloc(size2);
139cabdff1aSopenharmony_ci            if (!buf1 || !buf2) {
140cabdff1aSopenharmony_ci                fprintf(stderr, "malloc failure\n");
141cabdff1aSopenharmony_ci                ret = 1;
142cabdff1aSopenharmony_ci                goto end;
143cabdff1aSopenharmony_ci            }
144cabdff1aSopenharmony_ci            RANDOM_INIT(buf1, size1);
145cabdff1aSopenharmony_ci            RANDOM_INIT(buf2, size2);
146cabdff1aSopenharmony_ci            ret = run_single_test("small", buf1, 1<<i, buf2, 1<<i, align, i);
147cabdff1aSopenharmony_ci            if (ret < 0)
148cabdff1aSopenharmony_ci                goto end;
149cabdff1aSopenharmony_ci        }
150cabdff1aSopenharmony_ci    }
151cabdff1aSopenharmony_ci
152cabdff1aSopenharmony_ciend:
153cabdff1aSopenharmony_ci    av_free(buf1);
154cabdff1aSopenharmony_ci    av_free(buf2);
155cabdff1aSopenharmony_ci    return ret;
156cabdff1aSopenharmony_ci}
157