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.
Showing the changes to libavfilter/avfilter.c (1 of 3 files). Show all
Unified · Split
| @@ -323,6 +323,10 @@ int ff_request_frame(AVFilterLink *link) · 322 unmodified lines | |||
| 323 | 323 | ||
| 324 | if (link->closed) | 324 | if (link->closed) |
| 325 | return AVERROR_EOF; | 325 | return AVERROR_EOF; |
| 326 | av_assert0(!link->frame_requested); | ||
| 327 | link->frame_requested = 1; | ||
| 328 | while (link->frame_requested) { | ||
| 329 | /* TODO reindent */ | ||
| 326 | if (link->srcpad->request_frame) | 330 | if (link->srcpad->request_frame) |
| 327 | ret = link->srcpad->request_frame(link); | 331 | ret = link->srcpad->request_frame(link); |
| 328 | else if (link->src->inputs[0]) | 332 | else if (link->src->inputs[0]) |
| @@ -332,8 +336,15 @@ int ff_request_frame(AVFilterLink *link) · 3 unmodified lines | |||
| 332 | link->partial_buf = NULL; | 336 | link->partial_buf = NULL; |
| 333 | ret = ff_filter_frame_framed(link, pbuf); | 337 | ret = ff_filter_frame_framed(link, pbuf); |
| 334 | } | 338 | } |
| 335 | if (ret == AVERROR_EOF) | 339 | if (ret < 0) { |
| 336 | link->closed = 1; | 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 | } | ||
| 337 | return ret; | 348 | return ret; |
| 338 | } | 349 | } |
| 339 | 350 | ||
| @@ -702,6 +713,7 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame) · 362 unmodified lines | |||
| 702 | 713 | ||
| 703 | pts = out->pts; | 714 | pts = out->pts; |
| 704 | ret = filter_frame(link, out); | 715 | ret = filter_frame(link, out); |
| 716 | link->frame_requested = 0; | ||
| 705 | ff_update_link_current_pts(link, pts); | 717 | ff_update_link_current_pts(link, pts); |
| 706 | return ret; | 718 | return ret; |
| 707 | } | 719 | } |
| @@ -713,6 +725,7 @@ static int ff_filter_frame_needs_framing(AVFilterLink *link, AVFrame *frame) · 5 unmodified lines | |||
| 713 | int nb_channels = av_frame_get_channels(frame); | 725 | int nb_channels = av_frame_get_channels(frame); |
| 714 | int ret = 0; | 726 | int ret = 0; |
| 715 | 727 | ||
| 728 | link->flags |= FF_LINK_FLAG_REQUEST_LOOP; | ||
| 716 | /* Handle framing (min_samples, max_samples) */ | 729 | /* Handle framing (min_samples, max_samples) */ |
| 717 | while (insamples) { | 730 | while (insamples) { |
| 718 | if (!pbuf) { | 731 | if (!pbuf) { |