summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-01-27 21:07:17 +0100
committerwm4 <wm4@nowhere>2016-01-27 21:07:17 +0100
commit34bead485987b416685e73ca918610fff75d618d (patch)
treea83b162051ee7c4cbd6cb8ea58ec2e4f3d6aa999
parent7b6e3772ab7a39fc81e7524540e69eb30c4da7ac (diff)
downloadmpv-34bead485987b416685e73ca918610fff75d618d.tar.bz2
mpv-34bead485987b416685e73ca918610fff75d618d.tar.xz
vo_opengl: replace tscale-interpolates-only with interpolation-threshold
The previous approach was too naive, and can e.g. ruin playback if scheduling switches e.g. between 1 and 2 vsync per frame.
-rw-r--r--DOCS/interface-changes.rst4
-rw-r--r--DOCS/man/vo.rst16
-rw-r--r--video/out/opengl/video.c19
-rw-r--r--video/out/opengl/video.h2
4 files changed, 28 insertions, 13 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index 5b9b45faeb..8a38bcc1ce 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -28,7 +28,9 @@ Interface changes
- VO opengl custom shaders must now use "sample_pixel" as function name,
instead of "sample"
- change VO opengl scaler-resizes-only default to enabled
- - add VO opengl "tscale-interpolates-only" suboption
+ - add VO opengl "interpolation-threshold" suboption (introduces new default
+ behavior, which can change e.g. ``--video-sync=display-vdrop`` to the
+ worse, but is usually what you want)
- make "volume" and "mute" properties changeable even if no audio output is
active (this gives not-ideal behavior if --softvol=no is used)
- add "volume-max" and "mixer-active" properties
diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst
index 0725cf19e6..58bd91cd55 100644
--- a/DOCS/man/vo.rst
+++ b/DOCS/man/vo.rst
@@ -549,9 +549,19 @@ Available video output drivers are:
manifest themselves as short flashes or fringes of black, mostly
around moving edges) in exchange for potentially adding more blur.
- ``tscale-interpolates-only=<yes|no>``
- If set, then don't perform interpolation if the playback rate matches
- the display refresh rate (default: yes).
+ ``interpolation-threshold=<0..1,-1>``
+ Threshold below which frame ratio interpolation gets disabled (default:
+ ``0.0001``). This is calculated as ``abs(disphz/vfps - 1) < threshold``,
+ where ``vfps`` is the speed-adjusted display FPS, and ``disphz`` the
+ display refresh rate.
+
+ The default is intended to almost always enable interpolation if the
+ playback rate is even slightly different from the display refresh rate.
+ But note that if you use e.g. ``--video-sync=display-vdrop``, small
+ deviations in the rate can disable interpolation and introduce a
+ discontinuity every other minute.
+
+ Set this to ``-1`` to disable this logic.
``dscale-radius``, ``cscale-radius``, ``tscale-radius``, etc.
Set filter parameters for ``dscale``, ``cscale`` and ``tscale``,
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index bbf01f2cbb..6945c82f9a 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -354,8 +354,8 @@ const struct gl_video_opts gl_video_opts_def = {
.clamp = 1, }, // tscale
},
.scaler_resizes_only = 1,
- .tscale_interpolates_only = 1,
.scaler_lut_size = 6,
+ .interpolation_threshold = 0.0001,
.alpha_mode = 3,
.background = {0, 0, 0, 255},
.gamma = 1.0f,
@@ -380,8 +380,8 @@ const struct gl_video_opts gl_video_opts_hq_def = {
.clamp = 1, }, // tscale
},
.scaler_resizes_only = 1,
- .tscale_interpolates_only = 1,
.scaler_lut_size = 6,
+ .interpolation_threshold = 0.0001,
.alpha_mode = 3,
.background = {0, 0, 0, 255},
.gamma = 1.0f,
@@ -424,7 +424,6 @@ const struct m_sub_options gl_video_conf = {
SCALER_OPTS("tscale", 3),
OPT_INTRANGE("scaler-lut-size", scaler_lut_size, 0, 4, 10),
OPT_FLAG("scaler-resizes-only", scaler_resizes_only, 0),
- OPT_FLAG("tscale-interpolates-only", tscale_interpolates_only, 0),
OPT_FLAG("linear-scaling", linear_scaling, 0),
OPT_FLAG("correct-downscaling", correct_downscaling, 0),
OPT_FLAG("sigmoid-upscaling", sigmoid_upscaling, 0),
@@ -460,6 +459,7 @@ const struct m_sub_options gl_video_conf = {
OPT_FLAG("rectangle-textures", use_rectangle, 0),
OPT_COLOR("background", background, 0),
OPT_FLAG("interpolation", interpolation, 0),
+ OPT_FLOAT("interpolation-threshold", interpolation_threshold, 0),
OPT_CHOICE("blend-subtitles", blend_subs, 0,
({"no", 0},
{"yes", 1},
@@ -2260,12 +2260,15 @@ void gl_video_render_frame(struct gl_video *p, struct vo_frame *frame, int fbo)
if (has_frame) {
gl_sc_set_vao(p->sc, &p->vao);
- bool same_rate = !(frame->repeat || frame->num_vsyncs > 1);
+ bool interpolate = p->opts.interpolation && frame->display_synced &&
+ (p->frames_drawn || !frame->still);
+ if (interpolate) {
+ double ratio = frame->ideal_frame_duration / frame->vsync_interval;
+ if (fabs(ratio - 1.0) < p->opts.interpolation_threshold)
+ interpolate = false;
+ }
- if (p->opts.interpolation && frame->display_synced &&
- (p->frames_drawn || !frame->still) &&
- (!same_rate || !p->opts.tscale_interpolates_only))
- {
+ if (interpolate) {
gl_video_interpolate_frame(p, frame, fbo);
} else {
bool is_new = !frame->redraw && !frame->repeat;
diff --git a/video/out/opengl/video.h b/video/out/opengl/video.h
index ea6981705c..a1918bef39 100644
--- a/video/out/opengl/video.h
+++ b/video/out/opengl/video.h
@@ -83,7 +83,6 @@ struct gl_video_opts {
float sigmoid_center;
float sigmoid_slope;
int scaler_resizes_only;
- int tscale_interpolates_only;
int pbo;
int dither_depth;
int dither_algo;
@@ -95,6 +94,7 @@ struct gl_video_opts {
int use_rectangle;
struct m_color background;
int interpolation;
+ float interpolation_threshold;
int blend_subs;
char *scale_shader;
char **pre_shaders;