* a filter enforcing given constant framerate
*/
+#include "libavutil/common.h"
#include "libavutil/fifo.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base,
outlink->time_base) + s->frames_out;
- ff_start_frame(outlink, buf);
- ff_draw_slice(outlink, 0, outlink->h, 1);
- ff_end_frame(outlink);
+ if ((ret = ff_start_frame(outlink, buf)) < 0 ||
+ (ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 ||
+ (ret = ff_end_frame(outlink)) < 0)
+ return ret;
+
s->frames_out++;
}
return 0;
int ret;
if (!av_fifo_space(fifo) &&
- (ret = av_fifo_realloc2(fifo, 2*av_fifo_size(fifo))))
+ (ret = av_fifo_realloc2(fifo, 2*av_fifo_size(fifo)))) {
+ avfilter_unref_bufferp(&buf);
return ret;
+ }
av_fifo_generic_write(fifo, &buf, sizeof(buf), NULL);
return 0;
}
-static void end_frame(AVFilterLink *inlink)
+static int end_frame(AVFilterLink *inlink)
{
AVFilterContext *ctx = inlink->dst;
FPSContext *s = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0];
AVFilterBufferRef *buf = inlink->cur_buf;
int64_t delta;
- int i;
+ int i, ret;
inlink->cur_buf = NULL;
s->frames_in++;
/* discard frames until we get the first timestamp */
if (s->pts == AV_NOPTS_VALUE) {
if (buf->pts != AV_NOPTS_VALUE) {
- write_to_fifo(s->fifo, buf);
+ ret = write_to_fifo(s->fifo, buf);
+ if (ret < 0)
+ return ret;
+
s->first_pts = s->pts = buf->pts;
} else {
av_log(ctx, AV_LOG_WARNING, "Discarding initial frame(s) with no "
avfilter_unref_buffer(buf);
s->drop++;
}
- return;
+ return 0;
}
/* now wait for the next timestamp */
if (buf->pts == AV_NOPTS_VALUE) {
- write_to_fifo(s->fifo, buf);
- return;
+ return write_to_fifo(s->fifo, buf);
}
/* number of output frames */
av_fifo_generic_read(s->fifo, &tmp, sizeof(tmp), NULL);
flush_fifo(s->fifo);
- write_to_fifo(s->fifo, tmp);
+ ret = write_to_fifo(s->fifo, tmp);
avfilter_unref_buffer(buf);
- return;
+ return ret;
}
/* can output >= 1 frames */
/* duplicate the frame if needed */
if (!av_fifo_size(s->fifo) && i < delta - 1) {
+ AVFilterBufferRef *dup = avfilter_ref_buffer(buf_out, AV_PERM_READ);
+
av_log(ctx, AV_LOG_DEBUG, "Duplicating frame.\n");
- write_to_fifo(s->fifo, avfilter_ref_buffer(buf_out, AV_PERM_READ));
+ if (dup)
+ ret = write_to_fifo(s->fifo, dup);
+ else
+ ret = AVERROR(ENOMEM);
+
+ if (ret < 0) {
+ avfilter_unref_bufferp(&buf_out);
+ avfilter_unref_bufferp(&buf);
+ return ret;
+ }
+
s->dup++;
}
buf_out->pts = av_rescale_q(s->first_pts, inlink->time_base,
outlink->time_base) + s->frames_out;
- ff_start_frame(outlink, buf_out);
- ff_draw_slice(outlink, 0, outlink->h, 1);
- ff_end_frame(outlink);
+ if ((ret = ff_start_frame(outlink, buf_out)) < 0 ||
+ (ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 ||
+ (ret = ff_end_frame(outlink)) < 0) {
+ avfilter_unref_bufferp(&buf);
+ return ret;
+ }
+
s->frames_out++;
}
flush_fifo(s->fifo);
- write_to_fifo(s->fifo, buf);
+ ret = write_to_fifo(s->fifo, buf);
s->pts = s->first_pts + av_rescale_q(s->frames_out, outlink->time_base, inlink->time_base);
+
+ return ret;
}
static int null_start_frame(AVFilterLink *link, AVFilterBufferRef *buf)