mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02: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)
|
if (link->closed)
|
||||||
return AVERROR_EOF;
|
return AVERROR_EOF;
|
||||||
|
av_assert0(!link->frame_requested);
|
||||||
|
link->frame_requested = 1;
|
||||||
|
while (link->frame_requested) {
|
||||||
|
/* TODO reindent */
|
||||||
if (link->srcpad->request_frame)
|
if (link->srcpad->request_frame)
|
||||||
ret = link->srcpad->request_frame(link);
|
ret = link->srcpad->request_frame(link);
|
||||||
else if (link->src->inputs[0])
|
else if (link->src->inputs[0])
|
||||||
@ -332,8 +336,15 @@ int ff_request_frame(AVFilterLink *link)
|
|||||||
link->partial_buf = NULL;
|
link->partial_buf = NULL;
|
||||||
ret = ff_filter_frame_framed(link, pbuf);
|
ret = ff_filter_frame_framed(link, pbuf);
|
||||||
}
|
}
|
||||||
if (ret == AVERROR_EOF)
|
if (ret < 0) {
|
||||||
link->closed = 1;
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -702,6 +713,7 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame)
|
|||||||
|
|
||||||
pts = out->pts;
|
pts = out->pts;
|
||||||
ret = filter_frame(link, out);
|
ret = filter_frame(link, out);
|
||||||
|
link->frame_requested = 0;
|
||||||
ff_update_link_current_pts(link, pts);
|
ff_update_link_current_pts(link, pts);
|
||||||
return ret;
|
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 nb_channels = av_frame_get_channels(frame);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
link->flags |= FF_LINK_FLAG_REQUEST_LOOP;
|
||||||
/* Handle framing (min_samples, max_samples) */
|
/* Handle framing (min_samples, max_samples) */
|
||||||
while (insamples) {
|
while (insamples) {
|
||||||
if (!pbuf) {
|
if (!pbuf) {
|
||||||
|
@ -682,6 +682,17 @@ struct AVFilterLink {
|
|||||||
* Number of channels.
|
* Number of channels.
|
||||||
*/
|
*/
|
||||||
int 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);
|
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 */
|
#endif /* AVFILTER_INTERNAL_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user