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