summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/command.c40
-rw-r--r--core/input/input.c2
-rw-r--r--core/input/input.h3
-rw-r--r--core/mp_core.h1
-rw-r--r--core/mplayer.c46
5 files changed, 80 insertions, 12 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;
diff --git a/core/input/input.c b/core/input/input.c
index 7ba6b64cdc..116e963b93 100644
--- a/core/input/input.c
+++ b/core/input/input.c
@@ -198,6 +198,8 @@ static const mp_cmd_t mp_cmds[] = {
{ MP_CMD_AF_CLR, "af_clr", },
{ MP_CMD_AF_CMDLINE, "af_cmdline", { ARG_STRING, ARG_STRING } },
+ { MP_CMD_VF, "vf", { ARG_STRING, ARG_STRING } },
+
{ MP_CMD_SHOW_CHAPTERS, "show_chapters", },
{ MP_CMD_SHOW_TRACKS, "show_tracks", },
{ MP_CMD_SHOW_PLAYLIST, "show_playlist", },
diff --git a/core/input/input.h b/core/input/input.h
index 367abedfca..12823dd004 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -78,6 +78,9 @@ enum mp_command_type {
MP_CMD_AF_CLR,
MP_CMD_AF_CMDLINE,
+ /// Video filter commands
+ MP_CMD_VF,
+
MP_CMD_SHOW_CHAPTERS,
MP_CMD_SHOW_TRACKS,
MP_CMD_SHOW_PLAYLIST,
diff --git a/core/mp_core.h b/core/mp_core.h
index 941396c48a..ce576273b4 100644
--- a/core/mp_core.h
+++ b/core/mp_core.h
@@ -298,6 +298,7 @@ double playing_audio_pts(struct MPContext *mpctx);
struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename,
float fps, int noerr);
int reinit_video_chain(struct MPContext *mpctx);
+int reinit_video_filters(struct MPContext *mpctx);
void pause_player(struct MPContext *mpctx);
void unpause_player(struct MPContext *mpctx);
void add_step_frame(struct MPContext *mpctx, int dir);
diff --git a/core/mplayer.c b/core/mplayer.c
index ac597beac1..a0b18cab62 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -2466,6 +2466,39 @@ static void update_fps(struct MPContext *mpctx)
#endif
}
+static void recreate_video_filters(struct MPContext *mpctx)
+{
+ struct MPOpts *opts = &mpctx->opts;
+ struct sh_video *sh_video = mpctx->sh_video;
+ assert(sh_video);
+
+ vf_uninit_filter_chain(sh_video->vfilter);
+
+ char *vf_arg[] = {
+ "_oldargs_", (char *)mpctx->video_out, NULL
+ };
+ sh_video->vfilter = vf_open_filter(opts, NULL, "vo", vf_arg);
+
+ sh_video->vfilter = append_filters(sh_video->vfilter, opts->vf_settings);
+
+ struct vf_instance *vf = sh_video->vfilter;
+ mpctx->osd->render_subs_in_filter
+ = vf->control(vf, VFCTRL_INIT_OSD, NULL) == VO_TRUE;
+}
+
+int reinit_video_filters(struct MPContext *mpctx)
+{
+ struct sh_video *sh_video = mpctx->sh_video;
+
+ if (!sh_video)
+ return -2;
+
+ recreate_video_filters(mpctx);
+ video_reinit_vo(sh_video);
+
+ return sh_video->vf_initialized > 0 ? 0 : -1;
+}
+
int reinit_video_chain(struct MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
@@ -2518,18 +2551,7 @@ int reinit_video_chain(struct MPContext *mpctx)
STREAM_CTRL_GET_ASPECT_RATIO, &ar) != STREAM_UNSUPPORTED)
mpctx->sh_video->stream_aspect = ar;
- {
- char *vf_arg[] = {
- "_oldargs_", (char *)mpctx->video_out, NULL
- };
- sh_video->vfilter = vf_open_filter(opts, NULL, "vo", vf_arg);
- }
-
- sh_video->vfilter = append_filters(sh_video->vfilter, opts->vf_settings);
-
- struct vf_instance *vf = sh_video->vfilter;
- mpctx->osd->render_subs_in_filter
- = vf->control(vf, VFCTRL_INIT_OSD, NULL) == VO_TRUE;
+ recreate_video_filters(mpctx);
init_best_video_codec(sh_video, opts->video_decoders);