summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/en/input.rst2
-rw-r--r--DOCS/man/en/options.rst15
-rw-r--r--demux/stheader.h1
-rw-r--r--mpvcore/command.c9
-rw-r--r--mpvcore/mp_core.h2
-rw-r--r--mpvcore/mplayer.c27
-rw-r--r--mpvcore/options.c6
-rw-r--r--mpvcore/options.h1
-rw-r--r--video/decode/vd.c2
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");