1 /*
2 * Copyright (c) 2011 Mark Himsley
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * @file
23 * video field order filter, heavily influenced by vf_pad.c
24 */
25
34
38 int line_size[4];
///< bytes of pixel data per line for each plane
40
42 {
46
47 /** accept any input pixel format that is not hardware accelerated, not
48 * a bitstream format, and does not have vertically sub-sampled chroma */
50 formats = NULL;
60 }
61 }
64 }
65
66 return 0;
67 }
68
70 {
73
75 }
76
78 {
82 int h, plane, src_line_step, dst_line_step, line_size,
line;
85
89 "Skipping %s.\n",
91 "frame with same field order" : "progressive frame");
93 }
94
97 } else {
99 if (!out) {
102 }
104 }
105
107 "picture will move %s one line\n",
110 for (plane = 0; plane < 4 && frame->
data[plane] && frame->
linesize[plane]; plane++) {
111 dst_line_step = out->
linesize[plane];
112 src_line_step = frame->
linesize[plane];
114 dst = out->
data[plane];
115 src = frame->
data[plane];
117 /** Move every line up one line, working from
118 * the top to the bottom of the frame.
119 * The original top line is lost.
120 * The new last line is created as a copy of the
121 * penultimate line from that field. */
122 for (line = 0; line < h; line++) {
124 memcpy(dst, src + src_line_step, line_size);
125 } else {
126 memcpy(dst, src - 2 * src_line_step, line_size);
127 }
128 dst += dst_line_step;
129 src += src_line_step;
130 }
131 } else {
132 /** Move every line down one line, working from
133 * the bottom to the top of the frame.
134 * The original bottom line is lost.
135 * The new first line is created as a copy of the
136 * second line from that field. */
137 dst += (h - 1) * dst_line_step;
138 src += (h - 1) * src_line_step;
139 for (line = h - 1; line >= 0 ; line--) {
140 if (line > 0) {
141 memcpy(dst, src - src_line_step, line_size);
142 } else {
143 memcpy(dst, src + 2 * src_line_step, line_size);
144 }
145 dst -= dst_line_step;
146 src -= src_line_step;
147 }
148 }
149 }
151
152 if (frame != out)
155 }
156
157 #define OFFSET(x) offsetof(FieldOrderContext, x)
158 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
159
164 { NULL }
165 };
166
168
170 {
175 },
176 { NULL }
177 };
178
180 {
183 },
184 { NULL }
185 };
186
188 .
name =
"fieldorder",
191 .priv_class = &fieldorder_class,
193 .
inputs = avfilter_vf_fieldorder_inputs,
194 .
outputs = avfilter_vf_fieldorder_outputs,
196 };