FFmpeg: libavfilter/graphparser.c Source File
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
30
33
34 #define WHITESPACES " \n\t\r"
35
36 /**
37 * Parse the name of a link, which has the format "[linkname]".
38 *
39 * @return a pointer (that need to be freed after use) to the name
40 * between parenthesis
41 */
43 {
44 const char *start = *buf;
46 (*buf)++;
47
51
54 "Bad (empty?) label found in the following: \"%s\".\n", start);
56 }
57
58 if (**buf != ']') {
60 "Mismatched '[' found in the following: \"%s\".\n", start);
64 }
65 (*buf)++;
66
68 }
69
71 {
73 }
74
76 {
77 while (*inout) {
81 *inout = next;
82 }
83 }
84
86 {
88
89 while (*
links && (!(*links)->name || strcmp((*links)->name, label)))
90 links = &((*links)->next);
91
93
97 }
98
100 }
101
103 {
104 while (*inouts && (*inouts)->
next)
105 inouts = &((*inouts)->next);
106
107 if (!*inouts)
108 *inouts = *element;
109 else
110 (*inouts)->
next = *element;
112 }
113
115 {
116 char *p = strchr(*buf, ';');
117
118 if (strncmp(*buf, "sws_flags=", 10))
119 return 0;
120
121 if (!p) {
124 }
125
126 *buf += 4; // keep the 'flags=' part
127
132
133 *buf = p + 1;
134 return 0;
135 }
136
140 {
143
147
151 goto end;
152
153 return 0;
154
155 end:
159
161 }
162
166 {
169
172
173 /* First input can be omitted if it is "[in]" */
179 "Not enough inputs specified for the \"%s\" filter.\n",
183 }
185 continue;
191 }
192
193 /* Last output can be omitted if it is "[out]" */
199 "Invalid filterchain containing an unlabelled output pad: \"%s\"\n",
203 }
205 continue;
211 }
212
218 }
224 }
225
227 {
229
230 if (!fpp)
231 return;
232
234
236 }
237
239 {
241
242 if (!p)
243 return;
244
248
252
254
257
259 }
260
262 {
264
265 if (!ch)
266 return;
267
271
273 }
274
276 {
278
279 if (!seg)
280 return;
281
285
287
289 }
290
293 {
295 int nb = 0;
297
298 while (**linklabels == '[') {
299 char *label;
301
303 if (!label) {
306 }
307
309 if (!par) {
313 }
314
316
321 }
322
324 }
325
326 *res = pp;
327 *nb_res = nb;
328
329 return 0;
331 for (
unsigned i = 0;
i < nb;
i++)
335 }
336
339 {
341 char *inst_name;
343
345 if (!p)
347
351
356 }
357
359 if (inst_name) {
360 *inst_name++ = 0;
365 }
366 }
367
371
372 (*filter)++;
373
378 }
379
385 }
386
390
392
393 *pp = p;
394 return 0;
397 "Error parsing a filter description around: %s\n", *
filter);
400 }
401
404 {
405 const char *chain = *pchain;
407 int ret, nb_filters = 0;
408
410
412 if (!ch)
414
415 while (*chain) {
417 char chr;
418
422
427 }
429
430 // a filter ends with one of: , ; end-of-string
431 chr = *chain;
432 if (chr && chr != ',' && chr != ';') {
434 "Trailing garbage after a filter: %s\n", chain);
437 }
438
439 if (chr) {
440 chain++;
442
443 if (chr == ';')
444 break;
445 }
446 }
447
448 *pchain = chain;
449 *pch = ch;
450
451 return 0;
454 "Error parsing filterchain '%s' around: %s\n", *pchain, chain);
457 }
458
461 {
463 int ret, nb_chains = 0;
464
466
469
471 if (!seg)
473
475
477
481
483
484 while (*graph_str) {
486
490
495 }
497
499 }
500
505 }
506
507 *pseg = seg;
508
509 return 0;
513 }
514
516 {
517 size_t idx = 0;
518
521
527 }
528
531
536 inst_name;
537
538 // skip already processed filters
540 continue;
541
546 }
547
549 snprintf(inst_name,
sizeof(inst_name),
"Parsed_%s_%zu",
f->name, idx);
550
554
557 "=", ":");
562 }
563 }
564
567
568 idx++;
569 }
570 }
571
572 return 0;
573 }
574
577 {
579 "A creation-pending filter '%s' present in the segment. All filters "
580 "must be created or disabled before calling %s().\n",
fn,
func);
582 }
583
585 {
586 int ret, leftover_opts = 0;
587
590
593
596
600 continue;
601
605
607 leftover_opts = 1;
608 }
609 }
610
612 }
613
615 {
618
621
625
629 continue;
630
634 }
635 }
636
637 return 0;
638 }
639
640 static unsigned
642 int output,
size_t idx_chain,
size_t idx_filter,
644 {
645 for (; idx_chain < seg->
nb_chains; idx_chain++) {
647
648 for (; idx_filter < ch->
nb_filters; idx_filter++) {
653 unsigned nb_l;
654
656 continue;
657
660
661 for (
unsigned i = 0;
i <
FFMIN(nb_io, nb_l);
i++)
662 if (!l[
i] && io[
i]->label && !strcmp(io[
i]->label, label)) {
663 *pp = p;
665 }
666 }
667
668 idx_filter = 0;
669 }
670
672 return 0;
673 }
674
676 const char *label)
677 {
679
680 if (!io)
682
685
686 if (label) {
691 }
692 }
693
695
696 return 0;
697 }
698
701 {
705
707
710 "More input link labels specified for filter '%s' than "
711 "it has inputs: %u > %d\n",
f->filter->name,
714 }
715
716 for (
unsigned in = 0; in <
f->nb_inputs; in++) {
718
719 // skip already linked inputs
721 continue;
722
723 if (label) {
725 unsigned idx =
find_linklabel(seg, label, 1, idx_chain, idx_filter, &po);
726
727 if (po) {
731
732 continue;
733 }
734 }
735
739 }
740
741 return 0;
742 }
743
746 {
750
752
755 "More output link labels specified for filter '%s' than "
756 "it has outputs: %u > %d\n",
f->filter->name,
759 }
760 for (
unsigned out = 0;
out <
f->nb_outputs;
out++) {
762
763 // skip already linked outputs
765 continue;
766
767 if (label) {
769 unsigned idx =
find_linklabel(seg, label, 0, idx_chain, idx_filter, &po);
770
771 if (po) {
775
776 continue;
777 }
778 }
779
780 // if this output is unlabeled, try linking it to an unlabeled
781 // input in the next non-disabled filter in the chain
782 for (
size_t i = idx_filter + 1;
i < ch->
nb_filters && !label;
i++) {
784
786 continue;
787
794
795 goto cont;
796 }
797 }
798 break;
799 }
800
804
805 cont:;
806 }
807
808 return 0;
809 }
810
814 {
816
819
822
823 for (
size_t idx_chain = 0; idx_chain < seg->
nb_chains; idx_chain++) {
825
826 for (
size_t idx_filter = 0; idx_filter < ch->
nb_filters; idx_filter++) {
828
832 }
833
835 continue;
836
840
844 }
845 }
846 return 0;
851 }
852
856 {
858
861
866 }
867
872 }
873
878 }
879
884 }
885
886 return 0;
887 }
888
891 void *log_ctx)
892 {
895
901
904 goto end;
905
908 goto end;
909
912 goto end;
913
916 goto end;
917
918 /* First input pad, assume it is "[in]" if not specified */
921 const char *
tmp =
"[in]";
922
925 goto end;
926 }
927
928 /* Last output pad, assume it is "[out]" if not specified */
932 const char *
tmp =
"[out]";
933
936 goto end;
937 }
938
942 goto end;
943
944 // process user-supplied inputs/outputs
947
951
954
955 if (match) {
961 goto end;
962 } else
964 }
967
971
974
975 if (match) {
981 goto end;
982 } else
984 }
985
986 end:
988
993 }
994
995 /* clear open_in/outputs only if not passed as parameters */
996 if (open_inputs_ptr) *open_inputs_ptr = user_inputs;
998 if (open_outputs_ptr) *open_outputs_ptr = user_outputs;
1000
1003
1005 }
static int link_inputs(AVFilterGraphSegment *seg, size_t idx_chain, size_t idx_filter, AVFilterInOut **inputs)
int(* func)(AVBPrint *dst, const char *in, const char *arg)
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
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
static int inout_add(AVFilterInOut **inouts, AVFilterContext *f, unsigned pad_idx, const char *label)
char * instance_name
Name to be used for this filter instance.
int avfilter_graph_segment_create_filters(AVFilterGraphSegment *seg, int flags)
Create filters specified in a graph segment.
int ff_filter_opt_parse(void *logctx, const AVClass *priv_class, AVDictionary **options, const char *args)
Parse filter options into a dictionary.
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
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 output
static int parse_sws_flags(const char **buf, char **dst, void *log_ctx)
struct AVFilterInOut * next
next input/input in the list, NULL if this is the last
static int fail_creation_pending(AVFilterGraphSegment *seg, const char *fn, const char *func)
unsigned nb_outputs
number of output pads
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
const char * name
Filter name.
AVFilterPadParams ** inputs
A link between two filters.
static int chain_parse(void *logctx, const char **pchain, AVFilterChain **pch)
AVFilterPadParams ** outputs
int av_set_options_string(void *ctx, const char *opts, const char *key_val_sep, const char *pairs_sep)
Parse the key/value pairs list in opts.
static void append_inout(AVFilterInOut **inouts, AVFilterInOut **element)
AVFilterContext * avfilter_graph_alloc_filter(AVFilterGraph *graph, const AVFilter *filter, const char *name)
Create a new filter instance in a filter graph.
static void pad_params_free(AVFilterPadParams **pfpp)
int avfilter_graph_segment_link(AVFilterGraphSegment *seg, int flags, AVFilterInOut **inputs, AVFilterInOut **outputs)
Link filters in a graph segment.
#define AVERROR_OPTION_NOT_FOUND
Option not found.
void avfilter_graph_segment_free(AVFilterGraphSegment **pseg)
Free the provided AVFilterGraphSegment and everything associated with it.
int avfilter_graph_segment_parse(AVFilterGraph *graph, const char *graph_str, int flags, AVFilterGraphSegment **pseg)
Parse a textual filtergraph description into an intermediate form.
void avfilter_inout_free(AVFilterInOut **inout)
Free the supplied list of AVFilterInOut and set *inout to NULL.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static unsigned find_linklabel(AVFilterGraphSegment *seg, const char *label, int output, size_t idx_chain, size_t idx_filter, AVFilterParams **pp)
AVFilterParams ** filters
static void chain_free(AVFilterChain **pch)
#define filters(fmt, type, inverse, clp, inverset, clip, one, clip_fn, packed)
static const AVFilterPad outputs[]
int avfilter_graph_segment_init(AVFilterGraphSegment *seg, int flags)
Initialize all filter instances in a graph segment.
char * label
An av_malloc()'ed string containing the pad label.
const AVFilter * avfilter_get_by_name(const char *name)
Get a filter definition matching the given name.
int avfilter_graph_segment_apply(AVFilterGraphSegment *seg, int flags, AVFilterInOut **inputs, AVFilterInOut **outputs)
Apply all filter/link descriptions from a graph segment to the associated filtergraph.
Parameters describing a filter to be created in a filtergraph.
AVFilterContext * filter
The filter context.
char * filter_name
Name of the AVFilter to be used.
AVFilterContext ** filters
AVFilterLink ** inputs
array of pointers to input links
AVFilterInOut * avfilter_inout_alloc(void)
Allocate a single AVFilterInOut entry.
AVFilterChain ** chains
A list of filter chain contained in this segment.
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_parse2(AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs)
Add a graph described by a string to a graph.
A parsed representation of a filtergraph segment.
int pad_idx
index of the filt_ctx pad to use for linking
char * scale_sws_opts
sws options to use for the auto-inserted scale filters
unsigned nb_inputs
number of input pads
AVFilterContext * filter_ctx
filter context associated to this input/output
int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad)
Link two filters together.
static char * parse_link_name(const char **buf, void *log_ctx)
Parse the name of a link, which has the format "[linkname]".
char * scale_sws_opts
A string containing a colon-separated list of key=value options applied to all scale filters in this ...
#define AV_OPT_SEARCH_CHILDREN
Search in possible children of the given object first.
static int link_outputs(AVFilterGraphSegment *seg, size_t idx_chain, size_t idx_filter, AVFilterInOut **outputs)
int av_opt_set_dict2(void *obj, AVDictionary **options, int search_flags)
Set all the options from a given dictionary on an object.
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
AVFilterGraph * graph
The filtergraph this segment is associated with.
#define i(width, name, range_min, range_max)
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.
static AVFilterInOut * extract_inout(const char *label, AVFilterInOut **links)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
const char * name
Pad name.
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
AVDictionary * opts
Options to be apllied to the filter.
int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem)
Add an element to a dynamic array.
static int linklabels_parse(void *logctx, const char **linklabels, AVFilterPadParams ***res, unsigned *nb_res)
int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
Initialize a filter with the supplied dictionary of options.
A filterchain is a list of filter specifications.
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...
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
#define AVERROR_FILTER_NOT_FOUND
Filter not found.
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.
char * av_strdup(const char *s)
Duplicate a string.
void avfilter_free(AVFilterContext *filter)
Free a filter context.
static void filter_params_free(AVFilterParams **pp)
char * name
unique name for this input/output in the list
#define flags(name, subs,...)
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.
int avfilter_graph_segment_apply_opts(AVFilterGraphSegment *seg, int flags)
Apply parsed options to filter instances in a graph segment.
const AVFilter * filter
the AVFilter of which this is an instance
A linked-list of the inputs/outputs of the filter chain.
static int filter_parse(void *logctx, const char **filter, AVFilterParams **pp)
Parameters of a filter's input or output pad.
AVFilterLink ** outputs
array of pointers to output links
Generated on Tue Feb 28 2023 21:33:51 for FFmpeg by
doxygen
1.8.17