diff options
-rw-r--r-- | DOCS/man/en/input.rst | 2 | ||||
-rw-r--r-- | DOCS/man/en/options.rst | 15 | ||||
-rw-r--r-- | demux/stheader.h | 1 | ||||
-rw-r--r-- | mpvcore/command.c | 9 | ||||
-rw-r--r-- | mpvcore/mp_core.h | 2 | ||||
-rw-r--r-- | mpvcore/mplayer.c | 27 | ||||
-rw-r--r-- | mpvcore/options.c | 6 | ||||
-rw-r--r-- | mpvcore/options.h | 1 | ||||
-rw-r--r-- | video/decode/vd.c | 2 |
9 files changed, 61 insertions, 4 deletions
diff --git a/DOCS/man/en/input.rst b/DOCS/man/en/input.rst index ea2ebd2f0b..e40457e099 100644 --- a/DOCS/man/en/input.rst +++ b/DOCS/man/en/input.rst @@ -432,7 +432,7 @@ Name W Comment ``audio`` x alias for ``aid`` ``balance`` x audio channel balance ``fullscreen`` x see ``--fullscreen`` -``deinterlace`` x deinterlacing, if available (bool) +``deinterlace`` x similar to ``--deinterlace`` ``colormatrix`` x see ``--colormatrix`` ``colormatrix-input-range`` x see ``--colormatrix-input-range`` ``colormatrix-output-range`` x see ``--colormatrix-output-range`` diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst index f34268bd6d..8ac563004a 100644 --- a/DOCS/man/en/options.rst +++ b/DOCS/man/en/options.rst @@ -569,6 +569,21 @@ Audio delay in seconds (positive or negative float value). Negative values delay the audio, and positive values delay the video. +``--deinterlace=<yes|no|auto>`` + Enable or disable interlacing (default: auto, which usually means no). + Interlaced video shows ugly comb-like artifacts, which are visible on + fast movement. Enabling this typically inserts the yadif video filter in + order to deinterlace the video, or lets the video output apply deinterlacing + if supported. + + This behaves exactly like the ``deinterlace`` input property (usually + mapped to ``Shift+D``). + + ``auto`` is a technicality. Strictly speaking, the default for this option + is deinterlacing disabled, but the ``auto`` case is needed if ``yadif`` was + added to the filter chain manually with ``--vf``. Then the core shouldn't + disable deinterlacing just because the ``--deinterlace`` was not set. + ``--demuxer=<[+]name>`` Force demuxer type. Use a '+' before the name to force it; this will skip some checks. Give the demuxer name as printed by ``--demuxer=help``. diff --git a/demux/stheader.h b/demux/stheader.h index 6109221442..1c2f8a2a3e 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -131,6 +131,7 @@ typedef struct sh_video { struct vf_instance *vfilter; // video filter chain const struct vd_functions *vd_driver; int vf_initialized; // -1 failed, 0 not done, 1 done + long vf_reconfig_count; // incremented each mpcodecs_reconfig_vo() call struct mp_image_params *vf_input; // video filter input params struct mp_hwdec_info *hwdec_info; // video output hwdec handles // win32-compatible codec parameters: diff --git a/mpvcore/command.c b/mpvcore/command.c index f5421d48fe..b3a1b7a360 100644 --- a/mpvcore/command.c +++ b/mpvcore/command.c @@ -1155,10 +1155,13 @@ static void set_deinterlacing(struct MPContext *mpctx, bool enable) 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); + if ((get_deinterlacing(mpctx) > 0) != enable) { + int arg = enable; + if (vf->control(vf, VFCTRL_SET_DEINTERLACE, &arg) != CONTROL_OK) + change_video_filters(mpctx, "add", VF_DEINTERLACE); + } } + mpctx->opts->deinterlace = get_deinterlacing(mpctx) > 0; } static int mp_property_deinterlace(m_option_t *prop, int action, diff --git a/mpvcore/mp_core.h b/mpvcore/mp_core.h index 777e04945a..d997aa4d58 100644 --- a/mpvcore/mp_core.h +++ b/mpvcore/mp_core.h @@ -229,6 +229,8 @@ typedef struct MPContext { double last_vo_pts; // Video PTS, or audio PTS if video has ended. double playback_pts; + // Used to determine whether the video filter chain was rebuilt. + long last_vf_reconfig_count; // History of video frames timestamps that were queued in the VO // This includes even skipped frames during hr-seek diff --git a/mpvcore/mplayer.c b/mpvcore/mplayer.c index caa26b71b4..d20f321042 100644 --- a/mpvcore/mplayer.c +++ b/mpvcore/mplayer.c @@ -840,6 +840,7 @@ static const char *backup_properties[] = { "contrast", "saturation", "hue", + "deinterlace", "panscan", "aid", "vid", @@ -2438,6 +2439,7 @@ int reinit_video_chain(struct MPContext *mpctx) sh_video->last_pts = MP_NOPTS_VALUE; sh_video->num_buffered_pts = 0; sh_video->next_frame_time = 0; + mpctx->last_vf_reconfig_count = 0; mpctx->restart_playback = true; mpctx->sync_audio_to_video = !sh_video->gsh->attached_picture; mpctx->delay = 0; @@ -2524,10 +2526,35 @@ static bool load_next_vo_frame(struct MPContext *mpctx, bool eof) return false; } +static void init_filter_params(struct MPContext *mpctx) +{ + struct MPOpts *opts = mpctx->opts; + struct sh_video *sh_video = mpctx->sh_video; + + // Note that the video decoder already initializes the filter chain. This + // might recreate the chain a second time, which is not very elegant, but + // allows us to test whether enabling deinterlacing works with the current + // video format and other filters. + if (sh_video->vf_initialized != 1) + return; + + if (sh_video->vf_reconfig_count <= mpctx->last_vf_reconfig_count) { + if (opts->deinterlace >= 0) { + mp_property_do("deinterlace", M_PROPERTY_SET, &opts->deinterlace, + mpctx); + } + } + // Setting filter params has to be "stable" (no change if params already + // set) - checking the reconfig count is just an optimization. + mpctx->last_vf_reconfig_count = sh_video->vf_reconfig_count; +} + static void filter_video(struct MPContext *mpctx, struct mp_image *frame) { struct sh_video *sh_video = mpctx->sh_video; + init_filter_params(mpctx); + frame->pts = sh_video->pts; mp_image_set_params(frame, sh_video->vf_input); vf_filter_frame(sh_video->vfilter, frame); diff --git a/mpvcore/options.c b/mpvcore/options.c index cf09702dcb..a09a28856f 100644 --- a/mpvcore/options.c +++ b/mpvcore/options.c @@ -461,6 +461,11 @@ const m_option_t mp_opts[] = { OPT_SETTINGSLIST("af*", af_settings, 0, &af_obj_list), OPT_SETTINGSLIST("vf*", vf_settings, 0, &vf_obj_list), + OPT_CHOICE("deinterlace", deinterlace, M_OPT_OPTIONAL_PARAM, + ({"auto", -1}, + {"no", 0}, + {"yes", 1}, {"", 1})), + OPT_STRING("ad", audio_decoders, 0), OPT_STRING("vd", video_decoders, 0), @@ -745,6 +750,7 @@ const struct MPOpts mp_default_opts = { .audio_driver_list = NULL, .audio_decoders = "-spdif:*", // never select spdif by default .video_decoders = NULL, + .deinterlace = -1, .fixed_vo = 1, .softvol = SOFTVOL_AUTO, .softvol_max = 200, diff --git a/mpvcore/options.h b/mpvcore/options.h index 25ff391615..67074de241 100644 --- a/mpvcore/options.h +++ b/mpvcore/options.h @@ -169,6 +169,7 @@ typedef struct MPOpts { double playback_speed; struct m_obj_settings *vf_settings; struct m_obj_settings *af_settings; + int deinterlace; float movie_aspect; int flip; int field_dominance; diff --git a/video/decode/vd.c b/video/decode/vd.c index fad9adbdf7..42244de209 100644 --- a/video/decode/vd.c +++ b/video/decode/vd.c @@ -56,6 +56,8 @@ int mpcodecs_reconfig_vo(sh_video_t *sh, const struct mp_image_params *params) int vocfg_flags = 0; struct mp_image_params p = *params; + sh->vf_reconfig_count++; + if (!p.w || !p.h) { // ideally, this should be dead code mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Unknown size, using container size.\n"); |