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
35
40
46
52 };
53
58
62
64 {
67
75 }
76
77
79 return 0;
80 }
81
83 {
89
92 "dir values greater than 3 are deprecated, use the passthrough option instead\n");
95 }
96
100 "w:%d h:%d -> w:%d h:%d (passthrough mode)\n",
101 inlink->
w, inlink->
h, inlink->
w, inlink->
h);
102 return 0;
103 } else {
105 }
106
109
111
112 outlink->
w = inlink->
h;
113 outlink->
h = inlink->
w;
114
118 else
120
122 "w:%d h:%d dir:%d -> w:%d h:%d rotation:%s vflip:%d\n",
123 inlink->
w, inlink->
h, trans->
dir, outlink->
w, outlink->
h,
124 trans->
dir == 1 || trans->
dir == 3 ?
"clockwise" :
"counterclockwise",
125 trans->
dir == 0 || trans->
dir == 3);
126 return 0;
127 }
128
130 {
132
136 }
137
141
143 int nb_jobs)
144 {
149 int plane;
150
151 for (plane = 0; out->
data[plane]; plane++) {
152 int hsub = plane == 1 || plane == 2 ? trans->
hsub : 0;
153 int vsub = plane == 1 || plane == 2 ? trans->
vsub : 0;
154 int pixstep = trans->
pixsteps[plane];
155 int inh = in->
height >> vsub;
158 int start = (outh * jobnr ) / nb_jobs;
159 int end = (outh * (jobnr+1)) / nb_jobs;
161 int dstlinesize, srclinesize;
163
165 dst = out->
data[plane] + start * dstlinesize;
166 src = in->
data[plane];
168
169 if (trans->
dir & 1) {
170 src += in->
linesize[plane] * (inh - 1);
171 srclinesize *= -1;
172 }
173
174 if (trans->
dir & 2) {
175 dst = out->
data[plane] + dstlinesize * (outh - start - 1);
176 dstlinesize *= -1;
177 }
178
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++) {
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 }
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);
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 }
222 }
223
224 return 0;
225 }
226
228 {
234
237
239 if (!out) {
242 }
244
247 } else {
250 }
251
256 }
257
258 #define OFFSET(x) offsetof(TransContext, x)
259 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
260
267
268 { "passthrough", "do not apply transposition if the input matches the specified geometry",
273
275 };
276
278
280 {
285 },
287 };
288
290 {
294 },
296 };
297
302 .priv_class = &transpose_class,
304 .
inputs = avfilter_vf_transpose_inputs,
305 .
outputs = avfilter_vf_transpose_outputs,
307 };