mirror of https://github.com/mpv-player/mpv
vf_format: add gross mechanism for forcing scaler for testing
This sucks, but is helpful for testing. Obviously, it would be much nicer if there were a way to specify _all_ scaler options per filter (if the user wanted), instead of always using the global options. But this is "too hard" for now. For testing, it is extremely convenient to select the scaler backend, so add this option, but make clear that it could go away. We'd delete it once there is a better mechanism for this.
This commit is contained in:
parent
28f2d7454d
commit
c99d95ac17
|
@ -335,6 +335,10 @@ Available mpv-only filters are:
|
||||||
but values such as ``[16:9]`` can be passed too (``[...]`` for quoting
|
but values such as ``[16:9]`` can be passed too (``[...]`` for quoting
|
||||||
to prevent the option parser from interpreting the ``:`` character).
|
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]]``
|
``lavfi=graph[:sws-flags[:o=opts]]``
|
||||||
Filter video using FFmpeg's libavfilter.
|
Filter video using FFmpeg's libavfilter.
|
||||||
|
|
||||||
|
|
|
@ -244,6 +244,8 @@ static bool build_image_converter(struct mp_autoconvert *c, struct mp_log *log,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sws->force_scaler = c->force_scaler;
|
||||||
|
|
||||||
int out = mp_sws_find_best_out_format(sws, src_fmt, fmts, num_fmts);
|
int out = mp_sws_find_best_out_format(sws, src_fmt, fmts, num_fmts);
|
||||||
if (!out) {
|
if (!out) {
|
||||||
mp_err(log, "can't find video conversion for %s\n",
|
mp_err(log, "can't find video conversion for %s\n",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
|
#include "video/sws_utils.h"
|
||||||
|
|
||||||
struct mp_image;
|
struct mp_image;
|
||||||
struct mp_image_params;
|
struct mp_image_params;
|
||||||
|
@ -12,6 +13,8 @@ struct mp_autoconvert {
|
||||||
// f->pins[0] is input, f->pins[1] is output
|
// f->pins[0] is input, f->pins[1] is output
|
||||||
struct mp_filter *f;
|
struct mp_filter *f;
|
||||||
|
|
||||||
|
enum mp_sws_scaler force_scaler;
|
||||||
|
|
||||||
// If this is set, the callback is invoked (from the process function), and
|
// If this is set, the callback is invoked (from the process function), and
|
||||||
// further data flow is blocked until mp_autoconvert_format_change_continue()
|
// further data flow is blocked until mp_autoconvert_format_change_continue()
|
||||||
// is called. The idea is that you can reselect the output parameters on
|
// is called. The idea is that you can reselect the output parameters on
|
||||||
|
|
|
@ -43,6 +43,8 @@
|
||||||
int mp_sws_find_best_out_format(struct mp_sws_filter *sws, int in_format,
|
int mp_sws_find_best_out_format(struct mp_sws_filter *sws, int in_format,
|
||||||
int *out_formats, int num_out_formats)
|
int *out_formats, int num_out_formats)
|
||||||
{
|
{
|
||||||
|
sws->sws->force_scaler = sws->force_scaler;
|
||||||
|
|
||||||
int best = 0;
|
int best = 0;
|
||||||
for (int n = 0; n < num_out_formats; n++) {
|
for (int n = 0; n < num_out_formats; n++) {
|
||||||
int out_format = 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]))
|
if (!mp_pin_can_transfer_data(f->ppins[1], f->ppins[0]))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
s->sws->force_scaler = s->force_scaler;
|
||||||
|
|
||||||
struct mp_frame frame = mp_pin_out_read(f->ppins[0]);
|
struct mp_frame frame = mp_pin_out_read(f->ppins[0]);
|
||||||
if (mp_frame_is_signaling(frame)) {
|
if (mp_frame_is_signaling(frame)) {
|
||||||
mp_pin_in_write(f->ppins[1], frame);
|
mp_pin_in_write(f->ppins[1], frame);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "video/mp_image.h"
|
#include "video/mp_image.h"
|
||||||
|
#include "video/sws_utils.h"
|
||||||
|
|
||||||
struct mp_sws_filter {
|
struct mp_sws_filter {
|
||||||
struct mp_filter *f;
|
struct mp_filter *f;
|
||||||
|
@ -11,6 +12,8 @@ struct mp_sws_filter {
|
||||||
// If set, force all image params; ignores out_format.
|
// If set, force all image params; ignores out_format.
|
||||||
bool use_out_params;
|
bool use_out_params;
|
||||||
struct mp_image_params out_params;
|
struct mp_image_params out_params;
|
||||||
|
// Other options.
|
||||||
|
enum mp_sws_scaler force_scaler;
|
||||||
// private state
|
// private state
|
||||||
struct mp_sws_context *sws;
|
struct mp_sws_context *sws;
|
||||||
struct mp_image_pool *pool;
|
struct mp_image_pool *pool;
|
||||||
|
|
|
@ -54,6 +54,7 @@ struct vf_format_opts {
|
||||||
int dw, dh;
|
int dw, dh;
|
||||||
double dar;
|
double dar;
|
||||||
int convert;
|
int convert;
|
||||||
|
int force_scaler;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void set_params(struct vf_format_opts *p, struct mp_image_params *out,
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->conv->force_scaler = priv->opts->force_scaler;
|
||||||
|
|
||||||
if (priv->opts->fmt)
|
if (priv->opts->fmt)
|
||||||
mp_autoconvert_add_imgfmt(priv->conv, priv->opts->fmt, 0);
|
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)},
|
{"dh", OPT_INT(dh)},
|
||||||
{"dar", OPT_DOUBLE(dar)},
|
{"dar", OPT_DOUBLE(dar)},
|
||||||
{"convert", OPT_FLAG(convert)},
|
{"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")},
|
{"outputlevels", OPT_REMOVED("use the --video-output-levels global option")},
|
||||||
{"peak", OPT_REMOVED("use sig-peak instead (changed value scale!)")},
|
{"peak", OPT_REMOVED("use sig-peak instead (changed value scale!)")},
|
||||||
{0}
|
{0}
|
||||||
|
|
|
@ -124,18 +124,30 @@ bool mp_sws_supported_format(int imgfmt)
|
||||||
&& sws_isSupportedOutput(av_format);
|
&& 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,
|
bool mp_sws_supports_formats(struct mp_sws_context *ctx,
|
||||||
int imgfmt_out, int imgfmt_in)
|
int imgfmt_out, int imgfmt_in)
|
||||||
{
|
{
|
||||||
#if HAVE_ZIMG
|
#if HAVE_ZIMG
|
||||||
if (ctx->allow_zimg) {
|
if (allow_zimg(ctx)) {
|
||||||
if (mp_zimg_supports_in_format(imgfmt_in) &&
|
if (mp_zimg_supports_in_format(imgfmt_in) &&
|
||||||
mp_zimg_supports_out_format(imgfmt_out))
|
mp_zimg_supports_out_format(imgfmt_out))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return sws_isSupportedInput(imgfmt2pixfmt(imgfmt_in)) &&
|
return allow_sws(ctx) &&
|
||||||
|
sws_isSupportedInput(imgfmt2pixfmt(imgfmt_in)) &&
|
||||||
sws_isSupportedOutput(imgfmt2pixfmt(imgfmt_out));
|
sws_isSupportedOutput(imgfmt2pixfmt(imgfmt_out));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +170,7 @@ static bool cache_valid(struct mp_sws_context *ctx)
|
||||||
ctx->contrast == old->contrast &&
|
ctx->contrast == old->contrast &&
|
||||||
ctx->saturation == old->saturation &&
|
ctx->saturation == old->saturation &&
|
||||||
ctx->allow_zimg == old->allow_zimg &&
|
ctx->allow_zimg == old->allow_zimg &&
|
||||||
|
ctx->force_scaler == old->force_scaler &&
|
||||||
(!ctx->opts_cache || !m_config_cache_update(ctx->opts_cache));
|
(!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;
|
ctx->zimg_ok = false;
|
||||||
|
|
||||||
#if HAVE_ZIMG
|
#if HAVE_ZIMG
|
||||||
if (ctx->allow_zimg) {
|
if (allow_zimg(ctx)) {
|
||||||
ctx->zimg->log = ctx->log;
|
ctx->zimg->log = ctx->log;
|
||||||
ctx->zimg->src = *src;
|
ctx->zimg->src = *src;
|
||||||
ctx->zimg->dst = *dst;
|
ctx->zimg->dst = *dst;
|
||||||
|
@ -245,6 +258,11 @@ int mp_sws_reinit(struct mp_sws_context *ctx)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!allow_sws(ctx)) {
|
||||||
|
MP_ERR(ctx, "No scaler.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->sws = sws_alloc_context();
|
ctx->sws = sws_alloc_context();
|
||||||
if (!ctx->sws)
|
if (!ctx->sws)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -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,
|
int mp_image_sw_blur_scale(struct mp_image *dst, struct mp_image *src,
|
||||||
float gblur);
|
float gblur);
|
||||||
|
|
||||||
|
enum mp_sws_scaler {
|
||||||
|
MP_SWS_AUTO = 0, // use command line
|
||||||
|
MP_SWS_SWS,
|
||||||
|
MP_SWS_ZIMG,
|
||||||
|
};
|
||||||
|
|
||||||
struct mp_sws_context {
|
struct mp_sws_context {
|
||||||
// Can be set for verbose error printing.
|
// Can be set for verbose error printing.
|
||||||
struct mp_log *log;
|
struct mp_log *log;
|
||||||
|
@ -36,6 +42,9 @@ struct mp_sws_context {
|
||||||
// Setting them before that call makes sense when using mp_sws_reinit().
|
// Setting them before that call makes sense when using mp_sws_reinit().
|
||||||
struct mp_image_params src, dst;
|
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.
|
// Changing these requires setting force_reload=true.
|
||||||
// By default, they are NULL.
|
// By default, they are NULL.
|
||||||
// Freeing the mp_sws_context will deallocate these if set.
|
// Freeing the mp_sws_context will deallocate these if set.
|
||||||
|
|
Loading…
Reference in New Issue