FFmpeg
graphparser.c
Go to the documentation of this file.
1 /*
2  * filter graph parser
3  * Copyright (c) 2008 Vitor Sessak
4  * Copyright (c) 2007 Bobby Bingham
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include <string.h>
24 #include <stdio.h>
25 
26 #include "libavutil/avstring.h"
27 #include "libavutil/mem.h"
28 #include "avfilter.h"
29 
30 #define WHITESPACES " \n\t\r"
31 
32 /**
33  * Link two filters together.
34  *
35  * @see avfilter_link()
36  */
37 static int link_filter(AVFilterContext *src, int srcpad,
38  AVFilterContext *dst, int dstpad,
39  void *log_ctx)
40 {
41  int ret;
42  if ((ret = avfilter_link(src, srcpad, dst, dstpad))) {
43  av_log(log_ctx, AV_LOG_ERROR,
44  "Cannot create the link %s:%d -> %s:%d\n",
45  src->filter->name, srcpad, dst->filter->name, dstpad);
46  return ret;
47  }
48 
49  return 0;
50 }
51 
52 /**
53  * Parse the name of a link, which has the format "[linkname]".
54  *
55  * @return a pointer (that need to be freed after use) to the name
56  * between parenthesis
57  */
58 static char *parse_link_name(const char **buf, void *log_ctx)
59 {
60  const char *start = *buf;
61  char *name;
62  (*buf)++;
63 
64  name = av_get_token(buf, "]");
65  if (!name)
66  goto fail;
67 
68  if (!name[0]) {
69  av_log(log_ctx, AV_LOG_ERROR,
70  "Bad (empty?) label found in the following: \"%s\".\n", start);
71  goto fail;
72  }
73 
74  if (*(*buf)++ != ']') {
75  av_log(log_ctx, AV_LOG_ERROR,
76  "Mismatched '[' found in the following: \"%s\".\n", start);
77  fail:
78  av_freep(&name);
79  }
80 
81  return name;
82 }
83 
84 /**
85  * Create an instance of a filter, initialize and insert it in the
86  * filtergraph in *ctx.
87  *
88  * @param filt_ctx put here a filter context in case of successful creation and configuration, NULL otherwise.
89  * @param ctx the filtergraph context
90  * @param index an index which is supposed to be unique for each filter instance added to the filtergraph
91  * @param name the name of the filter to create, can be filter name or filter_name\@id as instance name
92  * @param args the arguments provided to the filter during its initialization
93  * @param log_ctx the log context to use
94  * @return >= 0 in case of success, a negative AVERROR code otherwise
95  */
96 static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int index,
97  const char *name, const char *args, void *log_ctx)
98 {
99  const AVFilter *filt;
100  char name2[30];
101  const char *inst_name = NULL, *filt_name = NULL;
102  char *tmp_args = NULL;
103  int ret, k;
104 
105  av_strlcpy(name2, name, sizeof(name2));
106 
107  for (k = 0; name2[k]; k++) {
108  if (name2[k] == '@' && name[k+1]) {
109  name2[k] = 0;
110  inst_name = name;
111  filt_name = name2;
112  break;
113  }
114  }
115 
116  if (!inst_name) {
117  snprintf(name2, sizeof(name2), "Parsed_%s_%d", name, index);
118  inst_name = name2;
119  filt_name = name;
120  }
121 
122  filt = avfilter_get_by_name(filt_name);
123 
124  if (!filt) {
125  av_log(log_ctx, AV_LOG_ERROR,
126  "No such filter: '%s'\n", filt_name);
127  return AVERROR(EINVAL);
128  }
129 
130  *filt_ctx = avfilter_graph_alloc_filter(ctx, filt, inst_name);
131  if (!*filt_ctx) {
132  av_log(log_ctx, AV_LOG_ERROR,
133  "Error creating filter '%s'\n", filt_name);
134  return AVERROR(ENOMEM);
135  }
136 
137  if (!strcmp(filt_name, "scale") && (!args || !strstr(args, "flags")) &&
138  ctx->scale_sws_opts) {
139  if (args) {
140  tmp_args = av_asprintf("%s:%s",
141  args, ctx->scale_sws_opts);
142  if (!tmp_args)
143  return AVERROR(ENOMEM);
144  args = tmp_args;
145  } else
146  args = ctx->scale_sws_opts;
147  }
148 
149  ret = avfilter_init_str(*filt_ctx, args);
150  if (ret < 0) {
151  av_log(log_ctx, AV_LOG_ERROR,
152  "Error initializing filter '%s'", filt_name);
153  if (args)
154  av_log(log_ctx, AV_LOG_ERROR, " with args '%s'", args);
155  av_log(log_ctx, AV_LOG_ERROR, "\n");
156  avfilter_free(*filt_ctx);
157  *filt_ctx = NULL;
158  }
159 
160  av_free(tmp_args);
161  return ret;
162 }
163 
164 /**
165  * Parse a string of the form FILTER_NAME[=PARAMS], and create a
166  * corresponding filter instance which is added to graph with
167  * create_filter().
168  *
169  * @param filt_ctx Pointer that is set to the created and configured filter
170  * context on success, set to NULL on failure.
171  * @param filt_ctx put here a pointer to the created filter context on
172  * success, NULL otherwise
173  * @param buf pointer to the buffer to parse, *buf will be updated to
174  * point to the char next after the parsed string
175  * @param index an index which is assigned to the created filter
176  * instance, and which is supposed to be unique for each filter
177  * instance added to the filtergraph
178  * @return >= 0 in case of success, a negative AVERROR code otherwise
179  */
180 static int parse_filter(AVFilterContext **filt_ctx, const char **buf, AVFilterGraph *graph,
181  int index, void *log_ctx)
182 {
183  char *opts = NULL;
184  char *name = av_get_token(buf, "=,;[");
185  int ret;
186 
187  if (**buf == '=') {
188  (*buf)++;
189  opts = av_get_token(buf, "[],;");
190  }
191 
192  ret = create_filter(filt_ctx, graph, index, name, opts, log_ctx);
193  av_free(name);
194  av_free(opts);
195  return ret;
196 }
197 
199 {
200  return av_mallocz(sizeof(AVFilterInOut));
201 }
202 
204 {
205  while (*inout) {
206  AVFilterInOut *next = (*inout)->next;
207  av_freep(&(*inout)->name);
208  av_freep(inout);
209  *inout = next;
210  }
211 }
212 
213 static AVFilterInOut *extract_inout(const char *label, AVFilterInOut **links)
214 {
216 
217  while (*links && (!(*links)->name || strcmp((*links)->name, label)))
218  links = &((*links)->next);
219 
220  ret = *links;
221 
222  if (ret) {
223  *links = ret->next;
224  ret->next = NULL;
225  }
226 
227  return ret;
228 }
229 
230 static void insert_inout(AVFilterInOut **inouts, AVFilterInOut *element)
231 {
232  element->next = *inouts;
233  *inouts = element;
234 }
235 
236 static void append_inout(AVFilterInOut **inouts, AVFilterInOut **element)
237 {
238  while (*inouts && (*inouts)->next)
239  inouts = &((*inouts)->next);
240 
241  if (!*inouts)
242  *inouts = *element;
243  else
244  (*inouts)->next = *element;
245  *element = NULL;
246 }
247 
248 static int link_filter_inouts(AVFilterContext *filt_ctx,
249  AVFilterInOut **curr_inputs,
250  AVFilterInOut **open_inputs, void *log_ctx)
251 {
252  int pad, ret;
253 
254  for (pad = 0; pad < filt_ctx->nb_inputs; pad++) {
255  AVFilterInOut *p = *curr_inputs;
256 
257  if (p) {
258  *curr_inputs = (*curr_inputs)->next;
259  p->next = NULL;
260  } else if (!(p = av_mallocz(sizeof(*p))))
261  return AVERROR(ENOMEM);
262 
263  if (p->filter_ctx) {
264  ret = link_filter(p->filter_ctx, p->pad_idx, filt_ctx, pad, log_ctx);
265  av_freep(&p->name);
266  av_freep(&p);
267  if (ret < 0)
268  return ret;
269  } else {
270  p->filter_ctx = filt_ctx;
271  p->pad_idx = pad;
272  append_inout(open_inputs, &p);
273  }
274  }
275 
276  if (*curr_inputs) {
277  av_log(log_ctx, AV_LOG_ERROR,
278  "Too many inputs specified for the \"%s\" filter.\n",
279  filt_ctx->filter->name);
280  return AVERROR(EINVAL);
281  }
282 
283  pad = filt_ctx->nb_outputs;
284  while (pad--) {
285  AVFilterInOut *currlinkn = av_mallocz(sizeof(AVFilterInOut));
286  if (!currlinkn)
287  return AVERROR(ENOMEM);
288  currlinkn->filter_ctx = filt_ctx;
289  currlinkn->pad_idx = pad;
290  insert_inout(curr_inputs, currlinkn);
291  }
292 
293  return 0;
294 }
295 
296 static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs,
297  AVFilterInOut **open_outputs, void *log_ctx)
298 {
299  AVFilterInOut *parsed_inputs = NULL;
300  int pad = 0;
301 
302  while (**buf == '[') {
303  char *name = parse_link_name(buf, log_ctx);
304  AVFilterInOut *match;
305 
306  if (!name)
307  return AVERROR(EINVAL);
308 
309  /* First check if the label is not in the open_outputs list */
310  match = extract_inout(name, open_outputs);
311 
312  if (match) {
313  av_free(name);
314  } else {
315  /* Not in the list, so add it as an input */
316  if (!(match = av_mallocz(sizeof(AVFilterInOut)))) {
317  av_free(name);
318  return AVERROR(ENOMEM);
319  }
320  match->name = name;
321  match->pad_idx = pad;
322  }
323 
324  append_inout(&parsed_inputs, &match);
325 
326  *buf += strspn(*buf, WHITESPACES);
327  pad++;
328  }
329 
330  append_inout(&parsed_inputs, curr_inputs);
331  *curr_inputs = parsed_inputs;
332 
333  return pad;
334 }
335 
336 static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs,
337  AVFilterInOut **open_inputs,
338  AVFilterInOut **open_outputs, void *log_ctx)
339 {
340  int ret, pad = 0;
341 
342  while (**buf == '[') {
343  char *name = parse_link_name(buf, log_ctx);
344  AVFilterInOut *match;
345 
346  AVFilterInOut *input = *curr_inputs;
347 
348  if (!name)
349  return AVERROR(EINVAL);
350 
351  if (!input) {
352  av_log(log_ctx, AV_LOG_ERROR,
353  "No output pad can be associated to link label '%s'.\n", name);
354  av_free(name);
355  return AVERROR(EINVAL);
356  }
357  *curr_inputs = (*curr_inputs)->next;
358 
359  /* First check if the label is not in the open_inputs list */
360  match = extract_inout(name, open_inputs);
361 
362  if (match) {
363  if ((ret = link_filter(input->filter_ctx, input->pad_idx,
364  match->filter_ctx, match->pad_idx, log_ctx)) < 0) {
365  av_free(name);
366  return ret;
367  }
368  av_freep(&match->name);
369  av_freep(&name);
370  av_freep(&match);
371  av_freep(&input);
372  } else {
373  /* Not in the list, so add the first input as an open_output */
374  input->name = name;
375  insert_inout(open_outputs, input);
376  }
377  *buf += strspn(*buf, WHITESPACES);
378  pad++;
379  }
380 
381  return pad;
382 }
383 
384 static int parse_sws_flags(const char **buf, AVFilterGraph *graph)
385 {
386  char *p = strchr(*buf, ';');
387 
388  if (strncmp(*buf, "sws_flags=", 10))
389  return 0;
390 
391  if (!p) {
392  av_log(graph, AV_LOG_ERROR, "sws_flags not terminated with ';'.\n");
393  return AVERROR(EINVAL);
394  }
395 
396  *buf += 4; // keep the 'flags=' part
397 
398  av_freep(&graph->scale_sws_opts);
399  if (!(graph->scale_sws_opts = av_mallocz(p - *buf + 1)))
400  return AVERROR(ENOMEM);
401  av_strlcpy(graph->scale_sws_opts, *buf, p - *buf + 1);
402 
403  *buf = p + 1;
404  return 0;
405 }
406 
410 {
411  int index = 0, ret = 0;
412  char chr = 0;
413 
414  AVFilterInOut *curr_inputs = NULL, *open_inputs = NULL, *open_outputs = NULL;
415 
416  filters += strspn(filters, WHITESPACES);
417 
418  if ((ret = parse_sws_flags(&filters, graph)) < 0)
419  goto fail;
420 
421  do {
423  filters += strspn(filters, WHITESPACES);
424 
425  if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, graph)) < 0)
426  goto end;
427  if ((ret = parse_filter(&filter, &filters, graph, index, graph)) < 0)
428  goto end;
429 
430 
431  if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, graph)) < 0)
432  goto end;
433 
434  if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs,
435  graph)) < 0)
436  goto end;
437 
438  filters += strspn(filters, WHITESPACES);
439  chr = *filters++;
440 
441  if (chr == ';' && curr_inputs)
442  append_inout(&open_outputs, &curr_inputs);
443  index++;
444  } while (chr == ',' || chr == ';');
445 
446  if (chr) {
447  av_log(graph, AV_LOG_ERROR,
448  "Unable to parse graph description substring: \"%s\"\n",
449  filters - 1);
450  ret = AVERROR(EINVAL);
451  goto end;
452  }
453 
454  append_inout(&open_outputs, &curr_inputs);
455 
456 
457  *inputs = open_inputs;
458  *outputs = open_outputs;
459  return 0;
460 
461  fail:end:
462  while (graph->nb_filters)
463  avfilter_free(graph->filters[0]);
464  av_freep(&graph->filters);
465  avfilter_inout_free(&open_inputs);
466  avfilter_inout_free(&open_outputs);
467  avfilter_inout_free(&curr_inputs);
468 
469  *inputs = NULL;
470  *outputs = NULL;
471 
472  return ret;
473 }
474 
476  AVFilterInOut *open_inputs,
477  AVFilterInOut *open_outputs, void *log_ctx)
478 {
479  int ret;
480  AVFilterInOut *cur, *match, *inputs = NULL, *outputs = NULL;
481 
482  if ((ret = avfilter_graph_parse2(graph, filters, &inputs, &outputs)) < 0)
483  goto fail;
484 
485  /* First input can be omitted if it is "[in]" */
486  if (inputs && !inputs->name)
487  inputs->name = av_strdup("in");
488  for (cur = inputs; cur; cur = cur->next) {
489  if (!cur->name) {
490  av_log(log_ctx, AV_LOG_ERROR,
491  "Not enough inputs specified for the \"%s\" filter.\n",
492  cur->filter_ctx->filter->name);
493  ret = AVERROR(EINVAL);
494  goto fail;
495  }
496  if (!(match = extract_inout(cur->name, &open_outputs)))
497  continue;
498  ret = avfilter_link(match->filter_ctx, match->pad_idx,
499  cur->filter_ctx, cur->pad_idx);
500  avfilter_inout_free(&match);
501  if (ret < 0)
502  goto fail;
503  }
504 
505  /* Last output can be omitted if it is "[out]" */
506  if (outputs && !outputs->name)
507  outputs->name = av_strdup("out");
508  for (cur = outputs; cur; cur = cur->next) {
509  if (!cur->name) {
510  av_log(log_ctx, AV_LOG_ERROR,
511  "Invalid filterchain containing an unlabelled output pad: \"%s\"\n",
512  filters);
513  ret = AVERROR(EINVAL);
514  goto fail;
515  }
516  if (!(match = extract_inout(cur->name, &open_inputs)))
517  continue;
518  ret = avfilter_link(cur->filter_ctx, cur->pad_idx,
519  match->filter_ctx, match->pad_idx);
520  avfilter_inout_free(&match);
521  if (ret < 0)
522  goto fail;
523  }
524 
525  fail:
526  if (ret < 0) {
527  while (graph->nb_filters)
528  avfilter_free(graph->filters[0]);
529  av_freep(&graph->filters);
530  }
531  avfilter_inout_free(&inputs);
532  avfilter_inout_free(&outputs);
533  avfilter_inout_free(&open_inputs);
534  avfilter_inout_free(&open_outputs);
535  return ret;
536 }
537 
539  AVFilterInOut **open_inputs_ptr, AVFilterInOut **open_outputs_ptr,
540  void *log_ctx)
541 {
542  int index = 0, ret = 0;
543  char chr = 0;
544 
545  AVFilterInOut *curr_inputs = NULL;
546  AVFilterInOut *open_inputs = open_inputs_ptr ? *open_inputs_ptr : NULL;
547  AVFilterInOut *open_outputs = open_outputs_ptr ? *open_outputs_ptr : NULL;
548 
549  if ((ret = parse_sws_flags(&filters, graph)) < 0)
550  goto end;
551 
552  do {
554  const char *filterchain = filters;
555  filters += strspn(filters, WHITESPACES);
556 
557  if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, log_ctx)) < 0)
558  goto end;
559 
560  if ((ret = parse_filter(&filter, &filters, graph, index, log_ctx)) < 0)
561  goto end;
562 
563  if (filter->nb_inputs == 1 && !curr_inputs && !index) {
564  /* First input pad, assume it is "[in]" if not specified */
565  const char *tmp = "[in]";
566  if ((ret = parse_inputs(&tmp, &curr_inputs, &open_outputs, log_ctx)) < 0)
567  goto end;
568  }
569 
570  if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, log_ctx)) < 0)
571  goto end;
572 
573  if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs,
574  log_ctx)) < 0)
575  goto end;
576 
577  filters += strspn(filters, WHITESPACES);
578  chr = *filters++;
579 
580  if (chr == ';' && curr_inputs) {
581  av_log(log_ctx, AV_LOG_ERROR,
582  "Invalid filterchain containing an unlabelled output pad: \"%s\"\n",
583  filterchain);
584  ret = AVERROR(EINVAL);
585  goto end;
586  }
587  index++;
588  } while (chr == ',' || chr == ';');
589 
590  if (chr) {
591  av_log(log_ctx, AV_LOG_ERROR,
592  "Unable to parse graph description substring: \"%s\"\n",
593  filters - 1);
594  ret = AVERROR(EINVAL);
595  goto end;
596  }
597 
598  if (curr_inputs) {
599  /* Last output pad, assume it is "[out]" if not specified */
600  const char *tmp = "[out]";
601  if ((ret = parse_outputs(&tmp, &curr_inputs, &open_inputs, &open_outputs,
602  log_ctx)) < 0)
603  goto end;
604  }
605 
606 end:
607  /* clear open_in/outputs only if not passed as parameters */
608  if (open_inputs_ptr) *open_inputs_ptr = open_inputs;
609  else avfilter_inout_free(&open_inputs);
610  if (open_outputs_ptr) *open_outputs_ptr = open_outputs;
611  else avfilter_inout_free(&open_outputs);
612  avfilter_inout_free(&curr_inputs);
613 
614  if (ret < 0) {
615  while (graph->nb_filters)
616  avfilter_free(graph->filters[0]);
617  av_freep(&graph->filters);
618  }
619  return ret;
620 }
AVFilterContext ** filters
Definition: avfilter.h:842
#define NULL
Definition: coverity.c:32
void avfilter_free(AVFilterContext *filter)
Free a filter context.
Definition: avfilter.c:760
Main libavfilter public API header.
Memory handling functions.
void avfilter_inout_free(AVFilterInOut **inout)
Free the supplied list of AVFilterInOut and set *inout to NULL.
Definition: graphparser.c:203
struct AVFilterInOut * next
next input/input in the list, NULL if this is the last
Definition: avfilter.h:1014
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
#define src
Definition: vp8dsp.c:254
char * scale_sws_opts
sws options to use for the auto-inserted scale filters
Definition: avfilter.h:845
int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad)
Link two filters together.
Definition: avfilter.c:135
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
static void insert_inout(AVFilterInOut **inouts, AVFilterInOut *element)
Definition: graphparser.c:230
int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs)
Add a graph described by a string to a graph.
Definition: graphparser.c:407
#define av_log(a,...)
static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs, AVFilterInOut **open_outputs, void *log_ctx)
Definition: graphparser.c:296
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
static AVFilterInOut * extract_inout(const char *label, AVFilterInOut **links)
Definition: graphparser.c:213
unsigned nb_outputs
number of output pads
Definition: avfilter.h:351
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:83
#define fail()
Definition: checkasm.h:120
char * av_get_token(const char **buf, const char *term)
Unescape the given string until a non escaped terminating char, and return the token corresponding to...
Definition: avstring.c:149
static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int index, const char *name, const char *args, void *log_ctx)
Create an instance of a filter, initialize and insert it in the filtergraph in *ctx.
Definition: graphparser.c:96
const AVFilter * avfilter_get_by_name(const char *name)
Get a filter definition matching the given name.
Definition: allfilters.c:484
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:113
AVDictionary * opts
Definition: movenc.c:50
unsigned nb_inputs
number of input pads
Definition: avfilter.h:347
AVFormatContext * ctx
Definition: movenc.c:48
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output links
AVFilterContext * filter_ctx
filter context associated to this input/output
Definition: avfilter.h:1008
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
int avfilter_init_str(AVFilterContext *filter, const char *args)
Initialize a filter with the supplied parameters.
Definition: avfilter.c:924
A linked-list of the inputs/outputs of the filter chain.
Definition: avfilter.h:1003
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
static int parse_sws_flags(const char **buf, AVFilterGraph *graph)
Definition: graphparser.c:384
static void append_inout(AVFilterInOut **inouts, AVFilterInOut **element)
Definition: graphparser.c:236
void * buf
Definition: avisynth_c.h:766
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, AVFilterInOut *open_inputs, AVFilterInOut *open_outputs, void *log_ctx)
Add a graph described by a string to a graph.
Definition: graphparser.c:475
Filter definition.
Definition: avfilter.h:144
int index
Definition: gxfenc.c:89
int pad_idx
index of the filt_ctx pad to use for linking
Definition: avfilter.h:1011
const char * name
Filter name.
Definition: avfilter.h:148
unsigned nb_filters
Definition: avfilter.h:843
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
#define snprintf
Definition: snprintf.h:34
static int parse_filter(AVFilterContext **filt_ctx, const char **buf, AVFilterGraph *graph, int index, void *log_ctx)
Parse a string of the form FILTER_NAME[=PARAMS], and create a corresponding filter instance which is ...
Definition: graphparser.c:180
char * name
unique name for this input/output in the list
Definition: avfilter.h:1005
static const int8_t filt[NUMTAPS]
Definition: af_earwax.c:39
static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs, AVFilterInOut **open_inputs, AVFilterInOut **open_outputs, void *log_ctx)
Definition: graphparser.c:336
AVFilterInOut * avfilter_inout_alloc(void)
Allocate a single AVFilterInOut entry.
Definition: graphparser.c:198
static int link_filter(AVFilterContext *src, int srcpad, AVFilterContext *dst, int dstpad, void *log_ctx)
Link two filters together.
Definition: graphparser.c:37
#define av_free(p)
AVFilterContext * avfilter_graph_alloc_filter(AVFilterGraph *graph, const AVFilter *filter, const char *name)
Create a new filter instance in a filter graph.
static const struct PPFilter filters[]
Definition: postprocess.c:134
static char * parse_link_name(const char **buf, void *log_ctx)
Parse the name of a link, which has the format "[linkname]".
Definition: graphparser.c:58
static int link_filter_inouts(AVFilterContext *filt_ctx, AVFilterInOut **curr_inputs, AVFilterInOut **open_inputs, void *log_ctx)
Definition: graphparser.c:248
int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters, AVFilterInOut **open_inputs_ptr, AVFilterInOut **open_outputs_ptr, void *log_ctx)
Add a graph described by a string to a graph.
Definition: graphparser.c:538
An instance of a filter.
Definition: avfilter.h:338
#define WHITESPACES
Definition: graphparser.c:30
#define av_freep(p)
void INT64 start
Definition: avisynth_c.h:766
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
const AVFilter * filter
the AVFilter of which this is an instance
Definition: avfilter.h:341
const char * name
Definition: opengl_enc.c:102
static uint8_t tmp[11]
Definition: aes_ctr.c:26