FFmpeg
Loading...
Searching...
No Matches
hscale_fast_bilinear_lsx.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 Loongson Technology Co. Ltd.
3 * Contributed by Bo Jin(jinbo@loongson.cn)
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include "swscale_loongarch.h"
24
25/* Each vector iteration scales 8 destination pixels. Their source
26 * position offsets ((xpos & 0xFFFF) + j*xInc) >> 16, j in [0, 7], must
27 * stay within the 32-byte gather window, which holds while
28 * xInc <= (1 << 18); otherwise fall back to the scalar loop. */
29#define LSX_HSCALE_FAST_MAX_XINC (1 << 18)
30
31void ff_hyscale_fast_lsx(SwsInternal *c, int16_t *dst, int dstWidth,
32 const uint8_t *src, int srcW, int xInc)
33{
34 int i = 0;
35 unsigned int xpos = 0;
36
37 if (xInc <= LSX_HSCALE_FAST_MAX_XINC) {
38 static const int32_t idx32[4] = {0, 1, 2, 3};
39 static const int16_t idx16[8] = {0, 1, 2, 3, 4, 5, 6, 7};
40 static const uint8_t shuf8[16] = {
41 0, 4, 8, 12, 16, 20, 24, 28,
42 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30
43 };
44
45 /* [0, xInc, 2*xInc, 3*xInc] as 32-bit lanes */
46 __m128i vadd_w = __lsx_vmul_w(__lsx_vreplgr2vr_w(xInc),
47 __lsx_vld(idx32, 0));
48 /* [0, xInc, ..., 7*xInc] modulo 2^16 as 16-bit lanes */
49 __m128i vadd16 = __lsx_vmul_h(__lsx_vreplgr2vr_h(xInc),
50 __lsx_vld(idx16, 0));
51 __m128i vx4 = __lsx_vreplgr2vr_w(4 * xInc);
52 __m128i vshuf8 = __lsx_vld(shuf8, 0);
53 __m128i v128 = __lsx_vreplgr2vr_h(128);
54
55 for (; i + 8 <= dstWidth && (xpos >> 16) + 32 < srcW; i += 8, xpos += 8 * xInc) {
56 unsigned int lo = xpos & 0xFFFF;
57 unsigned int xx = xpos >> 16;
58
59 /* full 32-bit positions of the 8 pixels */
60 __m128i vc0 = __lsx_vadd_w(__lsx_vreplgr2vr_w(lo), vadd_w);
61 __m128i vc1 = __lsx_vadd_w(vc0, vx4);
62
63 /* source offsets (j = 0..7), each in [0, 28] */
64 __m128i vperm = __lsx_vshuf_b(__lsx_vsrli_w(vc1, 16),
65 __lsx_vsrli_w(vc0, 16), vshuf8);
66
67 /* xalpha = (xpos & 0xFFFF) >> 9, 16-bit lanes */
68 __m128i valpha = __lsx_vsrli_h(__lsx_vadd_h(__lsx_vreplgr2vr_h(lo),
69 vadd16), 9);
70
71 __m128i v0 = __lsx_vsllwil_hu_bu(__lsx_vshuf_b(__lsx_vld(src + xx + 16, 0),
72 __lsx_vld(src + xx, 0),
73 vperm), 0);
74 __m128i v1 = __lsx_vsllwil_hu_bu(__lsx_vshuf_b(__lsx_vld(src + xx + 17, 0),
75 __lsx_vld(src + xx + 1, 0),
76 vperm), 0);
77
78 __m128i w0 = __lsx_vsub_h(v128, valpha);
79 __lsx_vst(__lsx_vadd_h(__lsx_vmul_h(v0, w0), __lsx_vmul_h(v1, valpha)),
80 dst + i, 0);
81 }
82 }
83
84 for (; i < dstWidth; i++) {
85 unsigned int xx = xpos >> 16;
86 unsigned int xalpha = (xpos & 0xFFFF) >> 9;
87 dst[i] = (src[xx] << 7) + (src[xx + 1] - src[xx]) * xalpha;
88 xpos += xInc;
89 }
90 for (i = dstWidth - 1; (i * (int64_t)xInc) >> 16 >= srcW - 1; i--)
91 dst[i] = src[srcW - 1] * 128;
92}
93
94void ff_hcscale_fast_lsx(SwsInternal *c, int16_t *dst1, int16_t *dst2,
95 int dstWidth, const uint8_t *src1,
96 const uint8_t *src2, int srcW, int xInc)
97{
98 int i = 0;
99 unsigned int xpos = 0;
100
101 if (xInc <= LSX_HSCALE_FAST_MAX_XINC) {
102 static const int32_t idx32[4] = {0, 1, 2, 3};
103 static const int16_t idx16[8] = {0, 1, 2, 3, 4, 5, 6, 7};
104 static const uint8_t shuf8[16] = {
105 0, 4, 8, 12, 16, 20, 24, 28,
106 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30
107 };
108
109 __m128i vadd_w = __lsx_vmul_w(__lsx_vreplgr2vr_w(xInc),
110 __lsx_vld(idx32, 0));
111 __m128i vadd16 = __lsx_vmul_h(__lsx_vreplgr2vr_h(xInc),
112 __lsx_vld(idx16, 0));
113 __m128i vx4 = __lsx_vreplgr2vr_w(4 * xInc);
114 __m128i vshuf8 = __lsx_vld(shuf8, 0);
115 __m128i v127 = __lsx_vreplgr2vr_h(127);
116
117 for (; i + 8 <= dstWidth && (xpos >> 16) + 32 < srcW; i += 8, xpos += 8 * xInc) {
118 unsigned int lo = xpos & 0xFFFF;
119 unsigned int xx = xpos >> 16;
120
121 __m128i vc0 = __lsx_vadd_w(__lsx_vreplgr2vr_w(lo), vadd_w);
122 __m128i vc1 = __lsx_vadd_w(vc0, vx4);
123
124 __m128i vperm = __lsx_vshuf_b(__lsx_vsrli_w(vc1, 16),
125 __lsx_vsrli_w(vc0, 16), vshuf8);
126
127 __m128i valpha = __lsx_vsrli_h(__lsx_vadd_h(__lsx_vreplgr2vr_h(lo),
128 vadd16), 9);
129
130 __m128i v10 = __lsx_vsllwil_hu_bu(__lsx_vshuf_b(__lsx_vld(src1 + xx + 16, 0),
131 __lsx_vld(src1 + xx, 0),
132 vperm), 0);
133 __m128i v11 = __lsx_vsllwil_hu_bu(__lsx_vshuf_b(__lsx_vld(src1 + xx + 17, 0),
134 __lsx_vld(src1 + xx + 1, 0),
135 vperm), 0);
136 __m128i v20 = __lsx_vsllwil_hu_bu(__lsx_vshuf_b(__lsx_vld(src2 + xx + 16, 0),
137 __lsx_vld(src2 + xx, 0),
138 vperm), 0);
139 __m128i v21 = __lsx_vsllwil_hu_bu(__lsx_vshuf_b(__lsx_vld(src2 + xx + 17, 0),
140 __lsx_vld(src2 + xx + 1, 0),
141 vperm), 0);
142
143 __m128i w0 = __lsx_vsub_h(v127, valpha);
144 __lsx_vst(__lsx_vadd_h(__lsx_vmul_h(v10, w0), __lsx_vmul_h(v11, valpha)),
145 dst1 + i, 0);
146 __lsx_vst(__lsx_vadd_h(__lsx_vmul_h(v20, w0), __lsx_vmul_h(v21, valpha)),
147 dst2 + i, 0);
148 }
149 }
150
151 for (; i < dstWidth; i++) {
152 unsigned int xx = xpos >> 16;
153 unsigned int xalpha = (xpos & 0xFFFF) >> 9;
154 dst1[i] = (src1[xx] * (xalpha ^ 127) + src1[xx + 1] * xalpha);
155 dst2[i] = (src2[xx] * (xalpha ^ 127) + src2[xx + 1] * xalpha);
156 xpos += xInc;
157 }
158 for (i = dstWidth - 1; (i * (int64_t)xInc) >> 16 >= srcW - 1; i--) {
159 dst1[i] = src1[srcW - 1] * 128;
160 dst2[i] = src2[srcW - 1] * 128;
161 }
162}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:97
int32_t
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
long long int64_t
Definition coverity.c:34
const pixel * src2
void ff_hcscale_fast_lsx(SwsInternal *c, int16_t *dst1, int16_t *dst2, int dstWidth, const uint8_t *src1, const uint8_t *src2, int srcW, int xInc)
#define LSX_HSCALE_FAST_MAX_XINC
void ff_hyscale_fast_lsx(SwsInternal *c, int16_t *dst, int dstWidth, const uint8_t *src, int srcW, int xInc)
#define src1
Definition h264pred.c:141
#define src
Definition vp8dsp.c:248
static double c[64]