mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-26 01:02:33 +00:00
lavfi: loop on request_frame if necessary.
Some filters need several input frames before producing output. For these filter, it becomes simpler to return 0 in request_frame() and let the framework call it again until output has been produced.
This commit is contained in:
parent
c208576cef
commit
79d8cfacf0
@ -323,6 +323,10 @@ 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])
|
||||
@ -332,8 +336,15 @@ int ff_request_frame(AVFilterLink *link)
|
||||
link->partial_buf = NULL;
|
||||
ret = ff_filter_frame_framed(link, pbuf);
|
||||
}
|
||||
if (ret == AVERROR_EOF)
|
||||
link->closed = 1;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -702,6 +713,7 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame)
|
||||
|
||||
pts = out->pts;
|
||||
ret = filter_frame(link, out);
|
||||
link->frame_requested = 0;
|
||||
ff_update_link_current_pts(link, pts);
|
||||
return ret;
|
||||
}
|
||||
@ -713,6 +725,7 @@ static int ff_filter_frame_needs_framing(AVFilterLink *link, AVFrame *frame)
|
||||
int nb_channels = av_frame_get_channels(frame);
|
||||
int ret = 0;
|
||||
|
||||
link->flags |= FF_LINK_FLAG_REQUEST_LOOP;
|
||||
/* Handle framing (min_samples, max_samples) */
|
||||
while (insamples) {
|
||||
if (!pbuf) {
|
||||
|
@ -682,6 +682,17 @@ struct AVFilterLink {
|
||||
* Number of channels.
|
||||
*/
|
||||
int channels;
|
||||
|
||||
/**
|
||||
* True if a frame is being requested on the link.
|
||||
* Used internally by the framework.
|
||||
*/
|
||||
unsigned frame_requested;
|
||||
|
||||
/**
|
||||
* Link processing flags.
|
||||
*/
|
||||
unsigned flags;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -325,4 +325,18 @@ int ff_buffersink_read_samples_compat(AVFilterContext *ctx, AVFilterBufferRef **
|
||||
*/
|
||||
int ff_filter_frame(AVFilterLink *link, AVFrame *frame);
|
||||
|
||||
/**
|
||||
* Flags for AVFilterLink.flags.
|
||||
*/
|
||||
enum {
|
||||
|
||||
/**
|
||||
* Frame requests may need to loop in order to be fulfilled.
|
||||
* A filter must set this flags on an output link if it may return 0 in
|
||||
* request_frame() without filtering a frame.
|
||||
*/
|
||||
FF_LINK_FLAG_REQUEST_LOOP = 1,
|
||||
|
||||
};
|
||||
|
||||
#endif /* AVFILTER_INTERNAL_H */
|
||||
|
Loading…
Reference in New Issue
Block a user