mirror of
https://github.com/mpv-player/mpv
synced 2024-10-30 04:46:41 +01:00
vf_gradfun: add size parameter, which sets radius according to movie diagonal
This patch adds a "size" parameter, which scales the filter radius according to movie diagonal, the unit being percent of diagonal. This makes the effect far more predictable across movies of different resolutions. Usage example (with possibly useless values): -vf gradfun=strength=1.2:size=2.3 Based on a patch by Radosław Szkodziński <astralstorm@gmail.com>
This commit is contained in:
parent
ae16c751c8
commit
278094e233
@ -31,6 +31,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "cpudetect.h"
|
||||
@ -47,6 +48,7 @@
|
||||
struct vf_priv_s {
|
||||
float cfg_thresh;
|
||||
int cfg_radius;
|
||||
float cfg_size;
|
||||
int thresh;
|
||||
int radius;
|
||||
uint16_t *buf;
|
||||
@ -56,7 +58,8 @@ struct vf_priv_s {
|
||||
uint8_t *src, int sstride, int width);
|
||||
} const vf_priv_dflt = {
|
||||
.cfg_thresh = 1.2,
|
||||
.cfg_radius = 16,
|
||||
.cfg_radius = -1,
|
||||
.cfg_size = -1,
|
||||
};
|
||||
|
||||
static const uint16_t __attribute__((aligned(16))) pw_7f[8] = {127,127,127,127,127,127,127,127};
|
||||
@ -362,6 +365,12 @@ static int config(struct vf_instance *vf,
|
||||
unsigned int flags, unsigned int outfmt)
|
||||
{
|
||||
free(vf->priv->buf);
|
||||
vf->priv->radius = vf->priv->cfg_radius;
|
||||
if (vf->priv->cfg_size > -1) {
|
||||
vf->priv->radius = (vf->priv->cfg_size / 100.0f)
|
||||
* sqrtf(width * width + height * height);
|
||||
}
|
||||
vf->priv->radius = av_clip((vf->priv->radius+1)&~1, 4, 32);
|
||||
vf->priv->buf = av_mallocz((((width+15)&~15)*(vf->priv->radius+1)/2+32)*sizeof(uint16_t));
|
||||
return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
|
||||
}
|
||||
@ -382,8 +391,19 @@ static int vf_open(vf_instance_t *vf, char *args)
|
||||
vf->config=config;
|
||||
vf->uninit=uninit;
|
||||
|
||||
bool have_radius = vf->priv->cfg_radius > -1;
|
||||
bool have_size = vf->priv->cfg_size > -1;
|
||||
|
||||
if (have_radius && have_size) {
|
||||
mp_msg(MSGT_VFILTER, MSGL_ERR, "scale: gradfun: only one of "
|
||||
"radius/size parameters allowed at the same time!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!have_radius && !have_size)
|
||||
vf->priv->cfg_radius = 16;
|
||||
|
||||
vf->priv->thresh = (1<<15)/av_clipf(vf->priv->cfg_thresh,0.51,255);
|
||||
vf->priv->radius = av_clip((vf->priv->cfg_radius+1)&~1,4,32);
|
||||
|
||||
vf->priv->blur_line = blur_line_c;
|
||||
vf->priv->filter_line = filter_line_c;
|
||||
@ -408,6 +428,7 @@ static int vf_open(vf_instance_t *vf, char *args)
|
||||
static const m_option_t vf_opts_fields[] = {
|
||||
{"strength", ST_OFF(cfg_thresh), CONF_TYPE_FLOAT, M_OPT_RANGE, 0.51, 255, NULL},
|
||||
{"radius", ST_OFF(cfg_radius), CONF_TYPE_INT, M_OPT_RANGE, 4, 32, NULL},
|
||||
{"size", ST_OFF(cfg_size), CONF_TYPE_FLOAT, M_OPT_RANGE, 0.1, 5.0, NULL},
|
||||
{ NULL, NULL, 0, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user