vf_fps: when reading EOF, using current_pts to duplicate the last frame if needed.

Fix ticket #2674
Tested with examples from ticket 2674.

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
pull/273/head
Thierry Foucu 7 years ago committed by Michael Niedermayer
parent c6314cd750
commit eea64ef4cf
  1. 44
      libavfilter/vf_fps.c
  2. 6
      tests/ref/fate/filter-fps
  3. 4
      tests/ref/fate/filter-fps-r
  4. 1
      tests/ref/fate/filter-mpdecimate
  5. 1
      tests/ref/fate/m4v-cfr

@ -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,45 @@ 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++;
}
} 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;
}

@ -85,3 +85,9 @@
0, 79, 79, 1, 30576, 0xa2fcd06f
0, 80, 80, 1, 30576, 0xa2fcd06f
0, 81, 81, 1, 30576, 0xd4150aad
0, 82, 82, 1, 30576, 0xd4150aad
0, 83, 83, 1, 30576, 0xd4150aad
0, 84, 84, 1, 30576, 0xd4150aad
0, 85, 85, 1, 30576, 0xd4150aad
0, 86, 86, 1, 30576, 0xd4150aad
0, 87, 87, 1, 30576, 0xd4150aad

@ -72,3 +72,7 @@
0, 79, 79, 1, 30576, 0xa2fcd06f
0, 80, 80, 1, 30576, 0xa2fcd06f
0, 82, 82, 1, 30576, 0xd4150aad
0, 83, 83, 1, 30576, 0xd4150aad
0, 84, 84, 1, 30576, 0xd4150aad
0, 85, 85, 1, 30576, 0xd4150aad
0, 86, 86, 1, 30576, 0xd4150aad

@ -22,4 +22,3 @@
0, 24, 24, 1, 115200, 0x056d40ca
0, 26, 26, 1, 115200, 0xa4374737
0, 27, 27, 1, 115200, 0x3eaa3ae8
0, 29, 29, 1, 115200, 0x7551e9ee

@ -44,4 +44,3 @@
0, 38, 38, 1, 115200, 0xf30825d5
0, 39, 39, 1, 115200, 0xe3c944a1
0, 40, 40, 1, 115200, 0x8fec4420
0, 41, 41, 1, 115200, 0x9381fdab

Loading…
Cancel
Save