History

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.

Nicolas George committed 13 years ago

Commit 79d8cfa1 parent c2085763 files · +40 −2Browse files

Unified · Split

3 files
  1. libavfilter/avfilter.c +15 −2
  2. libavfilter/avfilter.h +11 −0
  3. libavfilter/internal.h +14 −0
libavfilter/avfilter.c+15−2
@@ -323,6 +323,10 @@ int ff_request_frame(AVFilterLink *link) · 322 unmodified lines
323323
324324 if (link->closed)
325325 return AVERROR_EOF;
326+ av_assert0(!link->frame_requested);
327+ link->frame_requested = 1;
328+ while (link->frame_requested) {
329+ /* TODO reindent */
326330 if (link->srcpad->request_frame)
327331 ret = link->srcpad->request_frame(link);
328332 else if (link->src->inputs[0])
@@ -332,8 +336,15 @@ int ff_request_frame(AVFilterLink *link) · 3 unmodified lines
332336 link->partial_buf = NULL;
333337 ret = ff_filter_frame_framed(link, pbuf);
334338 }
335− if (ret == AVERROR_EOF)
336− link->closed = 1;
339+ if (ret < 0) {
340+ link->frame_requested = 0;
341+ if (ret == AVERROR_EOF)
342+ link->closed = 1;
343+ } else {
344+ av_assert0(!link->frame_requested ||
345+ link->flags & FF_LINK_FLAG_REQUEST_LOOP);
346+ }
347+ }
337348 return ret;
338349 }
339350
@@ -702,6 +713,7 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame) · 362 unmodified lines
702713
703714 pts = out->pts;
704715 ret = filter_frame(link, out);
716+ link->frame_requested = 0;
705717 ff_update_link_current_pts(link, pts);
706718 return ret;
707719 }
@@ -713,6 +725,7 @@ static int ff_filter_frame_needs_framing(AVFilterLink *link, AVFrame *frame) · 5 unmodified lines
713725 int nb_channels = av_frame_get_channels(frame);
714726 int ret = 0;
715727
728+ link->flags |= FF_LINK_FLAG_REQUEST_LOOP;
716729 /* Handle framing (min_samples, max_samples) */
717730 while (insamples) {
718731 if (!pbuf) {
libavfilter/avfilter.h+11−0
@@ -682,6 +682,17 @@ struct AVFilterLink { · 681 unmodified lines
682682 * Number of channels.
683683 */
684684 int channels;
685+
686+ /**
687+ * True if a frame is being requested on the link.
688+ * Used internally by the framework.
689+ */
690+ unsigned frame_requested;
691+
692+ /**
693+ * Link processing flags.
694+ */
695+ unsigned flags;
685696 };
686697
687698 /**
libavfilter/internal.h+14−0
@@ -325,4 +325,18 @@ int ff_buffersink_read_samples_compat(AVFilterContext *ctx, AVFilterBufferRef ** · 324 unmodified lines
325325 */
326326 int ff_filter_frame(AVFilterLink *link, AVFrame *frame);
327327
328+/**
329+ * Flags for AVFilterLink.flags.
330+ */
331+enum {
332+
333+ /**
334+ * Frame requests may need to loop in order to be fulfilled.
335+ * A filter must set this flags on an output link if it may return 0 in
336+ * request_frame() without filtering a frame.
337+ */
338+ FF_LINK_FLAG_REQUEST_LOOP = 1,
339+
340+};
341+
328342 #endif /* AVFILTER_INTERNAL_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t