mirror of https://github.com/mpv-player/mpv
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:
parent
9243249a0e
commit
4049532501
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue