--- 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
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"); +} -- 2.19.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel