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"
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 
66  if (!name[0]) {
67  av_log(log_ctx, AV_LOG_ERROR,
68  "Bad (empty?) label found in the following: \"%s\".\n", start);
69  goto fail;
70  }
71 
72  if (*(*buf)++ != ']') {
73  av_log(log_ctx, AV_LOG_ERROR,
74  "Mismatched '[' found in the following: \"%s\".\n", start);
75  fail:
76  av_freep(&name);
77  }
78 
79  return name;
80 }
81 
82 /**
83  * Create an instance of a filter, initialize and insert it in the
84  * filtergraph in *ctx.
85  *
86  * @param filt_ctx put here a filter context in case of successful creation and configuration, NULL otherwise.
87  * @param ctx the filtergraph context
88  * @param index an index which is supposed to be unique for each filter instance added to the filtergraph
89  * @param filt_name the name of the filter to create
90  * @param args the arguments provided to the filter during its initialization
91  * @param log_ctx the log context to use
92  * @return 0 in case of success, a negative AVERROR code otherwise
93  */
94 static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int index,
95  const char *filt_name, const char *args, void *log_ctx)
96 {
97  AVFilter *filt;
98  char inst_name[30];
99  char tmp_args[256];
100  int ret;
101 
102  snprintf(inst_name, sizeof(inst_name), "Parsed_%s_%d", filt_name, index);
103 
104  filt = avfilter_get_by_name(filt_name);
105 
106  if (!filt) {
107  av_log(log_ctx, AV_LOG_ERROR,
108  "No such filter: '%s'\n", filt_name);
109  return AVERROR(EINVAL);
110  }
111 
112  *filt_ctx = avfilter_graph_alloc_filter(ctx, filt, inst_name);
113  if (!*filt_ctx) {
114  av_log(log_ctx, AV_LOG_ERROR,
115  "Error creating filter '%s'\n", filt_name);
116  return AVERROR(ENOMEM);
117  }
118 
119  if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags") &&
120  ctx->scale_sws_opts) {
121  snprintf(tmp_args, sizeof(tmp_args), "%s:%s",
122  args, ctx->scale_sws_opts);
123  args = tmp_args;
124  }
125 
126  ret = avfilter_init_str(*filt_ctx, args);
127  if (ret < 0) {
128  av_log(log_ctx, AV_LOG_ERROR,
129  "Error initializing filter '%s' with args '%s'\n", filt_name, args);
130  return ret;
131  }
132 
133  return 0;
134 }
135 
136 /**
137  * Parse a string of the form FILTER_NAME[=PARAMS], and create a
138  * corresponding filter instance which is added to graph with
139  * create_filter().
140  *
141  * @param filt_ctx Pointer that is set to the created and configured filter
142  * context on success, set to NULL on failure.
143  * @param filt_ctx put here a pointer to the created filter context on
144  * success, NULL otherwise
145  * @param buf pointer to the buffer to parse, *buf will be updated to
146  * point to the char next after the parsed string
147  * @param index an index which is assigned to the created filter
148  * instance, and which is supposed to be unique for each filter
149  * instance added to the filtergraph
150  * @return 0 in case of success, a negative AVERROR code otherwise
151  */
152 static int parse_filter(AVFilterContext **filt_ctx, const char **buf, AVFilterGraph *graph,
153  int index, void *log_ctx)
154 {
155  char *opts = NULL;
156  char *name = av_get_token(buf, "=,;[\n");
157  int ret;
158 
159  if (**buf == '=') {
160  (*buf)++;
161  opts = av_get_token(buf, "[],;\n");
162  }
163 
164  ret = create_filter(filt_ctx, graph, index, name, opts, log_ctx);
165  av_free(name);
166  av_free(opts);
167  return ret;
168 }
169 
171 {
172  return av_mallocz(sizeof(AVFilterInOut));
173 }
174 
176 {
177  while (*inout) {
178  AVFilterInOut *next = (*inout)->next;
179  av_freep(&(*inout)->name);
180  av_freep(inout);
181  *inout = next;
182  }
183 }
184 
185 static AVFilterInOut *extract_inout(const char *label, AVFilterInOut **links)
186 {
188 
189  while (*links && (!(*links)->name || strcmp((*links)->name, label)))
190  links = &((*links)->next);
191 
192  ret = *links;
193 
194  if (ret) {
195  *links = ret->next;
196  ret->next = NULL;
197  }
198 
199  return ret;
200 }
201 
202 static void insert_inout(AVFilterInOut **inouts, AVFilterInOut *element)
203 {
204  element->next = *inouts;
205  *inouts = element;
206 }
207 
208 static void append_inout(AVFilterInOut **inouts, AVFilterInOut **element)
209 {
210  while (*inouts && (*inouts)->next)
211  inouts = &((*inouts)->next);
212 
213  if (!*inouts)
214  *inouts = *element;
215  else
216  (*inouts)->next = *element;
217  *element = NULL;
218 }
219 
220 static int link_filter_inouts(AVFilterContext *filt_ctx,
221  AVFilterInOut **curr_inputs,
222  AVFilterInOut **open_inputs, void *log_ctx)
223 {
224  int pad, ret;
225 
226  for (pad = 0; pad < filt_ctx->nb_inputs; pad++) {
227  AVFilterInOut *p = *curr_inputs;
228 
229  if (p) {
230  *curr_inputs = (*curr_inputs)->next;
231  p->next = NULL;
232  } else if (!(p = av_mallocz(sizeof(*p))))
233  return AVERROR(ENOMEM);
234 
235  if (p->filter_ctx) {
236  ret = link_filter(p->filter_ctx, p->pad_idx, filt_ctx, pad, log_ctx);
237  av_free(p->name);
238  av_free(p);
239  if (ret < 0)
240  return ret;
241  } else {
242  p->filter_ctx = filt_ctx;
243  p->pad_idx = pad;
244  append_inout(open_inputs, &p);
245  }
246  }
247 
248  if (*curr_inputs) {
249  av_log(log_ctx, AV_LOG_ERROR,
250  "Too many inputs specified for the \"%s\" filter.\n",
251  filt_ctx->filter->name);
252  return AVERROR(EINVAL);
253  }
254 
255  pad = filt_ctx->nb_outputs;
256  while (pad--) {
257  AVFilterInOut *currlinkn = av_mallocz(sizeof(AVFilterInOut));
258  if (!currlinkn)
259  return AVERROR(ENOMEM);
260  currlinkn->filter_ctx = filt_ctx;
261  currlinkn->pad_idx = pad;
262  insert_inout(curr_inputs, currlinkn);
263  }
264 
265  return 0;
266 }
267 
268 static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs,
269  AVFilterInOut **open_outputs, void *log_ctx)
270 {
271  AVFilterInOut *parsed_inputs = NULL;
272  int pad = 0;
273 
274  while (**buf == '[') {
275  char *name = parse_link_name(buf, log_ctx);
276  AVFilterInOut *match;
277 
278  if (!name)
279  return AVERROR(EINVAL);
280 
281  /* First check if the label is not in the open_outputs list */
282  match = extract_inout(name, open_outputs);
283 
284  if (match) {
285  av_free(name);
286  } else {
287  /* Not in the list, so add it as an input */
288  if (!(match = av_mallocz(sizeof(AVFilterInOut)))) {
289  av_free(name);
290  return AVERROR(ENOMEM);
291  }
292  match->name = name;
293  match->pad_idx = pad;
294  }
295 
296  append_inout(&parsed_inputs, &match);
297 
298  *buf += strspn(*buf, WHITESPACES);
299  pad++;
300  }
301 
302  append_inout(&parsed_inputs, curr_inputs);
303  *curr_inputs = parsed_inputs;
304 
305  return pad;
306 }
307 
308 static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs,
309  AVFilterInOut **open_inputs,
310  AVFilterInOut **open_outputs, void *log_ctx)
311 {
312  int ret, pad = 0;
313 
314  while (**buf == '[') {
315  char *name = parse_link_name(buf, log_ctx);
316  AVFilterInOut *match;
317 
318  AVFilterInOut *input = *curr_inputs;
319 
320  if (!name)
321  return AVERROR(EINVAL);
322 
323  if (!input) {
324  av_log(log_ctx, AV_LOG_ERROR,
325  "No output pad can be associated to link label '%s'.\n", name);
326  av_free(name);
327  return AVERROR(EINVAL);
328  }
329  *curr_inputs = (*curr_inputs)->next;
330 
331  /* First check if the label is not in the open_inputs list */
332  match = extract_inout(name, open_inputs);
333 
334  if (match) {
335  if ((ret = link_filter(input->filter_ctx, input->pad_idx,
336  match->filter_ctx, match->pad_idx, log_ctx)) < 0) {
337  av_free(name);
338  return ret;
339  }
340  av_free(match->name);
341  av_free(name);
342  av_free(match);
343  av_free(input);
344  } else {
345  /* Not in the list, so add the first input as a open_output */
346  input->name = name;
347  insert_inout(open_outputs, input);
348  }
349  *buf += strspn(*buf, WHITESPACES);
350  pad++;
351  }
352 
353  return pad;
354 }
355 
356 static int parse_sws_flags(const char **buf, AVFilterGraph *graph)
357 {
358  char *p = strchr(*buf, ';');
359 
360  if (strncmp(*buf, "sws_flags=", 10))
361  return 0;
362 
363  if (!p) {
364  av_log(graph, AV_LOG_ERROR, "sws_flags not terminated with ';'.\n");
365  return AVERROR(EINVAL);
366  }
367 
368  *buf += 4; // keep the 'flags=' part
369 
370  av_freep(&graph->scale_sws_opts);
371  if (!(graph->scale_sws_opts = av_mallocz(p - *buf + 1)))
372  return AVERROR(ENOMEM);
373  av_strlcpy(graph->scale_sws_opts, *buf, p - *buf + 1);
374 
375  *buf = p + 1;
376  return 0;
377 }
378 
382 {
383  int index = 0, ret = 0;
384  char chr = 0;
385 
386  AVFilterInOut *curr_inputs = NULL, *open_inputs = NULL, *open_outputs = NULL;
387 
388  filters += strspn(filters, WHITESPACES);
389 
390  if ((ret = parse_sws_flags(&filters, graph)) < 0)
391  goto fail;
392 
393  do {
395  filters += strspn(filters, WHITESPACES);
396 
397  if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, graph)) < 0)
398  goto end;
399  if ((ret = parse_filter(&filter, &filters, graph, index, graph)) < 0)
400  goto end;
401 
402 
403  if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, graph)) < 0)
404  goto end;
405 
406  if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs,
407  graph)) < 0)
408  goto end;
409 
410  filters += strspn(filters, WHITESPACES);
411  chr = *filters++;
412 
413  if (chr == ';' && curr_inputs)
414  append_inout(&open_outputs, &curr_inputs);
415  index++;
416  } while (chr == ',' || chr == ';');
417 
418  if (chr) {
419  av_log(graph, AV_LOG_ERROR,
420  "Unable to parse graph description substring: \"%s\"\n",
421  filters - 1);
422  ret = AVERROR(EINVAL);
423  goto end;
424  }
425 
426  append_inout(&open_outputs, &curr_inputs);
427 
428 
429  *inputs = open_inputs;
430  *outputs = open_outputs;
431  return 0;
432 
433  fail:end:
434  while (graph->nb_filters)
435  avfilter_free(graph->filters[0]);
436  av_freep(&graph->filters);
437  avfilter_inout_free(&open_inputs);
438  avfilter_inout_free(&open_outputs);
439  avfilter_inout_free(&curr_inputs);
440 
441  *inputs = NULL;
442  *outputs = NULL;
443 
444  return ret;
445 }
446 
448  AVFilterInOut **open_inputs_ptr, AVFilterInOut **open_outputs_ptr,
449  void *log_ctx)
450 {
451 #if 0
452  int ret;
453  AVFilterInOut *open_inputs = open_inputs_ptr ? *open_inputs_ptr : NULL;
454  AVFilterInOut *open_outputs = open_outputs_ptr ? *open_outputs_ptr : NULL;
455  AVFilterInOut *cur, *match, *inputs = NULL, *outputs = NULL;
456 
457  if ((ret = avfilter_graph_parse2(graph, filters, &inputs, &outputs)) < 0)
458  goto fail;
459 
460  /* First input can be omitted if it is "[in]" */
461  if (inputs && !inputs->name)
462  inputs->name = av_strdup("in");
463  for (cur = inputs; cur; cur = cur->next) {
464  if (!cur->name) {
465  av_log(log_ctx, AV_LOG_ERROR,
466  "Not enough inputs specified for the \"%s\" filter.\n",
467  cur->filter_ctx->filter->name);
468  ret = AVERROR(EINVAL);
469  goto fail;
470  }
471  if (!(match = extract_inout(cur->name, &open_outputs)))
472  continue;
473  ret = avfilter_link(match->filter_ctx, match->pad_idx,
474  cur->filter_ctx, cur->pad_idx);
475  avfilter_inout_free(&match);
476  if (ret < 0)
477  goto fail;
478  }
479 
480  /* Last output can be omitted if it is "[out]" */
481  if (outputs && !outputs->name)
482  outputs->name = av_strdup("out");
483  for (cur = outputs; cur; cur = cur->next) {
484  if (!cur->name) {
485  av_log(log_ctx, AV_LOG_ERROR,
486  "Invalid filterchain containing an unlabelled output pad: \"%s\"\n",
487  filters);
488  ret = AVERROR(EINVAL);
489  goto fail;
490  }
491  if (!(match = extract_inout(cur->name, &open_inputs)))
492  continue;
493  ret = avfilter_link(cur->filter_ctx, cur->pad_idx,
494  match->filter_ctx, match->pad_idx);
495  avfilter_inout_free(&match);
496  if (ret < 0)
497  goto fail;
498  }
499 
500  fail:
501  if (ret < 0) {
502  while (graph->nb_filters)
503  avfilter_free(graph->filters[0]);
504  av_freep(&graph->filters);
505  }
506  avfilter_inout_free(&inputs);
507  avfilter_inout_free(&outputs);
508  /* clear open_in/outputs only if not passed as parameters */
509  if (open_inputs_ptr) *open_inputs_ptr = open_inputs;
510  else avfilter_inout_free(&open_inputs);
511  if (open_outputs_ptr) *open_outputs_ptr = open_outputs;
512  else avfilter_inout_free(&open_outputs);
513  return ret;
514 }
515 #else
516  int index = 0, ret = 0;
517  char chr = 0;
518 
519  AVFilterInOut *curr_inputs = NULL;
520  AVFilterInOut *open_inputs = open_inputs_ptr ? *open_inputs_ptr : NULL;
521  AVFilterInOut *open_outputs = open_outputs_ptr ? *open_outputs_ptr : NULL;
522 
523  if ((ret = parse_sws_flags(&filters, graph)) < 0)
524  goto end;
525 
526  do {
528  const char *filterchain = filters;
529  filters += strspn(filters, WHITESPACES);
530 
531  if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, log_ctx)) < 0)
532  goto end;
533 
534  if ((ret = parse_filter(&filter, &filters, graph, index, log_ctx)) < 0)
535  goto end;
536 
537  if (filter->input_count == 1 && !curr_inputs && !index) {
538  /* First input pad, assume it is "[in]" if not specified */
539  const char *tmp = "[in]";
540  if ((ret = parse_inputs(&tmp, &curr_inputs, &open_outputs, log_ctx)) < 0)
541  goto end;
542  }
543 
544  if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, log_ctx)) < 0)
545  goto end;
546 
547  if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs,
548  log_ctx)) < 0)
549  goto end;
550 
551  filters += strspn(filters, WHITESPACES);
552  chr = *filters++;
553 
554  if (chr == ';' && curr_inputs) {
555  av_log(log_ctx, AV_LOG_ERROR,
556  "Invalid filterchain containing an unlabelled output pad: \"%s\"\n",
557  filterchain);
558  ret = AVERROR(EINVAL);
559  goto end;
560  }
561  index++;
562  } while (chr == ',' || chr == ';');
563 
564  if (chr) {
565  av_log(log_ctx, AV_LOG_ERROR,
566  "Unable to parse graph description substring: \"%s\"\n",
567  filters - 1);
568  ret = AVERROR(EINVAL);
569  goto end;
570  }
571 
572  if (curr_inputs) {
573  /* Last output pad, assume it is "[out]" if not specified */
574  const char *tmp = "[out]";
575  if ((ret = parse_outputs(&tmp, &curr_inputs, &open_inputs, &open_outputs,
576  log_ctx)) < 0)
577  goto end;
578  }
579 
580 end:
581  /* clear open_in/outputs only if not passed as parameters */
582  if (open_inputs_ptr) *open_inputs_ptr = open_inputs;
583  else avfilter_inout_free(&open_inputs);
584  if (open_outputs_ptr) *open_outputs_ptr = open_outputs;
585  else avfilter_inout_free(&open_outputs);
586  avfilter_inout_free(&curr_inputs);
587 
588  if (ret < 0) {
589  while (graph->nb_filters)
590  avfilter_free(graph->filters[0]);
591  av_freep(&graph->filters);
592  }
593  return ret;
594 }
595 
596 #endif
AVFilterContext ** filters
Definition: avfilter.h:997
const char * name
Definition: avisynth_c.h:675
Definition: start.py:1
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
void avfilter_free(AVFilterContext *filter)
Free a filter context.
Definition: avfilter.c:568
static const AVFilterPad outputs[]
Definition: af_ashowinfo.c:117
external 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:175
struct AVFilterInOut * next
next input/input in the list, NULL if this is the last
Definition: avfilter.h:1134
struct line * next
Definition: graph2dot.c:50
char * scale_sws_opts
sws options to use for the auto-inserted scale filters
Definition: avfilter.h:1002
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad)
Link two filters together.
Definition: avfilter.c:114
end end
static void insert_inout(AVFilterInOut **inouts, AVFilterInOut *element)
Definition: graphparser.c:202
the mask is usually to keep the same permissions Filters should remove permissions on reference they give to output whenever necessary It can be automatically done by setting the rej_perms field on the output pad Here are a few guidelines corresponding to common 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
for audio filters
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:379
static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs, AVFilterInOut **open_outputs, void *log_ctx)
Definition: graphparser.c:268
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
static AVFilterInOut * extract_inout(const char *label, AVFilterInOut **links)
Definition: graphparser.c:185
unsigned nb_outputs
number of output pads
Definition: avfilter.h:543
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 the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame This method is called when a frame is wanted on an output For an input
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
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:82
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:148
unsigned nb_inputs
number of input pads
Definition: avfilter.h:536
ret
Definition: avfilter.c:821
AVFilterContext * filter_ctx
filter context associated to this input/output
Definition: avfilter.h:1128
int avfilter_init_str(AVFilterContext *filter, const char *args)
Initialize a filter with the supplied parameters.
Definition: avfilter.c:715
A linked-list of the inputs/outputs of the filter chain.
Definition: avfilter.h:1123
NULL
Definition: eval.c:55
AVS_Value src
Definition: avisynth_c.h:523
char * av_strdup(const char *s)
Duplicate the string s.
Definition: mem.c:220
static int parse_sws_flags(const char **buf, AVFilterGraph *graph)
Definition: graphparser.c:356
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
static void append_inout(AVFilterInOut **inouts, AVFilterInOut **element)
Definition: graphparser.c:208
void * buf
Definition: avisynth_c.h:594
Filter definition.
Definition: avfilter.h:436
int index
Definition: gxfenc.c:89
int pad_idx
index of the filt_ctx pad to use for linking
Definition: avfilter.h:1131
const char * name
filter name
Definition: avfilter.h:437
unsigned nb_filters
Definition: avfilter.h:999
#define snprintf
Definition: snprintf.h:34
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
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:152
char * name
unique name for this input/output in the list
Definition: avfilter.h:1125
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:308
AVFilterInOut * avfilter_inout_alloc(void)
Allocate a single AVFilterInOut entry.
Definition: graphparser.c:170
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output links
static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int index, const char *filt_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:94
static int link_filter(AVFilterContext *src, int srcpad, AVFilterContext *dst, int dstpad, void *log_ctx)
Link two filters together.
Definition: graphparser.c:37
AVFilterContext * avfilter_graph_alloc_filter(AVFilterGraph *graph, const AVFilter *filter, const char *name)
Create a new filter instance in a filter graph.
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
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:220
An instance of a filter.
Definition: avfilter.h:524
#define WHITESPACES
Definition: graphparser.c:30
AVFilter * avfilter_get_by_name(const char *name)
Get a filter definition matching the given name.
Definition: avfilter.c:391
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
const AVFilter * filter
the AVFilter of which this is an instance
Definition: avfilter.h:527
int avfilter_graph_parse(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:447