mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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>
This commit is contained in:
parent
c6314cd750
commit
eea64ef4cf
@ -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…
Reference in New Issue
Block a user