| @@ -44,6 +44,7 @@ | |||||
| #include "audio.h" | #include "audio.h" | ||||
| #include "avfilter.h" | #include "avfilter.h" | ||||
| #include "filters.h" | |||||
| #include "formats.h" | #include "formats.h" | ||||
| #include "internal.h" | #include "internal.h" | ||||
| #include "video.h" | #include "video.h" | ||||
| @@ -97,7 +98,6 @@ static const AVOption movie_options[]= { | |||||
| }; | }; | ||||
| static int movie_config_output_props(AVFilterLink *outlink); | static int movie_config_output_props(AVFilterLink *outlink); | ||||
| static int movie_request_frame(AVFilterLink *outlink); | |||||
| static AVStream *find_stream(void *log, AVFormatContext *avf, const char *spec) | static AVStream *find_stream(void *log, AVFormatContext *avf, const char *spec) | ||||
| { | { | ||||
| @@ -309,7 +309,6 @@ static av_cold int movie_common_init(AVFilterContext *ctx) | |||||
| if (!pad.name) | if (!pad.name) | ||||
| return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
| pad.config_props = movie_config_output_props; | pad.config_props = movie_config_output_props; | ||||
| pad.request_frame = movie_request_frame; | |||||
| if ((ret = ff_insert_outpad(ctx, i, &pad)) < 0) { | if ((ret = ff_insert_outpad(ctx, i, &pad)) < 0) { | ||||
| av_freep(&pad.name); | av_freep(&pad.name); | ||||
| return ret; | return ret; | ||||
| @@ -595,17 +594,33 @@ static int movie_push_frame(AVFilterContext *ctx, unsigned out_id) | |||||
| return pkt_out_id == out_id; | return pkt_out_id == out_id; | ||||
| } | } | ||||
| static int movie_request_frame(AVFilterLink *outlink) | |||||
| static int activate(AVFilterContext *ctx) | |||||
| { | { | ||||
| AVFilterContext *ctx = outlink->src; | |||||
| unsigned out_id = FF_OUTLINK_IDX(outlink); | |||||
| int ret; | |||||
| MovieContext *movie = ctx->priv; | |||||
| int nb_eofs = 0; | |||||
| for (int i = 0; i < ctx->nb_outputs; i++) { | |||||
| AVFilterLink *outlink = ctx->outputs[i]; | |||||
| nb_eofs += !!ff_outlink_get_status(outlink); | |||||
| if (ff_outlink_frame_wanted(outlink)) { | |||||
| int ret = movie_push_frame(ctx, i); | |||||
| while (1) { | |||||
| ret = movie_push_frame(ctx, out_id); | |||||
| if (ret) | |||||
| return FFMIN(ret, 0); | |||||
| if (ret == AVERROR_EOF) { | |||||
| ff_outlink_set_status(outlink, AVERROR_EOF, movie->st[i].last_pts); | |||||
| return 0; | |||||
| } else if (ret) { | |||||
| return FFMIN(ret, 0); | |||||
| } | |||||
| } | |||||
| } | |||||
| if (nb_eofs != ctx->nb_outputs) { | |||||
| ff_filter_set_ready(ctx, 100); | |||||
| return 0; | |||||
| } | } | ||||
| return FFERROR_NOT_READY; | |||||
| } | } | ||||
| static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, | static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, | ||||
| @@ -666,6 +681,7 @@ AVFilter ff_avsrc_movie = { | |||||
| .inputs = NULL, | .inputs = NULL, | ||||
| .outputs = NULL, | .outputs = NULL, | ||||
| .activate = activate, | |||||
| .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS, | .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS, | ||||
| .process_command = process_command | .process_command = process_command | ||||
| }; | }; | ||||
| @@ -687,6 +703,7 @@ AVFilter ff_avsrc_amovie = { | |||||
| .inputs = NULL, | .inputs = NULL, | ||||
| .outputs = NULL, | .outputs = NULL, | ||||
| .activate = activate, | |||||
| .priv_class = &amovie_class, | .priv_class = &amovie_class, | ||||
| .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS, | .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS, | ||||
| .process_command = process_command, | .process_command = process_command, | ||||