summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-05-01 19:29:17 +0200
committerwm4 <wm4@nowhere>2014-05-02 01:08:06 +0200
commit404953250163fcce550072efcba8d9c55b9cca44 (patch)
tree90554de935991b7544784f3aacbffb7b5082d0b7 /video
parent9243249a0e1fed9bb22213b651f285f796eb4759 (diff)
downloadmpv-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.c66
-rw-r--r--video/filter/vf.h4
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,