diff mbox series

[FFmpeg-devel,v2,3/3] checkasm: add hevc_deblock tests

Message ID 20210805105901.33478-2-jdek@itanimul.li
State New
Headers show
Series None | expand

Commit Message

J. Dekker Aug. 5, 2021, 10:59 a.m. UTC
Signed-off-by: J. Dekker <jdek@itanimul.li>
---
 tests/checkasm/Makefile       |   2 +-
 tests/checkasm/checkasm.c     |   1 +
 tests/checkasm/checkasm.h     |   1 +
 tests/checkasm/hevc_deblock.c | 126 ++++++++++++++++++++++++++++++++++
 tests/fate/checkasm.mak       |   1 +
 5 files changed, 130 insertions(+), 1 deletion(-)
 create mode 100644 tests/checkasm/hevc_deblock.c

Comments

Martin Storsjö Aug. 5, 2021, 9:33 p.m. UTC | #1
On Thu, 5 Aug 2021, J. Dekker wrote:

> Signed-off-by: J. Dekker <jdek@itanimul.li>
> ---
> tests/checkasm/Makefile       |   2 +-
> tests/checkasm/checkasm.c     |   1 +
> tests/checkasm/checkasm.h     |   1 +
> tests/checkasm/hevc_deblock.c | 126 ++++++++++++++++++++++++++++++++++
> tests/fate/checkasm.mak       |   1 +
> 5 files changed, 130 insertions(+), 1 deletion(-)
> create mode 100644 tests/checkasm/hevc_deblock.c
>
> new file mode 100644
> index 0000000000..98f612921b
> --- /dev/null
> +++ b/tests/checkasm/hevc_deblock.c
> @@ -0,0 +1,126 @@
> +/*
> + * 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/intreadwrite.h"
> +#include "libavutil/mem_internal.h"
> +
> +#include "libavcodec/avcodec.h"
> +#include "libavcodec/hevcdsp.h"
> +
> +#include "checkasm.h"
> +
> +static const uint32_t pixel_mask[3] = { 0xffffffff, 0x03ff03ff, 0x0fff0fff };
> +
> +#define SIZEOF_PIXEL ((bit_depth + 7) / 8)
> +#define BUF_STRIDE (8 * 2)
> +#define BUF_LINES (8)
> +#define BUF_OFFSET (BUF_STRIDE * BUF_LINES)
> +#define BUF_SIZE (BUF_STRIDE * BUF_LINES + BUF_OFFSET * 2)
> +
> +#define randomize_buffers(buf0, buf1, size)                 \
> +    do {                                                    \
> +        uint32_t mask = pixel_mask[(bit_depth - 8) >> 1];   \
> +        int k;                                              \
> +        for (k = 0; k < size; k += 4) {                     \
> +            uint32_t r = rnd() & mask;                      \
> +            AV_WN32A(buf0 + k, r);                          \
> +            AV_WN32A(buf1 + k, r);                          \

Plain random input is pretty bad test data for deblocking, since it 
doesn't actually trigger the deblocking in most cases. To make it actually 
do the deblocking, the pixels across the edge need to have the right 
properties.

Have a look at how the vp9dsp checkasm test initializes its buffers, to 
make sure that one run actually triggers all cases once (d0+d3 >= beta, 
strong filtering, normal filtering).

(For vp9, it initializes all possible cases in one buffer, but you can 
also iterate and run the test multiple times with different input 
patterns.)

// Martin
diff mbox series

Patch

diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile
index 41222c3827..862142d8e6 100644
--- a/tests/checkasm/Makefile
+++ b/tests/checkasm/Makefile
@@ -25,7 +25,7 @@  AVCODECOBJS-$(CONFIG_HUFFYUV_DECODER)   += huffyuvdsp.o
 AVCODECOBJS-$(CONFIG_JPEG2000_DECODER)  += jpeg2000dsp.o
 AVCODECOBJS-$(CONFIG_OPUS_DECODER)      += opusdsp.o
 AVCODECOBJS-$(CONFIG_PIXBLOCKDSP)       += pixblockdsp.o
-AVCODECOBJS-$(CONFIG_HEVC_DECODER)      += hevc_add_res.o hevc_idct.o hevc_sao.o hevc_pel.o
+AVCODECOBJS-$(CONFIG_HEVC_DECODER)      += hevc_add_res.o hevc_deblock.o hevc_idct.o hevc_sao.o hevc_pel.o
 AVCODECOBJS-$(CONFIG_UTVIDEO_DECODER)   += utvideodsp.o
 AVCODECOBJS-$(CONFIG_V210_DECODER)      += v210dec.o
 AVCODECOBJS-$(CONFIG_V210_ENCODER)      += v210enc.o
diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
index 154c4a5c01..a1e8c4d92e 100644
--- a/tests/checkasm/checkasm.c
+++ b/tests/checkasm/checkasm.c
@@ -118,6 +118,7 @@  static const struct {
     #endif
     #if CONFIG_HEVC_DECODER
         { "hevc_add_res", checkasm_check_hevc_add_res },
+        { "hevc_deblock", checkasm_check_hevc_deblock },
         { "hevc_idct", checkasm_check_hevc_idct },
         { "hevc_pel", checkasm_check_hevc_pel },
         { "hevc_sao", checkasm_check_hevc_sao },
diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h
index ac2f22af05..386ecbf69a 100644
--- a/tests/checkasm/checkasm.h
+++ b/tests/checkasm/checkasm.h
@@ -61,6 +61,7 @@  void checkasm_check_h264dsp(void);
 void checkasm_check_h264pred(void);
 void checkasm_check_h264qpel(void);
 void checkasm_check_hevc_add_res(void);
+void checkasm_check_hevc_deblock(void);
 void checkasm_check_hevc_idct(void);
 void checkasm_check_hevc_pel(void);
 void checkasm_check_hevc_sao(void);
diff --git a/tests/checkasm/hevc_deblock.c b/tests/checkasm/hevc_deblock.c
new file mode 100644
index 0000000000..98f612921b
--- /dev/null
+++ b/tests/checkasm/hevc_deblock.c
@@ -0,0 +1,126 @@ 
+/*
+ * 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/intreadwrite.h"
+#include "libavutil/mem_internal.h"
+
+#include "libavcodec/avcodec.h"
+#include "libavcodec/hevcdsp.h"
+
+#include "checkasm.h"
+
+static const uint32_t pixel_mask[3] = { 0xffffffff, 0x03ff03ff, 0x0fff0fff };
+
+#define SIZEOF_PIXEL ((bit_depth + 7) / 8)
+#define BUF_STRIDE (8 * 2)
+#define BUF_LINES (8)
+#define BUF_OFFSET (BUF_STRIDE * BUF_LINES)
+#define BUF_SIZE (BUF_STRIDE * BUF_LINES + BUF_OFFSET * 2)
+
+#define randomize_buffers(buf0, buf1, size)                 \
+    do {                                                    \
+        uint32_t mask = pixel_mask[(bit_depth - 8) >> 1];   \
+        int k;                                              \
+        for (k = 0; k < size; k += 4) {                     \
+            uint32_t r = rnd() & mask;                      \
+            AV_WN32A(buf0 + k, r);                          \
+            AV_WN32A(buf1 + k, r);                          \
+        }                                                   \
+    } while (0)
+
+
+static void check_deblock_luma(HEVCDSPContext h, int bit_depth)
+{
+    int32_t tc[2] = { 1, 1 };
+    uint8_t no_p[2] = { 0, 0 };
+    uint8_t no_q[2] = { 0, 0 };
+    int beta = rnd() & (0x40 - 1);
+    LOCAL_ALIGNED_32(uint8_t, buf0, [BUF_SIZE]);
+    LOCAL_ALIGNED_32(uint8_t, buf1, [BUF_SIZE]);
+
+    declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *pix, ptrdiff_t stride, int beta, int32_t *tc, uint8_t *no_p, uint8_t *no_q);
+
+    randomize_buffers(buf0, buf1, BUF_SIZE);
+    if (check_func(h.hevc_h_loop_filter_luma, "hevc_h_loop_filter_luma_%d", bit_depth)) {
+        call_ref(buf0 + BUF_OFFSET, BUF_STRIDE, beta, tc, no_p, no_q);
+        call_new(buf1 + BUF_OFFSET, BUF_STRIDE, beta, tc, no_p, no_q);
+        if (memcmp(buf0, buf1, BUF_SIZE))
+            fail();
+        bench_new(buf1 + BUF_OFFSET, BUF_STRIDE, beta, tc, no_p, no_q);
+    }
+
+    randomize_buffers(buf0, buf1, BUF_SIZE);
+    if (check_func(h.hevc_v_loop_filter_luma, "hevc_v_loop_filter_luma_%d", bit_depth)) {
+        call_ref(buf0 + BUF_OFFSET, BUF_STRIDE, beta, tc, no_p, no_q);
+        call_new(buf1 + BUF_OFFSET, BUF_STRIDE, beta, tc, no_p, no_q);
+        if (memcmp(buf0, buf1, BUF_SIZE))
+            fail();
+        bench_new(buf1 + BUF_OFFSET, BUF_STRIDE, beta, tc, no_p, no_q);
+    }
+}
+
+static void check_deblock_chroma(HEVCDSPContext h, int bit_depth)
+{
+    int32_t tc[2] = { 1, 1 };
+    uint8_t no_p[2] = { 0, 0 };
+    uint8_t no_q[2] = { 0, 0 };
+    LOCAL_ALIGNED_32(uint8_t, buf0, [BUF_SIZE]);
+    LOCAL_ALIGNED_32(uint8_t, buf1, [BUF_SIZE]);
+
+    declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *pix, ptrdiff_t stride, int32_t *tc, uint8_t *no_p, uint8_t *no_q);
+
+    randomize_buffers(buf0, buf1, BUF_SIZE);
+    if (check_func(h.hevc_h_loop_filter_chroma, "hevc_h_loop_filter_chroma_%d", bit_depth)) {
+        call_ref(buf0 + BUF_OFFSET, BUF_STRIDE, tc, no_p, no_q);
+        call_new(buf1 + BUF_OFFSET, BUF_STRIDE, tc, no_p, no_q);
+        if (memcmp(buf0, buf1, BUF_SIZE))
+            fail();
+        bench_new(buf1 + BUF_OFFSET, BUF_STRIDE, tc, no_p, no_q);
+    }
+
+    randomize_buffers(buf0, buf1, BUF_SIZE);
+    if (check_func(h.hevc_v_loop_filter_chroma, "hevc_v_loop_filter_chroma_%d", bit_depth)) {
+        call_ref(buf0 + BUF_OFFSET, BUF_STRIDE, tc, no_p, no_q);
+        call_new(buf1 + BUF_OFFSET, BUF_STRIDE, tc, no_p, no_q);
+        if (memcmp(buf0, buf1, BUF_SIZE))
+            fail();
+        bench_new(buf1 + BUF_OFFSET, BUF_STRIDE, tc, no_p, no_q);
+    }
+}
+
+void checkasm_check_hevc_deblock(void)
+{
+    int bit_depth;
+
+    for (bit_depth = 8; bit_depth <= 12; bit_depth += 2) {
+        HEVCDSPContext h;
+
+        ff_hevc_dsp_init(&h, bit_depth);
+        check_deblock_luma(h, bit_depth);
+    }
+    report("deblock_luma");
+
+    for (bit_depth = 8; bit_depth <= 12; bit_depth += 2) {
+        HEVCDSPContext h;
+        ff_hevc_dsp_init(&h, bit_depth);
+        check_deblock_chroma(h, bit_depth);
+    }
+    report("deblock_chroma");
+}
diff --git a/tests/fate/checkasm.mak b/tests/fate/checkasm.mak
index 449f8f89f9..a300caad08 100644
--- a/tests/fate/checkasm.mak
+++ b/tests/fate/checkasm.mak
@@ -16,6 +16,7 @@  FATE_CHECKASM = fate-checkasm-aacpsdsp                                  \
                 fate-checkasm-h264pred                                  \
                 fate-checkasm-h264qpel                                  \
                 fate-checkasm-hevc_add_res                              \
+                fate-checkasm-hevc_deblock                              \
                 fate-checkasm-hevc_idct                                 \
                 fate-checkasm-hevc_pel                                  \
                 fate-checkasm-hevc_sao                                  \