1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (c) 2022 Ben Avison
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or modify
7cabdff1aSopenharmony_ci * it under the terms of the GNU General Public License as published by
8cabdff1aSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or
9cabdff1aSopenharmony_ci * (at your option) any later version.
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14cabdff1aSopenharmony_ci * GNU General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU General Public License along
17cabdff1aSopenharmony_ci * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18cabdff1aSopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci#include <string.h>
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci#include "checkasm.h"
24cabdff1aSopenharmony_ci
25cabdff1aSopenharmony_ci#include "libavcodec/idctdsp.h"
26cabdff1aSopenharmony_ci
27cabdff1aSopenharmony_ci#include "libavutil/common.h"
28cabdff1aSopenharmony_ci#include "libavutil/internal.h"
29cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h"
30cabdff1aSopenharmony_ci#include "libavutil/mem_internal.h"
31cabdff1aSopenharmony_ci
32cabdff1aSopenharmony_ci#define IDCTDSP_TEST(func) { #func, offsetof(IDCTDSPContext, func) },
33cabdff1aSopenharmony_ci
34cabdff1aSopenharmony_citypedef struct {
35cabdff1aSopenharmony_ci    const char *name;
36cabdff1aSopenharmony_ci    size_t offset;
37cabdff1aSopenharmony_ci} test;
38cabdff1aSopenharmony_ci
39cabdff1aSopenharmony_ci#define RANDOMIZE_BUFFER16(name, size)          \
40cabdff1aSopenharmony_ci    do {                                        \
41cabdff1aSopenharmony_ci        int i;                                  \
42cabdff1aSopenharmony_ci        for (i = 0; i < size; ++i) {            \
43cabdff1aSopenharmony_ci            uint16_t r = rnd() % 0x201 - 0x100; \
44cabdff1aSopenharmony_ci            AV_WN16A(name##0 + i, r);           \
45cabdff1aSopenharmony_ci            AV_WN16A(name##1 + i, r);           \
46cabdff1aSopenharmony_ci        }                                       \
47cabdff1aSopenharmony_ci    } while (0)
48cabdff1aSopenharmony_ci
49cabdff1aSopenharmony_ci#define RANDOMIZE_BUFFER8(name, size)         \
50cabdff1aSopenharmony_ci    do {                                      \
51cabdff1aSopenharmony_ci        int i;                                \
52cabdff1aSopenharmony_ci        for (i = 0; i < size; ++i) {          \
53cabdff1aSopenharmony_ci            uint8_t r = rnd();                \
54cabdff1aSopenharmony_ci            name##0[i] = r;                   \
55cabdff1aSopenharmony_ci            name##1[i] = r;                   \
56cabdff1aSopenharmony_ci        }                                     \
57cabdff1aSopenharmony_ci    } while (0)
58cabdff1aSopenharmony_ci
59cabdff1aSopenharmony_cistatic void check_add_put_clamped(void)
60cabdff1aSopenharmony_ci{
61cabdff1aSopenharmony_ci    /* Source buffers are only as big as needed, since any over-read won't affect results */
62cabdff1aSopenharmony_ci    LOCAL_ALIGNED_16(int16_t, src0, [64]);
63cabdff1aSopenharmony_ci    LOCAL_ALIGNED_16(int16_t, src1, [64]);
64cabdff1aSopenharmony_ci    /* Destination buffers have borders of one row above/below and 8 columns left/right to catch overflows */
65cabdff1aSopenharmony_ci    LOCAL_ALIGNED_8(uint8_t, dst0, [10 * 24]);
66cabdff1aSopenharmony_ci    LOCAL_ALIGNED_8(uint8_t, dst1, [10 * 24]);
67cabdff1aSopenharmony_ci
68cabdff1aSopenharmony_ci    AVCodecContext avctx = { 0 };
69cabdff1aSopenharmony_ci    IDCTDSPContext h;
70cabdff1aSopenharmony_ci
71cabdff1aSopenharmony_ci    const test tests[] = {
72cabdff1aSopenharmony_ci        IDCTDSP_TEST(add_pixels_clamped)
73cabdff1aSopenharmony_ci        IDCTDSP_TEST(put_pixels_clamped)
74cabdff1aSopenharmony_ci        IDCTDSP_TEST(put_signed_pixels_clamped)
75cabdff1aSopenharmony_ci    };
76cabdff1aSopenharmony_ci
77cabdff1aSopenharmony_ci    ff_idctdsp_init(&h, &avctx);
78cabdff1aSopenharmony_ci
79cabdff1aSopenharmony_ci    for (size_t t = 0; t < FF_ARRAY_ELEMS(tests); ++t) {
80cabdff1aSopenharmony_ci        void (*func)(const int16_t *, uint8_t * ptrdiff_t) = *(void **)((intptr_t) &h + tests[t].offset);
81cabdff1aSopenharmony_ci        if (check_func(func, "idctdsp.%s", tests[t].name)) {
82cabdff1aSopenharmony_ci            declare_func_emms(AV_CPU_FLAG_MMX, void, const int16_t *, uint8_t *, ptrdiff_t);
83cabdff1aSopenharmony_ci            RANDOMIZE_BUFFER16(src, 64);
84cabdff1aSopenharmony_ci            RANDOMIZE_BUFFER8(dst, 10 * 24);
85cabdff1aSopenharmony_ci            call_ref(src0, dst0 + 24 + 8, 24);
86cabdff1aSopenharmony_ci            call_new(src1, dst1 + 24 + 8, 24);
87cabdff1aSopenharmony_ci            if (memcmp(dst0, dst1, 10 * 24))
88cabdff1aSopenharmony_ci                fail();
89cabdff1aSopenharmony_ci            bench_new(src1, dst1 + 24 + 8, 24);
90cabdff1aSopenharmony_ci        }
91cabdff1aSopenharmony_ci    }
92cabdff1aSopenharmony_ci}
93cabdff1aSopenharmony_ci
94cabdff1aSopenharmony_civoid checkasm_check_idctdsp(void)
95cabdff1aSopenharmony_ci{
96cabdff1aSopenharmony_ci    check_add_put_clamped();
97cabdff1aSopenharmony_ci    report("idctdsp");
98cabdff1aSopenharmony_ci}
99