vo_opengl: add tscale-clamp option

This significantly reduces the amount of noticeable flashing when using
tscale kernels with negative lobes, by cutting them off completely.

I'm not sure if this has any negative effects. It needs a bit of
subjective testing over a period of time, so I just made it an option.

Fixes #2155.
This commit is contained in:
Niklas Haas 2015-08-20 21:45:58 +02:00 committed by wm4
parent 96648169e3
commit e1fd80097c
5 changed files with 15 additions and 2 deletions

View File

@ -506,6 +506,12 @@ Available video output drivers are:
limitations in the number of video textures that can be loaded
simultaneously.
``tscale-clamp``
Clamp the ``tscale`` filter kernel's value range to [0-1]. This reduces
excessive ringing artifacts in the temporal domain (which typically
manifest themselves as short flashes or fringes of black, mostly
around moving edges) in exchange for potentially adding more blur.
``dscale-radius``, ``cscale-radius``, ``tscale-radius``, etc.
Set filter parameters for ``dscale``, ``cscale`` and ``tscale``,
respectively.

View File

@ -113,7 +113,8 @@ static double sample_filter(struct filter_kernel *filter,
double w = window->weight ? window->weight(window, x/bw * window->radius
/ filter->f.radius)
: 1.0;
return c < filter->f.radius ? w * filter->f.weight(&filter->f, c) : 0.0;
double v = c < filter->f.radius ? w * filter->f.weight(&filter->f, c) : 0.0;
return filter->clamp ? fmax(0.0, fmin(1.0, v)) : v;
}
// Calculate the 1D filtering kernel for N sample points.

View File

@ -33,6 +33,7 @@ struct filter_window {
struct filter_kernel {
struct filter_window f; // the kernel itself
struct filter_window w; // window storage
bool clamp; // clamp to the range [0-1]
// Constant values
const char *window; // default window
bool polar; // whether or not the filter uses polar coordinates

View File

@ -415,6 +415,7 @@ const struct m_sub_options gl_video_conf = {
OPT_FLOATRANGE("dscale-antiring", scaler[1].antiring, 0, 0.0, 1.0),
OPT_FLOATRANGE("cscale-antiring", scaler[2].antiring, 0, 0.0, 1.0),
OPT_FLOATRANGE("tscale-antiring", scaler[3].antiring, 0, 0.0, 1.0),
OPT_FLAG("tscale-clamp", scaler[3].clamp, 0),
OPT_FLAG("scaler-resizes-only", scaler_resizes_only, 0),
OPT_FLAG("linear-scaling", linear_scaling, 0),
OPT_FLAG("fancy-downscaling", fancy_downscaling, 0),
@ -950,7 +951,8 @@ static bool scaler_conf_eq(struct scaler_config a, struct scaler_config b)
// generation
return scaler_fun_eq(a.kernel, b.kernel) &&
scaler_fun_eq(a.window, b.window) &&
a.radius == b.radius;
a.radius == b.radius &&
a.clamp == b.clamp;
}
static void reinit_scaler(struct gl_video *p, struct scaler *scaler,
@ -1001,6 +1003,8 @@ static void reinit_scaler(struct gl_video *p, struct scaler *scaler,
if (scaler->kernel->f.resizable && conf->radius > 0.0)
scaler->kernel->f.radius = conf->radius;
scaler->kernel->clamp = conf->clamp;
scaler->insufficient = !mp_init_filter(scaler->kernel, sizes, scale_factor);
if (scaler->kernel->polar) {

View File

@ -39,6 +39,7 @@ struct scaler_config {
struct scaler_fun window;
float radius;
float antiring;
int clamp;
};
struct gl_video_opts {