Message ID | 20220818081645.3352481-1-martin@martin.st |
---|---|
State | Accepted |
Commit | f921c583353bde2403334b94c1a3ca0785364924 |
Headers | show |
Series | [FFmpeg-devel,v2] checkasm: sw_scale: Produce more realistic test filter coefficients for yuv2yuvX | expand |
Context | Check | Description |
---|---|---|
yinshiyou/make_loongarch64 | success | Make finished |
yinshiyou/make_fate_loongarch64 | success | Make fate finished |
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
Thanks Martin for doing this. On Thu, Aug 18, 2022 at 10:16 AM Martin Storsjö <martin@martin.st> wrote: > This avoids triggering overflows in the filters, and avoids stray > test failures in the approximate functions on x86; due to rounding > differences, one implementation might overflow while another one > doesn't. > > Signed-off-by: Martin Storsjö <martin@martin.st> > --- > FWIW, this modification runs successfully with over 1000 different > seeds in checkasm. > --- > tests/checkasm/sw_scale.c | 16 +++++++++++++++- > 1 file changed, 15 insertions(+), 1 deletion(-) > > diff --git a/tests/checkasm/sw_scale.c b/tests/checkasm/sw_scale.c > index d72506ed86..ec06eafebe 100644 > --- a/tests/checkasm/sw_scale.c > +++ b/tests/checkasm/sw_scale.c > @@ -188,7 +188,6 @@ static void check_yuv2yuvX(int accurate) > uint8_t d_val = rnd(); > memset(dither, d_val, LARGEST_INPUT_SIZE); > randomize_buffers((uint8_t*)src_pixels, LARGEST_FILTER * > LARGEST_INPUT_SIZE * sizeof(int16_t)); > - randomize_buffers((uint8_t*)filter_coeff, LARGEST_FILTER * > sizeof(int16_t)); > ctx = sws_alloc_context(); > if (accurate) > ctx->flags |= SWS_ACCURATE_RND; > @@ -202,6 +201,21 @@ static void check_yuv2yuvX(int accurate) > if (dstW <= osi) > continue; > for (fsi = 0; fsi < FILTER_SIZES; ++fsi) { > + // Generate filter coefficients for the given filter size, > + // with some properties: > + // - The coefficients add up to the intended sum (4096, > 1<<12) > + // - The coefficients contain negative values > + // - The filter intermediates don't overflow for worst > case > + // inputs (all positive coefficients are coupled with > + // input_max and all negative coefficients with > input_min, > + // or vice versa). > + // Produce a filter with all coefficients set to > + // -((1<<12)/(filter_size-1)) except for one (randomly > chosen) > + // which is set to ((1<<13)-1). > + for (i = 0; i < filter_sizes[fsi]; ++i) > + filter_coeff[i] = -((1 << 12) / (filter_sizes[fsi] - > 1)); > + filter_coeff[rnd() % filter_sizes[fsi]] = (1 << 13) - 1; > + > src = av_malloc(sizeof(int16_t*) * filter_sizes[fsi]); > vFilterData = av_malloc((filter_sizes[fsi] + 2) * > sizeof(union VFilterData)); > memset(vFilterData, 0, (filter_sizes[fsi] + 2) * > sizeof(union VFilterData)); > -- > 2.25.1 > >
On Thu, 18 Aug 2022, Alan Kelly wrote: > Thanks Martin for doing this. > > On Thu, Aug 18, 2022 at 10:16 AM Martin Storsjö <martin@martin.st> wrote: > This avoids triggering overflows in the filters, and avoids > stray > test failures in the approximate functions on x86; due to > rounding > differences, one implementation might overflow while another one > doesn't. > > Signed-off-by: Martin Storsjö <martin@martin.st> > --- > FWIW, this modification runs successfully with over 1000 > different > seeds in checkasm. > --- > tests/checkasm/sw_scale.c | 16 +++++++++++++++- > 1 file changed, 15 insertions(+), 1 deletion(-) I'll go ahead and push this patch later today, if there's no opposition, as it fixes spurious fate failures. // Martin
diff --git a/tests/checkasm/sw_scale.c b/tests/checkasm/sw_scale.c index d72506ed86..ec06eafebe 100644 --- a/tests/checkasm/sw_scale.c +++ b/tests/checkasm/sw_scale.c @@ -188,7 +188,6 @@ static void check_yuv2yuvX(int accurate) uint8_t d_val = rnd(); memset(dither, d_val, LARGEST_INPUT_SIZE); randomize_buffers((uint8_t*)src_pixels, LARGEST_FILTER * LARGEST_INPUT_SIZE * sizeof(int16_t)); - randomize_buffers((uint8_t*)filter_coeff, LARGEST_FILTER * sizeof(int16_t)); ctx = sws_alloc_context(); if (accurate) ctx->flags |= SWS_ACCURATE_RND; @@ -202,6 +201,21 @@ static void check_yuv2yuvX(int accurate) if (dstW <= osi) continue; for (fsi = 0; fsi < FILTER_SIZES; ++fsi) { + // Generate filter coefficients for the given filter size, + // with some properties: + // - The coefficients add up to the intended sum (4096, 1<<12) + // - The coefficients contain negative values + // - The filter intermediates don't overflow for worst case + // inputs (all positive coefficients are coupled with + // input_max and all negative coefficients with input_min, + // or vice versa). + // Produce a filter with all coefficients set to + // -((1<<12)/(filter_size-1)) except for one (randomly chosen) + // which is set to ((1<<13)-1). + for (i = 0; i < filter_sizes[fsi]; ++i) + filter_coeff[i] = -((1 << 12) / (filter_sizes[fsi] - 1)); + filter_coeff[rnd() % filter_sizes[fsi]] = (1 << 13) - 1; + src = av_malloc(sizeof(int16_t*) * filter_sizes[fsi]); vFilterData = av_malloc((filter_sizes[fsi] + 2) * sizeof(union VFilterData)); memset(vFilterData, 0, (filter_sizes[fsi] + 2) * sizeof(union VFilterData));
This avoids triggering overflows in the filters, and avoids stray test failures in the approximate functions on x86; due to rounding differences, one implementation might overflow while another one doesn't. Signed-off-by: Martin Storsjö <martin@martin.st> --- FWIW, this modification runs successfully with over 1000 different seeds in checkasm. --- tests/checkasm/sw_scale.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)