Index: ffmpeg.c =================================================================== --- ffmpeg.c (revision 26402) +++ ffmpeg.c (working copy) @@ -303,6 +303,15 @@ AVAudioConvert *reformat_ctx; AVFifoBuffer *fifo; /* for compression: one audio fifo per codec */ FILE *logfile; + /* placing filters on output streams context rather than on input stream context */ + /* This will make sepearte filtering contexts for each and every stream for multiple stream outputs */ +#if CONFIG_AVFILTER + AVFilterContext *output_video_filter; + AVFilterContext *input_video_filter; + AVFrame *filter_frame; + int has_filter_frame; + AVFilterBufferRef *picref; +#endif } AVOutputStream; static AVOutputStream **output_streams_for_file[MAX_FILES] = { NULL }; @@ -324,13 +333,6 @@ int is_start; /* is 1 at the start and after a discontinuity */ int showed_multi_packet_warning; int is_past_recording_time; -#if CONFIG_AVFILTER - AVFilterContext *output_video_filter; - AVFilterContext *input_video_filter; - AVFrame *filter_frame; - int has_filter_frame; - AVFilterBufferRef *picref; -#endif } AVInputStream; typedef struct AVInputFile { @@ -347,7 +349,7 @@ #endif #if CONFIG_AVFILTER - +/* filter context is put on AVOutputStream instead of AVInputStream */ static int configure_filters(AVInputStream *ist, AVOutputStream *ost) { AVFilterContext *last_filter, *filter; @@ -362,15 +364,15 @@ snprintf(args, 255, "%d:%d:%d:%d:%d", ist->st->codec->width, ist->st->codec->height, ist->st->codec->pix_fmt, 1, AV_TIME_BASE); - ret = avfilter_graph_create_filter(&ist->input_video_filter, avfilter_get_by_name("buffer"), + ret = avfilter_graph_create_filter(&ost->input_video_filter, avfilter_get_by_name("buffer"), "src", args, NULL, graph); if (ret < 0) return ret; - ret = avfilter_graph_create_filter(&ist->output_video_filter, &ffsink, + ret = avfilter_graph_create_filter(&ost->output_video_filter, &ffsink, "out", NULL, &ffsink_ctx, graph); if (ret < 0) return ret; - last_filter = ist->input_video_filter; + last_filter = ost->input_video_filter; if (codec->width != icodec->width || codec->height != icodec->height) { snprintf(args, 255, "%d:%d:flags=0x%X", @@ -398,7 +400,7 @@ outputs->next = NULL; inputs->name = av_strdup("out"); - inputs->filter_ctx = ist->output_video_filter; + inputs->filter_ctx = ost->output_video_filter; inputs->pad_idx = 0; inputs->next = NULL; @@ -406,15 +408,15 @@ return ret; av_freep(&vfilters); } else { - if ((ret = avfilter_link(last_filter, 0, ist->output_video_filter, 0)) < 0) + if ((ret = avfilter_link(last_filter, 0, ost->output_video_filter, 0)) < 0) return ret; } if ((ret = avfilter_graph_config(graph, NULL)) < 0) return ret; - codec->width = ist->output_video_filter->inputs[0]->w; - codec->height = ist->output_video_filter->inputs[0]->h; + codec->width = ost->output_video_filter->inputs[0]->w; + codec->height = ost->output_video_filter->inputs[0]->h; return 0; } @@ -1470,7 +1472,7 @@ AVSubtitle subtitle, *subtitle_to_free; int64_t pkt_pts = AV_NOPTS_VALUE; #if CONFIG_AVFILTER - int frame_available; + AVRational ist_pts_tb; #endif AVPacket avpkt; @@ -1606,12 +1608,16 @@ } #if CONFIG_AVFILTER - if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->input_video_filter) { - // add it to be filtered - av_vsrc_buffer_add_frame(ist->input_video_filter, &picture, + // add it to be filtered on every output video stream + if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO){ + for(i=0;ist->codec->codec_type == AVMEDIA_TYPE_VIDEO && ost->input_video_filter) + av_vsrc_buffer_add_frame(ost->input_video_filter, &picture, ist->pts, ist->st->codec->sample_aspect_ratio); } + } #endif // preprocess audio (volume) @@ -1635,21 +1641,10 @@ if (pts > now) usleep(pts - now); } -#if CONFIG_AVFILTER - frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || - !ist->output_video_filter || avfilter_poll_frame(ist->output_video_filter->inputs[0]); -#endif /* if output time reached then transcode raw format, encode packets and output them */ if (start_time == 0 || ist->pts >= start_time) -#if CONFIG_AVFILTER - while (frame_available) { - AVRational ist_pts_tb; - if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->output_video_filter) - get_filtered_video_frame(ist->output_video_filter, &picture, &ist->picref, &ist_pts_tb); - if (ist->picref) - ist->pts = av_rescale_q(ist->picref->pts, ist_pts_tb, AV_TIME_BASE_Q); -#endif + for(i=0;ipicref->video) - ost->st->codec->sample_aspect_ratio = ist->picref->video->pixel_aspect; + if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ost->output_video_filter) + get_filtered_video_frame(ost->output_video_filter, &picture, &ost->picref, &ist_pts_tb); + if (ost->picref) + ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q); + if (ost->picref->video) + ost->st->codec->sample_aspect_ratio = ost->picref->video->pixel_aspect; #endif do_video_out(os, ost, ist, &picture, &frame_size); +#if CONFIG_AVFILTER + if(ost->picref) + avfilter_unref_buffer(ost->picref); +#endif if (vstats_filename && frame_size) do_video_stats(os, ost, frame_size); break; @@ -1741,13 +1744,6 @@ } } -#if CONFIG_AVFILTER - frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) && - ist->output_video_filter && avfilter_poll_frame(ist->output_video_filter->inputs[0]); - if(ist->picref) - avfilter_unref_buffer(ist->picref); - } -#endif av_free(buffer_to_free); /* XXX: allocate the subtitles in the codec ? */ if (subtitle_to_free) {