Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Anton Khirnov authored on 2012/11/29 02:50:44... | ... |
@@ -121,90 +121,39 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int |
121 | 121 |
return ff_get_video_buffer(outlink, perms, w, h); |
122 | 122 |
} |
123 | 123 |
|
124 |
-static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
124 |
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame) |
|
125 | 125 |
{ |
126 |
- AVFilterContext *ctx = inlink->dst; |
|
127 |
- AVFilterLink *outlink = ctx->outputs[0]; |
|
128 |
- |
|
129 |
- AVFilterBufferRef *outpicref, *for_next_filter; |
|
130 |
- int ret = 0; |
|
131 |
- |
|
132 |
- outpicref = avfilter_ref_buffer(inpicref, ~0); |
|
133 |
- if (!outpicref) |
|
134 |
- return AVERROR(ENOMEM); |
|
135 |
- |
|
136 |
- for_next_filter = avfilter_ref_buffer(outpicref, ~0); |
|
137 |
- if (!for_next_filter) { |
|
138 |
- avfilter_unref_bufferp(&outpicref); |
|
139 |
- return AVERROR(ENOMEM); |
|
140 |
- } |
|
141 |
- |
|
142 |
- ret = ff_start_frame(outlink, for_next_filter); |
|
143 |
- if (ret < 0) { |
|
144 |
- avfilter_unref_bufferp(&outpicref); |
|
145 |
- return ret; |
|
146 |
- } |
|
147 |
- |
|
148 |
- outlink->out_buf = outpicref; |
|
149 |
- return 0; |
|
150 |
-} |
|
151 |
- |
|
152 |
-static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) |
|
153 |
-{ |
|
154 |
- AVFilterContext *ctx = inlink->dst; |
|
155 |
- FieldOrderContext *fieldorder = ctx->priv; |
|
156 |
- AVFilterLink *outlink = ctx->outputs[0]; |
|
157 |
- |
|
158 |
- AVFilterBufferRef *inpicref = inlink->cur_buf; |
|
126 |
+ AVFilterContext *ctx = inlink->dst; |
|
127 |
+ FieldOrderContext *s = ctx->priv; |
|
128 |
+ AVFilterLink *outlink = ctx->outputs[0]; |
|
129 |
+ int h, plane, line_step, line_size, line; |
|
130 |
+ uint8_t *data; |
|
159 | 131 |
|
160 |
- /** can only currently do slices if this filter is doing nothing |
|
161 |
- * because this filter is moving picture content, the output |
|
162 |
- * slice will contain different video lines than the input slice |
|
163 |
- * and that complexity will be added later */ |
|
164 |
- if ( !inpicref->video->interlaced |
|
165 |
- || inpicref->video->top_field_first == fieldorder->dst_tff) { |
|
166 |
- return ff_draw_slice(outlink, y, h, slice_dir); |
|
167 |
- } |
|
168 |
- return 0; |
|
169 |
-} |
|
132 |
+ if (!frame->video->interlaced || |
|
133 |
+ frame->video->top_field_first == s->dst_tff) |
|
134 |
+ return ff_filter_frame(outlink, frame); |
|
170 | 135 |
|
171 |
-static int end_frame(AVFilterLink *inlink) |
|
172 |
-{ |
|
173 |
- AVFilterContext *ctx = inlink->dst; |
|
174 |
- FieldOrderContext *fieldorder = ctx->priv; |
|
175 |
- AVFilterLink *outlink = ctx->outputs[0]; |
|
176 |
- |
|
177 |
- AVFilterBufferRef *inpicref = inlink->cur_buf; |
|
178 |
- AVFilterBufferRef *outpicref = outlink->out_buf; |
|
179 |
- |
|
180 |
- int h, plane, line_step, line_size, line; |
|
181 |
- uint8_t *cpy_src, *cpy_dst; |
|
182 |
- |
|
183 |
- if ( inpicref->video->interlaced |
|
184 |
- && inpicref->video->top_field_first != fieldorder->dst_tff) { |
|
185 | 136 |
av_dlog(ctx, |
186 | 137 |
"picture will move %s one line\n", |
187 |
- fieldorder->dst_tff ? "up" : "down"); |
|
188 |
- h = inpicref->video->h; |
|
189 |
- for (plane = 0; plane < 4 && inpicref->data[plane]; plane++) { |
|
190 |
- line_step = inpicref->linesize[plane]; |
|
191 |
- line_size = fieldorder->line_size[plane]; |
|
192 |
- cpy_src = inpicref->data[plane]; |
|
193 |
- cpy_dst = outpicref->data[plane]; |
|
194 |
- if (fieldorder->dst_tff) { |
|
138 |
+ s->dst_tff ? "up" : "down"); |
|
139 |
+ h = frame->video->h; |
|
140 |
+ for (plane = 0; plane < 4 && frame->data[plane]; plane++) { |
|
141 |
+ line_step = frame->linesize[plane]; |
|
142 |
+ line_size = s->line_size[plane]; |
|
143 |
+ data = frame->data[plane]; |
|
144 |
+ if (s->dst_tff) { |
|
195 | 145 |
/** Move every line up one line, working from |
196 | 146 |
* the top to the bottom of the frame. |
197 | 147 |
* The original top line is lost. |
198 | 148 |
* The new last line is created as a copy of the |
199 | 149 |
* penultimate line from that field. */ |
200 | 150 |
for (line = 0; line < h; line++) { |
201 |
- if (1 + line < outpicref->video->h) { |
|
202 |
- memcpy(cpy_dst, cpy_src + line_step, line_size); |
|
151 |
+ if (1 + line < frame->video->h) { |
|
152 |
+ memcpy(data, data + line_step, line_size); |
|
203 | 153 |
} else { |
204 |
- memcpy(cpy_dst, cpy_src - line_step - line_step, line_size); |
|
154 |
+ memcpy(data, data - line_step - line_step, line_size); |
|
205 | 155 |
} |
206 |
- cpy_src += line_step; |
|
207 |
- cpy_dst += line_step; |
|
156 |
+ data += line_step; |
|
208 | 157 |
} |
209 | 158 |
} else { |
210 | 159 |
/** Move every line down one line, working from |
... | ... |
@@ -212,27 +161,20 @@ static int end_frame(AVFilterLink *inlink) |
212 | 212 |
* The original bottom line is lost. |
213 | 213 |
* The new first line is created as a copy of the |
214 | 214 |
* second line from that field. */ |
215 |
- cpy_src += (h - 1) * line_step; |
|
216 |
- cpy_dst += (h - 1) * line_step; |
|
215 |
+ data += (h - 1) * line_step; |
|
217 | 216 |
for (line = h - 1; line >= 0 ; line--) { |
218 | 217 |
if (line > 0) { |
219 |
- memcpy(cpy_dst, cpy_src - line_step, line_size); |
|
218 |
+ memcpy(data, data - line_step, line_size); |
|
220 | 219 |
} else { |
221 |
- memcpy(cpy_dst, cpy_src + line_step + line_step, line_size); |
|
220 |
+ memcpy(data, data + line_step + line_step, line_size); |
|
222 | 221 |
} |
223 |
- cpy_src -= line_step; |
|
224 |
- cpy_dst -= line_step; |
|
222 |
+ data -= line_step; |
|
225 | 223 |
} |
226 | 224 |
} |
227 | 225 |
} |
228 |
- outpicref->video->top_field_first = fieldorder->dst_tff; |
|
229 |
- ff_draw_slice(outlink, 0, h, 1); |
|
230 |
- } else { |
|
231 |
- av_dlog(ctx, |
|
232 |
- "not interlaced or field order already correct\n"); |
|
233 |
- } |
|
226 |
+ frame->video->top_field_first = s->dst_tff; |
|
234 | 227 |
|
235 |
- return ff_end_frame(outlink); |
|
228 |
+ return ff_filter_frame(outlink, frame); |
|
236 | 229 |
} |
237 | 230 |
|
238 | 231 |
static const AVFilterPad avfilter_vf_fieldorder_inputs[] = { |
... | ... |
@@ -240,11 +182,9 @@ static const AVFilterPad avfilter_vf_fieldorder_inputs[] = { |
240 | 240 |
.name = "default", |
241 | 241 |
.type = AVMEDIA_TYPE_VIDEO, |
242 | 242 |
.config_props = config_input, |
243 |
- .start_frame = start_frame, |
|
244 | 243 |
.get_video_buffer = get_video_buffer, |
245 |
- .draw_slice = draw_slice, |
|
246 |
- .end_frame = end_frame, |
|
247 |
- .min_perms = AV_PERM_READ | AV_PERM_PRESERVE, |
|
244 |
+ .filter_frame = filter_frame, |
|
245 |
+ .min_perms = AV_PERM_READ | AV_PERM_WRITE, |
|
248 | 246 |
}, |
249 | 247 |
{ NULL } |
250 | 248 |
}; |