mirror of https://github.com/mpv-player/mpv
sws_utils, zimg: destroy vo_x11 and vo_drm performance
Raise swscale and zimg default parameters. This restores screenshot quality settings (maybe) unset in the commit before. Also expose some more libswscale and zimg options. Since these options are also used for VOs like x11 and drm, this will make x11/drm/etc. much slower. For compensation, provide a profile that sets the old option values: sw-fast. I'm also enabling zimg here, just as an experiment. The core problem is that we have a single set of command line options which control the settings used for most swscale/zimg uses. This was done in the previous commit. It cannot differentiate between the VOs, which need to be realtime and may accept/require lower quality options, and things like screenshots or vo_image, which can be slower, but should not sacrifice quality by default. Should this have two sets of options or something similar to do the right thing depending on the code which calls libswscale? Maybe. Or should I just ignore the problem, make it someone else's problem (users who want to use software conversion VOs), provide a sub-optimal solution, and call it a day? Definitely, sounds good, pushing to master, goodbye.
This commit is contained in:
parent
2c43d2b75a
commit
a7230dfed0
|
@ -27,6 +27,8 @@ Interface changes
|
|||
--- mpv 0.31.0 ---
|
||||
- add `--d3d11-output-csp` to enable explicit selection of a D3D11
|
||||
swap chain color space.
|
||||
- add an builtin "sw-fast" profile, which restores performance settings
|
||||
that were switched to higher quality since mpv 0.30.0
|
||||
--- mpv 0.30.0 ---
|
||||
- add `--d3d11-output-format` to enable explicit selection of a D3D11
|
||||
swap chain format.
|
||||
|
|
|
@ -3833,6 +3833,21 @@ Software Scaler
|
|||
``--sws-cvs=<v>``
|
||||
Software scaler chroma vertical shifting. See ``--sws-scaler``.
|
||||
|
||||
``--sws-bitexact=<yes|no>``
|
||||
Unknown functionality (default: no). Consult libswscale source code. The
|
||||
primary purpose of this, as far as libswscale API goes), is to produce
|
||||
exactly the same output for the same input on all platforms (output has the
|
||||
same "bits" everywhere, thus "bitexact"). Typically disables optimizations.
|
||||
|
||||
``--sws-fast=<yes|no>``
|
||||
Allow optimizations that help with performance, but reduce quality (default:
|
||||
no).
|
||||
|
||||
VOs like ``drm`` and ``x11`` will benefit a lot from using ``--sws-fast``.
|
||||
You may need to set other options, like ``--sws-scaler``. The builtin
|
||||
``sws-fast`` profile sets this option and some others to gain performance
|
||||
for reduced quality.
|
||||
|
||||
``--sws-allow-zimg=<yes|no>``
|
||||
Allow using zimg (if the component using the internal swscale wrapper
|
||||
explicitly allows so). In this case, zimg *may* be used, if the internal
|
||||
|
@ -3846,14 +3861,34 @@ Software Scaler
|
|||
correctly, a verbose priority log message will indicate whether zimg is
|
||||
being used.
|
||||
|
||||
Currently, barely anything uses this.
|
||||
Most things which need software conversion can make use of this.
|
||||
|
||||
``--zimg--scaler=<point|bilinear|bicubic|spline16|lanczos>``
|
||||
``--zimg--scaler=<point|bilinear|bicubic|spline16|spline36|lanczos>``
|
||||
Zimg luma scaler to use (default: bilinear).
|
||||
|
||||
``--zimg-scaler-param-a=<default|float>``, ``--zimg-scaler-param-b=<default|float>``
|
||||
Set scaler parameters. By default, these are set to the special string
|
||||
``default``, which maps to a scaler-specific default value. Ignored if the
|
||||
scaler is not tunable.
|
||||
|
||||
``lanczos``
|
||||
``--zimg-scaler-param-a`` is the number of taps.
|
||||
|
||||
``bicubic``
|
||||
a and b are the bicubic b and c parameters.
|
||||
|
||||
``--zimg-scaler-chroma=...``
|
||||
Same as ``--zimg--scaler``, for for chroma interpolation.
|
||||
|
||||
``--zimg-scaler-chroma-param-a``, ``--zimg-scaler-chroma-param-b``
|
||||
Same as ``--zimg-scaler-param-a`` / ``--zimg-scaler-param-b``, for chroma.
|
||||
|
||||
``--zimg-dither=<no|ordered|random|error-diffusion>``
|
||||
Dithering (default: random).
|
||||
|
||||
``--zimg-fast=<yes|no>``
|
||||
Allow optimizations that help with performance, but reduce quality (default:
|
||||
yes). Currently, this may simplify gamma conversion operations.
|
||||
no). Currently, this may simplify gamma conversion operations.
|
||||
|
||||
|
||||
Audio Resampler
|
||||
|
|
|
@ -71,6 +71,9 @@ Available video output drivers are:
|
|||
Shared memory video output driver without hardware acceleration that works
|
||||
whenever X11 is present.
|
||||
|
||||
Since mpv 0.30.0, you may need to use ``--profile=sw-fast`` to get decent
|
||||
performance.
|
||||
|
||||
.. note:: This is a fallback only, and should not be normally used.
|
||||
|
||||
``vdpau`` (X11 only)
|
||||
|
@ -383,6 +386,9 @@ Available video output drivers are:
|
|||
Depends on support of true color by modern terminals to display the images
|
||||
at full color range. On Windows it requires an ansi terminal such as mintty.
|
||||
|
||||
Since mpv 0.30.0, you may need to use ``--profile=sw-fast`` to get decent
|
||||
performance.
|
||||
|
||||
``--vo-tct-algo=<algo>``
|
||||
Select how to write the pixels to the terminal.
|
||||
|
||||
|
@ -482,6 +488,9 @@ Available video output drivers are:
|
|||
environment (e.g. no X). Does not support hardware acceleration (if you
|
||||
need this, check the ``drm`` backend for ``gpu`` VO).
|
||||
|
||||
Since mpv 0.30.0, you may need to use ``--profile=sw-fast`` to get decent
|
||||
performance.
|
||||
|
||||
The following global options are supported by this video output:
|
||||
|
||||
``--drm-connector=[<gpu_number>.]<name>``
|
||||
|
@ -583,4 +592,7 @@ Available video output drivers are:
|
|||
Shared memory video output driver without hardware acceleration that works
|
||||
whenever Wayland is present.
|
||||
|
||||
Since mpv 0.30.0, you may need to use ``--profile=sw-fast`` to get decent
|
||||
performance.
|
||||
|
||||
.. note:: This is a fallback only, and should not be normally used.
|
||||
|
|
|
@ -62,6 +62,15 @@ video-sync=audio # DS currently requires reading ahead a frame
|
|||
interpolation=no # requires reference frames (more buffering)
|
||||
video-latency-hacks=yes # typically 1 or 2 video frame less latency
|
||||
|
||||
[sw-fast]
|
||||
# For VOs which use software scalers, also affects screenshots and others.
|
||||
sws-scaler=bilinear
|
||||
sws-fast=yes
|
||||
sws-allow-zimg=yes
|
||||
zimg-scaler=bilinear
|
||||
zimg-dither=no
|
||||
zimg-fast=yes
|
||||
|
||||
# Compatibility alias (deprecated)
|
||||
[opengl-hq]
|
||||
profile=gpu-hq
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "common/common.h"
|
||||
#include "common/tags.h"
|
||||
#include "filters/filter.h"
|
||||
|
@ -204,6 +206,14 @@ static struct mp_filter *f_create(struct mp_filter *parent, void *options)
|
|||
MP_HANDLE_OOM(p->sws);
|
||||
p->zimg = mp_zimg_alloc();
|
||||
talloc_steal(p, p->zimg);
|
||||
p->zimg->opts = (struct zimg_opts){
|
||||
.scaler = ZIMG_RESIZE_BILINEAR,
|
||||
.scaler_params = {NAN, NAN},
|
||||
.scaler_chroma_params = {NAN, NAN},
|
||||
.scaler_chroma = ZIMG_RESIZE_BILINEAR,
|
||||
.dither = ZIMG_DITHER_NONE,
|
||||
.fast = 1,
|
||||
};
|
||||
return f;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,8 @@ struct sws_opts {
|
|||
int chr_hshift;
|
||||
float chr_sharpen;
|
||||
float lum_sharpen;
|
||||
int fast;
|
||||
int bitexact;
|
||||
int zimg;
|
||||
};
|
||||
|
||||
|
@ -73,19 +75,20 @@ const struct m_sub_options sws_conf = {
|
|||
OPT_INT("chs", chr_hshift, 0),
|
||||
OPT_FLOATRANGE("ls", lum_sharpen, 0, -100.0, 100.0),
|
||||
OPT_FLOATRANGE("cs", chr_sharpen, 0, -100.0, 100.0),
|
||||
OPT_FLAG("fast", fast, 0),
|
||||
OPT_FLAG("bitexact", bitexact, 0),
|
||||
OPT_FLAG("allow-zimg", zimg, 0),
|
||||
{0}
|
||||
},
|
||||
.size = sizeof(struct sws_opts),
|
||||
.defaults = &(const struct sws_opts){
|
||||
.scaler = SWS_BICUBIC,
|
||||
.scaler = SWS_LANCZOS,
|
||||
},
|
||||
};
|
||||
|
||||
// Highest quality, but also slowest.
|
||||
const int mp_sws_hq_flags = SWS_LANCZOS | SWS_FULL_CHR_H_INT |
|
||||
SWS_FULL_CHR_H_INP | SWS_ACCURATE_RND |
|
||||
SWS_BITEXACT;
|
||||
static const int mp_sws_hq_flags = SWS_FULL_CHR_H_INT | SWS_FULL_CHR_H_INP |
|
||||
SWS_ACCURATE_RND;
|
||||
|
||||
// Fast, lossy.
|
||||
const int mp_sws_fast_flags = SWS_BILINEAR;
|
||||
|
@ -104,6 +107,10 @@ static void mp_sws_update_from_cmdline(struct mp_sws_context *ctx)
|
|||
|
||||
ctx->flags = SWS_PRINT_INFO;
|
||||
ctx->flags |= opts->scaler;
|
||||
if (!opts->fast)
|
||||
ctx->flags |= mp_sws_hq_flags;
|
||||
if (opts->bitexact)
|
||||
ctx->flags |= SWS_BITEXACT;
|
||||
|
||||
ctx->allow_zimg = opts->zimg;
|
||||
}
|
||||
|
@ -357,7 +364,7 @@ int mp_image_sw_blur_scale(struct mp_image *dst, struct mp_image *src,
|
|||
float gblur)
|
||||
{
|
||||
struct mp_sws_context *ctx = mp_sws_alloc(NULL);
|
||||
ctx->flags = mp_sws_hq_flags;
|
||||
ctx->flags = SWS_LANCZOS | mp_sws_hq_flags;
|
||||
ctx->src_filter = sws_getDefaultFilter(gblur, gblur, 0, 0, 0, 0, 0);
|
||||
ctx->force_reload = true;
|
||||
int res = mp_sws_scale(ctx, dst, src);
|
||||
|
|
|
@ -13,7 +13,6 @@ struct mpv_global;
|
|||
// Guaranteed to be a power of 2 and > 1.
|
||||
#define SWS_MIN_BYTE_ALIGN MP_IMAGE_BYTE_ALIGN
|
||||
|
||||
extern const int mp_sws_hq_flags;
|
||||
extern const int mp_sws_fast_flags;
|
||||
|
||||
bool mp_sws_supported_format(int imgfmt);
|
||||
|
|
69
video/zimg.c
69
video/zimg.c
|
@ -27,27 +27,43 @@
|
|||
|
||||
static_assert(MP_IMAGE_BYTE_ALIGN >= ZIMG_ALIGN, "");
|
||||
|
||||
struct zimg_opts {
|
||||
int scaler;
|
||||
int fast;
|
||||
static const struct m_opt_choice_alternatives mp_zimg_scalers[] = {
|
||||
{"point", ZIMG_RESIZE_POINT},
|
||||
{"bilinear", ZIMG_RESIZE_BILINEAR},
|
||||
{"bicubic", ZIMG_RESIZE_BICUBIC},
|
||||
{"spline16", ZIMG_RESIZE_SPLINE16},
|
||||
{"spline36", ZIMG_RESIZE_SPLINE36},
|
||||
{"lanczos", ZIMG_RESIZE_LANCZOS},
|
||||
{0}
|
||||
};
|
||||
|
||||
#define OPT_PARAM(name, var, flags) \
|
||||
OPT_DOUBLE(name, var, (flags) | M_OPT_DEFAULT_NAN)
|
||||
|
||||
#define OPT_BASE_STRUCT struct zimg_opts
|
||||
const struct m_sub_options zimg_conf = {
|
||||
.opts = (struct m_option[]) {
|
||||
OPT_CHOICE("scaler", scaler, 0,
|
||||
({"point", ZIMG_RESIZE_POINT},
|
||||
{"bilinear", ZIMG_RESIZE_BILINEAR},
|
||||
{"bicubic", ZIMG_RESIZE_BICUBIC},
|
||||
{"spline16", ZIMG_RESIZE_SPLINE16},
|
||||
{"lanczos", ZIMG_RESIZE_LANCZOS})),
|
||||
OPT_CHOICE_C("scaler", scaler, 0, mp_zimg_scalers),
|
||||
OPT_PARAM("scaler-param-a", scaler_params[0], 0),
|
||||
OPT_PARAM("scaler-param-b", scaler_params[1], 0),
|
||||
OPT_CHOICE_C("scaler-chroma", scaler_chroma, 0, mp_zimg_scalers),
|
||||
OPT_PARAM("scaler-chroma-param-a", scaler_chroma_params[0], 0),
|
||||
OPT_PARAM("scaler-chroma-param-b", scaler_chroma_params[1], 0),
|
||||
OPT_CHOICE("dither", dither, 0,
|
||||
({"no", ZIMG_DITHER_NONE},
|
||||
{"ordered", ZIMG_DITHER_ORDERED},
|
||||
{"random", ZIMG_DITHER_RANDOM},
|
||||
{"error-diffusion", ZIMG_DITHER_ERROR_DIFFUSION})),
|
||||
OPT_FLAG("fast", fast, 0),
|
||||
{0}
|
||||
},
|
||||
.size = sizeof(struct zimg_opts),
|
||||
.defaults = &(const struct zimg_opts){
|
||||
.scaler = ZIMG_RESIZE_BILINEAR,
|
||||
.fast = 1,
|
||||
.scaler = ZIMG_RESIZE_LANCZOS,
|
||||
.scaler_params = {NAN, NAN},
|
||||
.scaler_chroma_params = {NAN, NAN},
|
||||
.scaler_chroma = ZIMG_RESIZE_BILINEAR,
|
||||
.dither = ZIMG_DITHER_RANDOM,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -90,9 +106,7 @@ static void mp_zimg_update_from_cmdline(struct mp_zimg_context *ctx)
|
|||
m_config_cache_update(ctx->opts_cache);
|
||||
|
||||
struct zimg_opts *opts = ctx->opts_cache->opts;
|
||||
|
||||
ctx->scaler = opts->scaler;
|
||||
ctx->fast = opts->fast;
|
||||
ctx->opts = *opts;
|
||||
}
|
||||
|
||||
static zimg_chroma_location_e mp_to_z_chroma(enum mp_chroma_location cl)
|
||||
|
@ -183,13 +197,8 @@ struct mp_zimg_context *mp_zimg_alloc(void)
|
|||
struct mp_zimg_context *ctx = talloc_ptrtype(NULL, ctx);
|
||||
*ctx = (struct mp_zimg_context) {
|
||||
.log = mp_null_log,
|
||||
.scaler = ZIMG_RESIZE_BILINEAR,
|
||||
.scaler_params = {NAN, NAN},
|
||||
.scaler_chroma = ZIMG_RESIZE_BILINEAR,
|
||||
.scaler_chroma_params = {NAN, NAN},
|
||||
.dither = ZIMG_DITHER_NONE,
|
||||
.fast = true,
|
||||
};
|
||||
ctx->opts = *(struct zimg_opts *)zimg_conf.defaults;
|
||||
talloc_set_destructor(ctx, free_mp_zimg);
|
||||
return ctx;
|
||||
}
|
||||
|
@ -504,7 +513,7 @@ static bool setup_format(zimg_image_format *zfmt, struct mp_zimg_repack *r,
|
|||
zfmt->color_primaries = mp_to_z_prim(fmt.color.primaries);
|
||||
zfmt->chroma_location = mp_to_z_chroma(fmt.chroma_location);
|
||||
|
||||
if (ctx && ctx->fast) {
|
||||
if (ctx && ctx->opts.fast) {
|
||||
// mpv's default for RGB output slows down zimg significantly.
|
||||
if (zfmt->transfer_characteristics == ZIMG_TRANSFER_IEC_61966_2_1 &&
|
||||
zfmt->color_family == ZIMG_COLOR_RGB)
|
||||
|
@ -547,6 +556,8 @@ static bool allocate_buffer(struct mp_zimg_context *ctx,
|
|||
|
||||
bool mp_zimg_config(struct mp_zimg_context *ctx)
|
||||
{
|
||||
struct zimg_opts *opts = &ctx->opts;
|
||||
|
||||
destroy_zimg(ctx);
|
||||
|
||||
if (ctx->opts_cache)
|
||||
|
@ -569,19 +580,19 @@ bool mp_zimg_config(struct mp_zimg_context *ctx)
|
|||
zimg_graph_builder_params params;
|
||||
zimg_graph_builder_params_default(¶ms, ZIMG_API_VERSION);
|
||||
|
||||
params.resample_filter = ctx->scaler;
|
||||
params.filter_param_a = ctx->scaler_params[0];
|
||||
params.filter_param_b = ctx->scaler_params[1];
|
||||
params.resample_filter = opts->scaler;
|
||||
params.filter_param_a = opts->scaler_params[0];
|
||||
params.filter_param_b = opts->scaler_params[1];
|
||||
|
||||
params.resample_filter_uv = ctx->scaler_chroma;
|
||||
params.filter_param_a_uv = ctx->scaler_chroma_params[0];
|
||||
params.filter_param_b_uv = ctx->scaler_chroma_params[1];
|
||||
params.resample_filter_uv = opts->scaler_chroma;
|
||||
params.filter_param_a_uv = opts->scaler_chroma_params[0];
|
||||
params.filter_param_b_uv = opts->scaler_chroma_params[1];
|
||||
|
||||
params.dither_type = ctx->dither;
|
||||
params.dither_type = opts->dither;
|
||||
|
||||
params.cpu_type = ZIMG_CPU_AUTO_64B;
|
||||
|
||||
if (ctx->fast)
|
||||
if (opts->fast)
|
||||
params.allow_approximate_gamma = 1;
|
||||
|
||||
if (ctx->src.color.sig_peak > 0)
|
||||
|
|
16
video/zimg.h
16
video/zimg.h
|
@ -13,6 +13,15 @@ struct mpv_global;
|
|||
bool mp_zimg_supports_in_format(int imgfmt);
|
||||
bool mp_zimg_supports_out_format(int imgfmt);
|
||||
|
||||
struct zimg_opts {
|
||||
int scaler;
|
||||
double scaler_params[2];
|
||||
int scaler_chroma;
|
||||
double scaler_chroma_params[2];
|
||||
int dither;
|
||||
int fast;
|
||||
};
|
||||
|
||||
struct mp_zimg_context {
|
||||
// Can be set for verbose error printing.
|
||||
struct mp_log *log;
|
||||
|
@ -20,12 +29,7 @@ struct mp_zimg_context {
|
|||
// User configuration. Note: changing these requires calling mp_zimg_config()
|
||||
// to update the filter graph. The first mp_zimg_convert() call (or if the
|
||||
// image format changes) will do this automatically.
|
||||
zimg_resample_filter_e scaler;
|
||||
double scaler_params[2];
|
||||
zimg_resample_filter_e scaler_chroma;
|
||||
double scaler_chroma_params[2];
|
||||
zimg_dither_type_e dither;
|
||||
bool fast; // reduce quality for better performance
|
||||
struct zimg_opts opts;
|
||||
|
||||
// Input/output parameters. Note: if these mismatch with the
|
||||
// mp_zimg_convert() parameters, mp_zimg_config() will be called
|
||||
|
|
Loading…
Reference in New Issue