#include "graphparser.h"
#include "avfilter.h"
#include "avfiltergraph.h"
+#include "parseutils.h"
+
+#define WHITESPACES " \n\t"
static int link_filter(AVFilterContext *src, int srcpad,
AVFilterContext *dst, int dstpad,
return 0;
}
-static int consume_whitespace(const char *buf)
-{
- return strspn(buf, " \n\t");
-}
-
-/**
- * Consumes a string from *buf.
- * @return a copy of the consumed string, which should be free'd after use
- */
-static char *consume_string(const char **buf)
-{
- char *out = av_malloc(strlen(*buf) + 1);
- char *ret = out;
-
- *buf += consume_whitespace(*buf);
-
- do{
- char c = *(*buf)++;
- switch (c) {
- case '\\':
- *out++ = *(*buf)++;
- break;
- case '\'':
- while(**buf && **buf != '\'')
- *out++ = *(*buf)++;
- if(**buf) (*buf)++;
- break;
- case 0:
- case ']':
- case '[':
- case '=':
- case ',':
- case ';':
- case ' ':
- case '\n':
- *out++ = 0;
- break;
- default:
- *out++ = c;
- }
- } while(out[-1]);
-
- (*buf)--;
- *buf += consume_whitespace(*buf);
-
- return ret;
-}
-
/**
* Parse "[linkname]"
* @param name a pointer (that need to be free'd after use) to the name between
char *name;
(*buf)++;
- name = consume_string(buf);
+ name = av_get_token(buf, "]");
if(!name[0]) {
av_log(log_ctx, AV_LOG_ERROR,
int index, AVClass *log_ctx)
{
char *opts = NULL;
- char *name = consume_string(buf);
+ char *name = av_get_token(buf, "=,[");
AVFilterContext *ret;
if(**buf == '=') {
(*buf)++;
- opts = consume_string(buf);
+ opts = av_get_token(buf, "[],\n");
}
ret = create_filter(graph, index, name, opts, log_ctx);
}
static int link_filter_inouts(AVFilterContext *filter,
- AVFilterInOut **currInputs,
- AVFilterInOut **openInputs, AVClass *log_ctx)
+ AVFilterInOut **curr_inputs,
+ AVFilterInOut **open_inputs, AVClass *log_ctx)
{
int pad = filter->input_count;
while(pad--) {
- AVFilterInOut *p = *currInputs;
+ AVFilterInOut *p = *curr_inputs;
if(!p) {
av_log(log_ctx, AV_LOG_ERROR,
"Not enough inputs specified for the \"%s\" filter.\n",
return -1;
}
- *currInputs = (*currInputs)->next;
+ *curr_inputs = (*curr_inputs)->next;
if(p->filter) {
if(link_filter(p->filter, p->pad_idx, filter, pad, log_ctx))
} else {
p->filter = filter;
p->pad_idx = pad;
- insert_inout(openInputs, p);
+ insert_inout(open_inputs, p);
}
}
- if(*currInputs) {
+ if(*curr_inputs) {
av_log(log_ctx, AV_LOG_ERROR,
"Too many inputs specified for the \"%s\" filter.\n",
filter->filter->name);
AVFilterInOut *currlinkn = av_mallocz(sizeof(AVFilterInOut));
currlinkn->filter = filter;
currlinkn->pad_idx = pad;
- insert_inout(currInputs, currlinkn);
+ insert_inout(curr_inputs, currlinkn);
}
return 0;
}
-static int parse_inputs(const char **buf, AVFilterInOut **currInputs,
- AVFilterInOut **openOutputs, AVClass *log_ctx)
+static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs,
+ AVFilterInOut **open_outputs, AVClass *log_ctx)
{
int pad = 0;
if(!name)
return -1;
- /* First check if the label is not in the openOutputs list */
- match = extract_inout(name, openOutputs);
+ /* First check if the label is not in the open_outputs list */
+ match = extract_inout(name, open_outputs);
if(match) {
av_free(name);
match->pad_idx = pad;
}
- insert_inout(currInputs, match);
+ insert_inout(curr_inputs, match);
- *buf += consume_whitespace(*buf);
+ *buf += strspn(*buf, WHITESPACES);
pad++;
}
return pad;
}
-static int parse_outputs(const char **buf, AVFilterInOut **currInputs,
- AVFilterInOut **openInputs,
- AVFilterInOut **openOutputs, AVClass *log_ctx)
+static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs,
+ AVFilterInOut **open_inputs,
+ AVFilterInOut **open_outputs, AVClass *log_ctx)
{
int pad = 0;
char *name = parse_link_name(buf, log_ctx);
AVFilterInOut *match;
- AVFilterInOut *input = *currInputs;
- *currInputs = (*currInputs)->next;
+ AVFilterInOut *input = *curr_inputs;
+ *curr_inputs = (*curr_inputs)->next;
if(!name)
return -1;
- /* First check if the label is not in the openInputs list */
- match = extract_inout(name, openInputs);
+ /* First check if the label is not in the open_inputs list */
+ match = extract_inout(name, open_inputs);
if(match) {
if(link_filter(input->filter, input->pad_idx,
av_free(match);
av_free(input);
} else {
- /* Not in the list, so add the first input as a openOutput */
+ /* Not in the list, so add the first input as a open_output */
input->name = name;
- insert_inout(openOutputs, input);
+ insert_inout(open_outputs, input);
}
- *buf += consume_whitespace(*buf);
+ *buf += strspn(*buf, WHITESPACES);
pad++;
}
return pad;
}
-int avfilter_parse_graph(AVFilterGraph *graph, const char *filters,
- AVFilterInOut *openInputs,
- AVFilterInOut *openOutputs, AVClass *log_ctx)
+int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
+ AVFilterInOut *open_inputs,
+ AVFilterInOut *open_outputs, AVClass *log_ctx)
{
int index = 0;
char chr = 0;
- AVFilterInOut *currInputs = NULL;
+ AVFilterInOut *curr_inputs = NULL;
do {
AVFilterContext *filter;
- filters += consume_whitespace(filters);
+ filters += strspn(filters, WHITESPACES);
- if(parse_inputs(&filters, &currInputs, &openOutputs, log_ctx) < 0)
+ if(parse_inputs(&filters, &curr_inputs, &open_outputs, log_ctx) < 0)
goto fail;
filter = parse_filter(&filters, graph, index, log_ctx);
if(!filter)
goto fail;
- if(filter->input_count == 1 && !currInputs && !index) {
+ if(filter->input_count == 1 && !curr_inputs && !index) {
/* First input can be omitted if it is "[in]" */
const char *tmp = "[in]";
- if(parse_inputs(&tmp, &currInputs, &openOutputs, log_ctx) < 0)
+ if(parse_inputs(&tmp, &curr_inputs, &open_outputs, log_ctx) < 0)
goto fail;
}
- if(link_filter_inouts(filter, &currInputs, &openInputs, log_ctx) < 0)
+ if(link_filter_inouts(filter, &curr_inputs, &open_inputs, log_ctx) < 0)
goto fail;
- if(parse_outputs(&filters, &currInputs, &openInputs, &openOutputs,
+ if(parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs,
log_ctx) < 0)
goto fail;
- filters += consume_whitespace(filters);
+ filters += strspn(filters, WHITESPACES);
chr = *filters++;
- if(chr == ';' && currInputs) {
+ if(chr == ';' && curr_inputs) {
av_log(log_ctx, AV_LOG_ERROR,
"Could not find a output to link when parsing \"%s\"\n",
filters - 1);
index++;
} while(chr == ',' || chr == ';');
- if(openInputs && !strcmp(openInputs->name, "out") && currInputs) {
+ if (chr) {
+ av_log(log_ctx, AV_LOG_ERROR,
+ "Unable to parse graph description substring: \"%s\"\n",
+ filters - 1);
+ goto fail;
+ }
+
+ if(open_inputs && !strcmp(open_inputs->name, "out") && curr_inputs) {
/* Last output can be omitted if it is "[out]" */
const char *tmp = "[out]";
- if(parse_outputs(&tmp, &currInputs, &openInputs,
- &openOutputs, log_ctx) < 0)
+ if(parse_outputs(&tmp, &curr_inputs, &open_inputs,
+ &open_outputs, log_ctx) < 0)
goto fail;
}
return 0;
fail:
- avfilter_destroy_graph(graph);
- free_inout(openInputs);
- free_inout(openOutputs);
- free_inout(currInputs);
+ avfilter_graph_destroy(graph);
+ free_inout(open_inputs);
+ free_inout(open_outputs);
+ free_inout(curr_inputs);
return -1;
}