diff --git a/avconv.c b/avconv.c index 6557754da7..291c4d4ce3 100644 --- a/avconv.c +++ b/avconv.c @@ -1679,11 +1679,6 @@ static int transcode_init(void) input_streams[j + ifile->ist_index]->start = av_gettime_relative(); } - /* init complex filtergraphs */ - for (i = 0; i < nb_filtergraphs; i++) - if ((ret = avfilter_graph_config(filtergraphs[i]->graph, NULL)) < 0) - return ret; - /* for each output stream, we compute the right encoding parameters */ for (i = 0; i < nb_output_streams; i++) { AVCodecContext *enc_ctx; diff --git a/avconv.h b/avconv.h index 5fddf98127..ec57fc8799 100644 --- a/avconv.h +++ b/avconv.h @@ -202,6 +202,7 @@ typedef struct OutputFilter { /* temporary storage until stream maps are processed */ AVFilterInOut *out_tmp; + enum AVMediaType type; } OutputFilter; typedef struct FilterGraph { @@ -424,6 +425,7 @@ int configure_filtergraph(FilterGraph *fg); int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out); int ist_in_filtergraph(FilterGraph *fg, InputStream *ist); FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost); +int init_complex_filtergraph(FilterGraph *fg); int avconv_parse_options(int argc, char **argv); diff --git a/avconv_filter.c b/avconv_filter.c index c3360f1741..18deb1f891 100644 --- a/avconv_filter.c +++ b/avconv_filter.c @@ -176,6 +176,45 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1]; } +int init_complex_filtergraph(FilterGraph *fg) +{ + AVFilterInOut *inputs, *outputs, *cur; + AVFilterGraph *graph; + int ret = 0; + + /* this graph is only used for determining the kinds of inputs + * and outputs we have, and is discarded on exit from this function */ + graph = avfilter_graph_alloc(); + if (!graph) + return AVERROR(ENOMEM); + + ret = avfilter_graph_parse2(graph, fg->graph_desc, &inputs, &outputs); + if (ret < 0) + goto fail; + + for (cur = inputs; cur; cur = cur->next) + init_input_filter(fg, cur); + + for (cur = outputs; cur;) { + GROW_ARRAY(fg->outputs, fg->nb_outputs); + fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0])); + if (!fg->outputs[fg->nb_outputs - 1]) + exit(1); + + fg->outputs[fg->nb_outputs - 1]->graph = fg; + fg->outputs[fg->nb_outputs - 1]->out_tmp = cur; + fg->outputs[fg->nb_outputs - 1]->type = avfilter_pad_get_type(cur->filter_ctx->output_pads, + cur->pad_idx); + cur = cur->next; + fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL; + } + +fail: + avfilter_inout_free(&inputs); + avfilter_graph_free(&graph); + return ret; +} + static int insert_trim(int64_t start_time, int64_t duration, AVFilterContext **last_filter, int *pad_idx, const char *filter_name) @@ -622,7 +661,7 @@ static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter, int configure_filtergraph(FilterGraph *fg) { AVFilterInOut *inputs, *outputs, *cur; - int ret, i, init = !fg->graph, simple = !fg->graph_desc; + int ret, i, simple = !fg->graph_desc; const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter : fg->graph_desc; @@ -657,35 +696,17 @@ int configure_filtergraph(FilterGraph *fg) return AVERROR(EINVAL); } - for (cur = inputs; !simple && init && cur; cur = cur->next) - init_input_filter(fg, cur); - for (cur = inputs, i = 0; cur; cur = cur->next, i++) if ((ret = configure_input_filter(fg, fg->inputs[i], cur)) < 0) return ret; avfilter_inout_free(&inputs); - if (!init || simple) { - /* we already know the mappings between lavfi outputs and output streams, - * so we can finish the setup */ - for (cur = outputs, i = 0; cur; cur = cur->next, i++) - configure_output_filter(fg, fg->outputs[i], cur); - avfilter_inout_free(&outputs); + for (cur = outputs, i = 0; cur; cur = cur->next, i++) + configure_output_filter(fg, fg->outputs[i], cur); + avfilter_inout_free(&outputs); - if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0) - return ret; - } else { - /* wait until output mappings are processed */ - for (cur = outputs; cur;) { - GROW_ARRAY(fg->outputs, fg->nb_outputs); - if (!(fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0])))) - exit(1); - fg->outputs[fg->nb_outputs - 1]->graph = fg; - fg->outputs[fg->nb_outputs - 1]->out_tmp = cur; - cur = cur->next; - fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL; - } - } + if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0) + return ret; return 0; } diff --git a/avconv_opt.c b/avconv_opt.c index 4505a8e6a9..fbac91f441 100644 --- a/avconv_opt.c +++ b/avconv_opt.c @@ -1367,8 +1367,7 @@ static void init_output_filter(OutputFilter *ofilter, OptionsContext *o, { OutputStream *ost; - switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads, - ofilter->out_tmp->pad_idx)) { + switch (ofilter->type) { case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break; case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break; default: @@ -1389,13 +1388,21 @@ static void init_output_filter(OutputFilter *ofilter, OptionsContext *o, exit_program(1); } - if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) { - av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n"); - exit_program(1); - } avfilter_inout_free(&ofilter->out_tmp); } +static int init_complex_filters(void) +{ + int i, ret = 0; + + for (i = 0; i < nb_filtergraphs; i++) { + ret = init_complex_filtergraph(filtergraphs[i]); + if (ret < 0) + return ret; + } + return 0; +} + static int configure_complex_filters(void) { int i, ret = 0; @@ -1471,8 +1478,7 @@ static int open_output_file(OptionsContext *o, const char *filename) if (!ofilter->out_tmp || ofilter->out_tmp->name) continue; - switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads, - ofilter->out_tmp->pad_idx)) { + switch (ofilter->type) { case AVMEDIA_TYPE_VIDEO: o->video_disable = 1; break; case AVMEDIA_TYPE_AUDIO: o->audio_disable = 1; break; case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break; @@ -2228,9 +2234,9 @@ int avconv_parse_options(int argc, char **argv) } /* create the complex filtergraphs */ - ret = configure_complex_filters(); + ret = init_complex_filters(); if (ret < 0) { - av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n"); + av_log(NULL, AV_LOG_FATAL, "Error initializing complex filters.\n"); goto fail; } @@ -2241,6 +2247,13 @@ int avconv_parse_options(int argc, char **argv) goto fail; } + /* configure the complex filtergraphs */ + ret = configure_complex_filters(); + if (ret < 0) { + av_log(NULL, AV_LOG_FATAL, "Error configuring complex filters.\n"); + goto fail; + } + fail: uninit_parse_context(&octx); if (ret < 0) {