From 580cf433bd3713f1c00a612be2d57d5b959e8496 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 18 Sep 2014 19:25:46 +0200 Subject: video/filter: allow better dataflow Consider a filter which turns 1 frame into 2 frames (such as an deinterlacer). Until now, we forced filters to produce all output frames at once. This was done for simplicity. Change the filter API such that a filter can produce frames incrementally. --- video/filter/vf.c | 13 +++++++++++-- video/filter/vf.h | 9 +++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/video/filter/vf.c b/video/filter/vf.c index e76d30ea23..f00e9689c6 100644 --- a/video/filter/vf.c +++ b/video/filter/vf.c @@ -379,10 +379,19 @@ void vf_add_output_frame(struct vf_instance *vf, struct mp_image *img) } } +static bool vf_has_output_frame(struct vf_instance *vf) +{ + if (!vf->num_out_queued && vf->filter_out) { + if (vf->filter_out(vf) < 0) + MP_ERR(vf, "Error filtering frame.\n"); + } + return vf->num_out_queued > 0; +} + static struct mp_image *vf_dequeue_output_frame(struct vf_instance *vf) { struct mp_image *res = NULL; - if (vf->num_out_queued) { + if (vf_has_output_frame(vf)) { res = vf->out_queued[0]; MP_TARRAY_REMOVE_AT(vf->out_queued, vf->num_out_queued, 0); } @@ -445,7 +454,7 @@ int vf_output_frame(struct vf_chain *c, bool eof) if (r < 0) return r; } - if (cur->num_out_queued) + if (vf_has_output_frame(cur)) last = cur; } if (!last) diff --git a/video/filter/vf.h b/video/filter/vf.h index 71dcb699c2..6f0985293e 100644 --- a/video/filter/vf.h +++ b/video/filter/vf.h @@ -75,6 +75,15 @@ typedef struct vf_instance { // can be used to output delayed or otherwise remaining images. int (*filter_ext)(struct vf_instance *vf, struct mp_image *mpi); + // Produce an output frame. This is called after filter or filter_ext. + // You can add 0 or more frames with vf_add_output_frame(). (This allows + // distributing the filter load over time -> typically add at most 1 frame.) + // If this adds no frame (or is NULL), then the caller assumes that the + // filter needs new input. + // Return a negative value on error. (No more frames is not an error.) + // May be called multiple times, even if the filter gives no output. + int (*filter_out)(struct vf_instance *vf); + void (*uninit)(struct vf_instance *vf); char *label; -- cgit v1.2.3