PR #21098 opened by hwmin URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21098 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21098.patch
This is a PR for review for [fps overloads system when there is a huge timestamp jump between two samples](https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/21039). The code propose to limit the filter's frame duplication to a user defined limit, arbitrarily set to 360 (6s @ 60fps) by default. Setting this value to less than 1 (one) will deactivate the feature. >From 926c504a3d8fd1648a24bab897f0c5baa93ea038 Mon Sep 17 00:00:00 2001 From: Wai-Ming Ho <[email protected]> Date: Thu, 4 Dec 2025 11:17:23 +0100 Subject: [PATCH] Limit fps frame filling --- libavfilter/vf_fps.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index 0257a8ef78..32b7148d05 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -96,6 +96,7 @@ typedef struct FPSContext { int frames_out; ///< number of frames on output int dup; ///< number of frames duplicated int drop; ///< number of framed dropped + int max_fill; ///< number of frames to fill when gap in timestamp } FPSContext; #define OFFSET(x) offsetof(FPSContext, x) @@ -113,6 +114,8 @@ static const AVOption fps_options[] = { { "eof_action", "action performed for last frame", OFFSET(eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_ROUND }, 0, EOF_ACTION_NB-1, V|F, .unit = "eof_action" }, { "round", "round similar to other frames", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ROUND }, 0, 0, V|F, .unit = "eof_action" }, { "pass", "pass through last frame", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, 0, 0, V|F, .unit = "eof_action" }, + // default max fill arbitrarily set to 6s @ 60fps + { "max_fill", "Max frames to fill when timestamp jumps forward", OFFSET(max_fill), AV_OPT_TYPE_INT, { .i64 = 360 }, -1, INT_MAX, V|F, "Maximum fill" }, { NULL } }; @@ -221,8 +224,7 @@ static int config_props(AVFilterLink* outlink) return ret; } - av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d\n", ol->frame_rate.num, ol->frame_rate.den); - + av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d max_fill=%d\n", ol->frame_rate.num, ol->frame_rate.den, s->max_fill); return 0; } @@ -288,7 +290,8 @@ static int write_frame(AVFilterContext *ctx, FPSContext *s, AVFilterLink *outlin * - If we have status (EOF) set, drop frames when we hit the * status timestamp. */ if ((s->frames_count == 2 && s->frames[1]->pts <= s->next_pts) || - (s->status && s->status_pts <= s->next_pts)) { + (s->status && s->status_pts <= s->next_pts) || + (s->max_fill > 0 && s->cur_frame_out >= s->max_fill)) { frame = shift_frame(ctx, s); av_frame_free(&frame); @@ -366,6 +369,8 @@ static int activate(AVFilterContext *ctx) /* Couldn't generate a frame, so schedule us to perform another step */ if (again && ff_inoutlink_check_flow(inlink, outlink)) ff_filter_set_ready(ctx, 100); + else if (AVERROR_EOF == s->status) /* EOF and not filling frames */ + ff_outlink_set_status(outlink, s->status, s->next_pts); return ret; } -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
