* commit '6d592fbd0d8e89ecade3fc93b36ea200213dc01c': avconv: split creating and (re-)configuring complex filtergraphs Conflicts: ffmpeg_filter.c ffmpeg_opt.c Merged-by: Michael Niedermayer <michael@niedermayer.cc>tags/n2.8
| @@ -2765,11 +2765,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; | |||
| @@ -229,6 +229,7 @@ typedef struct OutputFilter { | |||
| /* temporary storage until stream maps are processed */ | |||
| AVFilterInOut *out_tmp; | |||
| enum AVMediaType type; | |||
| } OutputFilter; | |||
| typedef struct FilterGraph { | |||
| @@ -536,6 +537,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 ffmpeg_parse_options(int argc, char **argv); | |||
| @@ -289,6 +289,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_program(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) | |||
| @@ -904,7 +943,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; | |||
| @@ -971,9 +1010,6 @@ 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) { | |||
| avfilter_inout_free(&inputs); | |||
| @@ -982,27 +1018,12 @@ int configure_filtergraph(FilterGraph *fg) | |||
| } | |||
| 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_program(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; | |||
| fg->reconfiguration = 1; | |||
| @@ -1782,8 +1782,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, -1); break; | |||
| case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc, -1); break; | |||
| default: | |||
| @@ -1816,13 +1815,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; | |||
| @@ -1899,8 +1906,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; | |||
| @@ -2919,9 +2925,9 @@ int ffmpeg_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; | |||
| } | |||
| @@ -2932,6 +2938,13 @@ int ffmpeg_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) { | |||