Avoid searching by instance name when it is not necessary

Commited in SoC by Vitor Sessak on 2008-04-06 18:00:58

Originally committed as revision 13289 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Vitor Sessak 2008-05-24 20:38:25 +00:00
parent 27a669ab00
commit 9710beaf14
1 changed files with 47 additions and 64 deletions

View File

@ -41,8 +41,8 @@ static const AVClass filter_parser_class = {
static const AVClass *log_ctx = &filter_parser_class;
static int create_filter(AVFilterGraph *ctx, int index, char *name,
char *args)
static AVFilterContext *create_filter(AVFilterGraph *ctx, int index,
char *name, char *args)
{
AVFilterContext *filt;
@ -54,46 +54,34 @@ static int create_filter(AVFilterGraph *ctx, int index, char *name,
if(!(filterdef = avfilter_get_by_name(name))) {
av_log(&log_ctx, AV_LOG_ERROR,
"no such filter: '%s'\n", name);
return -1;
return NULL;
}
if(!(filt = avfilter_open(filterdef, tmp))) {
av_log(&log_ctx, AV_LOG_ERROR,
"error creating filter '%s'\n", name);
return -1;
return NULL;
}
if (avfilter_graph_add_filter(ctx, filt) < 0)
return -1;
return NULL;
if(avfilter_init_filter(filt, args, NULL)) {
av_log(&log_ctx, AV_LOG_ERROR,
"error initializing filter '%s' with args '%s'\n", name, args);
return -1;
return NULL;
}
return 0;
return filt;
}
static int link_filter(AVFilterGraph *ctx, int src, int srcpad,
int dst, int dstpad)
static int link_filter(AVFilterContext *src, int srcpad,
AVFilterContext *dst, int dstpad)
{
AVFilterContext *filt, *filtb;
char tmp[20];
snprintf(tmp, 20, "%d", src);
if(!(filt = avfilter_graph_get_filter(ctx, tmp))) {
av_log(&log_ctx, AV_LOG_ERROR, "link source does not exist in graph\n");
return -1;
}
snprintf(tmp, 20, "%d", dst);
if(!(filtb = avfilter_graph_get_filter(ctx, tmp))) {
av_log(&log_ctx, AV_LOG_ERROR, "link destination does not exist in graph\n");
return -1;
}
if(avfilter_link(filt, srcpad, filtb, dstpad)) {
av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
if(avfilter_link(src, srcpad, dst, dstpad)) {
av_log(&log_ctx, AV_LOG_ERROR,
"cannot create the link %s:%d -> %s:%d\n",
src->filter->name, srcpad, dst->filter->name, dstpad);
return -1;
}
@ -201,7 +189,7 @@ static void parse_link_name(const char **buf, char **name)
* @arg ars a pointer (that need to be free'd after use) to the args of the
* filter
*/
static int parse_filter(const char **buf, AVFilterGraph *graph, int index)
static AVFilterContext *parse_filter(const char **buf, AVFilterGraph *graph, int index)
{
char *name, *opts;
name = consume_string(buf);
@ -227,7 +215,7 @@ enum LinkType {
typedef struct AVFilterInOut {
enum LinkType type;
char *name;
int instance;
AVFilterContext *instance;
int pad_idx;
struct AVFilterInOut *next;
@ -247,7 +235,7 @@ static void free_inout(AVFilterInOut *head)
* Parse "(a1)(link2) ... (etc)"
*/
static int parse_inouts(const char **buf, AVFilterInOut **inout, int firstpad,
enum LinkType type, int instance)
enum LinkType type, AVFilterContext *instance)
{
int pad = firstpad;
while (**buf == '(') {
@ -262,6 +250,16 @@ static int parse_inouts(const char **buf, AVFilterInOut **inout, int firstpad,
return pad;
}
static const char *skip_inouts(const char *buf)
{
while (*buf == '(') {
buf += strcspn(buf, ")");
buf++;
}
return buf;
}
/**
* Parse a string describing a filter graph.
*/
@ -275,70 +273,61 @@ int avfilter_graph_parse_chain(AVFilterGraph *graph, const char *filters, AVFilt
int pad = 0;
int has_out = 0;
char tmp[20];
AVFilterContext *filt;
AVFilterContext *last_filt = NULL;
consume_whitespace(&filters);
do {
AVFilterContext *filter;
int oldpad = pad;
const char *inouts = filters;
pad = parse_inouts(&filters, &inout, chr == ',', LinkTypeIn, index);
// We need to parse the inputs of the filter after we create it, so
// skip it by now
filters = skip_inouts(filters);
if (parse_filter(&filters, graph, index) < 0)
if (!(filter = parse_filter(&filters, graph, index)))
goto fail;
pad = parse_inouts(&inouts, &inout, chr == ',', LinkTypeIn, filter);
// If the first filter has an input and none was given, it is
// implicitly the input of the whole graph.
if (pad == 0 && graph->filters[graph->filter_count-1]->input_count == 1) {
snprintf(tmp, 20, "%d", index);
if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
goto fail;
}
if(avfilter_link(in, inpad, filt, 0)) {
if(avfilter_link(in, inpad, filter, 0)) {
av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
goto fail;
}
}
if(chr == ',') {
if (link_filter(graph, index-1, oldpad, index, 0) < 0)
if (link_filter(last_filt, oldpad, filter, 0) < 0)
goto fail;
}
pad = parse_inouts(&filters, &inout, 0, LinkTypeOut, index);
pad = parse_inouts(&filters, &inout, 0, LinkTypeOut, filter);
chr = *filters++;
index++;
last_filt = filter;
} while (chr == ',' || chr == ';');
head = inout;
for (; inout != NULL; inout = inout->next) {
if (inout->instance == -1)
if (inout->instance == NULL)
continue; // Already processed
if (!strcmp(inout->name, "in")) {
snprintf(tmp, 20, "%d", inout->instance);
if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
goto fail;
}
if(avfilter_link(in, inpad, filt, inout->pad_idx)) {
if(avfilter_link(in, inpad, inout->instance, inout->pad_idx)) {
av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
goto fail;
}
} else if (!strcmp(inout->name, "out")) {
has_out = 1;
snprintf(tmp, 20, "%d", inout->instance);
if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
goto fail;
}
if(avfilter_link(filt, inout->pad_idx, out, outpad)) {
if(avfilter_link(inout->instance, inout->pad_idx, out, outpad)) {
av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
goto fail;
}
}
} else {
AVFilterInOut *p, *src, *dst;
@ -363,24 +352,18 @@ int avfilter_graph_parse_chain(AVFilterGraph *graph, const char *filters, AVFilt
goto fail;
}
if (link_filter(graph, src->instance, src->pad_idx, dst->instance, dst->pad_idx) < 0)
if (link_filter(src->instance, src->pad_idx, dst->instance, dst->pad_idx) < 0)
goto fail;
src->instance = -1;
dst->instance = -1;
src->instance = NULL;
dst->instance = NULL;
}
}
free_inout(head);
if (!has_out) {
snprintf(tmp, 20, "%d", index-1);
if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
goto fail;
}
if(avfilter_link(filt, pad, out, outpad)) {
if(avfilter_link(last_filt, pad, out, outpad)) {
av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
goto fail;
}