X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_fps.c;h=1e5d07e31c14877512b33dd7ffe94b3167744359;hb=42f27d1b8eab9ea88d2e9faeb35f72dd72eca7b4;hp=20ccd797d10d3a48de77c6c75c5901ca3435591e;hpb=aec4812cb3b35e1ceb68e8cdd15e80e5c91ab768;p=ffmpeg diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index 20ccd797d10..1e5d07e31c1 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -34,6 +34,8 @@ #include "libavutil/opt.h" #include "libavutil/parseutils.h" +#define FF_INTERNAL_FIELDS 1 +#include "framequeue.h" #include "avfilter.h" #include "internal.h" #include "video.h" @@ -137,13 +139,46 @@ static int request_frame(AVFilterLink *outlink) AVFrame *buf; 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 (av_fifo_size(s->fifo)) { + 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; + if ((ret = ff_filter_frame(outlink, buf)) < 0) + return ret; - s->frames_out++; + s->frames_out++; + } else { + /* This is the last frame, we may have to duplicate it to match + * the last frame duration */ + int j; + int delta = av_rescale_q_rnd(ctx->inputs[0]->current_pts - s->first_pts, + ctx->inputs[0]->time_base, + outlink->time_base, s->rounding) - s->frames_out ; + /* if the delta is equal to 1, it means we just need to output + * the last frame. Greater than 1 means we will need duplicate + * delta-1 frames */ + if (delta > 0 ) { + for (j = 0; j < delta; j++) { + AVFrame *dup = av_frame_clone(buf); + + av_log(ctx, AV_LOG_DEBUG, "Duplicating frame.\n"); + dup->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base, + outlink->time_base) + s->frames_out; + + if ((ret = ff_filter_frame(outlink, dup)) < 0) + return ret; + + s->frames_out++; + if (j > 0) s->dup++; + } + av_frame_free(&buf); + } else { + /* for delta less or equal to 0, we should drop the frame, + * otherwise, we will have one or more extra frames */ + av_frame_free(&buf); + s->drop++; + } + } } return 0; }