summaryrefslogtreecommitdiffstats
path: root/core/command.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-05-18 11:44:17 +0200
committerwm4 <wm4@nowhere>2013-05-18 17:45:54 +0200
commitf569d245ba37898a79e853cb6fbd906dd992b531 (patch)
tree713d484af2df18abf8c388863ea6341d64a981aa /core/command.c
parentd1b37aff32f459e2d9fd8361beb14138458012ec (diff)
downloadmpv-f569d245ba37898a79e853cb6fbd906dd992b531.tar.bz2
mpv-f569d245ba37898a79e853cb6fbd906dd992b531.tar.xz
core: allow changing filter filters at runtime
Add the "vf" command, which allows changing the video filter chain at runtime. For example, the 'y' key could be bound to toggle deinterlacing by adding 'y vf toggle yadif' to the input.conf. Reconfiguring the video filter chain normally resets the VO, so that it will be "stuck" until a new video frame is rendered. To mitigate this, a seek to the current position is issued when the filter chain is changed. This is done only if playback is paused, because normal playback will show an actual new frame quickly enough. If vdpau hardware decoding is used, filter insertion (whether it fails or not) will break the video for a while. This is because vo_vdpau resets decoding related things on vo_config().
Diffstat (limited to 'core/command.c')
-rw-r--r--core/command.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/core/command.c b/core/command.c
index ebc8d93485..9e16804e8a 100644
--- a/core/command.c
+++ b/core/command.c
@@ -1775,6 +1775,42 @@ static void show_playlist_on_osd(MPContext *mpctx)
talloc_free(res);
}
+static void change_video_filters(MPContext *mpctx, const char *cmd,
+ const char *arg)
+{
+ struct MPOpts *opts = &mpctx->opts;
+ struct m_config *conf = mpctx->mconfig;
+ struct m_obj_settings *old_vf_settings = NULL;
+ bool success = false;
+ bool need_refresh = false;
+ double refresh_pts = mpctx->last_vo_pts;
+
+ // The option parser is used to modify the filter list itself.
+ char optname[20];
+ snprintf(optname, sizeof(optname), "vf-%s", cmd);
+ const struct m_option *type = m_config_get_option(conf, bstr0(optname));
+
+ // Backup old settings, in case it fails
+ m_option_copy(type, &old_vf_settings, &opts->vf_settings);
+
+ if (m_config_set_option0(conf, optname, arg) >= 0) {
+ need_refresh = true;
+ success = reinit_video_filters(mpctx) >= 0;
+ }
+
+ if (!success) {
+ m_option_copy(type, &opts->vf_settings, &old_vf_settings);
+ if (need_refresh)
+ reinit_video_filters(mpctx);
+ }
+ m_option_free(type, &old_vf_settings);
+
+ // Try to refresh the video by doing a precise seek to the currently
+ // displayed frame.
+ if (need_refresh && opts->pause)
+ queue_seek(mpctx, MPSEEK_ABSOLUTE, refresh_pts, 1);
+}
+
void run_command(MPContext *mpctx, mp_cmd_t *cmd)
{
struct MPOpts *opts = &mpctx->opts;
@@ -2289,6 +2325,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
af_uninit(mpctx->mixer.afilter);
af_init(mpctx->mixer.afilter);
}
+ /* fallthrough */
case MP_CMD_AF_ADD:
case MP_CMD_AF_DEL: {
if (!sh_audio)
@@ -2331,6 +2368,9 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
af_reinit(sh_audio->afilter);
}
break;
+ case MP_CMD_VF:
+ change_video_filters(mpctx, cmd->args[0].v.s, cmd->args[1].v.s);
+ break;
case MP_CMD_SHOW_CHAPTERS:
show_chapters_on_osd(mpctx);
break;