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 <stddef.h>
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci#include "config.h"
22cabdff1aSopenharmony_ci#include "pixelutils.h"
23cabdff1aSopenharmony_ci
24cabdff1aSopenharmony_ci#if CONFIG_PIXELUTILS
25cabdff1aSopenharmony_ci#include <stdlib.h>
26cabdff1aSopenharmony_ci#include <string.h>
27cabdff1aSopenharmony_ci
28cabdff1aSopenharmony_ci#include "attributes.h"
29cabdff1aSopenharmony_ci#include "macros.h"
30cabdff1aSopenharmony_ci
31cabdff1aSopenharmony_ci#include "x86/pixelutils.h"
32cabdff1aSopenharmony_ci
33cabdff1aSopenharmony_cistatic av_always_inline int sad_wxh(const uint8_t *src1, ptrdiff_t stride1,
34cabdff1aSopenharmony_ci                                    const uint8_t *src2, ptrdiff_t stride2,
35cabdff1aSopenharmony_ci                                    int w, int h)
36cabdff1aSopenharmony_ci{
37cabdff1aSopenharmony_ci    int x, y, sum = 0;
38cabdff1aSopenharmony_ci
39cabdff1aSopenharmony_ci    for (y = 0; y < h; y++) {
40cabdff1aSopenharmony_ci        for (x = 0; x < w; x++)
41cabdff1aSopenharmony_ci            sum += abs(src1[x] - src2[x]);
42cabdff1aSopenharmony_ci        src1 += stride1;
43cabdff1aSopenharmony_ci        src2 += stride2;
44cabdff1aSopenharmony_ci    }
45cabdff1aSopenharmony_ci    return sum;
46cabdff1aSopenharmony_ci}
47cabdff1aSopenharmony_ci
48cabdff1aSopenharmony_ci#define DECLARE_BLOCK_FUNCTIONS(size)                                               \
49cabdff1aSopenharmony_cistatic int block_sad_##size##x##size##_c(const uint8_t *src1, ptrdiff_t stride1,    \
50cabdff1aSopenharmony_ci                                         const uint8_t *src2, ptrdiff_t stride2)    \
51cabdff1aSopenharmony_ci{                                                                                   \
52cabdff1aSopenharmony_ci    return sad_wxh(src1, stride1, src2, stride2, size, size);                       \
53cabdff1aSopenharmony_ci}
54cabdff1aSopenharmony_ci
55cabdff1aSopenharmony_ciDECLARE_BLOCK_FUNCTIONS(2)
56cabdff1aSopenharmony_ciDECLARE_BLOCK_FUNCTIONS(4)
57cabdff1aSopenharmony_ciDECLARE_BLOCK_FUNCTIONS(8)
58cabdff1aSopenharmony_ciDECLARE_BLOCK_FUNCTIONS(16)
59cabdff1aSopenharmony_ciDECLARE_BLOCK_FUNCTIONS(32)
60cabdff1aSopenharmony_ci
61cabdff1aSopenharmony_cistatic const av_pixelutils_sad_fn sad_c[] = {
62cabdff1aSopenharmony_ci    block_sad_2x2_c,
63cabdff1aSopenharmony_ci    block_sad_4x4_c,
64cabdff1aSopenharmony_ci    block_sad_8x8_c,
65cabdff1aSopenharmony_ci    block_sad_16x16_c,
66cabdff1aSopenharmony_ci    block_sad_32x32_c,
67cabdff1aSopenharmony_ci};
68cabdff1aSopenharmony_ci#else
69cabdff1aSopenharmony_ci#include "log.h"
70cabdff1aSopenharmony_ci#endif /* CONFIG_PIXELUTILS */
71cabdff1aSopenharmony_ci
72cabdff1aSopenharmony_ciav_pixelutils_sad_fn av_pixelutils_get_sad_fn(int w_bits, int h_bits, int aligned, void *log_ctx)
73cabdff1aSopenharmony_ci{
74cabdff1aSopenharmony_ci#if !CONFIG_PIXELUTILS
75cabdff1aSopenharmony_ci    av_log(log_ctx, AV_LOG_ERROR, "pixelutils support is required "
76cabdff1aSopenharmony_ci           "but libavutil is not compiled with it\n");
77cabdff1aSopenharmony_ci    return NULL;
78cabdff1aSopenharmony_ci#else
79cabdff1aSopenharmony_ci    av_pixelutils_sad_fn sad[FF_ARRAY_ELEMS(sad_c)];
80cabdff1aSopenharmony_ci
81cabdff1aSopenharmony_ci    memcpy(sad, sad_c, sizeof(sad));
82cabdff1aSopenharmony_ci
83cabdff1aSopenharmony_ci    if (w_bits < 1 || w_bits > FF_ARRAY_ELEMS(sad) ||
84cabdff1aSopenharmony_ci        h_bits < 1 || h_bits > FF_ARRAY_ELEMS(sad))
85cabdff1aSopenharmony_ci        return NULL;
86cabdff1aSopenharmony_ci    if (w_bits != h_bits) // only squared sad for now
87cabdff1aSopenharmony_ci        return NULL;
88cabdff1aSopenharmony_ci
89cabdff1aSopenharmony_ci#if ARCH_X86
90cabdff1aSopenharmony_ci    ff_pixelutils_sad_init_x86(sad, aligned);
91cabdff1aSopenharmony_ci#endif
92cabdff1aSopenharmony_ci
93cabdff1aSopenharmony_ci    return sad[w_bits - 1];
94cabdff1aSopenharmony_ci#endif
95cabdff1aSopenharmony_ci}
96