FFmpeg
Loading...
Searching...
No Matches
pixblockdsp_altivec.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2002 Brian Foley
3 * Copyright (c) 2002 Dieter Shirley
4 * Copyright (c) 2003-2004 Romain Dolbeau <romain@dolbeau.org>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "config.h"
24
27
29
30#include "pixblockdsp_altivec.h"
31
32#if HAVE_VSX
33static void get_pixels_altivec(int16_t *restrict block, const uint8_t *pixels,
34 ptrdiff_t stride)
35{
36 int i;
37 vector unsigned char perm =
38 (vector unsigned char) {0x00,0x10, 0x01,0x11,0x02,0x12,0x03,0x13,\
39 0x04,0x14,0x05,0x15,0x06,0x16,0x07,0x17};
40 const vector unsigned char zero =
41 (const vector unsigned char) vec_splat_u8(0);
42
43 for (i = 0; i < 8; i++) {
44 /* Read potentially unaligned pixels.
45 * We're reading 16 pixels, and actually only want 8,
46 * but we simply ignore the extras. */
47 vector unsigned char bytes = vec_vsx_ld(0, pixels);
48
49 // Convert the bytes into shorts.
50 //vector signed short shorts = (vector signed short) vec_perm(zero, bytes, perm);
51 vector signed short shorts = (vector signed short) vec_perm(bytes, zero, perm);
52
53 // Save the data to the block, we assume the block is 16-byte aligned.
54 vec_vsx_st(shorts, i * 16, (vector signed short *) block);
55
56 pixels += stride;
57 }
58}
59#else
60static void get_pixels_altivec(int16_t *restrict block, const uint8_t *pixels,
61 ptrdiff_t stride)
62{
63 int i;
64 const vec_u8 zero = (const vec_u8)vec_splat_u8(0);
65
66 for (i = 0; i < 8; i++) {
67 vec_u8 perm = vec_lvsl(0, pixels);
68 /* Read potentially unaligned pixels.
69 * We're reading 16 pixels, and actually only want 8,
70 * but we simply ignore the extras. */
71 vec_u8 pixl = vec_ld(0, pixels);
72 vec_u8 pixr = vec_ld(7, pixels);
73 vec_u8 bytes = vec_perm(pixl, pixr, perm);
74
75 // Convert the bytes into shorts.
76 vec_s16 shorts = (vec_s16)vec_mergeh(zero, bytes);
77
78 // Save the data to the block, we assume the block is 16-byte aligned.
79 vec_st(shorts, i * 16, (vec_s16 *)block);
80
81 pixels += stride;
82 }
83}
84
85#endif /* HAVE_VSX */
86
87#if HAVE_VSX
88static void diff_pixels_altivec(int16_t *restrict block, const uint8_t *s1,
89 const uint8_t *s2, ptrdiff_t stride)
90{
91 int i;
92 const vector unsigned char zero =
93 (const vector unsigned char) vec_splat_u8(0);
94 vector signed short shorts1, shorts2;
95
96 for (i = 0; i < 4; i++) {
97 /* Read potentially unaligned pixels.
98 * We're reading 16 pixels, and actually only want 8,
99 * but we simply ignore the extras. */
100 vector unsigned char bytes = vec_vsx_ld(0, s1);
101
102 // Convert the bytes into shorts.
103 shorts1 = (vector signed short) vec_mergeh(bytes, zero);
104
105 // Do the same for the second block of pixels.
106 bytes =vec_vsx_ld(0, s2);
107
108 // Convert the bytes into shorts.
109 shorts2 = (vector signed short) vec_mergeh(bytes, zero);
110
111 // Do the subtraction.
112 shorts1 = vec_sub(shorts1, shorts2);
113
114 // Save the data to the block, we assume the block is 16-byte aligned.
115 vec_vsx_st(shorts1, 0, (vector signed short *) block);
116
117 s1 += stride;
118 s2 += stride;
119 block += 8;
120
121 /* The code below is a copy of the code above...
122 * This is a manual unroll. */
123
124 /* Read potentially unaligned pixels.
125 * We're reading 16 pixels, and actually only want 8,
126 * but we simply ignore the extras. */
127 bytes = vec_vsx_ld(0, s1);
128
129 // Convert the bytes into shorts.
130 shorts1 = (vector signed short) vec_mergeh(bytes, zero);
131
132 // Do the same for the second block of pixels.
133 bytes = vec_vsx_ld(0, s2);
134
135 // Convert the bytes into shorts.
136 shorts2 = (vector signed short) vec_mergeh(bytes, zero);
137
138 // Do the subtraction.
139 shorts1 = vec_sub(shorts1, shorts2);
140
141 // Save the data to the block, we assume the block is 16-byte aligned.
142 vec_vsx_st(shorts1, 0, (vector signed short *) block);
143
144 s1 += stride;
145 s2 += stride;
146 block += 8;
147 }
148}
149#else
150static void diff_pixels_altivec(int16_t *restrict block, const uint8_t *s1,
151 const uint8_t *s2, ptrdiff_t stride)
152{
153 int i;
154 vec_u8 perm;
155 const vec_u8 zero = (const vec_u8)vec_splat_u8(0);
156 vec_s16 shorts1, shorts2;
157
158 for (i = 0; i < 4; i++) {
159 /* Read potentially unaligned pixels.
160 * We're reading 16 pixels, and actually only want 8,
161 * but we simply ignore the extras. */
162 perm = vec_lvsl(0, s1);
163 vec_u8 pixl = vec_ld(0, s1);
164 vec_u8 pixr = vec_ld(15, s1);
165 vec_u8 bytes = vec_perm(pixl, pixr, perm);
166
167 // Convert the bytes into shorts.
168 shorts1 = (vec_s16)vec_mergeh(zero, bytes);
169
170 // Do the same for the second block of pixels.
171 perm = vec_lvsl(0, s2);
172 pixl = vec_ld(0, s2);
173 pixr = vec_ld(15, s2);
174 bytes = vec_perm(pixl, pixr, perm);
175
176 // Convert the bytes into shorts.
177 shorts2 = (vec_s16)vec_mergeh(zero, bytes);
178
179 // Do the subtraction.
180 shorts1 = vec_sub(shorts1, shorts2);
181
182 // Save the data to the block, we assume the block is 16-byte aligned.
183 vec_st(shorts1, 0, (vec_s16 *)block);
184
185 s1 += stride;
186 s2 += stride;
187 block += 8;
188
189 /* The code below is a copy of the code above...
190 * This is a manual unroll. */
191
192 /* Read potentially unaligned pixels.
193 * We're reading 16 pixels, and actually only want 8,
194 * but we simply ignore the extras. */
195 perm = vec_lvsl(0, s1);
196 pixl = vec_ld(0, s1);
197 pixr = vec_ld(15, s1);
198 bytes = vec_perm(pixl, pixr, perm);
199
200 // Convert the bytes into shorts.
201 shorts1 = (vec_s16)vec_mergeh(zero, bytes);
202
203 // Do the same for the second block of pixels.
204 perm = vec_lvsl(0, s2);
205 pixl = vec_ld(0, s2);
206 pixr = vec_ld(15, s2);
207 bytes = vec_perm(pixl, pixr, perm);
208
209 // Convert the bytes into shorts.
210 shorts2 = (vec_s16)vec_mergeh(zero, bytes);
211
212 // Do the subtraction.
213 shorts1 = vec_sub(shorts1, shorts2);
214
215 // Save the data to the block, we assume the block is 16-byte aligned.
216 vec_st(shorts1, 0, (vec_s16 *)block);
217
218 s1 += stride;
219 s2 += stride;
220 block += 8;
221 }
222}
223
224#endif /* HAVE_VSX */
225
227 unsigned high_bit_depth)
228{
229 c->diff_pixels = diff_pixels_altivec;
230
231 if (!high_bit_depth) {
232 c->get_pixels = get_pixels_altivec;
233 }
234}
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
static int16_t block[64]
Definition dct.c:125
perm
Definition f_perms.c:75
static int zero(InterplayACMContext *s, unsigned ind, unsigned col)
Macro definitions for various function/variable attributes.
#define av_cold
Definition attributes.h:117
av_cold void ff_pixblockdsp_init_altivec(PixblockDSPContext *c, unsigned high_bit_depth)
static void get_pixels_altivec(int16_t *restrict block, const uint8_t *pixels, ptrdiff_t stride)
static void diff_pixels_altivec(int16_t *restrict block, const uint8_t *s1, const uint8_t *s2, ptrdiff_t stride)
#define stride
Contains misc utility macros and inline functions.
#define vec_s16
#define vec_u8
static double c[64]