diff --git a/doc/filter_design.txt b/doc/filter_design.txt index d784d8471e..e8a7c53ee9 100644 --- a/doc/filter_design.txt +++ b/doc/filter_design.txt @@ -232,7 +232,8 @@ Frame scheduling one of its inputs, repeatedly until at least one frame has been pushed. Return values: - if request_frame could produce a frame, it should return 0; + if request_frame could produce a frame, or at least make progress + towards producing a frame, it should return 0; if it could not for temporary reasons, it should return AVERROR(EAGAIN); if it could not because there are no more frames, it should return AVERROR_EOF. @@ -244,20 +245,18 @@ Frame scheduling push_one_frame(); return 0; } - while (!frame_pushed) { - input = input_where_a_frame_is_most_needed(); - ret = ff_request_frame(input); - if (ret == AVERROR_EOF) { - process_eof_on_input(); - } else if (ret < 0) { - return ret; - } + input = input_where_a_frame_is_most_needed(); + ret = ff_request_frame(input); + if (ret == AVERROR_EOF) { + process_eof_on_input(); + } else if (ret < 0) { + return ret; } return 0; Note that, except for filters that can have queued frames, request_frame does not push frames: it requests them to its input, and as a reaction, - the filter_frame method will be called and do the work. + the filter_frame method possibly will be called and do the work. Legacy API ========== diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 7da6cf2643..b9fadb3d59 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -347,9 +347,7 @@ int ff_request_frame(AVFilterLink *link) if (link->closed) return AVERROR_EOF; - av_assert0(!link->frame_requested); - link->frame_requested = 1; - while (link->frame_requested) { + // TODO reindent if (link->srcpad->request_frame) ret = link->srcpad->request_frame(link); else if (link->src->inputs[0]) @@ -360,14 +358,9 @@ int ff_request_frame(AVFilterLink *link) ret = ff_filter_frame_framed(link, pbuf); } if (ret < 0) { - link->frame_requested = 0; if (ret == AVERROR_EOF) link->closed = 1; - } else { - av_assert0(!link->frame_requested || - link->flags & FF_LINK_FLAG_REQUEST_LOOP); } - } return ret; } @@ -1088,7 +1081,6 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame) } ret = filter_frame(link, out); link->frame_count++; - link->frame_requested = 0; ff_update_link_current_pts(link, pts); return ret; diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 642aa834ab..5d4cd6ce12 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -499,12 +499,6 @@ struct AVFilterLink { */ int channels; - /** - * True if a frame is being requested on the link. - * Used internally by the framework. - */ - unsigned frame_requested; - /** * Link processing flags. */ diff --git a/libavfilter/internal.h b/libavfilter/internal.h index 7816654010..1454112433 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -102,9 +102,9 @@ struct AVFilterPad { int (*poll_frame)(AVFilterLink *link); /** - * Frame request callback. A call to this should result in at least one - * frame being output over the given link. This should return zero on - * success, and another value on error. + * Frame request callback. A call to this should result in some progress + * towards producing output over the given link. This should return zero + * on success, and another value on error. * * Output pads only. */ @@ -291,8 +291,11 @@ int ff_poll_frame(AVFilterLink *link); * caller (generally eventually a user application) as this step may (but does * not have to be) necessary to provide the input with the next frame. * - * If a request is successful then the filter_frame() function will be called - * at least once before ff_request_frame() returns + * If a request is successful then some progress has been made towards + * providing a frame on the link (through ff_filter_frame()). A filter that + * needs several frames to produce one is allowed to return success if one + * more frame has been processed but no output has been produced yet. A + * filter is also allowed to simply forward a success return value. * * @param link the input link * @return zero on success