Commit 8f33810e authored by Michael Niedermayer's avatar Michael Niedermayer

avfilter/vf_fps: fix rounding error accumulation

Fixes Ticket3329
Reviewed-by: 's avatarNicolas George <george@nsup.org>
Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent c849b00b
...@@ -45,7 +45,6 @@ typedef struct FPSContext { ...@@ -45,7 +45,6 @@ typedef struct FPSContext {
/* timestamps in input timebase */ /* timestamps in input timebase */
int64_t first_pts; ///< pts of the first frame that arrived on this filter int64_t first_pts; ///< pts of the first frame that arrived on this filter
int64_t pts; ///< pts of the first frame currently in the fifo
double start_time; ///< pts, in seconds, of the expected first frame double start_time; ///< pts, in seconds, of the expected first frame
...@@ -83,7 +82,6 @@ static av_cold int init(AVFilterContext *ctx) ...@@ -83,7 +82,6 @@ static av_cold int init(AVFilterContext *ctx)
if (!(s->fifo = av_fifo_alloc(2*sizeof(AVFrame*)))) if (!(s->fifo = av_fifo_alloc(2*sizeof(AVFrame*))))
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
s->pts = AV_NOPTS_VALUE;
s->first_pts = AV_NOPTS_VALUE; s->first_pts = AV_NOPTS_VALUE;
av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d\n", s->framerate.num, s->framerate.den); av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d\n", s->framerate.num, s->framerate.den);
...@@ -179,7 +177,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) ...@@ -179,7 +177,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
s->frames_in++; s->frames_in++;
/* discard frames until we get the first timestamp */ /* discard frames until we get the first timestamp */
if (s->pts == AV_NOPTS_VALUE) { if (s->first_pts == AV_NOPTS_VALUE) {
if (buf->pts != AV_NOPTS_VALUE) { if (buf->pts != AV_NOPTS_VALUE) {
ret = write_to_fifo(s->fifo, buf); ret = write_to_fifo(s->fifo, buf);
if (ret < 0) if (ret < 0)
...@@ -188,13 +186,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) ...@@ -188,13 +186,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
if (s->start_time != DBL_MAX && s->start_time != AV_NOPTS_VALUE) { if (s->start_time != DBL_MAX && s->start_time != AV_NOPTS_VALUE) {
double first_pts = s->start_time * AV_TIME_BASE; double first_pts = s->start_time * AV_TIME_BASE;
first_pts = FFMIN(FFMAX(first_pts, INT64_MIN), INT64_MAX); first_pts = FFMIN(FFMAX(first_pts, INT64_MIN), INT64_MAX);
s->first_pts = s->pts = av_rescale_q(first_pts, AV_TIME_BASE_Q, s->first_pts = av_rescale_q(first_pts, AV_TIME_BASE_Q,
inlink->time_base); inlink->time_base);
av_log(ctx, AV_LOG_VERBOSE, "Set first pts to (in:%"PRId64" out:%"PRId64")\n", av_log(ctx, AV_LOG_VERBOSE, "Set first pts to (in:%"PRId64" out:%"PRId64")\n",
s->first_pts, av_rescale_q(first_pts, AV_TIME_BASE_Q, s->first_pts, av_rescale_q(first_pts, AV_TIME_BASE_Q,
outlink->time_base)); outlink->time_base));
} else { } else {
s->first_pts = s->pts = buf->pts; s->first_pts = buf->pts;
} }
} else { } else {
av_log(ctx, AV_LOG_WARNING, "Discarding initial frame(s) with no " av_log(ctx, AV_LOG_WARNING, "Discarding initial frame(s) with no "
...@@ -211,8 +209,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) ...@@ -211,8 +209,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
} }
/* number of output frames */ /* number of output frames */
delta = av_rescale_q_rnd(buf->pts - s->pts, inlink->time_base, delta = av_rescale_q_rnd(buf->pts - s->first_pts, inlink->time_base,
outlink->time_base, s->rounding); outlink->time_base, s->rounding) - s->frames_out ;
if (delta < 1) { if (delta < 1) {
/* drop the frame and everything buffered except the first */ /* drop the frame and everything buffered except the first */
...@@ -267,7 +265,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) ...@@ -267,7 +265,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
flush_fifo(s->fifo); flush_fifo(s->fifo);
ret = write_to_fifo(s->fifo, buf); ret = write_to_fifo(s->fifo, buf);
s->pts = s->first_pts + av_rescale_q(s->frames_out, outlink->time_base, inlink->time_base);
return ret; return ret;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment