1 /*
2 * Copyright (c) 2010 Stefano Sabatini
3 * Copyright (c) 2008 Vitor Sessak
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 /**
23 * @file
24 * transposition filter
25 * Based on MPlayer libmpcodecs/vf_rotate.c.
26 */
27
28 #include <stdio.h>
29
36
42
48
49 int passthrough;
///< PassthroughType, landscape passthrough mode enabled
50 int dir;
///< TransposeDir
51
54
56 {
60
65 desc->log2_chroma_w !=
desc->log2_chroma_h) &&
68 }
69
70
72 }
73
75 uint8_t *dst, ptrdiff_t dst_linesize,
77 {
78 int x, y;
79 for (y = 0; y <
h; y++, dst += dst_linesize,
src++)
80 for (x = 0; x <
w; x++)
81 dst[x] =
src[x*src_linesize];
82 }
83
85 uint8_t *dst, ptrdiff_t dst_linesize)
86 {
88 }
89
91 uint8_t *dst, ptrdiff_t dst_linesize,
93 {
94 int x, y;
95 for (y = 0; y <
h; y++, dst += dst_linesize,
src += 2)
96 for (x = 0; x <
w; x++)
97 *((uint16_t *)(dst + 2*x)) = *((uint16_t *)(
src + x*src_linesize));
98 }
99
101 uint8_t *dst, ptrdiff_t dst_linesize)
102 {
104 }
105
107 uint8_t *dst, ptrdiff_t dst_linesize,
109 {
110 int x, y;
111 for (y = 0; y <
h; y++, dst += dst_linesize) {
112 for (x = 0; x <
w; x++) {
115 }
116 }
117 }
118
120 uint8_t *dst, ptrdiff_t dst_linesize)
121 {
123 }
124
126 uint8_t *dst, ptrdiff_t dst_linesize,
128 {
129 int x, y;
130 for (y = 0; y <
h; y++, dst += dst_linesize,
src += 4) {
131 for (x = 0; x <
w; x++)
132 *((uint32_t *)(dst + 4*x)) = *((uint32_t *)(
src + x*src_linesize));
133 }
134 }
135
137 uint8_t *dst, ptrdiff_t dst_linesize)
138 {
140 }
141
143 uint8_t *dst, ptrdiff_t dst_linesize,
145 {
146 int x, y;
147 for (y = 0; y <
h; y++, dst += dst_linesize,
src += 6) {
148 for (x = 0; x <
w; x++) {
151 }
152 }
153 }
154
156 uint8_t *dst, ptrdiff_t dst_linesize)
157 {
159 }
160
162 uint8_t *dst, ptrdiff_t dst_linesize,
164 {
165 int x, y;
166 for (y = 0; y <
h; y++, dst += dst_linesize,
src += 8)
167 for (x = 0; x <
w; x++)
168 *((uint64_t *)(dst + 8*x)) = *((uint64_t *)(
src + x*src_linesize));
169 }
170
172 uint8_t *dst, ptrdiff_t dst_linesize)
173 {
175 }
176
178 {
184
187 "dir values greater than 3 are deprecated, use the passthrough option instead\n");
190 }
191
195 "w:%d h:%d -> w:%d h:%d (passthrough mode)\n",
197 return 0;
198 } else {
200 }
201
205
207
208
210
213
214 if (
inlink->sample_aspect_ratio.num)
216 inlink->sample_aspect_ratio);
217 else
219
220 for (
int i = 0;
i < 4;
i++) {
222 switch (
s->pixsteps[
i]) {
235 }
236 }
237
238 #if ARCH_X86
239 for (
int i = 0;
i < 4;
i++) {
241
243 }
244 #endif
245
247 "w:%d h:%d dir:%d -> w:%d h:%d rotation:%s vflip:%d\n",
249 s->dir == 1 ||
s->dir == 3 ?
"clockwise" :
"counterclockwise",
250 s->dir == 0 ||
s->dir == 3);
251 return 0;
252 }
253
255 {
257
258 return s->passthrough ?
261 }
262
266
268 int nb_jobs)
269 {
274 int plane;
275
276 for (plane = 0; plane <
s->planes; plane++) {
277 int hsub = plane == 1 || plane == 2 ?
s->hsub : 0;
278 int vsub = plane == 1 || plane == 2 ?
s->vsub : 0;
279 int pixstep =
s->pixsteps[plane];
283 int start = (outh * jobnr ) / nb_jobs;
284 int end = (outh * (jobnr+1)) / nb_jobs;
286 int dstlinesize, srclinesize;
287 int x, y;
289
290 dstlinesize =
out->linesize[plane];
291 dst =
out->data[plane] + start * dstlinesize;
294
297 srclinesize *= -1;
298 }
299
301 dst =
out->data[plane] + dstlinesize * (outh - start - 1);
302 dstlinesize *= -1;
303 }
304
305 for (y = start; y < end - 7; y += 8) {
306 for (x = 0; x < outw - 7; x += 8) {
308 srclinesize,
309 dst + (y - start) * dstlinesize + x * pixstep,
310 dstlinesize);
311 }
312 if (outw - x > 0 && end - y > 0)
314 srclinesize,
315 dst + (y - start) * dstlinesize + x * pixstep,
316 dstlinesize, outw - x, end - y);
317 }
318
319 if (end - y > 0)
321 srclinesize,
322 dst + (y - start) * dstlinesize + 0 * pixstep,
323 dstlinesize, outw, end - y);
324 }
325
326 return 0;
327 }
328
330 {
331 int err = 0;
337
340
345 }
346
348 if (err < 0)
350
353 } else {
356 }
357
363
367 return err;
368 }
369
370 #define OFFSET(x) offsetof(TransContext, x)
371 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
372
379
380 { "passthrough", "do not apply transposition if the input matches the specified geometry",
385
387 };
388
390
392 {
397 },
398 };
399
401 {
405 },
406 };
407
412 .priv_class = &transpose_class,
417 };