summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/vf.rst4
-rw-r--r--filters/f_autoconvert.c2
-rw-r--r--filters/f_autoconvert.h3
-rw-r--r--filters/f_swscale.c4
-rw-r--r--filters/f_swscale.h3
-rw-r--r--video/filter/vf_format.c7
-rw-r--r--video/sws_utils.c24
-rw-r--r--video/sws_utils.h9
8 files changed, 53 insertions, 3 deletions
diff --git a/DOCS/man/vf.rst b/DOCS/man/vf.rst
index 50609f978a..4f9268256c 100644
--- a/DOCS/man/vf.rst
+++ b/DOCS/man/vf.rst
@@ -335,6 +335,10 @@ Available mpv-only filters are:
but values such as ``[16:9]`` can be passed too (``[...]`` for quoting
to prevent the option parser from interpreting the ``:`` character).
+ ``<force-scaler=auto|zimg|sws>``
+ Force a specific scaler backend, if applicable. This is a debug option
+ and could go away any time.
+
``lavfi=graph[:sws-flags[:o=opts]]``
Filter video using FFmpeg's libavfilter.
diff --git a/filters/f_autoconvert.c b/filters/f_autoconvert.c
index 5e0caaf321..7452a13ae8 100644
--- a/filters/f_autoconvert.c
+++ b/filters/f_autoconvert.c
@@ -244,6 +244,8 @@ static bool build_image_converter(struct mp_autoconvert *c, struct mp_log *log,
goto fail;
}
+ sws->force_scaler = c->force_scaler;
+
int out = mp_sws_find_best_out_format(sws, src_fmt, fmts, num_fmts);
if (!out) {
mp_err(log, "can't find video conversion for %s\n",
diff --git a/filters/f_autoconvert.h b/filters/f_autoconvert.h
index 7cb144aa59..6d6660c46a 100644
--- a/filters/f_autoconvert.h
+++ b/filters/f_autoconvert.h
@@ -1,6 +1,7 @@
#pragma once
#include "filter.h"
+#include "video/sws_utils.h"
struct mp_image;
struct mp_image_params;
@@ -12,6 +13,8 @@ struct mp_autoconvert {
// f->pins[0] is input, f->pins[1] is output
struct mp_filter *f;
+ enum mp_sws_scaler force_scaler;
+
// If this is set, the callback is invoked (from the process function), and
// further data flow is blocked until mp_autoconvert_format_change_continue()
// is called. The idea is that you can reselect the output parameters on
diff --git a/filters/f_swscale.c b/filters/f_swscale.c
index f9af4d18fb..614de1466c 100644
--- a/filters/f_swscale.c
+++ b/filters/f_swscale.c
@@ -43,6 +43,8 @@
int mp_sws_find_best_out_format(struct mp_sws_filter *sws, int in_format,
int *out_formats, int num_out_formats)
{
+ sws->sws->force_scaler = sws->force_scaler;
+
int best = 0;
for (int n = 0; n < num_out_formats; n++) {
int out_format = out_formats[n];
@@ -73,6 +75,8 @@ static void process(struct mp_filter *f)
if (!mp_pin_can_transfer_data(f->ppins[1], f->ppins[0]))
return;
+ s->sws->force_scaler = s->force_scaler;
+
struct mp_frame frame = mp_pin_out_read(f->ppins[0]);
if (mp_frame_is_signaling(frame)) {
mp_pin_in_write(f->ppins[1], frame);
diff --git a/filters/f_swscale.h b/filters/f_swscale.h
index 861ad029dd..3ee7455ecd 100644
--- a/filters/f_swscale.h
+++ b/filters/f_swscale.h
@@ -3,6 +3,7 @@
#include <stdbool.h>
#include "video/mp_image.h"
+#include "video/sws_utils.h"
struct mp_sws_filter {
struct mp_filter *f;
@@ -11,6 +12,8 @@ struct mp_sws_filter {
// If set, force all image params; ignores out_format.
bool use_out_params;
struct mp_image_params out_params;
+ // Other options.
+ enum mp_sws_scaler force_scaler;
// private state
struct mp_sws_context *sws;
struct mp_image_pool *pool;
diff --git a/video/filter/vf_format.c b/video/filter/vf_format.c
index a2adcca54a..793e37bc4a 100644
--- a/video/filter/vf_format.c
+++ b/video/filter/vf_format.c
@@ -54,6 +54,7 @@ struct vf_format_opts {
int dw, dh;
double dar;
int convert;
+ int force_scaler;
};
static void set_params(struct vf_format_opts *p, struct mp_image_params *out,
@@ -175,6 +176,8 @@ static struct mp_filter *vf_format_create(struct mp_filter *parent, void *option
return NULL;
}
+ priv->conv->force_scaler = priv->opts->force_scaler;
+
if (priv->opts->fmt)
mp_autoconvert_add_imgfmt(priv->conv, priv->opts->fmt, 0);
@@ -199,6 +202,10 @@ static const m_option_t vf_opts_fields[] = {
{"dh", OPT_INT(dh)},
{"dar", OPT_DOUBLE(dar)},
{"convert", OPT_FLAG(convert)},
+ {"force-scaler", OPT_CHOICE(force_scaler,
+ {"auto", MP_SWS_AUTO},
+ {"sws", MP_SWS_SWS},
+ {"zimg", MP_SWS_ZIMG})},
{"outputlevels", OPT_REMOVED("use the --video-output-levels global option")},
{"peak", OPT_REMOVED("use sig-peak instead (changed value scale!)")},
{0}
diff --git a/video/sws_utils.c b/video/sws_utils.c
index ee37fc4f91..1a29d87308 100644
--- a/video/sws_utils.c
+++ b/video/sws_utils.c
@@ -124,18 +124,30 @@ bool mp_sws_supported_format(int imgfmt)
&& sws_isSupportedOutput(av_format);
}
+static bool allow_zimg(struct mp_sws_context *ctx)
+{
+ return ctx->force_scaler == MP_SWS_ZIMG ||
+ (ctx->force_scaler == MP_SWS_AUTO && ctx->allow_zimg);
+}
+
+static bool allow_sws(struct mp_sws_context *ctx)
+{
+ return ctx->force_scaler == MP_SWS_SWS || ctx->force_scaler == MP_SWS_AUTO;
+}
+
bool mp_sws_supports_formats(struct mp_sws_context *ctx,
int imgfmt_out, int imgfmt_in)
{
#if HAVE_ZIMG
- if (ctx->allow_zimg) {
+ if (allow_zimg(ctx)) {
if (mp_zimg_supports_in_format(imgfmt_in) &&
mp_zimg_supports_out_format(imgfmt_out))
return true;
}
#endif
- return sws_isSupportedInput(imgfmt2pixfmt(imgfmt_in)) &&
+ return allow_sws(ctx) &&
+ sws_isSupportedInput(imgfmt2pixfmt(imgfmt_in)) &&
sws_isSupportedOutput(imgfmt2pixfmt(imgfmt_out));
}
@@ -158,6 +170,7 @@ static bool cache_valid(struct mp_sws_context *ctx)
ctx->contrast == old->contrast &&
ctx->saturation == old->saturation &&
ctx->allow_zimg == old->allow_zimg &&
+ ctx->force_scaler == old->force_scaler &&
(!ctx->opts_cache || !m_config_cache_update(ctx->opts_cache));
}
@@ -232,7 +245,7 @@ int mp_sws_reinit(struct mp_sws_context *ctx)
ctx->zimg_ok = false;
#if HAVE_ZIMG
- if (ctx->allow_zimg) {
+ if (allow_zimg(ctx)) {
ctx->zimg->log = ctx->log;
ctx->zimg->src = *src;
ctx->zimg->dst = *dst;
@@ -245,6 +258,11 @@ int mp_sws_reinit(struct mp_sws_context *ctx)
}
#endif
+ if (!allow_sws(ctx)) {
+ MP_ERR(ctx, "No scaler.\n");
+ return -1;
+ }
+
ctx->sws = sws_alloc_context();
if (!ctx->sws)
return -1;
diff --git a/video/sws_utils.h b/video/sws_utils.h
index ddf628cf23..24846f544e 100644
--- a/video/sws_utils.h
+++ b/video/sws_utils.h
@@ -23,6 +23,12 @@ int mp_image_swscale(struct mp_image *dst, struct mp_image *src,
int mp_image_sw_blur_scale(struct mp_image *dst, struct mp_image *src,
float gblur);
+enum mp_sws_scaler {
+ MP_SWS_AUTO = 0, // use command line
+ MP_SWS_SWS,
+ MP_SWS_ZIMG,
+};
+
struct mp_sws_context {
// Can be set for verbose error printing.
struct mp_log *log;
@@ -36,6 +42,9 @@ struct mp_sws_context {
// Setting them before that call makes sense when using mp_sws_reinit().
struct mp_image_params src, dst;
+ // This is unfortunately a hack: bypass command line choice
+ enum mp_sws_scaler force_scaler;
+
// Changing these requires setting force_reload=true.
// By default, they are NULL.
// Freeing the mp_sws_context will deallocate these if set.