diff options
author | Nicolas Gaullier <nicolas.gaullier@cji.paris> | 2024-10-04 11:02:49 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2024-10-13 13:54:03 +0200 |
commit | de976eaf30df33e86c58c8c9af9905c1d8441934 (patch) | |
tree | 59a515f587d84dad638b9c9aac3244cef5794c13 /libavfilter/framesync.c | |
parent | 31a63e4e011a63e3ae6dd2a02864055e29bd467a (diff) | |
download | ffmpeg-de976eaf30df33e86c58c8c9af9905c1d8441934.tar.gz |
avfilter/framesync: fix forward EOF pts
Note1: when the EOF pts is not accurate enough, the last frame
can be dropped by vf_fps with default rounding.
Note2: vf_scale use framesync since e82a3997cdd6c0894869b33ba42430ac3,
so this is a very commonplace scenario.
For example:
./ffprobe -f lavfi testsrc=d=1,scale,fps -of flat \
-count_frames -show_entries stream=nb_read_frames
Before:
streams.stream.0.nb_read_frames="24"
After:
streams.stream.0.nb_read_frames="25"
Signed-off-by: Anton Khirnov <anton@khirnov.net>
Diffstat (limited to 'libavfilter/framesync.c')
-rw-r--r-- | libavfilter/framesync.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/libavfilter/framesync.c b/libavfilter/framesync.c index 8e06e0e700..0d5779f830 100644 --- a/libavfilter/framesync.c +++ b/libavfilter/framesync.c @@ -103,14 +103,14 @@ int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in) return 0; } -static void framesync_eof(FFFrameSync *fs) +static void framesync_eof(FFFrameSync *fs, int64_t pts) { fs->eof = 1; fs->frame_ready = 0; - ff_outlink_set_status(fs->parent->outputs[0], AVERROR_EOF, AV_NOPTS_VALUE); + ff_outlink_set_status(fs->parent->outputs[0], AVERROR_EOF, pts); } -static void framesync_sync_level_update(FFFrameSync *fs) +static void framesync_sync_level_update(FFFrameSync *fs, int64_t eof_pts) { unsigned i, level = 0; @@ -131,7 +131,7 @@ static void framesync_sync_level_update(FFFrameSync *fs) if (level) fs->sync_level = level; else - framesync_eof(fs); + framesync_eof(fs, eof_pts); } int ff_framesync_configure(FFFrameSync *fs) @@ -179,7 +179,7 @@ int ff_framesync_configure(FFFrameSync *fs) for (i = 0; i < fs->nb_in; i++) fs->in[i].pts = fs->in[i].pts_next = AV_NOPTS_VALUE; fs->sync_level = UINT_MAX; - framesync_sync_level_update(fs); + framesync_sync_level_update(fs, AV_NOPTS_VALUE); return 0; } @@ -200,7 +200,7 @@ static int framesync_advance(FFFrameSync *fs) if (fs->in[i].have_next && fs->in[i].pts_next < pts) pts = fs->in[i].pts_next; if (pts == INT64_MAX) { - framesync_eof(fs); + framesync_eof(fs, AV_NOPTS_VALUE); break; } for (i = 0; i < fs->nb_in; i++) { @@ -222,7 +222,7 @@ static int framesync_advance(FFFrameSync *fs) fs->frame_ready = 1; if (fs->in[i].state == STATE_EOF && fs->in[i].after == EXT_STOP) - framesync_eof(fs); + framesync_eof(fs, AV_NOPTS_VALUE); } } if (fs->frame_ready) @@ -255,15 +255,14 @@ static void framesync_inject_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) fs->in[in].have_next = 1; } -static void framesync_inject_status(FFFrameSync *fs, unsigned in, int status, int64_t pts) +static void framesync_inject_status(FFFrameSync *fs, unsigned in, int status, int64_t eof_pts) { av_assert0(!fs->in[in].have_next); - pts = fs->in[in].state != STATE_RUN || fs->in[in].after == EXT_INFINITY - ? INT64_MAX : framesync_pts_extrapolate(fs, in, fs->in[in].pts); fs->in[in].sync = 0; - framesync_sync_level_update(fs); + framesync_sync_level_update(fs, status == AVERROR_EOF ? eof_pts : AV_NOPTS_VALUE); fs->in[in].frame_next = NULL; - fs->in[in].pts_next = pts; + fs->in[in].pts_next = fs->in[in].state != STATE_RUN || fs->in[in].after == EXT_INFINITY + ? INT64_MAX : framesync_pts_extrapolate(fs, in, fs->in[in].pts); fs->in[in].have_next = 1; } |