diff options
author | wm4 <wm4@nowhere> | 2014-05-01 19:29:17 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-05-02 01:08:06 +0200 |
commit | 404953250163fcce550072efcba8d9c55b9cca44 (patch) | |
tree | 90554de935991b7544784f3aacbffb7b5082d0b7 /video | |
parent | 9243249a0e1fed9bb22213b651f285f796eb4759 (diff) | |
download | mpv-404953250163fcce550072efcba8d9c55b9cca44.tar.bz2 mpv-404953250163fcce550072efcba8d9c55b9cca44.tar.xz |
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).
Diffstat (limited to 'video')
-rw-r--r-- | video/filter/vf.c | 66 | ||||
-rw-r--r-- | video/filter/vf.h | 4 |
2 files changed, 57 insertions, 13 deletions
diff --git a/video/filter/vf.c b/video/filter/vf.c index fb3dee6e91..0939631ca4 100644 --- a/video/filter/vf.c +++ b/video/filter/vf.c @@ -173,6 +173,14 @@ int vf_control_by_label(struct vf_chain *c,int cmd, void *arg, bstr label) 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) { // 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. +// 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 // 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) - return NULL; + return -1; while (1) { struct vf_instance *last = NULL; for (struct vf_instance * cur = c->first; cur; cur = cur->next) { // Flush remaining frames on EOF, but do that only if the previous // filters have been flushed (i.e. they have no more output). - if (eof && !last) - vf_do_filter(cur, NULL); + if (eof && !last) { + int r = vf_do_filter(cur, NULL); + if (r < 0) + return r; + } if (cur->num_out_queued) last = cur; } if (!last) - return NULL; + return 0; struct mp_image *img = vf_dequeue_output_frame(last); - if (!last->next) - return img; - vf_do_filter(last->next, img); + if (!last->next) { + c->output = 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) { 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; } -void vf_seek_reset(struct vf_chain *c) +static void vf_chain_forget_frames(struct vf_chain *c) { - for (struct vf_instance *cur = c->first; cur; cur = cur->next) { - if (cur->control) - cur->control(cur, VFCTRL_SEEK_RESET, NULL); + 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) +{ + vf_control_all(c, VFCTRL_SEEK_RESET, NULL); + vf_chain_forget_frames(c); } 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; int r = 0; + vf_chain_forget_frames(c); for (struct vf_instance *vf = c->first; vf; ) { struct vf_instance *next = vf->next; if (vf->autoinserted) @@ -642,6 +681,7 @@ void vf_destroy(struct vf_chain *c) c->first = vf->next; vf_uninit_filter(vf); } + vf_chain_forget_frames(c); talloc_free(c); } diff --git a/video/filter/vf.h b/video/filter/vf.h index 9ae9740380..399e3f1e42 100644 --- a/video/filter/vf.h +++ b/video/filter/vf.h @@ -110,6 +110,8 @@ struct vf_chain { struct MPOpts *opts; struct mpv_global *global; struct mp_hwdec_info *hwdec; + + struct mp_image *output; }; 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_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_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); void vf_seek_reset(struct vf_chain *c); struct vf_instance *vf_append_filter(struct vf_chain *c, const char *name, |