diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/command.c | 40 | ||||
-rw-r--r-- | core/input/input.c | 2 | ||||
-rw-r--r-- | core/input/input.h | 3 | ||||
-rw-r--r-- | core/mp_core.h | 1 | ||||
-rw-r--r-- | core/mplayer.c | 46 |
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); |