summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-01-20 03:03:40 +0100
committerwm4 <wm4@nowhere>2013-01-20 03:25:44 +0100
commit326820b0ff437e044a5dcf1788fd1fc5e811067c (patch)
tree90f7f2dcd6b70057d5c1f6f9c8d70f705c7f639f /video
parentf7d96fe03286d07e874d1c6acdd942b57a900a7e (diff)
downloadmpv-326820b0ff437e044a5dcf1788fd1fc5e811067c.tar.bz2
mpv-326820b0ff437e044a5dcf1788fd1fc5e811067c.tar.xz
video: reset filters on seek
Drop queued frames on seek. Reset the internal state of some filters that seem to need it as well: at least vf_divtc still produced some frames using the previous PTS. This fixes weird behavior with some filters on seeking. In particular, this could lead to A/V desync or apparent lockups due to the PTS of filtered frames being too far away from audio PTS. This commit does only the minimally required work to fix these PTS related issues. Some filters have state dependent on previously filtered frames, and these are not automatically reset with this commit (even vf_divtc and vf_softpulldown reset the PTS info only). Filters that actually require a full reset can implement VFCTRL_SEEK_RESET.
Diffstat (limited to 'video')
-rw-r--r--video/filter/vf.c7
-rw-r--r--video/filter/vf.h2
-rw-r--r--video/filter/vf_divtc.c11
-rw-r--r--video/filter/vf_softpulldown.c11
4 files changed, 31 insertions, 0 deletions
diff --git a/video/filter/vf.c b/video/filter/vf.c
index 93088953dc..a4b78ab5ab 100644
--- a/video/filter/vf.c
+++ b/video/filter/vf.c
@@ -401,6 +401,13 @@ static void vf_forget_frames(struct vf_instance *vf)
vf->num_out_queued = 0;
}
+void vf_chain_seek_reset(struct vf_instance *vf)
+{
+ vf->control(vf, VFCTRL_SEEK_RESET, NULL);
+ for (struct vf_instance *cur = vf; cur; cur = cur->next)
+ vf_forget_frames(cur);
+}
+
int vf_config_wrapper(struct vf_instance *vf,
int width, int height, int d_width, int d_height,
unsigned int flags, unsigned int outfmt)
diff --git a/video/filter/vf.h b/video/filter/vf.h
index 2a6fc5a41e..4398abebc7 100644
--- a/video/filter/vf.h
+++ b/video/filter/vf.h
@@ -86,6 +86,7 @@ typedef struct vf_seteq {
int value;
} vf_equalizer_t;
+#define VFCTRL_SEEK_RESET 1 // reset on picture and PTS discontinuities
#define VFCTRL_QUERY_MAX_PP_LEVEL 4 // query max postprocessing level (if any)
#define VFCTRL_SET_PP_LEVEL 5 // set postprocessing level
#define VFCTRL_SET_EQUALIZER 6 // set color options (brightness,contrast etc)
@@ -109,6 +110,7 @@ void vf_add_output_frame(struct vf_instance *vf, struct mp_image *img);
int vf_filter_frame(struct vf_instance *vf, struct mp_image *img);
struct mp_image *vf_chain_output_queued_frame(struct vf_instance *vf);
+void vf_chain_seek_reset(struct vf_instance *vf);
vf_instance_t *vf_open_plugin(struct MPOpts *opts,
const vf_info_t * const *filter_list, vf_instance_t *next,
diff --git a/video/filter/vf_divtc.c b/video/filter/vf_divtc.c
index 093b70f5b6..5b57e5a4cb 100644
--- a/video/filter/vf_divtc.c
+++ b/video/filter/vf_divtc.c
@@ -592,6 +592,16 @@ static void uninit(struct vf_instance *vf)
}
}
+static int control(vf_instance_t *vf, int request, void *data)
+{
+ switch (request) {
+ case VFCTRL_SEEK_RESET:
+ vf_detc_init_pts_buf(&vf->priv->ptsbuf);
+ break;
+ }
+ return vf_next_control(vf, request, data);
+}
+
static int vf_open(vf_instance_t *vf, char *args)
{
struct vf_priv_s *p;
@@ -611,6 +621,7 @@ static int vf_open(vf_instance_t *vf, char *args)
vf->filter=filter;
vf->uninit=uninit;
vf->query_format=query_format;
+ vf->control=control;
if(!(vf->priv=p=calloc(1, sizeof(struct vf_priv_s))))
goto nomem;
diff --git a/video/filter/vf_softpulldown.c b/video/filter/vf_softpulldown.c
index 11eab7c0c3..9fd75a0ba0 100644
--- a/video/filter/vf_softpulldown.c
+++ b/video/filter/vf_softpulldown.c
@@ -123,6 +123,16 @@ static int config(struct vf_instance *vf,
return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
}
+static int control(vf_instance_t *vf, int request, void *data)
+{
+ switch (request) {
+ case VFCTRL_SEEK_RESET:
+ vf_detc_init_pts_buf(&vf->priv->ptsbuf);
+ break;
+ }
+ return vf_next_control(vf, request, data);
+}
+
static void uninit(struct vf_instance *vf)
{
mp_msg(MSGT_VFILTER, MSGL_INFO, "softpulldown: %lld frames in, %lld frames out\n", vf->priv->in, vf->priv->out);
@@ -143,6 +153,7 @@ static int vf_open(vf_instance_t *vf, char *args)
{
vf->config = config;
vf->filter_ext = filter;
+ vf->control = control;
vf->uninit = uninit;
vf->query_format = query_format;
vf->priv = calloc(1, sizeof(struct vf_priv_s));