1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (c) 2007 Luca Barbato <lu_zero@gentoo.org>
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
9cabdff1aSopenharmony_ci * version 2.1 of the License, or (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 GNU
14cabdff1aSopenharmony_ci * Lesser General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci#include "config.h"
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci#include <stdint.h>
24cabdff1aSopenharmony_ci
25cabdff1aSopenharmony_ci#include "libavutil/attributes.h"
26cabdff1aSopenharmony_ci#include "libavutil/cpu.h"
27cabdff1aSopenharmony_ci#include "libavutil/ppc/cpu.h"
28cabdff1aSopenharmony_ci#include "libavutil/ppc/util_altivec.h"
29cabdff1aSopenharmony_ci
30cabdff1aSopenharmony_ci#include "libavcodec/svq1enc.h"
31cabdff1aSopenharmony_ci
32cabdff1aSopenharmony_ci#if HAVE_ALTIVEC
33cabdff1aSopenharmony_cistatic int ssd_int8_vs_int16_altivec(const int8_t *pix1, const int16_t *pix2,
34cabdff1aSopenharmony_ci                                     intptr_t size)
35cabdff1aSopenharmony_ci{
36cabdff1aSopenharmony_ci    int i, size16 = size >> 4;
37cabdff1aSopenharmony_ci    vector signed char vpix1;
38cabdff1aSopenharmony_ci    vector signed short vpix2, vdiff, vpix1l, vpix1h;
39cabdff1aSopenharmony_ci    union {
40cabdff1aSopenharmony_ci        vector signed int vscore;
41cabdff1aSopenharmony_ci        int32_t score[4];
42cabdff1aSopenharmony_ci    } u = { .vscore = vec_splat_s32(0) };
43cabdff1aSopenharmony_ci
44cabdff1aSopenharmony_ci    while (size16) {
45cabdff1aSopenharmony_ci        // score += (pix1[i] - pix2[i]) * (pix1[i] - pix2[i]);
46cabdff1aSopenharmony_ci        // load pix1 and the first batch of pix2
47cabdff1aSopenharmony_ci
48cabdff1aSopenharmony_ci        vpix1 = vec_unaligned_load(pix1);
49cabdff1aSopenharmony_ci        vpix2 = vec_unaligned_load(pix2);
50cabdff1aSopenharmony_ci        pix2 += 8;
51cabdff1aSopenharmony_ci        // unpack
52cabdff1aSopenharmony_ci        vpix1h = vec_unpackh(vpix1);
53cabdff1aSopenharmony_ci        vdiff  = vec_sub(vpix1h, vpix2);
54cabdff1aSopenharmony_ci        vpix1l = vec_unpackl(vpix1);
55cabdff1aSopenharmony_ci        // load another batch from pix2
56cabdff1aSopenharmony_ci        vpix2    = vec_unaligned_load(pix2);
57cabdff1aSopenharmony_ci        u.vscore = vec_msum(vdiff, vdiff, u.vscore);
58cabdff1aSopenharmony_ci        vdiff    = vec_sub(vpix1l, vpix2);
59cabdff1aSopenharmony_ci        u.vscore = vec_msum(vdiff, vdiff, u.vscore);
60cabdff1aSopenharmony_ci        pix1    += 16;
61cabdff1aSopenharmony_ci        pix2    += 8;
62cabdff1aSopenharmony_ci        size16--;
63cabdff1aSopenharmony_ci    }
64cabdff1aSopenharmony_ci    u.vscore = vec_sums(u.vscore, vec_splat_s32(0));
65cabdff1aSopenharmony_ci
66cabdff1aSopenharmony_ci    size %= 16;
67cabdff1aSopenharmony_ci    for (i = 0; i < size; i++)
68cabdff1aSopenharmony_ci        u.score[3] += (pix1[i] - pix2[i]) * (pix1[i] - pix2[i]);
69cabdff1aSopenharmony_ci
70cabdff1aSopenharmony_ci    return u.score[3];
71cabdff1aSopenharmony_ci}
72cabdff1aSopenharmony_ci#endif /* HAVE_ALTIVEC */
73cabdff1aSopenharmony_ci
74cabdff1aSopenharmony_ciav_cold void ff_svq1enc_init_ppc(SVQ1EncContext *c)
75cabdff1aSopenharmony_ci{
76cabdff1aSopenharmony_ci#if HAVE_ALTIVEC
77cabdff1aSopenharmony_ci    if (!PPC_ALTIVEC(av_get_cpu_flags()))
78cabdff1aSopenharmony_ci        return;
79cabdff1aSopenharmony_ci
80cabdff1aSopenharmony_ci    c->ssd_int8_vs_int16 = ssd_int8_vs_int16_altivec;
81cabdff1aSopenharmony_ci#endif /* HAVE_ALTIVEC */
82cabdff1aSopenharmony_ci}
83