xref: /third_party/ffmpeg/tests/checkasm/motion.c (revision cabdff1a)
1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci *
3cabdff1aSopenharmony_ci * This file is part of FFmpeg.
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or modify
6cabdff1aSopenharmony_ci * it under the terms of the GNU General Public License as published by
7cabdff1aSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or
8cabdff1aSopenharmony_ci * (at your option) any later version.
9cabdff1aSopenharmony_ci *
10cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
11cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
12cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13cabdff1aSopenharmony_ci * GNU General Public License for more details.
14cabdff1aSopenharmony_ci *
15cabdff1aSopenharmony_ci * You should have received a copy of the GNU General Public License along
16cabdff1aSopenharmony_ci * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
17cabdff1aSopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18cabdff1aSopenharmony_ci */
19cabdff1aSopenharmony_ci
20cabdff1aSopenharmony_ci#include <string.h>
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci#include "libavutil/common.h"
23cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h"
24cabdff1aSopenharmony_ci#include "libavutil/mem_internal.h"
25cabdff1aSopenharmony_ci
26cabdff1aSopenharmony_ci#include "libavcodec/me_cmp.h"
27cabdff1aSopenharmony_ci
28cabdff1aSopenharmony_ci#include "checkasm.h"
29cabdff1aSopenharmony_ci
30cabdff1aSopenharmony_cistatic void fill_random(uint8_t *tab, int size)
31cabdff1aSopenharmony_ci{
32cabdff1aSopenharmony_ci    int i;
33cabdff1aSopenharmony_ci    for (i = 0; i < size; i++) {
34cabdff1aSopenharmony_ci        tab[i] = rnd() % 256;
35cabdff1aSopenharmony_ci    }
36cabdff1aSopenharmony_ci}
37cabdff1aSopenharmony_ci
38cabdff1aSopenharmony_cistatic void test_motion(const char *name, me_cmp_func test_func)
39cabdff1aSopenharmony_ci{
40cabdff1aSopenharmony_ci    /* test configurarion */
41cabdff1aSopenharmony_ci#define ITERATIONS 16
42cabdff1aSopenharmony_ci#define WIDTH 64
43cabdff1aSopenharmony_ci#define HEIGHT 64
44cabdff1aSopenharmony_ci
45cabdff1aSopenharmony_ci    /* motion estimation can look up to 17 bytes ahead */
46cabdff1aSopenharmony_ci    static const int look_ahead = 17;
47cabdff1aSopenharmony_ci
48cabdff1aSopenharmony_ci    int i, x, y, d1, d2;
49cabdff1aSopenharmony_ci    uint8_t *ptr;
50cabdff1aSopenharmony_ci
51cabdff1aSopenharmony_ci    LOCAL_ALIGNED_16(uint8_t, img1, [WIDTH * HEIGHT]);
52cabdff1aSopenharmony_ci    LOCAL_ALIGNED_16(uint8_t, img2, [WIDTH * HEIGHT]);
53cabdff1aSopenharmony_ci
54cabdff1aSopenharmony_ci    declare_func_emms(AV_CPU_FLAG_MMX, int, struct MpegEncContext *c,
55cabdff1aSopenharmony_ci                      uint8_t *blk1 /* align width (8 or 16) */,
56cabdff1aSopenharmony_ci                      uint8_t *blk2 /* align 1 */, ptrdiff_t stride,
57cabdff1aSopenharmony_ci                      int h);
58cabdff1aSopenharmony_ci
59cabdff1aSopenharmony_ci    if (test_func == NULL) {
60cabdff1aSopenharmony_ci        return;
61cabdff1aSopenharmony_ci    }
62cabdff1aSopenharmony_ci
63cabdff1aSopenharmony_ci    /* test correctness */
64cabdff1aSopenharmony_ci    fill_random(img1, WIDTH * HEIGHT);
65cabdff1aSopenharmony_ci    fill_random(img2, WIDTH * HEIGHT);
66cabdff1aSopenharmony_ci
67cabdff1aSopenharmony_ci    if (check_func(test_func, "%s", name)) {
68cabdff1aSopenharmony_ci        for (i = 0; i < ITERATIONS; i++) {
69cabdff1aSopenharmony_ci            x = rnd() % (WIDTH - look_ahead);
70cabdff1aSopenharmony_ci            y = rnd() % (HEIGHT - look_ahead);
71cabdff1aSopenharmony_ci
72cabdff1aSopenharmony_ci            ptr = img2 + y * WIDTH + x;
73cabdff1aSopenharmony_ci            d2 = call_ref(NULL, img1, ptr, WIDTH, 8);
74cabdff1aSopenharmony_ci            d1 = call_new(NULL, img1, ptr, WIDTH, 8);
75cabdff1aSopenharmony_ci
76cabdff1aSopenharmony_ci            if (d1 != d2) {
77cabdff1aSopenharmony_ci                fail();
78cabdff1aSopenharmony_ci                printf("func: %s, x=%d y=%d, error: asm=%d c=%d\n", name, x, y, d1, d2);
79cabdff1aSopenharmony_ci                break;
80cabdff1aSopenharmony_ci            }
81cabdff1aSopenharmony_ci        }
82cabdff1aSopenharmony_ci        // benchmark with the final value of ptr
83cabdff1aSopenharmony_ci        bench_new(NULL, img1, ptr, WIDTH, 8);
84cabdff1aSopenharmony_ci    }
85cabdff1aSopenharmony_ci}
86cabdff1aSopenharmony_ci
87cabdff1aSopenharmony_ci#define ME_CMP_1D_ARRAYS(XX)                                                   \
88cabdff1aSopenharmony_ci    XX(sad)                                                                    \
89cabdff1aSopenharmony_ci    XX(sse)                                                                    \
90cabdff1aSopenharmony_ci    XX(hadamard8_diff)                                                         \
91cabdff1aSopenharmony_ci    XX(vsad)                                                                   \
92cabdff1aSopenharmony_ci    XX(vsse)                                                                   \
93cabdff1aSopenharmony_ci    XX(nsse)                                                                   \
94cabdff1aSopenharmony_ci    XX(me_pre_cmp)                                                             \
95cabdff1aSopenharmony_ci    XX(me_cmp)                                                                 \
96cabdff1aSopenharmony_ci    XX(me_sub_cmp)                                                             \
97cabdff1aSopenharmony_ci    XX(mb_cmp)                                                                 \
98cabdff1aSopenharmony_ci    XX(ildct_cmp)                                                              \
99cabdff1aSopenharmony_ci    XX(frame_skip_cmp)                                                         \
100cabdff1aSopenharmony_ci    XX(median_sad)
101cabdff1aSopenharmony_ci
102cabdff1aSopenharmony_ci// tests for functions not yet implemented
103cabdff1aSopenharmony_ci#if 0
104cabdff1aSopenharmony_ci    XX(dct_sad)                                                                \
105cabdff1aSopenharmony_ci    XX(quant_psnr)                                                             \
106cabdff1aSopenharmony_ci    XX(bit)                                                                    \
107cabdff1aSopenharmony_ci    XX(rd)                                                                     \
108cabdff1aSopenharmony_ci    XX(w53)                                                                    \
109cabdff1aSopenharmony_ci    XX(w97)                                                                    \
110cabdff1aSopenharmony_ci    XX(dct_max)                                                                \
111cabdff1aSopenharmony_ci    XX(dct264_sad)                                                             \
112cabdff1aSopenharmony_ci
113cabdff1aSopenharmony_ci#endif
114cabdff1aSopenharmony_ci
115cabdff1aSopenharmony_cistatic void check_motion(void)
116cabdff1aSopenharmony_ci{
117cabdff1aSopenharmony_ci    char buf[64];
118cabdff1aSopenharmony_ci    AVCodecContext *av_ctx;
119cabdff1aSopenharmony_ci    MECmpContext me_ctx;
120cabdff1aSopenharmony_ci
121cabdff1aSopenharmony_ci    memset(&me_ctx, 0, sizeof(me_ctx));
122cabdff1aSopenharmony_ci
123cabdff1aSopenharmony_ci    /* allocate AVCodecContext */
124cabdff1aSopenharmony_ci    av_ctx = avcodec_alloc_context3(NULL);
125cabdff1aSopenharmony_ci    av_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
126cabdff1aSopenharmony_ci
127cabdff1aSopenharmony_ci    ff_me_cmp_init(&me_ctx, av_ctx);
128cabdff1aSopenharmony_ci
129cabdff1aSopenharmony_ci    for (int i = 0; i < FF_ARRAY_ELEMS(me_ctx.pix_abs); i++) {
130cabdff1aSopenharmony_ci        for (int j = 0; j < FF_ARRAY_ELEMS(me_ctx.pix_abs[0]); j++) {
131cabdff1aSopenharmony_ci            snprintf(buf, sizeof(buf), "pix_abs_%d_%d", i, j);
132cabdff1aSopenharmony_ci            test_motion(buf, me_ctx.pix_abs[i][j]);
133cabdff1aSopenharmony_ci        }
134cabdff1aSopenharmony_ci    }
135cabdff1aSopenharmony_ci
136cabdff1aSopenharmony_ci#define XX(me_cmp_array)                                                        \
137cabdff1aSopenharmony_ci    for (int i = 0; i < FF_ARRAY_ELEMS(me_ctx.me_cmp_array); i++) {             \
138cabdff1aSopenharmony_ci        snprintf(buf, sizeof(buf), #me_cmp_array "_%d", i);                     \
139cabdff1aSopenharmony_ci        test_motion(buf, me_ctx.me_cmp_array[i]);                               \
140cabdff1aSopenharmony_ci    }
141cabdff1aSopenharmony_ci    ME_CMP_1D_ARRAYS(XX)
142cabdff1aSopenharmony_ci#undef XX
143cabdff1aSopenharmony_ci
144cabdff1aSopenharmony_ci    avcodec_free_context(&av_ctx);
145cabdff1aSopenharmony_ci}
146cabdff1aSopenharmony_ci
147cabdff1aSopenharmony_civoid checkasm_check_motion(void)
148cabdff1aSopenharmony_ci{
149cabdff1aSopenharmony_ci    check_motion();
150cabdff1aSopenharmony_ci    report("motion");
151cabdff1aSopenharmony_ci}
152