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

Submitted by Rodger Combs on Jan. 23, 2019, 2:39 a.m.

Details

Message ID 20190123023914.20619-3-rodger.combs@gmail.com
State New
Headers show

Commit Message

Rodger Combs Jan. 23, 2019, 2:39 a.m.
---
 libavfilter/vf_yadif.c    |  23 ++++---
 libavfilter/yadif.h       |   2 +
 tests/checkasm/Makefile   |   1 +
 tests/checkasm/checkasm.c |   3 +
 tests/checkasm/checkasm.h |   1 +
 tests/checkasm/vf_yadif.c | 137 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 158 insertions(+), 9 deletions(-)
 create mode 100644 tests/checkasm/vf_yadif.c

Patch hide | download patch | download mbox

diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index 3107924932..575b5a421e 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -311,6 +311,19 @@  static int query_formats(AVFilterContext *ctx)
     return ff_set_common_formats(ctx, fmts_list);
 }
 
+void ff_yadif_init(YADIFContext *s) {
+    if (s->csp->comp[0].depth > 8) {
+        s->filter_line  = filter_line_c_16bit;
+        s->filter_edges = filter_edges_16bit;
+    } else {
+        s->filter_line  = filter_line_c;
+        s->filter_edges = filter_edges;
+    }
+
+    if (ARCH_X86)
+        ff_yadif_init_x86(s);
+}
+
 static int config_props(AVFilterLink *link)
 {
     AVFilterContext *ctx = link->src;
@@ -332,16 +345,8 @@  static int config_props(AVFilterLink *link)
 
     s->csp = av_pix_fmt_desc_get(link->format);
     s->filter = filter;
-    if (s->csp->comp[0].depth > 8) {
-        s->filter_line  = filter_line_c_16bit;
-        s->filter_edges = filter_edges_16bit;
-    } else {
-        s->filter_line  = filter_line_c;
-        s->filter_edges = filter_edges;
-    }
 
-    if (ARCH_X86)
-        ff_yadif_init_x86(s);
+    ff_yadif_init(s);
 
     return 0;
 }
diff --git a/libavfilter/yadif.h b/libavfilter/yadif.h
index c928911b35..aa0ae744f2 100644
--- a/libavfilter/yadif.h
+++ b/libavfilter/yadif.h
@@ -86,6 +86,8 @@  typedef struct YADIFContext {
     int current_field;  ///< YADIFCurrentField
 } YADIFContext;
 
+void ff_yadif_init(YADIFContext *s);
+
 void ff_yadif_init_x86(YADIFContext *yadif);
 
 int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame);
diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile
index 47b7b06d28..eb1ac06151 100644
--- a/tests/checkasm/Makefile
+++ b/tests/checkasm/Makefile
@@ -37,6 +37,7 @@  AVFILTEROBJS-$(CONFIG_COLORSPACE_FILTER) += vf_colorspace.o
 AVFILTEROBJS-$(CONFIG_HFLIP_FILTER)      += vf_hflip.o
 AVFILTEROBJS-$(CONFIG_THRESHOLD_FILTER)  += vf_threshold.o
 AVFILTEROBJS-$(CONFIG_NLMEANS_FILTER)    += vf_nlmeans.o
+AVFILTEROBJS-$(CONFIG_YADIF_FILTER)      += vf_yadif.o
 
 CHECKASMOBJS-$(CONFIG_AVFILTER) += $(AVFILTEROBJS-yes)
 
diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
index c3f5160132..23cdcb27ae 100644
--- a/tests/checkasm/checkasm.c
+++ b/tests/checkasm/checkasm.c
@@ -168,6 +168,9 @@  static const struct {
     #if CONFIG_THRESHOLD_FILTER
         { "vf_threshold", checkasm_check_vf_threshold },
     #endif
+    #if CONFIG_YADIF_FILTER
+        { "vf_yadif", checkasm_check_vf_yadif },
+    #endif
 #endif
 #if CONFIG_SWSCALE
     { "sw_rgb", checkasm_check_sw_rgb },
diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h
index 9e8e879fd3..a5c593e7b9 100644
--- a/tests/checkasm/checkasm.h
+++ b/tests/checkasm/checkasm.h
@@ -72,6 +72,7 @@  void checkasm_check_utvideodsp(void);
 void checkasm_check_v210enc(void);
 void checkasm_check_vf_hflip(void);
 void checkasm_check_vf_threshold(void);
+void checkasm_check_vf_yadif(void);
 void checkasm_check_vp8dsp(void);
 void checkasm_check_vp9dsp(void);
 void checkasm_check_videodsp(void);
diff --git a/tests/checkasm/vf_yadif.c b/tests/checkasm/vf_yadif.c
new file mode 100644
index 0000000000..d011a2771d
--- /dev/null
+++ b/tests/checkasm/vf_yadif.c
@@ -0,0 +1,137 @@ 
+/*
+ * 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 "checkasm.h"
+#include "libavfilter/yadif.h"
+#include "libavutil/intreadwrite.h"
+
+#define WIDTH 64
+#define HEIGHT 4
+#define SIZE WIDTH * HEIGHT + 32
+
+#define randomize_buffers(buf, size)      \
+    do {                                  \
+        int j;                            \
+        uint8_t *tmp_buf = (uint8_t*)buf; \
+        for (j = 0; j < size; j++)        \
+            tmp_buf[j] = rnd() & 0xFF;    \
+    } while (0)
+
+#define randomize_buffers_10(buf, size)    \
+    do {                                   \
+        int j;                             \
+        uint16_t *tmp_buf = (uint16_t*)buf;\
+        for (j = 0; j < size / 2; j++)     \
+            tmp_buf[j] = rnd() & 0x03FF;   \
+    } while (0)
+
+static void check_yadif(enum AVPixelFormat fmt, int imode, const char * report_name){
+    LOCAL_ALIGNED_32(uint8_t, cur_buf,     [SIZE]);
+    LOCAL_ALIGNED_32(uint8_t, prev_buf,    [SIZE]);
+    LOCAL_ALIGNED_32(uint8_t, next_buf,    [SIZE]);
+    LOCAL_ALIGNED_32(uint8_t, dst_ref_buf, [SIZE]);
+    LOCAL_ALIGNED_32(uint8_t, dst_new_buf, [SIZE]);
+    int w = WIDTH, refs = WIDTH, h = HEIGHT;
+    int df, pix_3, edge;
+    int y;
+    YADIFContext s;
+
+    declare_func(void, void *dst1, void *prev1, void *cur1, void *next1,
+                 int w, int prefs, int mrefs, int parity, int mode);
+
+    memset(cur_buf,     0,  SIZE);
+    memset(prev_buf,    0,  SIZE);
+    memset(next_buf,    0,  SIZE);
+    memset(dst_ref_buf, 0,  SIZE);
+    memset(dst_new_buf, 0,  SIZE);
+
+    s.csp = av_pix_fmt_desc_get(fmt);
+    df = (s.csp->comp[0].depth + 7) / 8;
+    w /= df;
+    pix_3 = 3 * df;
+    edge = 3 + 8 / df - 1;
+
+    if (s.csp->comp[0].depth == 10) {
+        randomize_buffers_10(cur_buf,  WIDTH * HEIGHT);
+        randomize_buffers_10(prev_buf, WIDTH * HEIGHT);
+        randomize_buffers_10(next_buf, WIDTH * HEIGHT);
+    } else {
+        randomize_buffers(cur_buf,  WIDTH * HEIGHT);
+        randomize_buffers(prev_buf, WIDTH * HEIGHT);
+        randomize_buffers(next_buf, WIDTH * HEIGHT);
+    }
+
+    ff_yadif_init(&s);
+
+    if (check_func(s.filter_line, "yadif_%s", report_name)) {
+        for (int parity = 0; parity <= 1; parity++) {
+            for (y = 0; y < HEIGHT; y++) {
+                uint8_t *prev    = &prev_buf[y * refs];
+                uint8_t *cur     = &cur_buf[y * refs];
+                uint8_t *next    = &next_buf[y * refs];
+                uint8_t *dst_ref = &dst_ref_buf[y * refs];
+                uint8_t *dst_new = &dst_new_buf[y * refs];
+                int     mode  = y == 1 || y + 2 == HEIGHT ? 2 : imode;
+                call_ref(dst_ref + pix_3, prev + pix_3, cur + pix_3,
+                         next + pix_3, w - edge,
+                         y + 1 < h ? refs : -refs,
+                         y ? -refs : refs,
+                         parity, mode);
+                call_new(dst_new + pix_3, prev + pix_3, cur + pix_3,
+                         next + pix_3, w - edge,
+                         y + 1 < h ? refs : -refs,
+                         y ? -refs : refs,
+                         parity, mode);
+                s.filter_edges(dst_ref, prev, cur, next, w,
+                               y + 1 < h ? refs : -refs,
+                               y ? -refs : refs,
+                               parity, mode);
+                s.filter_edges(dst_new, prev, cur, next, w,
+                               y + 1 < h ? refs : -refs,
+                               y ? -refs : refs,
+                               parity, mode);
+            }
+            if (memcmp(dst_new_buf, dst_ref_buf, WIDTH * HEIGHT))
+                fail();
+        }
+        bench_new(dst_new_buf + pix_3, prev_buf + pix_3,
+                  cur_buf + pix_3, next_buf + pix_3,
+                  w - edge, WIDTH, WIDTH, 0, imode);
+    }
+}
+void checkasm_check_vf_yadif(void)
+{
+    check_yadif(AV_PIX_FMT_YUV420P, 0, "8");
+    report("yadif_8");
+
+    check_yadif(AV_PIX_FMT_YUV420P, 2, "8_nospatial");
+    report("yadif_8_nospatial");
+
+    check_yadif(AV_PIX_FMT_YUV420P10, 0, "10");
+    report("yadif_10");
+
+    check_yadif(AV_PIX_FMT_YUV420P10, 2, "10_nospatial");
+    report("yadif_10_nospatial");
+
+    check_yadif(AV_PIX_FMT_YUV420P16, 0, "16");
+    report("yadif_16");
+
+    check_yadif(AV_PIX_FMT_YUV420P16, 2, "16_nospatial");
+    report("yadif_16_nospatial");
+}