[FFmpeg-devel] [PATCH 5/5] lavfi/vf_fps: accept EOF timestamp.
Nicolas George
george at nsup.org
Sun Aug 3 15:15:40 CEST 2014
This makes the FPS filter duplicate the last frame to take
its duration into account, exactly like the other ones.
Fix trac ticket #2674.
Signed-off-by: Nicolas George <george at nsup.org>
---
libavfilter/vf_fps.c | 33 +++++++++++++++++++++++++--------
1 file changed, 25 insertions(+), 8 deletions(-)
Aded a ref to the trac ticket and fixed a corner case raised by it.
Note that the whole logic of vf_fps is overly complex, but this is for
another patch.
diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c
index a3ad1bb..5bf5bda 100644
--- a/libavfilter/vf_fps.c
+++ b/libavfilter/vf_fps.c
@@ -28,6 +28,7 @@
#include <float.h>
#include <stdint.h>
+#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/fifo.h"
#include "libavutil/mathematics.h"
@@ -150,10 +151,8 @@ static int request_frame(AVFilterLink *outlink)
while (ret >= 0 && s->frames_out == frames_out)
ret = ff_request_frame(ctx->inputs[0]);
-
- /* flush the fifo */
- if (ret == AVERROR_EOF && av_fifo_size(s->fifo))
- return flush_fifo_to_out(ctx);
+ if (ret == AVERROR_EOF)
+ av_assert1(!av_fifo_size(s->fifo));
return ret;
}
@@ -161,6 +160,7 @@ static int write_to_fifo(AVFifoBuffer *fifo, AVFrame *buf)
{
int ret;
+ av_assert1(buf->format >= 0);
if (!av_fifo_space(fifo) &&
(ret = av_fifo_realloc2(fifo, 2*av_fifo_size(fifo)))) {
av_frame_free(&buf);
@@ -198,6 +198,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
} else {
s->first_pts = buf->pts;
}
+ } else if (buf->format < 0) {
+ return 0;
} else {
av_log(ctx, AV_LOG_WARNING, "Discarding initial frame(s) with no "
"timestamp.\n");
@@ -207,8 +209,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
return 0;
}
+ if (buf->format < 0) {
+ if (buf->format != FF_METAFRAME_EOF)
+ return 0;
+ if (buf->pts == AV_NOPTS_VALUE)
+ return flush_fifo_to_out(ctx);
+ if (!av_fifo_size(s->fifo))
+ return 0;
+ }
+
/* now wait for the next timestamp */
if (buf->pts == AV_NOPTS_VALUE || av_fifo_size(s->fifo) <= 0) {
+ av_assert1(buf->format >= 0);
return write_to_fifo(s->fifo, buf);
}
@@ -226,10 +238,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
av_fifo_generic_read(s->fifo, &tmp, sizeof(tmp), NULL);
flush_fifo(s->fifo);
- ret = write_to_fifo(s->fifo, tmp);
- av_frame_free(&buf);
- return ret;
+ if (buf->format >= 0) {
+ /* requeue last frame if not EOF */
+ ret = write_to_fifo(s->fifo, tmp);
+ av_frame_free(&buf);
+ return ret;
+ }
+ return 0;
}
/* can output >= 1 frames */
@@ -268,7 +284,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
}
flush_fifo(s->fifo);
- ret = write_to_fifo(s->fifo, buf);
+ ret = buf->format < 0 ? 0 : write_to_fifo(s->fifo, buf);
return ret;
}
@@ -299,6 +315,7 @@ AVFilter ff_vf_fps = {
.uninit = uninit,
.priv_size = sizeof(FPSContext),
.priv_class = &fps_class,
+ .flags = FF_FILTER_FLAG_SUPPORT_METAFRAMES,
.inputs = avfilter_vf_fps_inputs,
.outputs = avfilter_vf_fps_outputs,
};
--
2.0.1
More information about the ffmpeg-devel
mailing list