From 449704b47500bbd3530c584e50a5d76f02d90113 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 6 May 2013 23:51:27 +0200 Subject: [PATCH 1/3] ffmpeg: move a local variable definition later. Fix a segfault when using the -map option without input files. --- ffmpeg_opt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index ff80c8ab44..c87bf01100 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -1719,7 +1719,6 @@ static int open_output_file(OptionsContext *o, const char *filename) } else { for (i = 0; i < o->nb_stream_maps; i++) { StreamMap *map = &o->stream_maps[i]; - int src_idx = input_files[map->file_index]->ist_index + map->stream_index; if (map->disabled) continue; @@ -1747,6 +1746,8 @@ loop_end: } init_output_filter(ofilter, o, oc); } else { + int src_idx = input_files[map->file_index]->ist_index + map->stream_index; + ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index]; if(o->subtitle_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) continue; From 78d16b6a51095cde231524dd394ac200b7bddde9 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 6 May 2013 13:46:23 +0200 Subject: [PATCH 2/3] lavfi: fix filter format negotiation loop. query_formats() returning EAGAIN is not considered a progress in the format negotiation. If the filter returns EAGAIN but did set some of its formats lists, it could be considered a partial success and counted as progress in the negotiation. Not counting it is not a problem because it currently only happens in the first round, where there will always be some progress on the other filters. --- libavfilter/avfiltergraph.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 582a87023d..860f1d892b 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -333,7 +333,8 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) ret = ff_default_query_formats(f); if (ret < 0 && ret != AVERROR(EAGAIN)) return ret; - count_queried++; + /* note: EAGAIN could indicate a partial success, not counted yet */ + count_queried += ret >= 0; } /* go through and merge as many format lists as possible */ From 4582e4c086bc36e20e3c0b85c8108cfa352e0d88 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 6 May 2013 14:09:53 +0200 Subject: [PATCH 3/3] lavfi: add comments to explain the negotiation loop. --- libavfilter/avfiltergraph.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 860f1d892b..c5a9e3b59d 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -316,12 +316,24 @@ static int formats_declared(AVFilterContext *f) return 1; } +/** + * Perform one round of query_formats() and merging formats lists on the + * filter graph. + * @return >=0 if all links formats lists could be queried and merged; + * AVERROR(EAGAIN) some progress was made in the queries or merging + * and a later call may succeed; + * AVERROR(EIO) (may be changed) plus a log message if no progress + * was made and the negotiation is stuck; + * a negative error code if some other error happened + */ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) { int i, j, ret; int scaler_count = 0, resampler_count = 0; - int count_queried = 0, count_merged = 0, count_already_merged = 0, - count_delayed = 0; + int count_queried = 0; /* successful calls to query_formats() */ + int count_merged = 0; /* successful merge of formats lists */ + int count_already_merged = 0; /* lists already merged */ + int count_delayed = 0; /* lists that need to be merged later */ for (i = 0; i < graph->nb_filters; i++) { AVFilterContext *f = graph->filters[i]; @@ -464,6 +476,11 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) if (count_delayed) { AVBPrint bp; + /* if count_queried > 0, one filter at least did set its formats, + that will give additional information to its neighbour; + if count_merged > 0, one pair of formats lists at least was merged, + that will give additional information to all connected filters; + in both cases, progress was made and a new round must be done */ if (count_queried || count_merged) return AVERROR(EAGAIN); av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);