[FFmpeg-devel] [PATCH] vf_fps: Don't flush a cached frame if it should have been dropped

Derek Buitenhuis derek.buitenhuis at gmail.com
Tue Oct 4 23:21:29 EEST 2016


This fixes downconverting framerates to multiples.

For example, prior to this patch, converting 900 frames at 60 fps
to 30 fps would output 451 frames instead of the correct 450.

Signed-off-by: Derek Buitenhuis <derek.buitenhuis at gmail.com>
---
DISCLAIMER: I don't know libavfilter very well, and I am not
sure this is the correct fix to the problem. Comments definitely
welcome.

Also, I would be happy if any replies could be CC'd to me.

Thanks,
  Derek
---
 libavfilter/vf_fps.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c
index 20ccd79..b6df968 100644
--- a/libavfilter/vf_fps.c
+++ b/libavfilter/vf_fps.c
@@ -135,15 +135,21 @@ static int request_frame(AVFilterLink *outlink)
         int i;
         for (i = 0; av_fifo_size(s->fifo); i++) {
             AVFrame *buf;
+            int64_t delta;
 
             av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL);
             buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base,
                                     outlink->time_base) + s->frames_out;
 
-            if ((ret = ff_filter_frame(outlink, buf)) < 0)
-                return ret;
+            /* number of output frames */
+            delta = av_rescale_q_rnd(buf->pts - s->first_pts, ctx->inputs[0]->time_base,
+                                     outlink->time_base, s->rounding) - s->frames_out ;
+            if (delta >= 0) {
+                if ((ret = ff_filter_frame(outlink, buf)) < 0)
+                    return ret;
 
-            s->frames_out++;
+                s->frames_out++;
+            }
         }
         return 0;
     }
-- 
1.8.3.1



More information about the ffmpeg-devel mailing list