vf: add alternate functions for retrieving filter output

These replace vf_read_output_frame(), although we still emulate that
function. This change is preparation for another commit (and this is
basically just to reduce the diff and signal/noise ratio in that
commit).
This commit is contained in:
wm4 2014-05-01 19:29:17 +02:00
parent 9243249a0e
commit 4049532501
2 changed files with 57 additions and 13 deletions

View File

@ -173,6 +173,14 @@ int vf_control_by_label(struct vf_chain *c,int cmd, void *arg, bstr label)
return CONTROL_UNKNOWN; return CONTROL_UNKNOWN;
} }
static void vf_control_all(struct vf_chain *c, int cmd, void *arg)
{
for (struct vf_instance *cur = c->first; cur; cur = cur->next) {
if (cur->control)
cur->control(cur, cmd, arg);
}
}
static void vf_fix_img_params(struct mp_image *img, struct mp_image_params *p) static void vf_fix_img_params(struct mp_image *img, struct mp_image_params *p)
{ {
// Filters must absolutely set these correctly. // Filters must absolutely set these correctly.
@ -400,31 +408,57 @@ int vf_filter_frame(struct vf_chain *c, struct mp_image *img)
} }
// Output the next queued image (if any) from the full filter chain. // Output the next queued image (if any) from the full filter chain.
// The frame can be retrieved with vf_read_output_frame().
// eof: if set, assume there's no more input i.e. vf_filter_frame() will // eof: if set, assume there's no more input i.e. vf_filter_frame() will
// not be called (until reset) - flush all internally delayed frames // not be called (until reset) - flush all internally delayed frames
struct mp_image *vf_output_queued_frame(struct vf_chain *c, bool eof) // returns: -1: error, 0: no output, 1: output available
int vf_output_frame(struct vf_chain *c, bool eof)
{ {
if (c->output)
return 1;
if (c->initialized < 1) if (c->initialized < 1)
return NULL; return -1;
while (1) { while (1) {
struct vf_instance *last = NULL; struct vf_instance *last = NULL;
for (struct vf_instance * cur = c->first; cur; cur = cur->next) { for (struct vf_instance * cur = c->first; cur; cur = cur->next) {
// Flush remaining frames on EOF, but do that only if the previous // Flush remaining frames on EOF, but do that only if the previous
// filters have been flushed (i.e. they have no more output). // filters have been flushed (i.e. they have no more output).
if (eof && !last) if (eof && !last) {
vf_do_filter(cur, NULL); int r = vf_do_filter(cur, NULL);
if (r < 0)
return r;
}
if (cur->num_out_queued) if (cur->num_out_queued)
last = cur; last = cur;
} }
if (!last) if (!last)
return NULL; return 0;
struct mp_image *img = vf_dequeue_output_frame(last); struct mp_image *img = vf_dequeue_output_frame(last);
if (!last->next) if (!last->next) {
return img; c->output = img;
vf_do_filter(last->next, img); return !!c->output;
}
int r = vf_do_filter(last->next, img);
if (r < 0)
return r;
} }
} }
struct mp_image *vf_read_output_frame(struct vf_chain *c)
{
if (!c->output)
vf_output_frame(c, false);
struct mp_image *res = c->output;
c->output = NULL;
return res;
}
struct mp_image *vf_output_queued_frame(struct vf_chain *c, bool eof)
{
vf_output_frame(c, eof);
return vf_read_output_frame(c);
}
static void vf_forget_frames(struct vf_instance *vf) static void vf_forget_frames(struct vf_instance *vf)
{ {
for (int n = 0; n < vf->num_out_queued; n++) for (int n = 0; n < vf->num_out_queued; n++)
@ -432,13 +466,17 @@ static void vf_forget_frames(struct vf_instance *vf)
vf->num_out_queued = 0; vf->num_out_queued = 0;
} }
static void vf_chain_forget_frames(struct vf_chain *c)
{
for (struct vf_instance *cur = c->first; cur; cur = cur->next)
vf_forget_frames(cur);
mp_image_unrefp(&c->output);
}
void vf_seek_reset(struct vf_chain *c) void vf_seek_reset(struct vf_chain *c)
{ {
for (struct vf_instance *cur = c->first; cur; cur = cur->next) { vf_control_all(c, VFCTRL_SEEK_RESET, NULL);
if (cur->control) vf_chain_forget_frames(c);
cur->control(cur, VFCTRL_SEEK_RESET, NULL);
vf_forget_frames(cur);
}
} }
int vf_next_config(struct vf_instance *vf, int vf_next_config(struct vf_instance *vf,
@ -548,6 +586,7 @@ int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params)
{ {
struct mp_image_params cur = *params; struct mp_image_params cur = *params;
int r = 0; int r = 0;
vf_chain_forget_frames(c);
for (struct vf_instance *vf = c->first; vf; ) { for (struct vf_instance *vf = c->first; vf; ) {
struct vf_instance *next = vf->next; struct vf_instance *next = vf->next;
if (vf->autoinserted) if (vf->autoinserted)
@ -642,6 +681,7 @@ void vf_destroy(struct vf_chain *c)
c->first = vf->next; c->first = vf->next;
vf_uninit_filter(vf); vf_uninit_filter(vf);
} }
vf_chain_forget_frames(c);
talloc_free(c); talloc_free(c);
} }

View File

@ -110,6 +110,8 @@ struct vf_chain {
struct MPOpts *opts; struct MPOpts *opts;
struct mpv_global *global; struct mpv_global *global;
struct mp_hwdec_info *hwdec; struct mp_hwdec_info *hwdec;
struct mp_image *output;
}; };
typedef struct vf_seteq { typedef struct vf_seteq {
@ -137,6 +139,8 @@ int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params);
int vf_control_any(struct vf_chain *c, int cmd, void *arg); int vf_control_any(struct vf_chain *c, int cmd, void *arg);
int vf_control_by_label(struct vf_chain *c, int cmd, void *arg, bstr label); int vf_control_by_label(struct vf_chain *c, int cmd, void *arg, bstr label);
int vf_filter_frame(struct vf_chain *c, struct mp_image *img); int vf_filter_frame(struct vf_chain *c, struct mp_image *img);
int vf_output_frame(struct vf_chain *c, bool eof);
struct mp_image *vf_read_output_frame(struct vf_chain *c);
struct mp_image *vf_output_queued_frame(struct vf_chain *c, bool eof); struct mp_image *vf_output_queued_frame(struct vf_chain *c, bool eof);
void vf_seek_reset(struct vf_chain *c); void vf_seek_reset(struct vf_chain *c);
struct vf_instance *vf_append_filter(struct vf_chain *c, const char *name, struct vf_instance *vf_append_filter(struct vf_chain *c, const char *name,