summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-05-22 23:37:39 +0200
committerwm4 <wm4@nowhere>2013-05-23 01:02:24 +0200
commit89b8154aadd6982b5c6ddb1de5614daedb0850f1 (patch)
tree6b80a8193d351d691d93a6070a508614dae750ef /core
parent862989c0113da276ee9795f88541288da03015a6 (diff)
downloadmpv-89b8154aadd6982b5c6ddb1de5614daedb0850f1.tar.bz2
mpv-89b8154aadd6982b5c6ddb1de5614daedb0850f1.tar.xz
command: auto-insert yadif when switching deinterlacing
If VO deinterlacing is unavailable, try to insert vf_yadif. If vf_lavfi is available, actually use vf_yadif from libavfilter. The libavfilter version of this filter is faster, more correct, etc., so it is preferred. Unfortunately vf_yadif obviously doesn't support VFCTRL_GET/SET_DEINTERLACE, and with the current state of the libavfilter API, it doesn't look like there is any simple way to emulate it. Instead, we simply insert the filter with a specific label, and if deinterlacing is to be disabled, the filter is removed again by label. This won't do the right thing if the user inserts any deinterlacing filter manually (except native vf_yadif, which understands the VFCTRL). For example, with '-vf lavfi=yadif', pressing 'D' (toggle deinterlacing) will just insert a second deinterlacer filter. In these cases, the user is supposed to map a command that toggles his own filter instead of using 'D' and the deinterlace property. The same applies if the user wants to pass different parameters to the deinterlacer filters.
Diffstat (limited to 'core')
-rw-r--r--core/command.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/core/command.c b/core/command.c
index 7ef9982fc9..3ee8f39c3d 100644
--- a/core/command.c
+++ b/core/command.c
@@ -69,6 +69,9 @@
#include "mp_fifo.h"
#include "libavutil/avstring.h"
+static void change_video_filters(MPContext *mpctx, const char *cmd,
+ const char *arg);
+
static char *format_bitrate(int rate)
{
return talloc_asprintf(NULL, "%d kbps", rate * 8 / 1000);
@@ -891,21 +894,52 @@ static int mp_property_fullscreen(m_option_t *prop,
return mp_property_generic_option(prop, action, arg, mpctx);
}
-static int mp_property_deinterlace(m_option_t *prop, int action,
- void *arg, MPContext *mpctx)
+#define VF_DEINTERLACE_LABEL "deinterlace"
+
+#ifdef CONFIG_VF_LAVFI
+#define VF_DEINTERLACE "@" VF_DEINTERLACE_LABEL ":lavfi=yadif"
+#else
+#define VF_DEINTERLACE "@" VF_DEINTERLACE_LABEL ":yadif"
+#endif
+
+static int get_deinterlacing(struct MPContext *mpctx)
{
- if (!mpctx->sh_video || !mpctx->sh_video->vfilter)
- return M_PROPERTY_UNAVAILABLE;
vf_instance_t *vf = mpctx->sh_video->vfilter;
int enabled = 0;
if (vf->control(vf, VFCTRL_GET_DEINTERLACE, &enabled) != CONTROL_OK)
+ enabled = -1;
+ if (enabled < 0) {
+ // vf_lavfi doesn't support VFCTRL_GET_DEINTERLACE
+ if (vf_find_by_label(vf, VF_DEINTERLACE_LABEL))
+ enabled = 1;
+ }
+ return enabled;
+}
+
+static void set_deinterlacing(struct MPContext *mpctx, bool enable)
+{
+ vf_instance_t *vf = mpctx->sh_video->vfilter;
+ if (vf_find_by_label(vf, VF_DEINTERLACE_LABEL)) {
+ if (!enable)
+ change_video_filters(mpctx, "del", VF_DEINTERLACE);
+ } else {
+ int arg = enable;
+ if (vf->control(vf, VFCTRL_SET_DEINTERLACE, &arg) != CONTROL_OK)
+ change_video_filters(mpctx, "add", VF_DEINTERLACE);
+ }
+}
+
+static int mp_property_deinterlace(m_option_t *prop, int action,
+ void *arg, MPContext *mpctx)
+{
+ if (!mpctx->sh_video || !mpctx->sh_video->vfilter)
return M_PROPERTY_UNAVAILABLE;
switch (action) {
case M_PROPERTY_GET:
- *(int *)arg = !!enabled;
+ *(int *)arg = get_deinterlacing(mpctx) > 0;
return M_PROPERTY_OK;
case M_PROPERTY_SET:
- vf->control(vf, VFCTRL_SET_DEINTERLACE, arg);
+ set_deinterlacing(mpctx, *(int *)arg);
return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;