summaryrefslogtreecommitdiffstats
path: root/mpvcore
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-09-13 18:06:08 +0200
committerwm4 <wm4@nowhere>2013-09-13 21:32:28 +0200
commit6cec60a454889907df46bf37adddfd874884b24d (patch)
tree662b3b7c6ce6924af8161566b3c9180ba086ffa8 /mpvcore
parentddd3ade02309259cda20de14bdeef334a006ad1f (diff)
downloadmpv-6cec60a454889907df46bf37adddfd874884b24d.tar.bz2
mpv-6cec60a454889907df46bf37adddfd874884b24d.tar.xz
core: add --deinterlace option, restore it with resume functionality
The --deinterlace option does on playback start what the "deinterlace" property normally does at runtime. You could do this before by using the --vf option or by messing with the vo_vdpau default options, but this new option is supposed to be a "foolproof" way. The main motivation for adding this is so that the deinterlace property can be restored when using the video resume functionality (quit_watch_later command). Implementation-wise, this is a bit messy. The video chain is rebuilt in mpcodecs_reconfig_vo(), where we don't have access to MPContext, so the usual mechanism for enabling deinterlacing can't be used. Further, mpcodecs_reconfig_vo() is called by the video decoder, which doesn't have access to MPContext either. Moving this call to mplayer.c isn't currently possible either (see below). So we just do this before frames are filtered, which potentially means setting the deinterlacing every frame. Fortunately, setting deinterlacing is stable and idempotent, so this is hopefully not a problem. We also add a counter that is incremented on each reconfig to reduce the amount of additional work per frame to nearly zero. The reason we can't move mpcodecs_reconfig_vo() to mplayer.c is because of hardware decoding: we need to check whether the video chain works before we decide that we can use hardware decoding. Changing it so that this can be decided in advance without building a filter chain sounds like a good idea and should be done, but we aren't there yet.
Diffstat (limited to 'mpvcore')
-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
5 files changed, 42 insertions, 3 deletions
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;