mirror of https://git.ffmpeg.org/ffmpeg.git
avfilter/af_anlmdn: fix possible array overflow and increase options limits
This commit is contained in:
parent
248986a0db
commit
41cae501b7
|
@ -2266,7 +2266,7 @@ The filter accepts the following options:
|
||||||
|
|
||||||
@table @option
|
@table @option
|
||||||
@item strength, s
|
@item strength, s
|
||||||
Set denoising strength. Allowed range is from 0.00001 to 10. Default value is 0.00001.
|
Set denoising strength. Allowed range is from 0.00001 to 10000. Default value is 0.00001.
|
||||||
|
|
||||||
@item patch, p
|
@item patch, p
|
||||||
Set patch radius duration. Allowed range is from 1 to 100 milliseconds.
|
Set patch radius duration. Allowed range is from 1 to 100 milliseconds.
|
||||||
|
@ -2294,7 +2294,7 @@ Default value is @var{o}.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@item smooth, m
|
@item smooth, m
|
||||||
Set smooth factor. Default value is @var{11}. Allowed range is from @var{1} to @var{15}.
|
Set smooth factor. Default value is @var{11}. Allowed range is from @var{1} to @var{1000}.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@subsection Commands
|
@subsection Commands
|
||||||
|
|
|
@ -33,8 +33,6 @@
|
||||||
#define WEIGHT_LUT_NBITS 20
|
#define WEIGHT_LUT_NBITS 20
|
||||||
#define WEIGHT_LUT_SIZE (1<<WEIGHT_LUT_NBITS)
|
#define WEIGHT_LUT_SIZE (1<<WEIGHT_LUT_NBITS)
|
||||||
|
|
||||||
#define SQR(x) ((x) * (x))
|
|
||||||
|
|
||||||
typedef struct AudioNLMeansContext {
|
typedef struct AudioNLMeansContext {
|
||||||
const AVClass *class;
|
const AVClass *class;
|
||||||
|
|
||||||
|
@ -75,8 +73,8 @@ enum OutModes {
|
||||||
#define AFT AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
|
#define AFT AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
|
||||||
|
|
||||||
static const AVOption anlmdn_options[] = {
|
static const AVOption anlmdn_options[] = {
|
||||||
{ "strength", "set denoising strength", OFFSET(a), AV_OPT_TYPE_FLOAT, {.dbl=0.00001},0.00001, 10, AFT },
|
{ "strength", "set denoising strength", OFFSET(a), AV_OPT_TYPE_FLOAT, {.dbl=0.00001},0.00001, 10000, AFT },
|
||||||
{ "s", "set denoising strength", OFFSET(a), AV_OPT_TYPE_FLOAT, {.dbl=0.00001},0.00001, 10, AFT },
|
{ "s", "set denoising strength", OFFSET(a), AV_OPT_TYPE_FLOAT, {.dbl=0.00001},0.00001, 10000, AFT },
|
||||||
{ "patch", "set patch duration", OFFSET(pd), AV_OPT_TYPE_DURATION, {.i64=2000}, 1000, 100000, AFT },
|
{ "patch", "set patch duration", OFFSET(pd), AV_OPT_TYPE_DURATION, {.i64=2000}, 1000, 100000, AFT },
|
||||||
{ "p", "set patch duration", OFFSET(pd), AV_OPT_TYPE_DURATION, {.i64=2000}, 1000, 100000, AFT },
|
{ "p", "set patch duration", OFFSET(pd), AV_OPT_TYPE_DURATION, {.i64=2000}, 1000, 100000, AFT },
|
||||||
{ "research", "set research duration", OFFSET(rd), AV_OPT_TYPE_DURATION, {.i64=6000}, 2000, 300000, AFT },
|
{ "research", "set research duration", OFFSET(rd), AV_OPT_TYPE_DURATION, {.i64=6000}, 2000, 300000, AFT },
|
||||||
|
@ -86,19 +84,26 @@ static const AVOption anlmdn_options[] = {
|
||||||
{ "i", "input", 0, AV_OPT_TYPE_CONST, {.i64=IN_MODE}, 0, 0, AFT, "mode" },
|
{ "i", "input", 0, AV_OPT_TYPE_CONST, {.i64=IN_MODE}, 0, 0, AFT, "mode" },
|
||||||
{ "o", "output", 0, AV_OPT_TYPE_CONST, {.i64=OUT_MODE}, 0, 0, AFT, "mode" },
|
{ "o", "output", 0, AV_OPT_TYPE_CONST, {.i64=OUT_MODE}, 0, 0, AFT, "mode" },
|
||||||
{ "n", "noise", 0, AV_OPT_TYPE_CONST, {.i64=NOISE_MODE},0, 0, AFT, "mode" },
|
{ "n", "noise", 0, AV_OPT_TYPE_CONST, {.i64=NOISE_MODE},0, 0, AFT, "mode" },
|
||||||
{ "smooth", "set smooth factor", OFFSET(m), AV_OPT_TYPE_FLOAT, {.dbl=11.}, 1, 15, AFT },
|
{ "smooth", "set smooth factor", OFFSET(m), AV_OPT_TYPE_FLOAT, {.dbl=11.}, 1, 1000, AFT },
|
||||||
{ "m", "set smooth factor", OFFSET(m), AV_OPT_TYPE_FLOAT, {.dbl=11.}, 1, 15, AFT },
|
{ "m", "set smooth factor", OFFSET(m), AV_OPT_TYPE_FLOAT, {.dbl=11.}, 1, 1000, AFT },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
AVFILTER_DEFINE_CLASS(anlmdn);
|
AVFILTER_DEFINE_CLASS(anlmdn);
|
||||||
|
|
||||||
|
static inline float sqrdiff(float x, float y)
|
||||||
|
{
|
||||||
|
const float diff = x - y;
|
||||||
|
|
||||||
|
return diff * diff;
|
||||||
|
}
|
||||||
|
|
||||||
static float compute_distance_ssd_c(const float *f1, const float *f2, ptrdiff_t K)
|
static float compute_distance_ssd_c(const float *f1, const float *f2, ptrdiff_t K)
|
||||||
{
|
{
|
||||||
float distance = 0.;
|
float distance = 0.;
|
||||||
|
|
||||||
for (int k = -K; k <= K; k++)
|
for (int k = -K; k <= K; k++)
|
||||||
distance += SQR(f1[k] - f2[k]);
|
distance += sqrdiff(f1[k], f2[k]);
|
||||||
|
|
||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
|
@ -110,7 +115,7 @@ static void compute_cache_c(float *cache, const float *f,
|
||||||
int v = 0;
|
int v = 0;
|
||||||
|
|
||||||
for (int j = jj; j < jj + S; j++, v++)
|
for (int j = jj; j < jj + S; j++, v++)
|
||||||
cache[v] += -SQR(f[i - K - 1] - f[j - K - 1]) + SQR(f[i + K] - f[j + K]);
|
cache[v] += -sqrdiff(f[i - K - 1], f[j - K - 1]) + sqrdiff(f[i + K], f[j + K]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ff_anlmdn_init(AudioNLMDNDSPContext *dsp)
|
void ff_anlmdn_init(AudioNLMDNDSPContext *dsp)
|
||||||
|
@ -213,7 +218,9 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
|
||||||
float *cache = (float *)s->cache->extended_data[ch];
|
float *cache = (float *)s->cache->extended_data[ch];
|
||||||
const float sw = (65536.f / (4 * K + 2)) / sqrtf(s->a);
|
const float sw = (65536.f / (4 * K + 2)) / sqrtf(s->a);
|
||||||
float *dst = (float *)out->extended_data[ch] + s->offset;
|
float *dst = (float *)out->extended_data[ch] + s->offset;
|
||||||
const float smooth = s->m;
|
const float *const weight_lut = s->weight_lut;
|
||||||
|
const float pdiff_lut_scale = s->pdiff_lut_scale;
|
||||||
|
const float smooth = fminf(s->m, WEIGHT_LUT_SIZE / pdiff_lut_scale);
|
||||||
|
|
||||||
for (int i = S; i < s->H + S; i++) {
|
for (int i = S; i < s->H + S; i++) {
|
||||||
float P = 0.f, Q = 0.f;
|
float P = 0.f, Q = 0.f;
|
||||||
|
@ -231,26 +238,24 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 2 * S && !ctx->is_disabled; j++) {
|
for (int j = 0; j < 2 * S && !ctx->is_disabled; j++) {
|
||||||
const float distance = cache[j];
|
float distance = cache[j];
|
||||||
unsigned weight_lut_idx;
|
unsigned weight_lut_idx;
|
||||||
float w;
|
float w;
|
||||||
|
|
||||||
if (distance < 0.f) {
|
if (distance < 0.f)
|
||||||
cache[j] = 0.f;
|
cache[j] = distance = 0.f;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
w = distance * sw;
|
w = distance * sw;
|
||||||
if (w >= smooth)
|
if (w >= smooth)
|
||||||
continue;
|
continue;
|
||||||
weight_lut_idx = w * s->pdiff_lut_scale;
|
weight_lut_idx = w * pdiff_lut_scale;
|
||||||
av_assert2(weight_lut_idx < WEIGHT_LUT_SIZE);
|
av_assert2(weight_lut_idx < WEIGHT_LUT_SIZE);
|
||||||
w = s->weight_lut[weight_lut_idx];
|
w = weight_lut[weight_lut_idx];
|
||||||
P += w * f[i - S + j + (j >= S)];
|
P += w * f[i - S + j + (j >= S)];
|
||||||
Q += w;
|
Q += w;
|
||||||
}
|
}
|
||||||
|
|
||||||
P += f[i];
|
P += f[i];
|
||||||
Q += 1;
|
Q += 1.f;
|
||||||
|
|
||||||
switch (om) {
|
switch (om) {
|
||||||
case IN_MODE: dst[i - S] = f[i]; break;
|
case IN_MODE: dst[i - S] = f[i]; break;
|
||||||
|
|
Loading…
Reference in New Issue