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:
wm4 2012-01-08 18:25:26 +01:00
parent ae16c751c8
commit 278094e233
1 changed files with 23 additions and 2 deletions

View File

@ -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 }
};