avfilter/vf_amplify: add more options for finer filtering
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
@@ -5207,6 +5207,14 @@ Set threshold for difference amplification. Any differrence greater or equal to
|
|||||||
this value will not alter source pixel. Default is 10.
|
this value will not alter source pixel. Default is 10.
|
||||||
Allowed range is from 0 to 65535.
|
Allowed range is from 0 to 65535.
|
||||||
|
|
||||||
|
@item low
|
||||||
|
Set lower limit for changing source pixel. Default is 65535. Allowed range is from 0 to 65535.
|
||||||
|
This option controls maximum possible value that will decrease source pixel value.
|
||||||
|
|
||||||
|
@item high
|
||||||
|
Set high limit for changing source pixel. Default is 65535. Allowed range is from 0 to 65535.
|
||||||
|
This option controls maximum possible value that will increase source pixel value.
|
||||||
|
|
||||||
@item planes
|
@item planes
|
||||||
Set which planes to filter. Default is all. Allowed range is from 0 to 15.
|
Set which planes to filter. Default is all. Allowed range is from 0 to 15.
|
||||||
@end table
|
@end table
|
||||||
|
|||||||
@@ -36,11 +36,12 @@ typedef struct AmplifyContext {
|
|||||||
float threshold;
|
float threshold;
|
||||||
int planes;
|
int planes;
|
||||||
|
|
||||||
|
int llimit;
|
||||||
|
int hlimit;
|
||||||
int nb_inputs;
|
int nb_inputs;
|
||||||
int nb_frames;
|
int nb_frames;
|
||||||
|
|
||||||
int depth;
|
int depth;
|
||||||
int max;
|
|
||||||
int nb_planes;
|
int nb_planes;
|
||||||
int linesize[4];
|
int linesize[4];
|
||||||
int height[4];
|
int height[4];
|
||||||
@@ -104,6 +105,9 @@ static int amplify_frame(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs
|
|||||||
const int nb_inputs = s->nb_inputs;
|
const int nb_inputs = s->nb_inputs;
|
||||||
const float threshold = s->threshold;
|
const float threshold = s->threshold;
|
||||||
const float factor = s->factor;
|
const float factor = s->factor;
|
||||||
|
const int llimit = s->llimit;
|
||||||
|
const int hlimit = s->hlimit;
|
||||||
|
const int depth = s->depth;
|
||||||
int i, p, x, y;
|
int i, p, x, y;
|
||||||
|
|
||||||
if (s->depth <= 8) {
|
if (s->depth <= 8) {
|
||||||
@@ -132,10 +136,17 @@ static int amplify_frame(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs
|
|||||||
|
|
||||||
avg = sum / (float)nb_inputs;
|
avg = sum / (float)nb_inputs;
|
||||||
diff = src - avg;
|
diff = src - avg;
|
||||||
if (fabsf(diff) < threshold)
|
if (fabsf(diff) < threshold) {
|
||||||
dst[x] = av_clip_uint8(src + diff * factor);
|
int amp;
|
||||||
else
|
if (diff < 0) {
|
||||||
|
amp = -FFMIN(FFABS(diff * factor), llimit);
|
||||||
|
} else {
|
||||||
|
amp = FFMIN(FFABS(diff * factor), hlimit);
|
||||||
|
}
|
||||||
|
dst[x] = av_clip_uint8(src + amp);
|
||||||
|
} else {
|
||||||
dst[x] = src;
|
dst[x] = src;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dst += out->linesize[p];
|
dst += out->linesize[p];
|
||||||
@@ -168,10 +179,17 @@ static int amplify_frame(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs
|
|||||||
avg = sum / (float)nb_inputs;
|
avg = sum / (float)nb_inputs;
|
||||||
diff = src - avg;
|
diff = src - avg;
|
||||||
|
|
||||||
if (fabsf(diff) < threshold)
|
if (fabsf(diff) < threshold) {
|
||||||
dst[x] = av_clip(src + (src - avg) * factor, 0, s->max);
|
int amp;
|
||||||
else
|
if (diff < 0) {
|
||||||
|
amp = -FFMIN(FFABS(diff * factor), llimit);
|
||||||
|
} else {
|
||||||
|
amp = FFMIN(FFABS(diff * factor), hlimit);
|
||||||
|
}
|
||||||
|
dst[x] = av_clip_uintp2(src + amp, depth);
|
||||||
|
} else {
|
||||||
dst[x] = src;
|
dst[x] = src;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dst += out->linesize[p] / 2;
|
dst += out->linesize[p] / 2;
|
||||||
@@ -194,7 +212,6 @@ static int config_output(AVFilterLink *outlink)
|
|||||||
return AVERROR_BUG;
|
return AVERROR_BUG;
|
||||||
s->nb_planes = av_pix_fmt_count_planes(outlink->format);
|
s->nb_planes = av_pix_fmt_count_planes(outlink->format);
|
||||||
s->depth = s->desc->comp[0].depth;
|
s->depth = s->desc->comp[0].depth;
|
||||||
s->max = (1 << s->depth) - 1;
|
|
||||||
|
|
||||||
if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
|
if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -252,6 +269,8 @@ static const AVOption amplify_options[] = {
|
|||||||
{ "radius", "set radius", OFFSET(radius), AV_OPT_TYPE_INT, {.i64=2}, 1, 63, .flags = FLAGS },
|
{ "radius", "set radius", OFFSET(radius), AV_OPT_TYPE_INT, {.i64=2}, 1, 63, .flags = FLAGS },
|
||||||
{ "factor", "set factor", OFFSET(factor), AV_OPT_TYPE_FLOAT, {.dbl=2}, 0, UINT16_MAX, .flags = FLAGS },
|
{ "factor", "set factor", OFFSET(factor), AV_OPT_TYPE_FLOAT, {.dbl=2}, 0, UINT16_MAX, .flags = FLAGS },
|
||||||
{ "threshold", "set threshold", OFFSET(threshold), AV_OPT_TYPE_FLOAT, {.dbl=10}, 0, UINT16_MAX, .flags = FLAGS },
|
{ "threshold", "set threshold", OFFSET(threshold), AV_OPT_TYPE_FLOAT, {.dbl=10}, 0, UINT16_MAX, .flags = FLAGS },
|
||||||
|
{ "low", "set low limit for amplification", OFFSET(llimit), AV_OPT_TYPE_INT, {.i64=UINT16_MAX}, 0, UINT16_MAX, .flags = FLAGS },
|
||||||
|
{ "high", "set high limit for amplification", OFFSET(hlimit), AV_OPT_TYPE_INT, {.i64=UINT16_MAX}, 0, UINT16_MAX, .flags = FLAGS },
|
||||||
{ "planes", "set what planes to filter", OFFSET(planes), AV_OPT_TYPE_FLAGS, {.i64=7}, 0, 15, FLAGS },
|
{ "planes", "set what planes to filter", OFFSET(planes), AV_OPT_TYPE_FLAGS, {.i64=7}, 0, 15, FLAGS },
|
||||||
{ NULL },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user