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.
This commit is contained in:
wm4 2014-09-18 19:25:46 +02:00
parent 5c8549ac68
commit 580cf433bd
2 changed files with 20 additions and 2 deletions

View File

@ -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)

View File

@ -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;