diff options
author | Ramiro Polla <ramiro.polla@gmail.com> | 2024-08-07 23:29:43 +0200 |
---|---|---|
committer | Ramiro Polla <ramiro.polla@gmail.com> | 2024-08-26 11:04:46 +0200 |
commit | a2e01cade80cf297a5569b390058f2a9115d3db5 (patch) | |
tree | 0fd120268f12f2efcf9c8089574595975b03ae23 | |
parent | 4eb55942953bd4edba674625a0100aea348bb4c4 (diff) | |
download | ffmpeg-a2e01cade80cf297a5569b390058f2a9115d3db5.tar.gz |
checkasm/yuv2yuv: add tests for semiplanar unscaled converters
-rw-r--r-- | tests/checkasm/Makefile | 2 | ||||
-rw-r--r-- | tests/checkasm/checkasm.c | 1 | ||||
-rw-r--r-- | tests/checkasm/checkasm.h | 1 | ||||
-rw-r--r-- | tests/checkasm/sw_yuv2yuv.c | 133 |
4 files changed, 136 insertions, 1 deletions
diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile index 3a7670e24b..2d2e42e445 100644 --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile @@ -63,7 +63,7 @@ AVFILTEROBJS-$(CONFIG_SOBEL_FILTER) += vf_convolution.o CHECKASMOBJS-$(CONFIG_AVFILTER) += $(AVFILTEROBJS-yes) # swscale tests -SWSCALEOBJS += sw_gbrp.o sw_range_convert.o sw_rgb.o sw_scale.o sw_yuv2rgb.o +SWSCALEOBJS += sw_gbrp.o sw_range_convert.o sw_rgb.o sw_scale.o sw_yuv2rgb.o sw_yuv2yuv.o CHECKASMOBJS-$(CONFIG_SWSCALE) += $(SWSCALEOBJS) diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index 58597d3888..5c407de2ba 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -255,6 +255,7 @@ static const struct { { "sw_rgb", checkasm_check_sw_rgb }, { "sw_scale", checkasm_check_sw_scale }, { "sw_yuv2rgb", checkasm_check_sw_yuv2rgb }, + { "sw_yuv2yuv", checkasm_check_sw_yuv2yuv }, #endif #if CONFIG_AVUTIL { "fixed_dsp", checkasm_check_fixed_dsp }, diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index 4d5f3e387e..3e73808739 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -123,6 +123,7 @@ void checkasm_check_sw_range_convert(void); void checkasm_check_sw_rgb(void); void checkasm_check_sw_scale(void); void checkasm_check_sw_yuv2rgb(void); +void checkasm_check_sw_yuv2yuv(void); void checkasm_check_takdsp(void); void checkasm_check_utvideodsp(void); void checkasm_check_v210dec(void); diff --git a/tests/checkasm/sw_yuv2yuv.c b/tests/checkasm/sw_yuv2yuv.c new file mode 100644 index 0000000000..90a51601ed --- /dev/null +++ b/tests/checkasm/sw_yuv2yuv.c @@ -0,0 +1,133 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with FFmpeg; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <string.h> + +#include "libavutil/common.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/mem_internal.h" +#include "libavutil/pixdesc.h" + +#include "libswscale/swscale.h" +#include "libswscale/swscale_internal.h" + +#include "checkasm.h" + +#define randomize_buffers(buf, size) \ + do { \ + for (int j = 0; j < size; j += 4) \ + AV_WN32(buf + j, rnd()); \ + } while (0) + +static void check_semiplanar(int dst_pix_fmt) +{ + static const int src_fmts[] = { + AV_PIX_FMT_NV24, + AV_PIX_FMT_NV42, + }; + const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt); +#define NUM_LINES 4 +#define MAX_LINE_SIZE 1920 + static const int input_sizes[] = {8, 128, 1080, MAX_LINE_SIZE}; + + declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, + int, SwsContext *c, const uint8_t *src[], + int srcStride[], int srcSliceY, int srcSliceH, + uint8_t *dst[], int dstStride[]); + + LOCAL_ALIGNED_8(uint8_t, src_y, [MAX_LINE_SIZE * NUM_LINES]); + LOCAL_ALIGNED_8(uint8_t, src_uv, [MAX_LINE_SIZE * NUM_LINES * 2]); + const uint8_t *src[4] = { src_y, src_uv }; + + LOCAL_ALIGNED_8(uint8_t, dst0_y, [MAX_LINE_SIZE * NUM_LINES]); + LOCAL_ALIGNED_8(uint8_t, dst0_u, [MAX_LINE_SIZE * NUM_LINES / 2]); + LOCAL_ALIGNED_8(uint8_t, dst0_v, [MAX_LINE_SIZE * NUM_LINES / 2]); + uint8_t *dst0[4] = { dst0_y, dst0_u, dst0_v }; + + LOCAL_ALIGNED_8(uint8_t, dst1_y, [MAX_LINE_SIZE * NUM_LINES]); + LOCAL_ALIGNED_8(uint8_t, dst1_u, [MAX_LINE_SIZE * NUM_LINES / 2]); + LOCAL_ALIGNED_8(uint8_t, dst1_v, [MAX_LINE_SIZE * NUM_LINES / 2]); + uint8_t *dst1[4] = { dst1_y, dst1_u, dst1_v }; + + randomize_buffers(src_y, MAX_LINE_SIZE * NUM_LINES); + randomize_buffers(src_uv, MAX_LINE_SIZE * NUM_LINES * 2); + + for (int sfi = 0; sfi < FF_ARRAY_ELEMS(src_fmts); sfi++) { + int src_pix_fmt = src_fmts[sfi]; + const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt); + for (int isi = 0; isi < FF_ARRAY_ELEMS(input_sizes); isi++) { + struct SwsContext *ctx; + int log_level; + int width = input_sizes[isi]; + int srcSliceY = 0; + int srcSliceH = NUM_LINES; + int srcStride[4] = { + MAX_LINE_SIZE, + MAX_LINE_SIZE * 2, + }; + int dstStride[4] = { + MAX_LINE_SIZE, + MAX_LINE_SIZE >> dst_desc->log2_chroma_w, + MAX_LINE_SIZE >> dst_desc->log2_chroma_w, + }; + + // override log level to prevent spamming of the message + // "No accelerated colorspace conversion found from %s to %s" + log_level = av_log_get_level(); + av_log_set_level(AV_LOG_ERROR); + ctx = sws_getContext(width, srcSliceH, src_pix_fmt, + width, srcSliceH, dst_pix_fmt, + 0, NULL, NULL, NULL); + av_log_set_level(log_level); + if (!ctx) + fail(); + + if (check_func(ctx->convert_unscaled, "%s_%s_%d", src_desc->name, dst_desc->name, width)) { + memset(dst0_y, 0xFF, MAX_LINE_SIZE * NUM_LINES); + memset(dst0_u, 0xFF, MAX_LINE_SIZE * NUM_LINES / 2); + memset(dst0_v, 0xFF, MAX_LINE_SIZE * NUM_LINES / 2); + memset(dst1_y, 0xFF, MAX_LINE_SIZE * NUM_LINES); + memset(dst1_u, 0xFF, MAX_LINE_SIZE * NUM_LINES / 2); + memset(dst1_v, 0xFF, MAX_LINE_SIZE * NUM_LINES / 2); + + call_ref(ctx, src, srcStride, srcSliceY, + srcSliceH, dst0, dstStride); + call_new(ctx, src, srcStride, srcSliceY, + srcSliceH, dst1, dstStride); + + if (memcmp(dst0_y, dst1_y, MAX_LINE_SIZE * NUM_LINES) || + memcmp(dst0_u, dst1_u, MAX_LINE_SIZE * NUM_LINES / 2) || + memcmp(dst0_v, dst1_v, MAX_LINE_SIZE * NUM_LINES / 2)) + fail(); + + bench_new(ctx, src, srcStride, srcSliceY, + srcSliceH, dst0, dstStride); + } + sws_freeContext(ctx); + } + } +} + +#undef NUM_LINES +#undef MAX_LINE_SIZE + +void checkasm_check_sw_yuv2yuv(void) +{ + check_semiplanar(AV_PIX_FMT_YUV420P); + report("yuv420p"); +} |