aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.dev>2023-05-21 12:22:56 +0200
committerNiklas Haas <git@haasn.dev>2023-05-22 10:31:13 +0200
commitc00fd025587fc8f028cda2c36f0061070fe91a35 (patch)
tree7d0f0a569f02b4fd30d3a62f0a79f606131ebba2
parent7428f1e8f2d1ed2d43edbb240d776a39ea205512 (diff)
downloadffmpeg-c00fd025587fc8f028cda2c36f0061070fe91a35.tar.gz
lavfi/libplacebo: properly handle EOF
The current code relied on pl_queue eventually returning EOF back to the caller, which didn't work in all situations (e.g. single frame input). Also, the current code assumed that ff_inlink_acknowledge_status only fired once, which was patently not true, as the above edge cases demonstrated. Solve both issues by keeping track of the acknowledged link status and forwarding it (instead of trying to probe the pl_queue again) in the event that we run out of queued input frames, as well as (in CFR mode) when we pass the indicated status PTS.
-rw-r--r--libavfilter/vf_libplacebo.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index f26d0126be..a8904b0e6b 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -114,6 +114,8 @@ typedef struct LibplaceboContext {
/* filter state */
AVFifo *out_pts; ///< timestamps of wanted output frames
+ int64_t status_pts;
+ int status;
/* settings */
char *out_format_string;
@@ -808,19 +810,12 @@ static int libplacebo_activate(AVFilterContext *ctx)
if (ret < 0)
return ret;
- if (ff_inlink_acknowledge_status(inlink, &status, &pts)) {
+ if (!s->status && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
pts = av_rescale_q_rnd(pts, inlink->time_base, outlink->time_base,
AV_ROUND_UP);
- if (status == AVERROR_EOF) {
- /* Signal EOF to pl_queue, and enqueue this output frame to
- * make sure we see PL_QUEUE_EOF returned eventually */
- pl_queue_push(s->queue, NULL);
- if (!s->fps.num)
- av_fifo_write(s->out_pts, &pts, 1);
- } else {
- ff_outlink_set_status(outlink, status, pts);
- return 0;
- }
+ pl_queue_push(s->queue, NULL); /* Signal EOF to pl_queue */
+ s->status = status;
+ s->status_pts = pts;
}
if (ff_outlink_frame_wanted(outlink)) {
@@ -830,7 +825,17 @@ static int libplacebo_activate(AVFilterContext *ctx)
if (s->fps.num) {
pts = outlink->frame_count_out;
} else if (av_fifo_peek(s->out_pts, &pts, 1, 0) < 0) {
- ff_inlink_request_frame(inlink);
+ /* No frames queued */
+ if (s->status) {
+ pts = s->status_pts;
+ } else {
+ ff_inlink_request_frame(inlink);
+ return 0;
+ }
+ }
+
+ if (s->status && pts >= s->status_pts) {
+ ff_outlink_set_status(outlink, s->status, s->status_pts);
return 0;
}