140 int w = inlink->
w, h = inlink->
h;
142 double var_values[
VARS_NB], res;
153 var_values[
VAR_W] = inlink->
w;
154 var_values[
VAR_H] = inlink->
h;
160 #define EVAL_RADIUS_EXPR(comp) \
161 expr = s->comp##_param.radius_expr; \
162 ret = av_expr_parse_and_eval(&res, expr, var_names, var_values, \
163 NULL, NULL, NULL, NULL, NULL, 0, ctx); \
164 s->comp##_param.radius = res; \
166 av_log(NULL, AV_LOG_ERROR, \
167 "Error when evaluating " #comp " radius expression '%s'\n", expr); \
175 "luma_radius:%d luma_power:%d "
176 "chroma_radius:%d chroma_power:%d "
177 "alpha_radius:%d alpha_power:%d "
178 "w:%d chroma_w:%d h:%d chroma_h:%d\n",
184 #define CHECK_RADIUS_VAL(w_, h_, comp) \
185 if (s->comp##_param.radius < 0 || \
186 2*s->comp##_param.radius > FFMIN(w_, h_)) { \
187 av_log(ctx, AV_LOG_ERROR, \
188 "Invalid " #comp " radius value %d, must be >= 0 and <= %d\n", \
189 s->comp##_param.radius, FFMIN(w_, h_)/2); \
190 return AVERROR(EINVAL); \
224 const int length = radius*2 + 1;
225 const int inv = ((1<<16) + length/2)/
length;
226 int x, sum = src[radius*src_step];
228 for (x = 0; x < radius; x++)
229 sum += src[x*src_step]<<1;
231 sum = sum*inv + (1<<15);
233 for (x = 0; x <= radius; x++) {
234 sum += (src[(radius+x)*src_step] - src[(radius-x)*src_step])*inv;
235 dst[x*dst_step] = sum>>16;
238 for (; x < len-radius; x++) {
239 sum += (src[(radius+x)*src_step] - src[(x-radius-1)*src_step])*inv;
240 dst[x*dst_step] = sum >>16;
243 for (; x <
len; x++) {
244 sum += (src[(2*len-radius-x-1)*src_step] - src[(x-radius-1)*src_step])*inv;
245 dst[x*dst_step] = sum>>16;
249 static inline void blur16(uint16_t *dst,
int dst_step,
const uint16_t *
src,
int src_step,
252 const int length = radius*2 + 1;
253 const int inv = ((1<<16) + length/2)/
length;
254 int x, sum = src[radius*src_step];
256 for (x = 0; x < radius; x++)
257 sum += src[x*src_step]<<1;
259 sum = sum*inv + (1<<15);
261 for (x = 0; x <= radius; x++) {
262 sum += (src[(radius+x)*src_step] - src[(radius-x)*src_step])*inv;
263 dst[x*dst_step] = sum>>16;
266 for (; x < len-radius; x++) {
267 sum += (src[(radius+x)*src_step] - src[(x-radius-1)*src_step])*inv;
268 dst[x*dst_step] = sum >>16;
271 for (; x <
len; x++) {
272 sum += (src[(2*len-radius-x-1)*src_step] - src[(x-radius-1)*src_step])*inv;
273 dst[x*dst_step] = sum>>16;
278 int len,
int radius,
int pixsize)
280 if (pixsize == 1)
blur8 (dst, dst_step , src, src_step , len, radius);
281 else blur16((uint16_t*)dst, dst_step>>1, (
const uint16_t*)src, src_step>>1, len, radius);
289 if (radius && power) {
290 blur(a, pixsize, src, src_step, len, radius, pixsize);
291 for (; power > 2; power--) {
293 blur(b, pixsize, a, pixsize, len, radius, pixsize);
297 blur(dst, dst_step, a, pixsize, len, radius, pixsize);
301 for (i = 0; i <
len; i++)
302 dst[i*dst_step] = a[i];
304 for (i = 0; i <
len; i++)
305 *(uint16_t*)(dst + i*dst_step) = ((uint16_t*)
a)[i];
310 for (i = 0; i <
len; i++)
311 dst[i*dst_step] = src[i*src_step];
313 for (i = 0; i <
len; i++)
314 *(uint16_t*)(dst + i*dst_step) = *(uint16_t*)(src + i*src_step);
319 int w,
int h,
int radius,
int power,
uint8_t *
temp[2],
int pixsize)
323 if (radius == 0 && dst == src)
326 for (y = 0; y < h; y++)
327 blur_power(dst + y*dst_linesize, pixsize, src + y*src_linesize, pixsize,
328 w, radius, power, temp, pixsize);
332 int w,
int h,
int radius,
int power,
uint8_t *
temp[2],
int pixsize)
336 if (radius == 0 && dst == src)
339 for (x = 0; x < w; x++)
340 blur_power(dst + x*pixsize, dst_linesize, src + x*pixsize, src_linesize,
341 h, radius, power, temp, pixsize);
352 int w[4] = { inlink->
w, cw, cw, inlink->
w };
356 const int pixsize = (depth+7)/8;
365 for (plane = 0; plane < 4 && in->
data[plane] && in->
linesize[plane]; plane++)
368 w[plane], h[plane], s->
radius[plane], s->
power[plane],
371 for (plane = 0; plane < 4 && in->
data[plane] && in->
linesize[plane]; plane++)
374 w[plane], h[plane], s->
radius[plane], s->
power[plane],
382 #define OFFSET(x) offsetof(BoxBlurContext, x)
383 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
388 {
"luma_power",
"How many times should the boxblur be applied to luma",
OFFSET(luma_param.power),
AV_OPT_TYPE_INT, {.i64=2}, 0, INT_MAX, .flags =
FLAGS },
389 {
"lp",
"How many times should the boxblur be applied to luma",
OFFSET(luma_param.power),
AV_OPT_TYPE_INT, {.i64=2}, 0, INT_MAX, .flags =
FLAGS },
393 {
"chroma_power",
"How many times should the boxblur be applied to chroma",
OFFSET(chroma_param.power),
AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags =
FLAGS },
394 {
"cp",
"How many times should the boxblur be applied to chroma",
OFFSET(chroma_param.power),
AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags =
FLAGS },
398 {
"alpha_power",
"How many times should the boxblur be applied to alpha",
OFFSET(alpha_param.power),
AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags =
FLAGS },
399 {
"ap",
"How many times should the boxblur be applied to alpha",
OFFSET(alpha_param.power),
AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags =
FLAGS },
428 .priv_class = &boxblur_class,
432 .
inputs = avfilter_vf_boxblur_inputs,
433 .
outputs = avfilter_vf_boxblur_outputs,