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

Showing the changes to libavfilter (1 of 1 file). Show all

Unified · Split

libavfilter/vf_transpose.c+141−41
@@ -58,6 +58,12 @@ typedef struct TransContext { · 57 unmodified lines
5858
5959 int passthrough; ///< PassthroughType, landscape passthrough mode enabled
6060 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);
6167 } TransContext;
6268
6369 static int query_formats(AVFilterContext *ctx)
@@ -79,6 +85,109 @@ static int query_formats(AVFilterContext *ctx) · 15 unmodified lines
7985 return ff_set_common_formats(ctx, pix_fmts);
8086 }
8187
88+static 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+
98+static 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+
104+static 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+
114+static 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+
120+static 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+
133+static 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+
139+static 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+
150+static 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+
156+static 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+
169+static 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+
175+static 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+
185+static 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+
82191 static int config_props_output(AVFilterLink *outlink)
83192 {
84193 AVFilterContext *ctx = outlink->src;
@@ -118,6 +227,21 @@ static int config_props_output(AVFilterLink *outlink) · 33 unmodified lines
118227 else
119228 outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
120229
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+
121245 av_log(ctx, AV_LOG_VERBOSE,
122246 "w:%d h:%d dir:%d -> w:%d h:%d rotation:%s vflip:%d\n",
123247 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
176300 dstlinesize *= -1;
177301 }
178302
179− switch (pixstep) {
180− case 1:
181− for (y = start; y < end; y++, dst += dstlinesize)
182− for (x = 0; x < outw; x++)
183− dst[x] = src[x * srclinesize + y];
184− break;
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));
303+ for (y = start; y < end - 7; y += 8) {
304+ for (x = 0; x < outw - 7; x += 8) {
305+ s->transpose_8x8(src + x * srclinesize + y * pixstep,
306+ srclinesize,
307+ dst + (y - start) * dstlinesize + x * pixstep,
308+ dstlinesize);
205309 }
206− break;
207− case 6:
208− for (y = start; y < end; y++, dst += dstlinesize) {
209− for (x = 0; x < outw; x++) {
210− int64_t v = AV_RB48(src + x * srclinesize + y*6);
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;
310+ if (outw - x > 0 && end - y > 0)
311+ s->transpose_block(src + x * srclinesize + y * pixstep,
312+ srclinesize,
313+ dst + (y - start) * dstlinesize + x * pixstep,
314+ dstlinesize, outw - x, end - y);
221315 }
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);
222322 }
223323
224324 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