diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 4e5bfd2f10..5211c762e1 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -19,6 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include + #include "avfilter.h" #include "avfiltergraph.h" @@ -54,3 +57,62 @@ void avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter) graph->filters[graph->filter_count - 1] = filter; } +static AVFilterContext *create_filter_with_args(char *filter) +{ + AVFilterContext *ret; + char *name, *args; + + name = filter; + if((args = strchr(filter, '='))) { + /* ensure we at least have a name */ + if(args == filter) + return NULL; + + *args ++ = 0; + } + + av_log(NULL, AV_LOG_INFO, "creating filter \"%s\" with args \"%s\"\n", + name, args ? args : "(none)"); + + if((ret = avfilter_create_by_name(name, NULL))) { + if(avfilter_init_filter(ret, args)) { + av_log(NULL, AV_LOG_ERROR, "error initializing filter!\n"); + avfilter_destroy(ret); + ret = NULL; + } + } else av_log(NULL, AV_LOG_ERROR, "error creating filter!\n"); + + return ret; +} + +int avfilter_graph_load_chain(AVFilterGraph *graph, + unsigned count, char **filter_list, + AVFilterContext **first, AVFilterContext **last) +{ + unsigned i; + AVFilterContext *filters[2] = {NULL,NULL}; + + for(i = 0; i < count; i ++) { + if(!(filters[1] = create_filter_with_args(filter_list[i]))) + goto fail; + if(i == 0) { + if(first) *first = filters[1]; + } else { + if(avfilter_link(filters[0], 0, filters[1], 0)) { + av_log(NULL, AV_LOG_ERROR, "error linking filters!\n"); + goto fail; + } + } + avfilter_graph_add_filter(graph, filters[1]); + filters[0] = filters[1]; + } + + if(last) *last = filters[1]; + return 0; + +fail: + destroy_graph_filters(graph); + *first = *last = NULL; + return -1; +} + diff --git a/libavfilter/avfiltergraph.h b/libavfilter/avfiltergraph.h index 0bfb683d5e..942b10685a 100644 --- a/libavfilter/avfiltergraph.h +++ b/libavfilter/avfiltergraph.h @@ -44,4 +44,17 @@ void avfilter_destroy_graph(AVFilterGraph *graph); */ void avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter); +/** + * Loads the filter graph with a simple chain described by filters. + * @param graph The filter graph to load filters into + * @param count The number of filters to be created + * @param filters_list An array of strings describing the filters to be created. + * The format of each string is "name=params". + * @param first If non-NULL, will be set to the first filter in the chain. + * @param last If non-NULL, will be set to the last filter in the chain. + * @return 0 on success. -1 on error. + */ +int avfilter_graph_load_chain(AVFilterGraph *graph, + unsigned count, char **filter_list, + AVFilterContext **first, AVFilterContext **last); #endif /* FFMPEG_AVFILTER_H */