diff options
Diffstat (limited to 'libavfilter/graphparser.c')
-rw-r--r-- | libavfilter/graphparser.c | 133 |
1 files changed, 114 insertions, 19 deletions
diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c index e20dd62..7e25282 100644 --- a/libavfilter/graphparser.c +++ b/libavfilter/graphparser.c @@ -3,20 +3,20 @@ * Copyright (c) 2008 Vitor Sessak * Copyright (c) 2007 Bobby Bingham * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -89,17 +89,17 @@ static char *parse_link_name(const char **buf, void *log_ctx) * @param filt_name the name of the filter to create * @param args the arguments provided to the filter during its initialization * @param log_ctx the log context to use - * @return 0 in case of success, a negative AVERROR code otherwise + * @return >= 0 in case of success, a negative AVERROR code otherwise */ static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int index, const char *filt_name, const char *args, void *log_ctx) { AVFilter *filt; char inst_name[30]; - char tmp_args[256]; + char *tmp_args = NULL; int ret; - snprintf(inst_name, sizeof(inst_name), "Parsed filter %d %s", index, filt_name); + snprintf(inst_name, sizeof(inst_name), "Parsed_%s_%d", filt_name, index); filt = avfilter_get_by_name(filt_name); @@ -118,8 +118,10 @@ static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int ind if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags") && ctx->scale_sws_opts) { - snprintf(tmp_args, sizeof(tmp_args), "%s:%s", + tmp_args = av_asprintf("%s:%s", args, ctx->scale_sws_opts); + if (!tmp_args) + return AVERROR(ENOMEM); args = tmp_args; } @@ -131,10 +133,11 @@ static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int ind av_log(log_ctx, AV_LOG_ERROR, " with args '%s'", args); av_log(log_ctx, AV_LOG_ERROR, "\n"); avfilter_free(*filt_ctx); - return ret; + *filt_ctx = NULL; } - return 0; + av_free(tmp_args); + return ret; } /** @@ -151,7 +154,7 @@ static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int ind * @param index an index which is assigned to the created filter * instance, and which is supposed to be unique for each filter * instance added to the filtergraph - * @return 0 in case of success, a negative AVERROR code otherwise + * @return >= 0 in case of success, a negative AVERROR code otherwise */ static int parse_filter(AVFilterContext **filt_ctx, const char **buf, AVFilterGraph *graph, int index, void *log_ctx) @@ -384,7 +387,7 @@ int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs) { - int index = 0, ret; + int index = 0, ret = 0; char chr = 0; AVFilterInOut *curr_inputs = NULL, *open_inputs = NULL, *open_outputs = NULL; @@ -399,18 +402,17 @@ int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, filters += strspn(filters, WHITESPACES); if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, graph)) < 0) - goto fail; - + goto end; if ((ret = parse_filter(&filter, &filters, graph, index, graph)) < 0) - goto fail; + goto end; if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, graph)) < 0) - goto fail; + goto end; if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs, graph)) < 0) - goto fail; + goto end; filters += strspn(filters, WHITESPACES); chr = *filters++; @@ -425,16 +427,17 @@ int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, "Unable to parse graph description substring: \"%s\"\n", filters - 1); ret = AVERROR(EINVAL); - goto fail; + goto end; } append_inout(&open_outputs, &curr_inputs); + *inputs = open_inputs; *outputs = open_outputs; return 0; - fail: + fail:end: while (graph->nb_filters) avfilter_free(graph->filters[0]); av_freep(&graph->filters); @@ -448,6 +451,7 @@ int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, return ret; } +#if HAVE_INCOMPATIBLE_LIBAV_ABI || !FF_API_OLD_GRAPH_PARSE int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, AVFilterInOut *open_inputs, AVFilterInOut *open_outputs, void *log_ctx) @@ -509,4 +513,95 @@ int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, avfilter_inout_free(&open_inputs); avfilter_inout_free(&open_outputs); return ret; +#else +int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, + AVFilterInOut **inputs, AVFilterInOut **outputs, + void *log_ctx) +{ + return avfilter_graph_parse_ptr(graph, filters, inputs, outputs, log_ctx); +#endif +} + +int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters, + AVFilterInOut **open_inputs_ptr, AVFilterInOut **open_outputs_ptr, + void *log_ctx) +{ + int index = 0, ret = 0; + char chr = 0; + + AVFilterInOut *curr_inputs = NULL; + AVFilterInOut *open_inputs = open_inputs_ptr ? *open_inputs_ptr : NULL; + AVFilterInOut *open_outputs = open_outputs_ptr ? *open_outputs_ptr : NULL; + + if ((ret = parse_sws_flags(&filters, graph)) < 0) + goto end; + + do { + AVFilterContext *filter; + const char *filterchain = filters; + filters += strspn(filters, WHITESPACES); + + if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, log_ctx)) < 0) + goto end; + + if ((ret = parse_filter(&filter, &filters, graph, index, log_ctx)) < 0) + goto end; + + if (filter->nb_inputs == 1 && !curr_inputs && !index) { + /* First input pad, assume it is "[in]" if not specified */ + const char *tmp = "[in]"; + if ((ret = parse_inputs(&tmp, &curr_inputs, &open_outputs, log_ctx)) < 0) + goto end; + } + + if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, log_ctx)) < 0) + goto end; + + if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs, + log_ctx)) < 0) + goto end; + + filters += strspn(filters, WHITESPACES); + chr = *filters++; + + if (chr == ';' && curr_inputs) { + av_log(log_ctx, AV_LOG_ERROR, + "Invalid filterchain containing an unlabelled output pad: \"%s\"\n", + filterchain); + ret = AVERROR(EINVAL); + goto end; + } + index++; + } while (chr == ',' || chr == ';'); + + if (chr) { + av_log(log_ctx, AV_LOG_ERROR, + "Unable to parse graph description substring: \"%s\"\n", + filters - 1); + ret = AVERROR(EINVAL); + goto end; + } + + if (curr_inputs) { + /* Last output pad, assume it is "[out]" if not specified */ + const char *tmp = "[out]"; + if ((ret = parse_outputs(&tmp, &curr_inputs, &open_inputs, &open_outputs, + log_ctx)) < 0) + goto end; + } + +end: + /* clear open_in/outputs only if not passed as parameters */ + if (open_inputs_ptr) *open_inputs_ptr = open_inputs; + else avfilter_inout_free(&open_inputs); + if (open_outputs_ptr) *open_outputs_ptr = open_outputs; + else avfilter_inout_free(&open_outputs); + avfilter_inout_free(&curr_inputs); + + if (ret < 0) { + while (graph->nb_filters) + avfilter_free(graph->filters[0]); + av_freep(&graph->filters); + } + return ret; } |