History

avfilter/vf_transpose: rewrite for x86 SIMD

Transpose first in chunks of 8x8 blocks. 15% faster overall.

Paul B Mahol committed 9 years ago

Commit 7b19e761 parent cbd8e071 file · +141 −41Browse files

Unified · Split

libavfilter/vf_transpose.c+141−41
@@ -58,6 +58,12 @@ typedef struct TransContext { · 57 unmodified lines
58 58
59 int passthrough; ///< PassthroughType, landscape passthrough mode enabled59 int passthrough; ///< PassthroughType, landscape passthrough mode enabled
60 int dir; ///< TransposeDir60 int dir; ///< TransposeDir
61
62 void (*transpose_8x8)(uint8_t *src, ptrdiff_t src_linesize,
63 uint8_t *dst, ptrdiff_t dst_linesize);
64 void (*transpose_block)(uint8_t *src, ptrdiff_t src_linesize,
65 uint8_t *dst, ptrdiff_t dst_linesize,
66 int w, int h);
61} TransContext;67} TransContext;
62 68
63static int query_formats(AVFilterContext *ctx)69static int query_formats(AVFilterContext *ctx)
@@ -79,6 +85,109 @@ static int query_formats(AVFilterContext *ctx) · 15 unmodified lines
79 return ff_set_common_formats(ctx, pix_fmts);85 return ff_set_common_formats(ctx, pix_fmts);
80}86}
81 87
88static inline void transpose_block_8_c(uint8_t *src, ptrdiff_t src_linesize,
89 uint8_t *dst, ptrdiff_t dst_linesize,
90 int w, int h)
91{
92 int x, y;
93 for (y = 0; y < h; y++, dst += dst_linesize, src++)
94 for (x = 0; x < w; x++)
95 dst[x] = src[x*src_linesize];
96}
97
98static void transpose_8x8_8_c(uint8_t *src, ptrdiff_t src_linesize,
99 uint8_t *dst, ptrdiff_t dst_linesize)
100{
101 transpose_block_8_c(src, src_linesize, dst, dst_linesize, 8, 8);
102}
103
104static inline void transpose_block_16_c(uint8_t *src, ptrdiff_t src_linesize,
105 uint8_t *dst, ptrdiff_t dst_linesize,
106 int w, int h)
107{
108 int x, y;
109 for (y = 0; y < h; y++, dst += dst_linesize, src += 2)
110 for (x = 0; x < w; x++)
111 *((uint16_t *)(dst + 2*x)) = *((uint16_t *)(src + x*src_linesize));
112}
113
114static void transpose_8x8_16_c(uint8_t *src, ptrdiff_t src_linesize,
115 uint8_t *dst, ptrdiff_t dst_linesize)
116{
117 transpose_block_16_c(src, src_linesize, dst, dst_linesize, 8, 8);
118}
119
120static inline void transpose_block_24_c(uint8_t *src, ptrdiff_t src_linesize,
121 uint8_t *dst, ptrdiff_t dst_linesize,
122 int w, int h)
123{
124 int x, y;
125 for (y = 0; y < h; y++, dst += dst_linesize) {
126 for (x = 0; x < w; x++) {
127 int32_t v = AV_RB24(src + x*src_linesize + y*3);
128 AV_WB24(dst + 3*x, v);
129 }
130 }
131}
132
133static void transpose_8x8_24_c(uint8_t *src, ptrdiff_t src_linesize,
134 uint8_t *dst, ptrdiff_t dst_linesize)
135{
136 transpose_block_24_c(src, src_linesize, dst, dst_linesize, 8, 8);
137}
138
139static inline void transpose_block_32_c(uint8_t *src, ptrdiff_t src_linesize,
140 uint8_t *dst, ptrdiff_t dst_linesize,
141 int w, int h)
142{
143 int x, y;
144 for (y = 0; y < h; y++, dst += dst_linesize, src += 4) {
145 for (x = 0; x < w; x++)
146 *((uint32_t *)(dst + 4*x)) = *((uint32_t *)(src + x*src_linesize));
147 }
148}
149
150static void transpose_8x8_32_c(uint8_t *src, ptrdiff_t src_linesize,
151 uint8_t *dst, ptrdiff_t dst_linesize)
152{
153 transpose_block_32_c(src, src_linesize, dst, dst_linesize, 8, 8);
154}
155
156static inline void transpose_block_48_c(uint8_t *src, ptrdiff_t src_linesize,
157 uint8_t *dst, ptrdiff_t dst_linesize,
158 int w, int h)
159{
160 int x, y;
161 for (y = 0; y < h; y++, dst += dst_linesize, src += 6) {
162 for (x = 0; x < w; x++) {
163 int64_t v = AV_RB48(src + x*src_linesize);
164 AV_WB48(dst + 6*x, v);
165 }
166 }
167}
168
169static void transpose_8x8_48_c(uint8_t *src, ptrdiff_t src_linesize,
170 uint8_t *dst, ptrdiff_t dst_linesize)
171{
172 transpose_block_48_c(src, src_linesize, dst, dst_linesize, 8, 8);
173}
174
175static inline void transpose_block_64_c(uint8_t *src, ptrdiff_t src_linesize,
176 uint8_t *dst, ptrdiff_t dst_linesize,
177 int w, int h)
178{
179 int x, y;
180 for (y = 0; y < h; y++, dst += dst_linesize, src += 8)
181 for (x = 0; x < w; x++)
182 *((uint64_t *)(dst + 8*x)) = *((uint64_t *)(src + x*src_linesize));
183}
184
185static void transpose_8x8_64_c(uint8_t *src, ptrdiff_t src_linesize,
186 uint8_t *dst, ptrdiff_t dst_linesize)
187{
188 transpose_block_64_c(src, src_linesize, dst, dst_linesize, 8, 8);
189}
190
82static int config_props_output(AVFilterLink *outlink)191static int config_props_output(AVFilterLink *outlink)
83{192{
84 AVFilterContext *ctx = outlink->src;193 AVFilterContext *ctx = outlink->src;
@@ -118,6 +227,21 @@ static int config_props_output(AVFilterLink *outlink) · 33 unmodified lines
118 else227 else
119 outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;228 outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
120 229
230 switch (s->pixsteps[0]) {
231 case 1: s->transpose_block = transpose_block_8_c;
232 s->transpose_8x8 = transpose_8x8_8_c; break;
233 case 2: s->transpose_block = transpose_block_16_c;
234 s->transpose_8x8 = transpose_8x8_16_c; break;
235 case 3: s->transpose_block = transpose_block_24_c;
236 s->transpose_8x8 = transpose_8x8_24_c; break;
237 case 4: s->transpose_block = transpose_block_32_c;
238 s->transpose_8x8 = transpose_8x8_32_c; break;
239 case 6: s->transpose_block = transpose_block_48_c;
240 s->transpose_8x8 = transpose_8x8_48_c; break;
241 case 8: s->transpose_block = transpose_block_64_c;
242 s->transpose_8x8 = transpose_8x8_64_c; break;
243 }
244
121 av_log(ctx, AV_LOG_VERBOSE,245 av_log(ctx, AV_LOG_VERBOSE,
122 "w:%d h:%d dir:%d -> w:%d h:%d rotation:%s vflip:%d\n",246 "w:%d h:%d dir:%d -> w:%d h:%d rotation:%s vflip:%d\n",
123 inlink->w, inlink->h, s->dir, outlink->w, outlink->h,247 inlink->w, inlink->h, s->dir, outlink->w, outlink->h,
@@ -176,49 +300,25 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, · 52 unmodified lines
176 dstlinesize *= -1;300 dstlinesize *= -1;
177 }301 }
178 302
179 switch (pixstep) {303 for (y = start; y < end - 7; y += 8) {
180 case 1:304 for (x = 0; x < outw - 7; x += 8) {
181 for (y = start; y < end; y++, dst += dstlinesize)305 s->transpose_8x8(src + x * srclinesize + y * pixstep,
182 for (x = 0; x < outw; x++)306 srclinesize,
183 dst[x] = src[x * srclinesize + y];307 dst + (y - start) * dstlinesize + x * pixstep,
184 break;308 dstlinesize);
185 case 2:
186 for (y = start; y < end; y++, dst += dstlinesize) {
187 for (x = 0; x < outw; x++)
188 *((uint16_t *)(dst + 2 * x)) =
189 *((uint16_t *)(src + x * srclinesize + y * 2));
190 }
191 break;
192 case 3:
193 for (y = start; y < end; y++, dst += dstlinesize) {
194 for (x = 0; x < outw; x++) {
195 int32_t v = AV_RB24(src + x * srclinesize + y * 3);
196 AV_WB24(dst + 3 * x, v);
197 }
198 }
199 break;
200 case 4:
201 for (y = start; y < end; y++, dst += dstlinesize) {
202 for (x = 0; x < outw; x++)
203 *((uint32_t *)(dst + 4 * x)) =
204 *((uint32_t *)(src + x * srclinesize + y * 4));
205 }309 }
206 break;310 if (outw - x > 0 && end - y > 0)
207 case 6:311 s->transpose_block(src + x * srclinesize + y * pixstep,
208 for (y = start; y < end; y++, dst += dstlinesize) {312 srclinesize,
209 for (x = 0; x < outw; x++) {313 dst + (y - start) * dstlinesize + x * pixstep,
210 int64_t v = AV_RB48(src + x * srclinesize + y*6);314 dstlinesize, outw - x, end - y);
211 AV_WB48(dst + 6*x, v);
212 }
213 }
214 break;
215 case 8:
216 for (y = start; y < end; y++, dst += dstlinesize) {
217 for (x = 0; x < outw; x++)
218 *((uint64_t *)(dst + 8*x)) = *((uint64_t *)(src + x * srclinesize + y*8));
219 }
220 break;
221 }315 }
316
317 if (end - y > 0)
318 s->transpose_block(src + 0 * srclinesize + y * pixstep,
319 srclinesize,
320 dst + (y - start) * dstlinesize + 0 * pixstep,
321 dstlinesize, outw, end - y);
222 }322 }
223 323
224 return 0;324 return 0;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t