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

Submitted by Derek Buitenhuis on Oct. 4, 2016, 8:21 p.m.

Details

Message ID 1475612489-35802-1-git-send-email-derek.buitenhuis@gmail.com
State New
Headers show

Commit Message

Derek Buitenhuis Oct. 4, 2016, 8:21 p.m.
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@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(-)

Patch hide | download patch | download mbox

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;
     }