62 char luma_radius_expr [256];
63 char chroma_radius_expr[256];
64 char alpha_radius_expr [256];
84 "Filter expects 2 or 4 or 6 arguments, none provided\n");
88 e = sscanf(args,
"%255[^:]:%d:%255[^:]:%d:%255[^:]:%d",
93 if (e != 2 && e != 4 && e != 6) {
95 "Filter expects 2 or 4 or 6 params, provided %d\n", e);
141 int w = inlink->
w, h = inlink->
h;
143 double var_values[
VARS_NB], res;
159 var_values[
VAR_W] = inlink->
w;
160 var_values[
VAR_H] = inlink->
h;
166 #define EVAL_RADIUS_EXPR(comp) \
167 expr = boxblur->comp##_radius_expr; \
168 ret = av_expr_parse_and_eval(&res, expr, var_names, var_values, \
169 NULL, NULL, NULL, NULL, NULL, 0, ctx); \
170 boxblur->comp##_param.radius = res; \
172 av_log(NULL, AV_LOG_ERROR, \
173 "Error when evaluating " #comp " radius expression '%s'\n", expr); \
181 "luma_radius:%d luma_power:%d "
182 "chroma_radius:%d chroma_power:%d "
183 "alpha_radius:%d alpha_power:%d "
184 "w:%d chroma_w:%d h:%d chroma_h:%d\n",
190 #define CHECK_RADIUS_VAL(w_, h_, comp) \
191 if (boxblur->comp##_param.radius < 0 || \
192 2*boxblur->comp##_param.radius > FFMIN(w_, h_)) { \
193 av_log(ctx, AV_LOG_ERROR, \
194 "Invalid " #comp " radius value %d, must be >= 0 and <= %d\n", \
195 boxblur->comp##_param.radius, FFMIN(w_, h_)/2); \
196 return AVERROR(EINVAL); \
213 static inline void blur(uint8_t *dst,
int dst_step,
const uint8_t *src,
int src_step,
230 const int length = radius*2 + 1;
231 const int inv = ((1<<16) + length/2)/length;
234 for (x = 0; x < radius; x++)
235 sum += src[x*src_step]<<1;
236 sum += src[radius*src_step];
238 for (x = 0; x <= radius; x++) {
239 sum += src[(radius+x)*src_step] - src[(radius-x)*src_step];
240 dst[x*dst_step] = (sum*inv + (1<<15))>>16;
243 for (; x < len-radius; x++) {
244 sum += src[(radius+x)*src_step] - src[(x-radius-1)*src_step];
245 dst[x*dst_step] = (sum*inv + (1<<15))>>16;
248 for (; x <
len; x++) {
249 sum += src[(2*len-radius-x-1)*src_step] - src[(x-radius-1)*src_step];
250 dst[x*dst_step] = (sum*inv + (1<<15))>>16;
254 static inline void blur_power(uint8_t *dst,
int dst_step,
const uint8_t *src,
int src_step,
255 int len,
int radius,
int power, uint8_t *temp[2])
257 uint8_t *a = temp[0], *
b = temp[1];
259 if (radius && power) {
260 blur(a, 1, src, src_step, len, radius);
261 for (; power > 2; power--) {
263 blur(b, 1, a, 1, len, radius);
267 blur(dst, dst_step, a, 1, len, radius);
270 for (i = 0; i <
len; i++)
271 dst[i*dst_step] = a[i];
275 for (i = 0; i <
len; i++)
276 dst[i*dst_step] = src[i*src_step];
280 static void hblur(uint8_t *dst,
int dst_linesize,
const uint8_t *src,
int src_linesize,
281 int w,
int h,
int radius,
int power, uint8_t *temp[2])
285 if (radius == 0 && dst == src)
288 for (y = 0; y < h; y++)
289 blur_power(dst + y*dst_linesize, 1, src + y*src_linesize, 1,
290 w, radius, power, temp);
293 static void vblur(uint8_t *dst,
int dst_linesize,
const uint8_t *src,
int src_linesize,
294 int w,
int h,
int radius,
int power, uint8_t *temp[2])
298 if (radius == 0 && dst == src)
301 for (x = 0; x < w; x++)
302 blur_power(dst + x, dst_linesize, src + x, src_linesize,
303 h, radius, power, temp);
314 int cw = inlink->
w >> boxblur->
hsub, ch = h0 >> boxblur->
vsub;
315 int w[4] = { inlink->
w, cw, cw, inlink->
w };
316 int h[4] = { h0, ch, ch, h0 };
318 for (plane = 0; inpicref->
data[plane] && plane < 4; plane++)
321 w[plane], h[plane], boxblur->
radius[plane], boxblur->
power[plane],
324 for (plane = 0; inpicref->
data[plane] && plane < 4; plane++)
327 w[plane], h[plane], boxblur->
radius[plane], boxblur->
power[plane],