From: Michael Niedermayer Date: Sat, 16 Mar 2013 15:09:37 +0000 (+0100) Subject: Merge commit '42c7c61ab25809620b8c8809b3da73e25f5bbaaf' X-Git-Tag: android-x86-4.4-r1~5028 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=ecade984ac3ce5205f6276a9329e2b7bca09fa47;p=android-x86%2Fexternal-ffmpeg.git Merge commit '42c7c61ab25809620b8c8809b3da73e25f5bbaaf' * commit '42c7c61ab25809620b8c8809b3da73e25f5bbaaf': avfiltergraph: replace AVFilterGraph.filter_count with nb_filters Conflicts: doc/APIchanges libavfilter/avfiltergraph.c libavfilter/avfiltergraph.h libavfilter/graphparser.c libavfilter/version.h Merged-by: Michael Niedermayer --- ecade984ac3ce5205f6276a9329e2b7bca09fa47 diff --cc doc/APIchanges index 0b2295c562,2c08af44af..2bde666c35 --- a/doc/APIchanges +++ b/doc/APIchanges @@@ -15,135 -13,9 +15,138 @@@ libavutil: 2012-10-2 API changes, most recent first: +2013-03-07 - xxxxxx - lavu 52.18.100 - avstring.h,bprint.h + Add av_escape() and av_bprint_escape() API. + +2013-02-24 - xxxxxx - lavfi 3.41.100 - buffersink.h + Add sample_rates field to AVABufferSinkParams. + +2013-01-17 - a1a707f - lavf 54.61.100 + Add av_codec_get_tag2(). + +2013-01-01 - 2eb2e17 - lavfi 3.34.100 + Add avfilter_get_audio_buffer_ref_from_arrays_channels. + +2012-12-20 - 34de47aa - lavfi 3.29.100 - avfilter.h + Add AVFilterLink.channels, avfilter_link_get_channels() + and avfilter_ref_get_channels(). + +2012-12-15 - 2ada584d - lavc 54.80.100 - avcodec.h + Add pkt_size field to AVFrame. + +2012-11-25 - c70ec631 - lavu 52.9.100 - opt.h + Add the following convenience functions to opt.h: + av_opt_get_image_size + av_opt_get_pixel_fmt + av_opt_get_sample_fmt + av_opt_set_image_size + av_opt_set_pixel_fmt + av_opt_set_sample_fmt + +2012-11-17 - 4cd74c81 - lavu 52.8.100 - bprint.h + Add av_bprint_strftime(). + +2012-11-15 - 92648107 - lavu 52.7.100 - opt.h + Add av_opt_get_key_value(). + +2012-11-13 - 79456652 - lavfi 3.23.100 - avfilter.h + Add channels field to AVFilterBufferRefAudioProps. + +2012-11-03 - 481fdeee - lavu 52.3.100 - opt.h + Add AV_OPT_TYPE_SAMPLE_FMT value to AVOptionType enum. + +2012-10-21 - 6fb2fd8 - lavc 54.68.100 - avcodec.h + lavfi 3.20.100 - avfilter.h + Add AV_PKT_DATA_STRINGS_METADATA side data type, used to transmit key/value + strings between AVPacket and AVFrame, and add metadata field to + AVCodecContext (which shall not be accessed by users; see AVFrame metadata + instead). + +2012-09-27 - a70b493 - lavd 54.3.100 - version.h + Add LIBAVDEVICE_IDENT symbol. + +2012-09-27 - a70b493 - lavfi 3.18.100 - version.h + Add LIBAVFILTER_IDENT symbol. + +2012-09-27 - a70b493 - libswr 0.16.100 - version.h + Add LIBSWRESAMPLE_VERSION, LIBSWRESAMPLE_BUILD + and LIBSWRESAMPLE_IDENT symbols. + +2012-09-06 - 29e972f - lavu 51.72.100 - parseutils.h + Add av_small_strptime() time parsing function. + + Can be used as a stripped-down replacement for strptime(), on + systems which do not support it. + +2012-08-25 - 2626cc4 - lavf 54.28.100 + Matroska demuxer now identifies SRT subtitles as AV_CODEC_ID_SUBRIP instead + of AV_CODEC_ID_TEXT. + +2012-08-13 - 5c0d8bc - lavfi 3.8.100 - avfilter.h + Add avfilter_get_class() function, and priv_class field to AVFilter + struct. + +2012-08-12 - a25346e - lavu 51.69.100 - opt.h + Add AV_OPT_FLAG_FILTERING_PARAM symbol in opt.h. + +2012-07-31 - 23fc4dd - lavc 54.46.100 + Add channels field to AVFrame. + +2012-07-30 - f893904 - lavu 51.66.100 + Add av_get_channel_description() + and av_get_standard_channel_layout() functions. + +2012-07-21 - 016a472 - lavc 54.43.100 + Add decode_error_flags field to AVFrame. + +2012-07-20 - b062936 - lavf 54.18.100 + Add avformat_match_stream_specifier() function. + +2012-07-14 - f49ec1b - lavc 54.38.100 - avcodec.h + Add metadata to AVFrame, and the accessor functions + av_frame_get_metadata() and av_frame_set_metadata(). + +2012-07-10 - 0e003d8 - lavc 54.33.100 + Add av_fast_padded_mallocz(). + +2012-07-10 - 21d5609 - lavfi 3.2.0 - avfilter.h + Add init_opaque() callback to AVFilter struct. + +2012-06-26 - e6674e4 - lavu 51.63.100 - imgutils.h + Add functions to libavutil/imgutils.h: + av_image_get_buffer_size() + av_image_fill_arrays() + av_image_copy_to_buffer() + +2012-06-24 - c41899a - lavu 51.62.100 - version.h + version moved from avutil.h to version.h + +2012-04-11 - 359abb1 - lavu 51.58.100 - error.h + Add av_make_error_string() and av_err2str() utilities to + libavutil/error.h. + +2012-06-05 - 62b39d4 - lavc 54.24.100 + Add pkt_duration field to AVFrame. + +2012-05-24 - f2ee065 - lavu 51.54.100 + Move AVPALETTE_SIZE and AVPALETTE_COUNT macros from + libavcodec/avcodec.h to libavutil/pixfmt.h. + +2012-05-14 - 94a9ac1 - lavf 54.5.100 + Add av_guess_sample_aspect_ratio() function. + +2012-04-20 - 65fa7bc - lavfi 2.70.100 + Add avfilter_unref_bufferp() to avfilter.h. + +2012-04-13 - 162e400 - lavfi 2.68.100 + Install libavfilter/asrc_abuffer.h public header. + +2012-03-26 - a67d9cf - lavfi 2.66.100 + Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions. + + 2013-xx-xx - lavfi 3.6.0 + Add AVFilterGraph.nb_filters, deprecate AVFilterGraph.filter_count. + 2013-03-xx - Reference counted buffers - lavu 52.8.0, lavc 55.0.0, lavf 55.0.0, lavd 54.0.0, lavfi 3.5.0 xxxxxxx, xxxxxxx - add a new API for reference counted buffers and buffer diff --cc libavfilter/avfiltergraph.c index 2764b8c85a,7bbfc1ceb4..9b05c6d6d1 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@@ -62,11 -50,9 +62,11 @@@ void avfilter_graph_free(AVFilterGraph { if (!*graph) return; - for (; (*graph)->filter_count > 0; (*graph)->filter_count--) - avfilter_free((*graph)->filters[(*graph)->filter_count - 1]); + for (; (*graph)->nb_filters > 0; (*graph)->nb_filters--) + avfilter_free((*graph)->filters[(*graph)->nb_filters - 1]); + av_freep(&(*graph)->sink_links); av_freep(&(*graph)->scale_sws_opts); + av_freep(&(*graph)->aresample_swr_opts); av_freep(&(*graph)->resample_lavr_opts); av_freep(&(*graph)->filters); av_freep(graph); @@@ -124,8 -105,7 +124,8 @@@ static int graph_check_validity(AVFilte AVFilterContext *filt; int i, j; - for (i = 0; i < graph->filter_count; i++) { + for (i = 0; i < graph->nb_filters; i++) { + const AVFilterPad *pad; filt = graph->filters[i]; for (j = 0; j < filt->nb_inputs; j++) { @@@ -243,21 -168,12 +243,21 @@@ static int query_formats(AVFilterGraph int i, j, ret; int scaler_count = 0, resampler_count = 0; + for (j = 0; j < 2; j++) { /* ask all the sub-filters for their supported media formats */ - for (i = 0; i < graph->filter_count; i++) { + for (i = 0; i < graph->nb_filters; i++) { + /* Call query_formats on sources first. + This is a temporary workaround for amerge, + until format renegociation is implemented. */ + if (!graph->filters[i]->nb_inputs == j) + continue; if (graph->filters[i]->filter->query_formats) - graph->filters[i]->filter->query_formats(graph->filters[i]); + ret = filter_query_formats(graph->filters[i]); else - ff_default_query_formats(graph->filters[i]); + ret = ff_default_query_formats(graph->filters[i]); + if (ret < 0) + return ret; + } } /* go through and merge as many format lists as possible */ @@@ -774,43 -616,8 +774,43 @@@ static void swap_sample_fmts(AVFilterGr static int pick_formats(AVFilterGraph *graph) { int i, j, ret; + int change; + + do{ + change = 0; - for (i = 0; i < graph->filter_count; i++) { ++ for (i = 0; i < graph->nb_filters; i++) { + AVFilterContext *filter = graph->filters[i]; + if (filter->nb_inputs){ + for (j = 0; j < filter->nb_inputs; j++){ + if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->format_count == 1) { + if ((ret = pick_format(filter->inputs[j], NULL)) < 0) + return ret; + change = 1; + } + } + } + if (filter->nb_outputs){ + for (j = 0; j < filter->nb_outputs; j++){ + if(filter->outputs[j]->in_formats && filter->outputs[j]->in_formats->format_count == 1) { + if ((ret = pick_format(filter->outputs[j], NULL)) < 0) + return ret; + change = 1; + } + } + } + if (filter->nb_inputs && filter->nb_outputs && filter->inputs[0]->format>=0) { + for (j = 0; j < filter->nb_outputs; j++) { + if(filter->outputs[j]->format<0) { + if ((ret = pick_format(filter->outputs[j], filter->inputs[0])) < 0) + return ret; + change = 1; + } + } + } + } + }while(change); - for (i = 0; i < graph->filter_count; i++) { + for (i = 0; i < graph->nb_filters; i++) { AVFilterContext *filter = graph->filters[i]; for (j = 0; j < filter->nb_inputs; j++) @@@ -851,48 -658,6 +851,48 @@@ static int graph_config_formats(AVFilte return 0; } +static int ff_avfilter_graph_config_pointers(AVFilterGraph *graph, + AVClass *log_ctx) +{ + unsigned i, j; + int sink_links_count = 0, n = 0; + AVFilterContext *f; + AVFilterLink **sinks; + - for (i = 0; i < graph->filter_count; i++) { ++ for (i = 0; i < graph->nb_filters; i++) { + f = graph->filters[i]; + for (j = 0; j < f->nb_inputs; j++) { + f->inputs[j]->graph = graph; + f->inputs[j]->age_index = -1; + } + for (j = 0; j < f->nb_outputs; j++) { + f->outputs[j]->graph = graph; + f->outputs[j]->age_index= -1; + } + if (!f->nb_outputs) { + if (f->nb_inputs > INT_MAX - sink_links_count) + return AVERROR(EINVAL); + sink_links_count += f->nb_inputs; + } + } + sinks = av_calloc(sink_links_count, sizeof(*sinks)); + if (!sinks) + return AVERROR(ENOMEM); - for (i = 0; i < graph->filter_count; i++) { ++ for (i = 0; i < graph->nb_filters; i++) { + f = graph->filters[i]; + if (!f->nb_outputs) { + for (j = 0; j < f->nb_inputs; j++) { + sinks[n] = f->inputs[j]; + f->inputs[j]->age_index = n++; + } + } + } + av_assert0(n == sink_links_count); + graph->sink_links = sinks; + graph->sink_links_count = sink_links_count; + return 0; +} + static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx) { AVFilterContext *f; @@@ -948,126 -711,3 +948,126 @@@ int avfilter_graph_config(AVFilterGrap return 0; } + +int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags) +{ + int i, r = AVERROR(ENOSYS); + + if(!graph) + return r; + + if((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) { + r=avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST); + if(r != AVERROR(ENOSYS)) + return r; + } + + if(res_len && res) + res[0]= 0; + - for (i = 0; i < graph->filter_count; i++) { ++ for (i = 0; i < graph->nb_filters; i++) { + AVFilterContext *filter = graph->filters[i]; + if(!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)){ + r = avfilter_process_command(filter, cmd, arg, res, res_len, flags); + if(r != AVERROR(ENOSYS)) { + if((flags & AVFILTER_CMD_FLAG_ONE) || r<0) + return r; + } + } + } + + return r; +} + +int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts) +{ + int i; + + if(!graph) + return 0; + - for (i = 0; i < graph->filter_count; i++) { ++ for (i = 0; i < graph->nb_filters; i++) { + AVFilterContext *filter = graph->filters[i]; + if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){ + AVFilterCommand **queue = &filter->command_queue, *next; + while (*queue && (*queue)->time <= ts) + queue = &(*queue)->next; + next = *queue; + *queue = av_mallocz(sizeof(AVFilterCommand)); + (*queue)->command = av_strdup(command); + (*queue)->arg = av_strdup(arg); + (*queue)->time = ts; + (*queue)->flags = flags; + (*queue)->next = next; + if(flags & AVFILTER_CMD_FLAG_ONE) + return 0; + } + } + + return 0; +} + +static void heap_bubble_up(AVFilterGraph *graph, + AVFilterLink *link, int index) +{ + AVFilterLink **links = graph->sink_links; + + while (index) { + int parent = (index - 1) >> 1; + if (links[parent]->current_pts >= link->current_pts) + break; + links[index] = links[parent]; + links[index]->age_index = index; + index = parent; + } + links[index] = link; + link->age_index = index; +} + +static void heap_bubble_down(AVFilterGraph *graph, + AVFilterLink *link, int index) +{ + AVFilterLink **links = graph->sink_links; + + while (1) { + int child = 2 * index + 1; + if (child >= graph->sink_links_count) + break; + if (child + 1 < graph->sink_links_count && + links[child + 1]->current_pts < links[child]->current_pts) + child++; + if (link->current_pts < links[child]->current_pts) + break; + links[index] = links[child]; + links[index]->age_index = index; + index = child; + } + links[index] = link; + link->age_index = index; +} + +void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link) +{ + heap_bubble_up (graph, link, link->age_index); + heap_bubble_down(graph, link, link->age_index); +} + + +int avfilter_graph_request_oldest(AVFilterGraph *graph) +{ + while (graph->sink_links_count) { + AVFilterLink *oldest = graph->sink_links[0]; + int r = ff_request_frame(oldest); + if (r != AVERROR_EOF) + return r; + av_log(oldest->dst, AV_LOG_DEBUG, "EOF on sink link %s:%s.\n", + oldest->dst ? oldest->dst->name : "unknown", + oldest->dstpad ? oldest->dstpad->name : "unknown"); + /* EOF: remove the link from the heap */ + if (oldest->age_index < --graph->sink_links_count) + heap_bubble_down(graph, graph->sink_links[graph->sink_links_count], + oldest->age_index); + oldest->age_index = -1; + } + return AVERROR_EOF; +} diff --cc libavfilter/avfiltergraph.h index 3965412803,9859389390..61110f99a1 --- a/libavfilter/avfiltergraph.h +++ b/libavfilter/avfiltergraph.h @@@ -27,24 -27,20 +27,33 @@@ typedef struct AVFilterGraph { const AVClass *av_class; - unsigned filter_count; + #if FF_API_FOO_COUNT + attribute_deprecated - unsigned filter_count; ++ unsigned filter_count_unused; + #endif AVFilterContext **filters; + #if !FF_API_FOO_COUNT + unsigned nb_filters; + #endif char *scale_sws_opts; ///< sws options to use for the auto-inserted scale filters char *resample_lavr_opts; ///< libavresample options to use for the auto-inserted resample filters + #if FF_API_FOO_COUNT + unsigned nb_filters; + #endif + char *aresample_swr_opts; ///< swr options to use for the auto-inserted aresample filters, Access ONLY through AVOptions + + /** + * Private fields + * + * The following fields are for internal use only. + * Their type, offset, number and semantic can change without notice. + */ + + AVFilterLink **sink_links; + int sink_links_count; + + unsigned disable_auto_convert; } AVFilterGraph; /** diff --cc libavfilter/graphdump.c index 28e9bc9789,0000000000..756f63dc49 mode 100644,000000..100644 --- a/libavfilter/graphdump.c +++ b/libavfilter/graphdump.c @@@ -1,164 -1,0 +1,164 @@@ +/* + * Filter graphs to bad ASCII-art + * Copyright (c) 2012 Nicolas George + * + * This file is part of FFmpeg. + * + * 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. + * + * 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/channel_layout.h" +#include "libavutil/bprint.h" +#include "libavutil/pixdesc.h" +#include "avfilter.h" +#include "avfiltergraph.h" + +static int print_link_prop(AVBPrint *buf, AVFilterLink *link) +{ + char *format; + char layout[64]; + + if (!buf) + buf = &(AVBPrint){ 0 }; /* dummy buffer */ + switch (link->type) { + case AVMEDIA_TYPE_VIDEO: + format = av_x_if_null(av_get_pix_fmt_name(link->format), "?"); + av_bprintf(buf, "[%dx%d %d:%d %s]", link->w, link->h, + link->sample_aspect_ratio.num, + link->sample_aspect_ratio.den, + format); + break; + + case AVMEDIA_TYPE_AUDIO: + av_get_channel_layout_string(layout, sizeof(layout), + link->channels, link->channel_layout); + format = av_x_if_null(av_get_sample_fmt_name(link->format), "?"); + av_bprintf(buf, "[%dHz %s:%s]", + (int)link->sample_rate, format, layout); + break; + + default: + av_bprintf(buf, "?"); + break; + } + return buf->len; +} + +static void avfilter_graph_dump_to_buf(AVBPrint *buf, AVFilterGraph *graph) +{ + unsigned i, j, x, e; + - for (i = 0; i < graph->filter_count; i++) { ++ for (i = 0; i < graph->nb_filters; i++) { + AVFilterContext *filter = graph->filters[i]; + unsigned max_src_name = 0, max_dst_name = 0; + unsigned max_in_name = 0, max_out_name = 0; + unsigned max_in_fmt = 0, max_out_fmt = 0; + unsigned width, height, in_indent; + unsigned lname = strlen(filter->name); + unsigned ltype = strlen(filter->filter->name); + + for (j = 0; j < filter->input_count; j++) { + AVFilterLink *l = filter->inputs[j]; + unsigned ln = strlen(l->src->name) + 1 + strlen(l->srcpad->name); + max_src_name = FFMAX(max_src_name, ln); + max_in_name = FFMAX(max_in_name, strlen(l->dstpad->name)); + max_in_fmt = FFMAX(max_in_fmt, print_link_prop(NULL, l)); + } + for (j = 0; j < filter->output_count; j++) { + AVFilterLink *l = filter->outputs[j]; + unsigned ln = strlen(l->dst->name) + 1 + strlen(l->dstpad->name); + max_dst_name = FFMAX(max_dst_name, ln); + max_out_name = FFMAX(max_out_name, strlen(l->srcpad->name)); + max_out_fmt = FFMAX(max_out_fmt, print_link_prop(NULL, l)); + } + in_indent = max_src_name + max_in_name + max_in_fmt; + in_indent += in_indent ? 4 : 0; + width = FFMAX(lname + 2, ltype + 4); + height = FFMAX3(2, filter->input_count, filter->output_count); + av_bprint_chars(buf, ' ', in_indent); + av_bprintf(buf, "+"); + av_bprint_chars(buf, '-', width); + av_bprintf(buf, "+\n"); + for (j = 0; j < height; j++) { + unsigned in_no = j - (height - filter->input_count ) / 2; + unsigned out_no = j - (height - filter->output_count) / 2; + + /* Input link */ + if (in_no < filter->input_count) { + AVFilterLink *l = filter->inputs[in_no]; + e = buf->len + max_src_name + 2; + av_bprintf(buf, "%s:%s", l->src->name, l->srcpad->name); + av_bprint_chars(buf, '-', e - buf->len); + e = buf->len + max_in_fmt + 2 + + max_in_name - strlen(l->dstpad->name); + print_link_prop(buf, l); + av_bprint_chars(buf, '-', e - buf->len); + av_bprintf(buf, "%s", l->dstpad->name); + } else { + av_bprint_chars(buf, ' ', in_indent); + } + + /* Filter */ + av_bprintf(buf, "|"); + if (j == (height - 2) / 2) { + x = (width - lname) / 2; + av_bprintf(buf, "%*s%-*s", x, "", width - x, filter->name); + } else if (j == (height - 2) / 2 + 1) { + x = (width - ltype - 2) / 2; + av_bprintf(buf, "%*s(%s)%*s", x, "", filter->filter->name, + width - ltype - 2 - x, ""); + } else { + av_bprint_chars(buf, ' ', width); + } + av_bprintf(buf, "|"); + + /* Output link */ + if (out_no < filter->output_count) { + AVFilterLink *l = filter->outputs[out_no]; + unsigned ln = strlen(l->dst->name) + 1 + + strlen(l->dstpad->name); + e = buf->len + max_out_name + 2; + av_bprintf(buf, "%s", l->srcpad->name); + av_bprint_chars(buf, '-', e - buf->len); + e = buf->len + max_out_fmt + 2 + + max_dst_name - ln; + print_link_prop(buf, l); + av_bprint_chars(buf, '-', e - buf->len); + av_bprintf(buf, "%s:%s", l->dst->name, l->dstpad->name); + } + av_bprintf(buf, "\n"); + } + av_bprint_chars(buf, ' ', in_indent); + av_bprintf(buf, "+"); + av_bprint_chars(buf, '-', width); + av_bprintf(buf, "+\n"); + av_bprintf(buf, "\n"); + } +} + +char *avfilter_graph_dump(AVFilterGraph *graph, const char *options) +{ + AVBPrint buf; + char *dump; + + av_bprint_init(&buf, 0, 0); + avfilter_graph_dump_to_buf(&buf, graph); + av_bprint_init(&buf, buf.len + 1, buf.len + 1); + avfilter_graph_dump_to_buf(&buf, graph); + av_bprint_finalize(&buf, &dump); + return dump; +} diff --cc libavfilter/graphparser.c index 3e85261c38,ea0a86d51a..8d2fffc194 --- a/libavfilter/graphparser.c +++ b/libavfilter/graphparser.c @@@ -435,9 -434,9 +435,9 @@@ int avfilter_graph_parse2(AVFilterGrap *outputs = open_outputs; return 0; - fail: + fail:end: - for (; graph->filter_count > 0; graph->filter_count--) - avfilter_free(graph->filters[graph->filter_count - 1]); + for (; graph->nb_filters > 0; graph->nb_filters--) + avfilter_free(graph->filters[graph->nb_filters - 1]); av_freep(&graph->filters); avfilter_inout_free(&open_inputs); avfilter_inout_free(&open_outputs); @@@ -510,92 -506,7 +510,92 @@@ int avfilter_graph_parse(AVFilterGraph } avfilter_inout_free(&inputs); avfilter_inout_free(&outputs); - avfilter_inout_free(&open_inputs); - avfilter_inout_free(&open_outputs); + /* 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); return ret; } +#else + 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->input_count == 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) { - for (; graph->filter_count > 0; graph->filter_count--) - avfilter_free(graph->filters[graph->filter_count - 1]); ++ for (; graph->nb_filters > 0; graph->nb_filters--) ++ avfilter_free(graph->filters[graph->nb_filters - 1]); + av_freep(&graph->filters); + } + return ret; +} + +#endif diff --cc libavfilter/version.h index 3a2fff3bf8,1a5ec42916..3ec6f2db46 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@@ -29,8 -29,8 +29,8 @@@ #include "libavutil/avutil.h" #define LIBAVFILTER_VERSION_MAJOR 3 - #define LIBAVFILTER_VERSION_MINOR 46 -#define LIBAVFILTER_VERSION_MINOR 6 -#define LIBAVFILTER_VERSION_MICRO 0 ++#define LIBAVFILTER_VERSION_MINOR 47 +#define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ diff --cc tools/graph2dot.c index 74075c7af2,c0142ccd31..d53642f915 --- a/tools/graph2dot.c +++ b/tools/graph2dot.c @@@ -58,7 -58,7 +58,7 @@@ static void print_digraph(FILE *outfile fprintf(outfile, "node [shape=box]\n"); fprintf(outfile, "rankdir=LR\n"); -- for (i = 0; i < graph->filter_count; i++) { ++ for (i = 0; i < graph->nb_filters; i++) { char filter_ctx_label[128]; const AVFilterContext *filter_ctx = graph->filters[i];