yading@10
|
1 /*
|
yading@10
|
2 * filter layer
|
yading@10
|
3 * Copyright (c) 2007 Bobby Bingham
|
yading@10
|
4 *
|
yading@10
|
5 * This file is part of FFmpeg.
|
yading@10
|
6 *
|
yading@10
|
7 * FFmpeg is free software; you can redistribute it and/or
|
yading@10
|
8 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
9 * License as published by the Free Software Foundation; either
|
yading@10
|
10 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
11 *
|
yading@10
|
12 * FFmpeg is distributed in the hope that it will be useful,
|
yading@10
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
15 * Lesser General Public License for more details.
|
yading@10
|
16 *
|
yading@10
|
17 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
18 * License along with FFmpeg; if not, write to the Free Software
|
yading@10
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
20 */
|
yading@10
|
21
|
yading@10
|
22 #include "libavutil/avassert.h"
|
yading@10
|
23 #include "libavutil/avstring.h"
|
yading@10
|
24 #include "libavutil/channel_layout.h"
|
yading@10
|
25 #include "libavutil/common.h"
|
yading@10
|
26 #include "libavutil/imgutils.h"
|
yading@10
|
27 #include "libavutil/opt.h"
|
yading@10
|
28 #include "libavutil/pixdesc.h"
|
yading@10
|
29 #include "libavutil/rational.h"
|
yading@10
|
30 #include "libavutil/samplefmt.h"
|
yading@10
|
31
|
yading@10
|
32 #include "audio.h"
|
yading@10
|
33 #include "avfilter.h"
|
yading@10
|
34 #include "formats.h"
|
yading@10
|
35 #include "internal.h"
|
yading@10
|
36 #include "audio.h"
|
yading@10
|
37
|
yading@10
|
38 static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame);
|
yading@10
|
39
|
yading@10
|
40 void ff_tlog_ref(void *ctx, AVFrame *ref, int end)
|
yading@10
|
41 {
|
yading@10
|
42 av_unused char buf[16];
|
yading@10
|
43 ff_tlog(ctx,
|
yading@10
|
44 "ref[%p buf:%p data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
|
yading@10
|
45 ref, ref->buf, ref->data[0],
|
yading@10
|
46 ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
|
yading@10
|
47 ref->pts, av_frame_get_pkt_pos(ref));
|
yading@10
|
48
|
yading@10
|
49 if (ref->width) {
|
yading@10
|
50 ff_tlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
|
yading@10
|
51 ref->sample_aspect_ratio.num, ref->sample_aspect_ratio.den,
|
yading@10
|
52 ref->width, ref->height,
|
yading@10
|
53 !ref->interlaced_frame ? 'P' : /* Progressive */
|
yading@10
|
54 ref->top_field_first ? 'T' : 'B', /* Top / Bottom */
|
yading@10
|
55 ref->key_frame,
|
yading@10
|
56 av_get_picture_type_char(ref->pict_type));
|
yading@10
|
57 }
|
yading@10
|
58 if (ref->nb_samples) {
|
yading@10
|
59 ff_tlog(ctx, " cl:%"PRId64"d n:%d r:%d",
|
yading@10
|
60 ref->channel_layout,
|
yading@10
|
61 ref->nb_samples,
|
yading@10
|
62 ref->sample_rate);
|
yading@10
|
63 }
|
yading@10
|
64
|
yading@10
|
65 ff_tlog(ctx, "]%s", end ? "\n" : "");
|
yading@10
|
66 }
|
yading@10
|
67
|
yading@10
|
68 unsigned avfilter_version(void) {
|
yading@10
|
69 av_assert0(LIBAVFILTER_VERSION_MICRO >= 100);
|
yading@10
|
70 return LIBAVFILTER_VERSION_INT;
|
yading@10
|
71 }
|
yading@10
|
72
|
yading@10
|
73 const char *avfilter_configuration(void)
|
yading@10
|
74 {
|
yading@10
|
75 return FFMPEG_CONFIGURATION;
|
yading@10
|
76 }
|
yading@10
|
77
|
yading@10
|
78 const char *avfilter_license(void)
|
yading@10
|
79 {
|
yading@10
|
80 #define LICENSE_PREFIX "libavfilter license: "
|
yading@10
|
81 return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
|
yading@10
|
82 }
|
yading@10
|
83
|
yading@10
|
84 void ff_command_queue_pop(AVFilterContext *filter)
|
yading@10
|
85 {
|
yading@10
|
86 AVFilterCommand *c= filter->command_queue;
|
yading@10
|
87 av_freep(&c->arg);
|
yading@10
|
88 av_freep(&c->command);
|
yading@10
|
89 filter->command_queue= c->next;
|
yading@10
|
90 av_free(c);
|
yading@10
|
91 }
|
yading@10
|
92
|
yading@10
|
93 void ff_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
|
yading@10
|
94 AVFilterPad **pads, AVFilterLink ***links,
|
yading@10
|
95 AVFilterPad *newpad)
|
yading@10
|
96 {
|
yading@10
|
97 unsigned i;
|
yading@10
|
98
|
yading@10
|
99 idx = FFMIN(idx, *count);
|
yading@10
|
100
|
yading@10
|
101 *pads = av_realloc(*pads, sizeof(AVFilterPad) * (*count + 1));
|
yading@10
|
102 *links = av_realloc(*links, sizeof(AVFilterLink*) * (*count + 1));
|
yading@10
|
103 memmove(*pads +idx+1, *pads +idx, sizeof(AVFilterPad) * (*count-idx));
|
yading@10
|
104 memmove(*links+idx+1, *links+idx, sizeof(AVFilterLink*) * (*count-idx));
|
yading@10
|
105 memcpy(*pads+idx, newpad, sizeof(AVFilterPad));
|
yading@10
|
106 (*links)[idx] = NULL;
|
yading@10
|
107
|
yading@10
|
108 (*count)++;
|
yading@10
|
109 for (i = idx+1; i < *count; i++)
|
yading@10
|
110 if (*links[i])
|
yading@10
|
111 (*(unsigned *)((uint8_t *) *links[i] + padidx_off))++;
|
yading@10
|
112 }
|
yading@10
|
113
|
yading@10
|
114 int avfilter_link(AVFilterContext *src, unsigned srcpad,
|
yading@10
|
115 AVFilterContext *dst, unsigned dstpad)
|
yading@10
|
116 {
|
yading@10
|
117 AVFilterLink *link;
|
yading@10
|
118
|
yading@10
|
119 if (src->nb_outputs <= srcpad || dst->nb_inputs <= dstpad ||
|
yading@10
|
120 src->outputs[srcpad] || dst->inputs[dstpad])
|
yading@10
|
121 return -1;
|
yading@10
|
122
|
yading@10
|
123 if (src->output_pads[srcpad].type != dst->input_pads[dstpad].type) {
|
yading@10
|
124 av_log(src, AV_LOG_ERROR,
|
yading@10
|
125 "Media type mismatch between the '%s' filter output pad %d (%s) and the '%s' filter input pad %d (%s)\n",
|
yading@10
|
126 src->name, srcpad, (char *)av_x_if_null(av_get_media_type_string(src->output_pads[srcpad].type), "?"),
|
yading@10
|
127 dst->name, dstpad, (char *)av_x_if_null(av_get_media_type_string(dst-> input_pads[dstpad].type), "?"));
|
yading@10
|
128 return AVERROR(EINVAL);
|
yading@10
|
129 }
|
yading@10
|
130
|
yading@10
|
131 src->outputs[srcpad] =
|
yading@10
|
132 dst-> inputs[dstpad] = link = av_mallocz(sizeof(AVFilterLink));
|
yading@10
|
133
|
yading@10
|
134 link->src = src;
|
yading@10
|
135 link->dst = dst;
|
yading@10
|
136 link->srcpad = &src->output_pads[srcpad];
|
yading@10
|
137 link->dstpad = &dst->input_pads[dstpad];
|
yading@10
|
138 link->type = src->output_pads[srcpad].type;
|
yading@10
|
139 av_assert0(AV_PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
|
yading@10
|
140 link->format = -1;
|
yading@10
|
141
|
yading@10
|
142 return 0;
|
yading@10
|
143 }
|
yading@10
|
144
|
yading@10
|
145 void avfilter_link_free(AVFilterLink **link)
|
yading@10
|
146 {
|
yading@10
|
147 if (!*link)
|
yading@10
|
148 return;
|
yading@10
|
149
|
yading@10
|
150 av_frame_free(&(*link)->partial_buf);
|
yading@10
|
151
|
yading@10
|
152 av_freep(link);
|
yading@10
|
153 }
|
yading@10
|
154
|
yading@10
|
155 int avfilter_link_get_channels(AVFilterLink *link)
|
yading@10
|
156 {
|
yading@10
|
157 return link->channels;
|
yading@10
|
158 }
|
yading@10
|
159
|
yading@10
|
160 void avfilter_link_set_closed(AVFilterLink *link, int closed)
|
yading@10
|
161 {
|
yading@10
|
162 link->closed = closed;
|
yading@10
|
163 }
|
yading@10
|
164
|
yading@10
|
165 int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
|
yading@10
|
166 unsigned filt_srcpad_idx, unsigned filt_dstpad_idx)
|
yading@10
|
167 {
|
yading@10
|
168 int ret;
|
yading@10
|
169 unsigned dstpad_idx = link->dstpad - link->dst->input_pads;
|
yading@10
|
170
|
yading@10
|
171 av_log(link->dst, AV_LOG_VERBOSE, "auto-inserting filter '%s' "
|
yading@10
|
172 "between the filter '%s' and the filter '%s'\n",
|
yading@10
|
173 filt->name, link->src->name, link->dst->name);
|
yading@10
|
174
|
yading@10
|
175 link->dst->inputs[dstpad_idx] = NULL;
|
yading@10
|
176 if ((ret = avfilter_link(filt, filt_dstpad_idx, link->dst, dstpad_idx)) < 0) {
|
yading@10
|
177 /* failed to link output filter to new filter */
|
yading@10
|
178 link->dst->inputs[dstpad_idx] = link;
|
yading@10
|
179 return ret;
|
yading@10
|
180 }
|
yading@10
|
181
|
yading@10
|
182 /* re-hookup the link to the new destination filter we inserted */
|
yading@10
|
183 link->dst = filt;
|
yading@10
|
184 link->dstpad = &filt->input_pads[filt_srcpad_idx];
|
yading@10
|
185 filt->inputs[filt_srcpad_idx] = link;
|
yading@10
|
186
|
yading@10
|
187 /* if any information on supported media formats already exists on the
|
yading@10
|
188 * link, we need to preserve that */
|
yading@10
|
189 if (link->out_formats)
|
yading@10
|
190 ff_formats_changeref(&link->out_formats,
|
yading@10
|
191 &filt->outputs[filt_dstpad_idx]->out_formats);
|
yading@10
|
192
|
yading@10
|
193 if (link->out_samplerates)
|
yading@10
|
194 ff_formats_changeref(&link->out_samplerates,
|
yading@10
|
195 &filt->outputs[filt_dstpad_idx]->out_samplerates);
|
yading@10
|
196 if (link->out_channel_layouts)
|
yading@10
|
197 ff_channel_layouts_changeref(&link->out_channel_layouts,
|
yading@10
|
198 &filt->outputs[filt_dstpad_idx]->out_channel_layouts);
|
yading@10
|
199
|
yading@10
|
200 return 0;
|
yading@10
|
201 }
|
yading@10
|
202
|
yading@10
|
203 int avfilter_config_links(AVFilterContext *filter)
|
yading@10
|
204 {
|
yading@10
|
205 int (*config_link)(AVFilterLink *);
|
yading@10
|
206 unsigned i;
|
yading@10
|
207 int ret;
|
yading@10
|
208
|
yading@10
|
209 for (i = 0; i < filter->nb_inputs; i ++) {
|
yading@10
|
210 AVFilterLink *link = filter->inputs[i];
|
yading@10
|
211 AVFilterLink *inlink;
|
yading@10
|
212
|
yading@10
|
213 if (!link) continue;
|
yading@10
|
214
|
yading@10
|
215 inlink = link->src->nb_inputs ? link->src->inputs[0] : NULL;
|
yading@10
|
216 link->current_pts = AV_NOPTS_VALUE;
|
yading@10
|
217
|
yading@10
|
218 switch (link->init_state) {
|
yading@10
|
219 case AVLINK_INIT:
|
yading@10
|
220 continue;
|
yading@10
|
221 case AVLINK_STARTINIT:
|
yading@10
|
222 av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");
|
yading@10
|
223 return 0;
|
yading@10
|
224 case AVLINK_UNINIT:
|
yading@10
|
225 link->init_state = AVLINK_STARTINIT;
|
yading@10
|
226
|
yading@10
|
227 if ((ret = avfilter_config_links(link->src)) < 0)
|
yading@10
|
228 return ret;
|
yading@10
|
229
|
yading@10
|
230 if (!(config_link = link->srcpad->config_props)) {
|
yading@10
|
231 if (link->src->nb_inputs != 1) {
|
yading@10
|
232 av_log(link->src, AV_LOG_ERROR, "Source filters and filters "
|
yading@10
|
233 "with more than one input "
|
yading@10
|
234 "must set config_props() "
|
yading@10
|
235 "callbacks on all outputs\n");
|
yading@10
|
236 return AVERROR(EINVAL);
|
yading@10
|
237 }
|
yading@10
|
238 } else if ((ret = config_link(link)) < 0) {
|
yading@10
|
239 av_log(link->src, AV_LOG_ERROR,
|
yading@10
|
240 "Failed to configure output pad on %s\n",
|
yading@10
|
241 link->src->name);
|
yading@10
|
242 return ret;
|
yading@10
|
243 }
|
yading@10
|
244
|
yading@10
|
245 switch (link->type) {
|
yading@10
|
246 case AVMEDIA_TYPE_VIDEO:
|
yading@10
|
247 if (!link->time_base.num && !link->time_base.den)
|
yading@10
|
248 link->time_base = inlink ? inlink->time_base : AV_TIME_BASE_Q;
|
yading@10
|
249
|
yading@10
|
250 if (!link->sample_aspect_ratio.num && !link->sample_aspect_ratio.den)
|
yading@10
|
251 link->sample_aspect_ratio = inlink ?
|
yading@10
|
252 inlink->sample_aspect_ratio : (AVRational){1,1};
|
yading@10
|
253
|
yading@10
|
254 if (inlink && !link->frame_rate.num && !link->frame_rate.den)
|
yading@10
|
255 link->frame_rate = inlink->frame_rate;
|
yading@10
|
256
|
yading@10
|
257 if (inlink) {
|
yading@10
|
258 if (!link->w)
|
yading@10
|
259 link->w = inlink->w;
|
yading@10
|
260 if (!link->h)
|
yading@10
|
261 link->h = inlink->h;
|
yading@10
|
262 } else if (!link->w || !link->h) {
|
yading@10
|
263 av_log(link->src, AV_LOG_ERROR,
|
yading@10
|
264 "Video source filters must set their output link's "
|
yading@10
|
265 "width and height\n");
|
yading@10
|
266 return AVERROR(EINVAL);
|
yading@10
|
267 }
|
yading@10
|
268 break;
|
yading@10
|
269
|
yading@10
|
270 case AVMEDIA_TYPE_AUDIO:
|
yading@10
|
271 if (inlink) {
|
yading@10
|
272 if (!link->time_base.num && !link->time_base.den)
|
yading@10
|
273 link->time_base = inlink->time_base;
|
yading@10
|
274 }
|
yading@10
|
275
|
yading@10
|
276 if (!link->time_base.num && !link->time_base.den)
|
yading@10
|
277 link->time_base = (AVRational) {1, link->sample_rate};
|
yading@10
|
278 }
|
yading@10
|
279
|
yading@10
|
280 if ((config_link = link->dstpad->config_props))
|
yading@10
|
281 if ((ret = config_link(link)) < 0) {
|
yading@10
|
282 av_log(link->src, AV_LOG_ERROR,
|
yading@10
|
283 "Failed to configure input pad on %s\n",
|
yading@10
|
284 link->dst->name);
|
yading@10
|
285 return ret;
|
yading@10
|
286 }
|
yading@10
|
287
|
yading@10
|
288 link->init_state = AVLINK_INIT;
|
yading@10
|
289 }
|
yading@10
|
290 }
|
yading@10
|
291
|
yading@10
|
292 return 0;
|
yading@10
|
293 }
|
yading@10
|
294
|
yading@10
|
295 void ff_tlog_link(void *ctx, AVFilterLink *link, int end)
|
yading@10
|
296 {
|
yading@10
|
297 if (link->type == AVMEDIA_TYPE_VIDEO) {
|
yading@10
|
298 ff_tlog(ctx,
|
yading@10
|
299 "link[%p s:%dx%d fmt:%s %s->%s]%s",
|
yading@10
|
300 link, link->w, link->h,
|
yading@10
|
301 av_get_pix_fmt_name(link->format),
|
yading@10
|
302 link->src ? link->src->filter->name : "",
|
yading@10
|
303 link->dst ? link->dst->filter->name : "",
|
yading@10
|
304 end ? "\n" : "");
|
yading@10
|
305 } else {
|
yading@10
|
306 char buf[128];
|
yading@10
|
307 av_get_channel_layout_string(buf, sizeof(buf), -1, link->channel_layout);
|
yading@10
|
308
|
yading@10
|
309 ff_tlog(ctx,
|
yading@10
|
310 "link[%p r:%d cl:%s fmt:%s %s->%s]%s",
|
yading@10
|
311 link, (int)link->sample_rate, buf,
|
yading@10
|
312 av_get_sample_fmt_name(link->format),
|
yading@10
|
313 link->src ? link->src->filter->name : "",
|
yading@10
|
314 link->dst ? link->dst->filter->name : "",
|
yading@10
|
315 end ? "\n" : "");
|
yading@10
|
316 }
|
yading@10
|
317 }
|
yading@10
|
318
|
yading@10
|
319 int ff_request_frame(AVFilterLink *link)
|
yading@10
|
320 {
|
yading@10
|
321 int ret = -1;
|
yading@10
|
322 FF_TPRINTF_START(NULL, request_frame); ff_tlog_link(NULL, link, 1);
|
yading@10
|
323
|
yading@10
|
324 if (link->closed)
|
yading@10
|
325 return AVERROR_EOF;
|
yading@10
|
326 av_assert0(!link->frame_requested);
|
yading@10
|
327 link->frame_requested = 1;
|
yading@10
|
328 while (link->frame_requested) {
|
yading@10
|
329 if (link->srcpad->request_frame)
|
yading@10
|
330 ret = link->srcpad->request_frame(link);
|
yading@10
|
331 else if (link->src->inputs[0])
|
yading@10
|
332 ret = ff_request_frame(link->src->inputs[0]);
|
yading@10
|
333 if (ret == AVERROR_EOF && link->partial_buf) {
|
yading@10
|
334 AVFrame *pbuf = link->partial_buf;
|
yading@10
|
335 link->partial_buf = NULL;
|
yading@10
|
336 ret = ff_filter_frame_framed(link, pbuf);
|
yading@10
|
337 }
|
yading@10
|
338 if (ret < 0) {
|
yading@10
|
339 link->frame_requested = 0;
|
yading@10
|
340 if (ret == AVERROR_EOF)
|
yading@10
|
341 link->closed = 1;
|
yading@10
|
342 } else {
|
yading@10
|
343 av_assert0(!link->frame_requested ||
|
yading@10
|
344 link->flags & FF_LINK_FLAG_REQUEST_LOOP);
|
yading@10
|
345 }
|
yading@10
|
346 }
|
yading@10
|
347 return ret;
|
yading@10
|
348 }
|
yading@10
|
349
|
yading@10
|
350 int ff_poll_frame(AVFilterLink *link)
|
yading@10
|
351 {
|
yading@10
|
352 int i, min = INT_MAX;
|
yading@10
|
353
|
yading@10
|
354 if (link->srcpad->poll_frame)
|
yading@10
|
355 return link->srcpad->poll_frame(link);
|
yading@10
|
356
|
yading@10
|
357 for (i = 0; i < link->src->nb_inputs; i++) {
|
yading@10
|
358 int val;
|
yading@10
|
359 if (!link->src->inputs[i])
|
yading@10
|
360 return -1;
|
yading@10
|
361 val = ff_poll_frame(link->src->inputs[i]);
|
yading@10
|
362 min = FFMIN(min, val);
|
yading@10
|
363 }
|
yading@10
|
364
|
yading@10
|
365 return min;
|
yading@10
|
366 }
|
yading@10
|
367
|
yading@10
|
368 void ff_update_link_current_pts(AVFilterLink *link, int64_t pts)
|
yading@10
|
369 {
|
yading@10
|
370 if (pts == AV_NOPTS_VALUE)
|
yading@10
|
371 return;
|
yading@10
|
372 link->current_pts = av_rescale_q(pts, link->time_base, AV_TIME_BASE_Q);
|
yading@10
|
373 /* TODO use duration */
|
yading@10
|
374 if (link->graph && link->age_index >= 0)
|
yading@10
|
375 ff_avfilter_graph_update_heap(link->graph, link);
|
yading@10
|
376 }
|
yading@10
|
377
|
yading@10
|
378 int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags)
|
yading@10
|
379 {
|
yading@10
|
380 if(!strcmp(cmd, "ping")){
|
yading@10
|
381 av_strlcatf(res, res_len, "pong from:%s %s\n", filter->filter->name, filter->name);
|
yading@10
|
382 return 0;
|
yading@10
|
383 }else if(filter->filter->process_command) {
|
yading@10
|
384 return filter->filter->process_command(filter, cmd, arg, res, res_len, flags);
|
yading@10
|
385 }
|
yading@10
|
386 return AVERROR(ENOSYS);
|
yading@10
|
387 }
|
yading@10
|
388
|
yading@10
|
389 static AVFilter *first_filter;
|
yading@10
|
390
|
yading@10
|
391 AVFilter *avfilter_get_by_name(const char *name)
|
yading@10
|
392 {
|
yading@10
|
393 AVFilter *f = NULL;
|
yading@10
|
394
|
yading@10
|
395 if (!name)
|
yading@10
|
396 return NULL;
|
yading@10
|
397
|
yading@10
|
398 while ((f = avfilter_next(f)))
|
yading@10
|
399 if (!strcmp(f->name, name))
|
yading@10
|
400 return f;
|
yading@10
|
401
|
yading@10
|
402 return NULL;
|
yading@10
|
403 }
|
yading@10
|
404
|
yading@10
|
405 int avfilter_register(AVFilter *filter)
|
yading@10
|
406 {
|
yading@10
|
407 AVFilter **f = &first_filter;
|
yading@10
|
408 int i;
|
yading@10
|
409
|
yading@10
|
410 for(i=0; filter->inputs && filter->inputs[i].name; i++) {
|
yading@10
|
411 const AVFilterPad *input = &filter->inputs[i];
|
yading@10
|
412 av_assert0( !input->filter_frame
|
yading@10
|
413 || (!input->start_frame && !input->end_frame));
|
yading@10
|
414 }
|
yading@10
|
415
|
yading@10
|
416 while (*f)
|
yading@10
|
417 f = &(*f)->next;
|
yading@10
|
418 *f = filter;
|
yading@10
|
419 filter->next = NULL;
|
yading@10
|
420
|
yading@10
|
421 return 0;
|
yading@10
|
422 }
|
yading@10
|
423
|
yading@10
|
424 const AVFilter *avfilter_next(const AVFilter *prev)
|
yading@10
|
425 {
|
yading@10
|
426 return prev ? prev->next : first_filter;
|
yading@10
|
427 }
|
yading@10
|
428
|
yading@10
|
429 #if FF_API_OLD_FILTER_REGISTER
|
yading@10
|
430 AVFilter **av_filter_next(AVFilter **filter)
|
yading@10
|
431 {
|
yading@10
|
432 return filter ? &(*filter)->next : &first_filter;
|
yading@10
|
433 }
|
yading@10
|
434
|
yading@10
|
435 void avfilter_uninit(void)
|
yading@10
|
436 {
|
yading@10
|
437 }
|
yading@10
|
438 #endif
|
yading@10
|
439
|
yading@10
|
440 int avfilter_pad_count(const AVFilterPad *pads)
|
yading@10
|
441 {
|
yading@10
|
442 int count;
|
yading@10
|
443
|
yading@10
|
444 if (!pads)
|
yading@10
|
445 return 0;
|
yading@10
|
446
|
yading@10
|
447 for(count = 0; pads->name; count ++) pads ++;
|
yading@10
|
448 return count;
|
yading@10
|
449 }
|
yading@10
|
450
|
yading@10
|
451 static const char *default_filter_name(void *filter_ctx)
|
yading@10
|
452 {
|
yading@10
|
453 AVFilterContext *ctx = filter_ctx;
|
yading@10
|
454 return ctx->name ? ctx->name : ctx->filter->name;
|
yading@10
|
455 }
|
yading@10
|
456
|
yading@10
|
457 static void *filter_child_next(void *obj, void *prev)
|
yading@10
|
458 {
|
yading@10
|
459 AVFilterContext *ctx = obj;
|
yading@10
|
460 if (!prev && ctx->filter && ctx->filter->priv_class && ctx->priv)
|
yading@10
|
461 return ctx->priv;
|
yading@10
|
462 return NULL;
|
yading@10
|
463 }
|
yading@10
|
464
|
yading@10
|
465 static const AVClass *filter_child_class_next(const AVClass *prev)
|
yading@10
|
466 {
|
yading@10
|
467 AVFilter *f = NULL;
|
yading@10
|
468
|
yading@10
|
469 /* find the filter that corresponds to prev */
|
yading@10
|
470 while (prev && (f = avfilter_next(f)))
|
yading@10
|
471 if (f->priv_class == prev)
|
yading@10
|
472 break;
|
yading@10
|
473
|
yading@10
|
474 /* could not find filter corresponding to prev */
|
yading@10
|
475 if (prev && !f)
|
yading@10
|
476 return NULL;
|
yading@10
|
477
|
yading@10
|
478 /* find next filter with specific options */
|
yading@10
|
479 while ((f = avfilter_next(f)))
|
yading@10
|
480 if (f->priv_class)
|
yading@10
|
481 return f->priv_class;
|
yading@10
|
482
|
yading@10
|
483 return NULL;
|
yading@10
|
484 }
|
yading@10
|
485
|
yading@10
|
486 static const AVClass avfilter_class = {
|
yading@10
|
487 .class_name = "AVFilter",
|
yading@10
|
488 .item_name = default_filter_name,
|
yading@10
|
489 .version = LIBAVUTIL_VERSION_INT,
|
yading@10
|
490 .category = AV_CLASS_CATEGORY_FILTER,
|
yading@10
|
491 .child_next = filter_child_next,
|
yading@10
|
492 .child_class_next = filter_child_class_next,
|
yading@10
|
493 };
|
yading@10
|
494
|
yading@10
|
495 AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name)
|
yading@10
|
496 {
|
yading@10
|
497 AVFilterContext *ret;
|
yading@10
|
498
|
yading@10
|
499 if (!filter)
|
yading@10
|
500 return NULL;
|
yading@10
|
501
|
yading@10
|
502 ret = av_mallocz(sizeof(AVFilterContext));
|
yading@10
|
503 if (!ret)
|
yading@10
|
504 return NULL;
|
yading@10
|
505
|
yading@10
|
506 ret->av_class = &avfilter_class;
|
yading@10
|
507 ret->filter = filter;
|
yading@10
|
508 ret->name = inst_name ? av_strdup(inst_name) : NULL;
|
yading@10
|
509 if (filter->priv_size) {
|
yading@10
|
510 ret->priv = av_mallocz(filter->priv_size);
|
yading@10
|
511 if (!ret->priv)
|
yading@10
|
512 goto err;
|
yading@10
|
513 }
|
yading@10
|
514
|
yading@10
|
515 if (filter->priv_class) {
|
yading@10
|
516 *(const AVClass**)ret->priv = filter->priv_class;
|
yading@10
|
517 av_opt_set_defaults(ret->priv);
|
yading@10
|
518 }
|
yading@10
|
519
|
yading@10
|
520 ret->nb_inputs = avfilter_pad_count(filter->inputs);
|
yading@10
|
521 if (ret->nb_inputs ) {
|
yading@10
|
522 ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->nb_inputs);
|
yading@10
|
523 if (!ret->input_pads)
|
yading@10
|
524 goto err;
|
yading@10
|
525 memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->nb_inputs);
|
yading@10
|
526 ret->inputs = av_mallocz(sizeof(AVFilterLink*) * ret->nb_inputs);
|
yading@10
|
527 if (!ret->inputs)
|
yading@10
|
528 goto err;
|
yading@10
|
529 }
|
yading@10
|
530
|
yading@10
|
531 ret->nb_outputs = avfilter_pad_count(filter->outputs);
|
yading@10
|
532 if (ret->nb_outputs) {
|
yading@10
|
533 ret->output_pads = av_malloc(sizeof(AVFilterPad) * ret->nb_outputs);
|
yading@10
|
534 if (!ret->output_pads)
|
yading@10
|
535 goto err;
|
yading@10
|
536 memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->nb_outputs);
|
yading@10
|
537 ret->outputs = av_mallocz(sizeof(AVFilterLink*) * ret->nb_outputs);
|
yading@10
|
538 if (!ret->outputs)
|
yading@10
|
539 goto err;
|
yading@10
|
540 }
|
yading@10
|
541 #if FF_API_FOO_COUNT
|
yading@10
|
542 ret->output_count = ret->nb_outputs;
|
yading@10
|
543 ret->input_count = ret->nb_inputs;
|
yading@10
|
544 #endif
|
yading@10
|
545
|
yading@10
|
546 return ret;
|
yading@10
|
547
|
yading@10
|
548 err:
|
yading@10
|
549 av_freep(&ret->inputs);
|
yading@10
|
550 av_freep(&ret->input_pads);
|
yading@10
|
551 ret->nb_inputs = 0;
|
yading@10
|
552 av_freep(&ret->outputs);
|
yading@10
|
553 av_freep(&ret->output_pads);
|
yading@10
|
554 ret->nb_outputs = 0;
|
yading@10
|
555 av_freep(&ret->priv);
|
yading@10
|
556 av_free(ret);
|
yading@10
|
557 return NULL;
|
yading@10
|
558 }
|
yading@10
|
559
|
yading@10
|
560 #if FF_API_AVFILTER_OPEN
|
yading@10
|
561 int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)
|
yading@10
|
562 {
|
yading@10
|
563 *filter_ctx = ff_filter_alloc(filter, inst_name);
|
yading@10
|
564 return *filter_ctx ? 0 : AVERROR(ENOMEM);
|
yading@10
|
565 }
|
yading@10
|
566 #endif
|
yading@10
|
567
|
yading@10
|
568 void avfilter_free(AVFilterContext *filter)
|
yading@10
|
569 {
|
yading@10
|
570 int i;
|
yading@10
|
571 AVFilterLink *link;
|
yading@10
|
572
|
yading@10
|
573 if (!filter)
|
yading@10
|
574 return;
|
yading@10
|
575
|
yading@10
|
576 if (filter->graph)
|
yading@10
|
577 ff_filter_graph_remove_filter(filter->graph, filter);
|
yading@10
|
578
|
yading@10
|
579 if (filter->filter->uninit)
|
yading@10
|
580 filter->filter->uninit(filter);
|
yading@10
|
581
|
yading@10
|
582 for (i = 0; i < filter->nb_inputs; i++) {
|
yading@10
|
583 if ((link = filter->inputs[i])) {
|
yading@10
|
584 if (link->src)
|
yading@10
|
585 link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
|
yading@10
|
586 ff_formats_unref(&link->in_formats);
|
yading@10
|
587 ff_formats_unref(&link->out_formats);
|
yading@10
|
588 ff_formats_unref(&link->in_samplerates);
|
yading@10
|
589 ff_formats_unref(&link->out_samplerates);
|
yading@10
|
590 ff_channel_layouts_unref(&link->in_channel_layouts);
|
yading@10
|
591 ff_channel_layouts_unref(&link->out_channel_layouts);
|
yading@10
|
592 }
|
yading@10
|
593 avfilter_link_free(&link);
|
yading@10
|
594 }
|
yading@10
|
595 for (i = 0; i < filter->nb_outputs; i++) {
|
yading@10
|
596 if ((link = filter->outputs[i])) {
|
yading@10
|
597 if (link->dst)
|
yading@10
|
598 link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
|
yading@10
|
599 ff_formats_unref(&link->in_formats);
|
yading@10
|
600 ff_formats_unref(&link->out_formats);
|
yading@10
|
601 ff_formats_unref(&link->in_samplerates);
|
yading@10
|
602 ff_formats_unref(&link->out_samplerates);
|
yading@10
|
603 ff_channel_layouts_unref(&link->in_channel_layouts);
|
yading@10
|
604 ff_channel_layouts_unref(&link->out_channel_layouts);
|
yading@10
|
605 }
|
yading@10
|
606 avfilter_link_free(&link);
|
yading@10
|
607 }
|
yading@10
|
608
|
yading@10
|
609 if (filter->filter->priv_class)
|
yading@10
|
610 av_opt_free(filter->priv);
|
yading@10
|
611
|
yading@10
|
612 av_freep(&filter->name);
|
yading@10
|
613 av_freep(&filter->input_pads);
|
yading@10
|
614 av_freep(&filter->output_pads);
|
yading@10
|
615 av_freep(&filter->inputs);
|
yading@10
|
616 av_freep(&filter->outputs);
|
yading@10
|
617 av_freep(&filter->priv);
|
yading@10
|
618 while(filter->command_queue){
|
yading@10
|
619 ff_command_queue_pop(filter);
|
yading@10
|
620 }
|
yading@10
|
621 av_free(filter);
|
yading@10
|
622 }
|
yading@10
|
623
|
yading@10
|
624 static int process_options(AVFilterContext *ctx, AVDictionary **options,
|
yading@10
|
625 const char *args)
|
yading@10
|
626 {
|
yading@10
|
627 const AVOption *o = NULL;
|
yading@10
|
628 int ret, count = 0;
|
yading@10
|
629 char *av_uninit(parsed_key), *av_uninit(value);
|
yading@10
|
630 const char *key;
|
yading@10
|
631 int offset= -1;
|
yading@10
|
632
|
yading@10
|
633 if (!args)
|
yading@10
|
634 return 0;
|
yading@10
|
635
|
yading@10
|
636 while (*args) {
|
yading@10
|
637 const char *shorthand = NULL;
|
yading@10
|
638
|
yading@10
|
639 o = av_opt_next(ctx->priv, o);
|
yading@10
|
640 if (o) {
|
yading@10
|
641 if (o->type == AV_OPT_TYPE_CONST || o->offset == offset)
|
yading@10
|
642 continue;
|
yading@10
|
643 offset = o->offset;
|
yading@10
|
644 shorthand = o->name;
|
yading@10
|
645 }
|
yading@10
|
646
|
yading@10
|
647 ret = av_opt_get_key_value(&args, "=", ":",
|
yading@10
|
648 shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
|
yading@10
|
649 &parsed_key, &value);
|
yading@10
|
650 if (ret < 0) {
|
yading@10
|
651 if (ret == AVERROR(EINVAL))
|
yading@10
|
652 av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", args);
|
yading@10
|
653 else
|
yading@10
|
654 av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", args,
|
yading@10
|
655 av_err2str(ret));
|
yading@10
|
656 return ret;
|
yading@10
|
657 }
|
yading@10
|
658 if (*args)
|
yading@10
|
659 args++;
|
yading@10
|
660 if (parsed_key) {
|
yading@10
|
661 key = parsed_key;
|
yading@10
|
662 while ((o = av_opt_next(ctx->priv, o))); /* discard all remaining shorthand */
|
yading@10
|
663 } else {
|
yading@10
|
664 key = shorthand;
|
yading@10
|
665 }
|
yading@10
|
666
|
yading@10
|
667 av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
|
yading@10
|
668 av_dict_set(options, key, value, 0);
|
yading@10
|
669 if ((ret = av_opt_set(ctx->priv, key, value, 0)) < 0) {
|
yading@10
|
670 if (!av_opt_find(ctx->priv, key, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) {
|
yading@10
|
671 if (ret == AVERROR_OPTION_NOT_FOUND)
|
yading@10
|
672 av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
|
yading@10
|
673 av_free(value);
|
yading@10
|
674 av_free(parsed_key);
|
yading@10
|
675 return ret;
|
yading@10
|
676 }
|
yading@10
|
677 }
|
yading@10
|
678
|
yading@10
|
679 av_free(value);
|
yading@10
|
680 av_free(parsed_key);
|
yading@10
|
681 count++;
|
yading@10
|
682 }
|
yading@10
|
683 return count;
|
yading@10
|
684 }
|
yading@10
|
685
|
yading@10
|
686 #if FF_API_AVFILTER_INIT_FILTER
|
yading@10
|
687 int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
|
yading@10
|
688 {
|
yading@10
|
689 return avfilter_init_str(filter, args);
|
yading@10
|
690 }
|
yading@10
|
691 #endif
|
yading@10
|
692
|
yading@10
|
693 int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
|
yading@10
|
694 {
|
yading@10
|
695 int ret = 0;
|
yading@10
|
696
|
yading@10
|
697 if (ctx->filter->priv_class) {
|
yading@10
|
698 ret = av_opt_set_dict(ctx->priv, options);
|
yading@10
|
699 if (ret < 0) {
|
yading@10
|
700 av_log(ctx, AV_LOG_ERROR, "Error applying options to the filter.\n");
|
yading@10
|
701 return ret;
|
yading@10
|
702 }
|
yading@10
|
703 }
|
yading@10
|
704
|
yading@10
|
705 if (ctx->filter->init_opaque)
|
yading@10
|
706 ret = ctx->filter->init_opaque(ctx, NULL);
|
yading@10
|
707 else if (ctx->filter->init)
|
yading@10
|
708 ret = ctx->filter->init(ctx);
|
yading@10
|
709 else if (ctx->filter->init_dict)
|
yading@10
|
710 ret = ctx->filter->init_dict(ctx, options);
|
yading@10
|
711
|
yading@10
|
712 return ret;
|
yading@10
|
713 }
|
yading@10
|
714
|
yading@10
|
715 int avfilter_init_str(AVFilterContext *filter, const char *args)
|
yading@10
|
716 {
|
yading@10
|
717 AVDictionary *options = NULL;
|
yading@10
|
718 AVDictionaryEntry *e;
|
yading@10
|
719 int ret=0;
|
yading@10
|
720
|
yading@10
|
721 if (args && *args) {
|
yading@10
|
722 if (!filter->filter->priv_class) {
|
yading@10
|
723 av_log(filter, AV_LOG_ERROR, "This filter does not take any "
|
yading@10
|
724 "options, but options were provided: %s.\n", args);
|
yading@10
|
725 return AVERROR(EINVAL);
|
yading@10
|
726 }
|
yading@10
|
727
|
yading@10
|
728 #if FF_API_OLD_FILTER_OPTS
|
yading@10
|
729 if ( !strcmp(filter->filter->name, "format") ||
|
yading@10
|
730 !strcmp(filter->filter->name, "noformat") ||
|
yading@10
|
731 !strcmp(filter->filter->name, "frei0r") ||
|
yading@10
|
732 !strcmp(filter->filter->name, "frei0r_src") ||
|
yading@10
|
733 !strcmp(filter->filter->name, "ocv") ||
|
yading@10
|
734 !strcmp(filter->filter->name, "pan") ||
|
yading@10
|
735 !strcmp(filter->filter->name, "pp") ||
|
yading@10
|
736 !strcmp(filter->filter->name, "aevalsrc")) {
|
yading@10
|
737 /* a hack for compatibility with the old syntax
|
yading@10
|
738 * replace colons with |s */
|
yading@10
|
739 char *copy = av_strdup(args);
|
yading@10
|
740 char *p = copy;
|
yading@10
|
741 int nb_leading = 0; // number of leading colons to skip
|
yading@10
|
742 int deprecated = 0;
|
yading@10
|
743
|
yading@10
|
744 if (!copy) {
|
yading@10
|
745 ret = AVERROR(ENOMEM);
|
yading@10
|
746 goto fail;
|
yading@10
|
747 }
|
yading@10
|
748
|
yading@10
|
749 if (!strcmp(filter->filter->name, "frei0r") ||
|
yading@10
|
750 !strcmp(filter->filter->name, "ocv"))
|
yading@10
|
751 nb_leading = 1;
|
yading@10
|
752 else if (!strcmp(filter->filter->name, "frei0r_src"))
|
yading@10
|
753 nb_leading = 3;
|
yading@10
|
754
|
yading@10
|
755 while (nb_leading--) {
|
yading@10
|
756 p = strchr(p, ':');
|
yading@10
|
757 if (!p) {
|
yading@10
|
758 p = copy + strlen(copy);
|
yading@10
|
759 break;
|
yading@10
|
760 }
|
yading@10
|
761 p++;
|
yading@10
|
762 }
|
yading@10
|
763
|
yading@10
|
764 deprecated = strchr(p, ':') != NULL;
|
yading@10
|
765
|
yading@10
|
766 if (!strcmp(filter->filter->name, "aevalsrc")) {
|
yading@10
|
767 deprecated = 0;
|
yading@10
|
768 while ((p = strchr(p, ':')) && p[1] != ':') {
|
yading@10
|
769 const char *epos = strchr(p + 1, '=');
|
yading@10
|
770 const char *spos = strchr(p + 1, ':');
|
yading@10
|
771 const int next_token_is_opt = epos && (!spos || epos < spos);
|
yading@10
|
772 if (next_token_is_opt) {
|
yading@10
|
773 p++;
|
yading@10
|
774 break;
|
yading@10
|
775 }
|
yading@10
|
776 /* next token does not contain a '=', assume a channel expression */
|
yading@10
|
777 deprecated = 1;
|
yading@10
|
778 *p++ = '|';
|
yading@10
|
779 }
|
yading@10
|
780 if (p && *p == ':') { // double sep '::' found
|
yading@10
|
781 deprecated = 1;
|
yading@10
|
782 memmove(p, p + 1, strlen(p));
|
yading@10
|
783 }
|
yading@10
|
784 } else
|
yading@10
|
785 while ((p = strchr(p, ':')))
|
yading@10
|
786 *p++ = '|';
|
yading@10
|
787
|
yading@10
|
788 if (deprecated)
|
yading@10
|
789 av_log(filter, AV_LOG_WARNING, "This syntax is deprecated. Use "
|
yading@10
|
790 "'|' to separate the list items.\n");
|
yading@10
|
791
|
yading@10
|
792 av_log(filter, AV_LOG_DEBUG, "compat: called with args=[%s]\n", copy);
|
yading@10
|
793 ret = process_options(filter, &options, copy);
|
yading@10
|
794 av_freep(©);
|
yading@10
|
795
|
yading@10
|
796 if (ret < 0)
|
yading@10
|
797 goto fail;
|
yading@10
|
798 #endif
|
yading@10
|
799 } else {
|
yading@10
|
800 #if CONFIG_MP_FILTER
|
yading@10
|
801 if (!strcmp(filter->filter->name, "mp")) {
|
yading@10
|
802 char *escaped;
|
yading@10
|
803
|
yading@10
|
804 if (!strncmp(args, "filter=", 7))
|
yading@10
|
805 args += 7;
|
yading@10
|
806 ret = av_escape(&escaped, args, ":=", AV_ESCAPE_MODE_BACKSLASH, 0);
|
yading@10
|
807 if (ret < 0) {
|
yading@10
|
808 av_log(filter, AV_LOG_ERROR, "Unable to escape MPlayer filters arg '%s'\n", args);
|
yading@10
|
809 goto fail;
|
yading@10
|
810 }
|
yading@10
|
811 ret = process_options(filter, &options, escaped);
|
yading@10
|
812 av_free(escaped);
|
yading@10
|
813 } else
|
yading@10
|
814 #endif
|
yading@10
|
815 ret = process_options(filter, &options, args);
|
yading@10
|
816 if (ret < 0)
|
yading@10
|
817 goto fail;
|
yading@10
|
818 }
|
yading@10
|
819 }
|
yading@10
|
820
|
yading@10
|
821 ret = avfilter_init_dict(filter, &options);
|
yading@10
|
822 if (ret < 0)
|
yading@10
|
823 goto fail;
|
yading@10
|
824
|
yading@10
|
825 if ((e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
|
yading@10
|
826 av_log(filter, AV_LOG_ERROR, "No such option: %s.\n", e->key);
|
yading@10
|
827 ret = AVERROR_OPTION_NOT_FOUND;
|
yading@10
|
828 goto fail;
|
yading@10
|
829 }
|
yading@10
|
830
|
yading@10
|
831 fail:
|
yading@10
|
832 av_dict_free(&options);
|
yading@10
|
833
|
yading@10
|
834 return ret;
|
yading@10
|
835 }
|
yading@10
|
836
|
yading@10
|
837 const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx)
|
yading@10
|
838 {
|
yading@10
|
839 return pads[pad_idx].name;
|
yading@10
|
840 }
|
yading@10
|
841
|
yading@10
|
842 enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx)
|
yading@10
|
843 {
|
yading@10
|
844 return pads[pad_idx].type;
|
yading@10
|
845 }
|
yading@10
|
846
|
yading@10
|
847 static int default_filter_frame(AVFilterLink *link, AVFrame *frame)
|
yading@10
|
848 {
|
yading@10
|
849 return ff_filter_frame(link->dst->outputs[0], frame);
|
yading@10
|
850 }
|
yading@10
|
851
|
yading@10
|
852 static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame)
|
yading@10
|
853 {
|
yading@10
|
854 int (*filter_frame)(AVFilterLink *, AVFrame *);
|
yading@10
|
855 AVFilterPad *dst = link->dstpad;
|
yading@10
|
856 AVFrame *out;
|
yading@10
|
857 int ret;
|
yading@10
|
858 AVFilterCommand *cmd= link->dst->command_queue;
|
yading@10
|
859 int64_t pts;
|
yading@10
|
860
|
yading@10
|
861 if (link->closed) {
|
yading@10
|
862 av_frame_free(&frame);
|
yading@10
|
863 return AVERROR_EOF;
|
yading@10
|
864 }
|
yading@10
|
865
|
yading@10
|
866 if (!(filter_frame = dst->filter_frame))
|
yading@10
|
867 filter_frame = default_filter_frame;
|
yading@10
|
868
|
yading@10
|
869 /* copy the frame if needed */
|
yading@10
|
870 if (dst->needs_writable && !av_frame_is_writable(frame)) {
|
yading@10
|
871 av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
|
yading@10
|
872
|
yading@10
|
873 /* Maybe use ff_copy_buffer_ref instead? */
|
yading@10
|
874 switch (link->type) {
|
yading@10
|
875 case AVMEDIA_TYPE_VIDEO:
|
yading@10
|
876 out = ff_get_video_buffer(link, link->w, link->h);
|
yading@10
|
877 break;
|
yading@10
|
878 case AVMEDIA_TYPE_AUDIO:
|
yading@10
|
879 out = ff_get_audio_buffer(link, frame->nb_samples);
|
yading@10
|
880 break;
|
yading@10
|
881 default: return AVERROR(EINVAL);
|
yading@10
|
882 }
|
yading@10
|
883 if (!out) {
|
yading@10
|
884 av_frame_free(&frame);
|
yading@10
|
885 return AVERROR(ENOMEM);
|
yading@10
|
886 }
|
yading@10
|
887 av_frame_copy_props(out, frame);
|
yading@10
|
888
|
yading@10
|
889 switch (link->type) {
|
yading@10
|
890 case AVMEDIA_TYPE_VIDEO:
|
yading@10
|
891 av_image_copy(out->data, out->linesize, (const uint8_t **)frame->data, frame->linesize,
|
yading@10
|
892 frame->format, frame->width, frame->height);
|
yading@10
|
893 break;
|
yading@10
|
894 case AVMEDIA_TYPE_AUDIO:
|
yading@10
|
895 av_samples_copy(out->extended_data, frame->extended_data,
|
yading@10
|
896 0, 0, frame->nb_samples,
|
yading@10
|
897 av_get_channel_layout_nb_channels(frame->channel_layout),
|
yading@10
|
898 frame->format);
|
yading@10
|
899 break;
|
yading@10
|
900 default: return AVERROR(EINVAL);
|
yading@10
|
901 }
|
yading@10
|
902
|
yading@10
|
903 av_frame_free(&frame);
|
yading@10
|
904 } else
|
yading@10
|
905 out = frame;
|
yading@10
|
906
|
yading@10
|
907 while(cmd && cmd->time <= out->pts * av_q2d(link->time_base)){
|
yading@10
|
908 av_log(link->dst, AV_LOG_DEBUG,
|
yading@10
|
909 "Processing command time:%f command:%s arg:%s\n",
|
yading@10
|
910 cmd->time, cmd->command, cmd->arg);
|
yading@10
|
911 avfilter_process_command(link->dst, cmd->command, cmd->arg, 0, 0, cmd->flags);
|
yading@10
|
912 ff_command_queue_pop(link->dst);
|
yading@10
|
913 cmd= link->dst->command_queue;
|
yading@10
|
914 }
|
yading@10
|
915
|
yading@10
|
916 pts = out->pts;
|
yading@10
|
917 ret = filter_frame(link, out);
|
yading@10
|
918 link->frame_requested = 0;
|
yading@10
|
919 ff_update_link_current_pts(link, pts);
|
yading@10
|
920 return ret;
|
yading@10
|
921 }
|
yading@10
|
922
|
yading@10
|
923 static int ff_filter_frame_needs_framing(AVFilterLink *link, AVFrame *frame)
|
yading@10
|
924 {
|
yading@10
|
925 int insamples = frame->nb_samples, inpos = 0, nb_samples;
|
yading@10
|
926 AVFrame *pbuf = link->partial_buf;
|
yading@10
|
927 int nb_channels = av_frame_get_channels(frame);
|
yading@10
|
928 int ret = 0;
|
yading@10
|
929
|
yading@10
|
930 link->flags |= FF_LINK_FLAG_REQUEST_LOOP;
|
yading@10
|
931 /* Handle framing (min_samples, max_samples) */
|
yading@10
|
932 while (insamples) {
|
yading@10
|
933 if (!pbuf) {
|
yading@10
|
934 AVRational samples_tb = { 1, link->sample_rate };
|
yading@10
|
935 pbuf = ff_get_audio_buffer(link, link->partial_buf_size);
|
yading@10
|
936 if (!pbuf) {
|
yading@10
|
937 av_log(link->dst, AV_LOG_WARNING,
|
yading@10
|
938 "Samples dropped due to memory allocation failure.\n");
|
yading@10
|
939 return 0;
|
yading@10
|
940 }
|
yading@10
|
941 av_frame_copy_props(pbuf, frame);
|
yading@10
|
942 pbuf->pts = frame->pts +
|
yading@10
|
943 av_rescale_q(inpos, samples_tb, link->time_base);
|
yading@10
|
944 pbuf->nb_samples = 0;
|
yading@10
|
945 }
|
yading@10
|
946 nb_samples = FFMIN(insamples,
|
yading@10
|
947 link->partial_buf_size - pbuf->nb_samples);
|
yading@10
|
948 av_samples_copy(pbuf->extended_data, frame->extended_data,
|
yading@10
|
949 pbuf->nb_samples, inpos,
|
yading@10
|
950 nb_samples, nb_channels, link->format);
|
yading@10
|
951 inpos += nb_samples;
|
yading@10
|
952 insamples -= nb_samples;
|
yading@10
|
953 pbuf->nb_samples += nb_samples;
|
yading@10
|
954 if (pbuf->nb_samples >= link->min_samples) {
|
yading@10
|
955 ret = ff_filter_frame_framed(link, pbuf);
|
yading@10
|
956 pbuf = NULL;
|
yading@10
|
957 }
|
yading@10
|
958 }
|
yading@10
|
959 av_frame_free(&frame);
|
yading@10
|
960 link->partial_buf = pbuf;
|
yading@10
|
961 return ret;
|
yading@10
|
962 }
|
yading@10
|
963
|
yading@10
|
964 int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
|
yading@10
|
965 {
|
yading@10
|
966 FF_TPRINTF_START(NULL, filter_frame); ff_tlog_link(NULL, link, 1); ff_tlog(NULL, " "); ff_tlog_ref(NULL, frame, 1);
|
yading@10
|
967
|
yading@10
|
968 /* Consistency checks */
|
yading@10
|
969 if (link->type == AVMEDIA_TYPE_VIDEO) {
|
yading@10
|
970 if (strcmp(link->dst->filter->name, "scale")) {
|
yading@10
|
971 av_assert1(frame->format == link->format);
|
yading@10
|
972 av_assert1(frame->width == link->w);
|
yading@10
|
973 av_assert1(frame->height == link->h);
|
yading@10
|
974 }
|
yading@10
|
975 } else {
|
yading@10
|
976 av_assert1(frame->format == link->format);
|
yading@10
|
977 av_assert1(av_frame_get_channels(frame) == link->channels);
|
yading@10
|
978 av_assert1(frame->channel_layout == link->channel_layout);
|
yading@10
|
979 av_assert1(frame->sample_rate == link->sample_rate);
|
yading@10
|
980 }
|
yading@10
|
981
|
yading@10
|
982 /* Go directly to actual filtering if possible */
|
yading@10
|
983 if (link->type == AVMEDIA_TYPE_AUDIO &&
|
yading@10
|
984 link->min_samples &&
|
yading@10
|
985 (link->partial_buf ||
|
yading@10
|
986 frame->nb_samples < link->min_samples ||
|
yading@10
|
987 frame->nb_samples > link->max_samples)) {
|
yading@10
|
988 return ff_filter_frame_needs_framing(link, frame);
|
yading@10
|
989 } else {
|
yading@10
|
990 return ff_filter_frame_framed(link, frame);
|
yading@10
|
991 }
|
yading@10
|
992 }
|
yading@10
|
993
|
yading@10
|
994 const AVClass *avfilter_get_class(void)
|
yading@10
|
995 {
|
yading@10
|
996 return &avfilter_class;
|
yading@10
|
997 }
|