diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 2fe0033b21..d063dc65fc 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -214,7 +214,7 @@ OBJS-$(CONFIG_BM3D_FILTER)                   += vf_bm3d.o framesync.o
 OBJS-$(CONFIG_BOXBLUR_FILTER)                += vf_boxblur.o boxblur.o
 OBJS-$(CONFIG_BOXBLUR_OPENCL_FILTER)         += vf_avgblur_opencl.o opencl.o \
                                                 opencl/avgblur.o boxblur.o
-OBJS-$(CONFIG_BWDIF_FILTER)                  += vf_bwdif.o yadif_common.o
+OBJS-$(CONFIG_BWDIF_FILTER)                  += vf_bwdif.o bwdifdsp.o yadif_common.o
 OBJS-$(CONFIG_BWDIF_CUDA_FILTER)             += vf_bwdif_cuda.o vf_bwdif_cuda.ptx.o \
                                                 yadif_common.o
 OBJS-$(CONFIG_BWDIF_VULKAN_FILTER)           += vf_bwdif_vulkan.o yadif_common.o vulkan.o vulkan_filter.o
diff --git a/libavfilter/bwdifdsp.c b/libavfilter/bwdifdsp.c
new file mode 100644
index 0000000000..af217481a5
--- /dev/null
+++ b/libavfilter/bwdifdsp.c
@@ -0,0 +1,251 @@
+/*
+ * BobWeaver Deinterlacing Filter DSP functions
+ * Copyright (C) 2016 Thomas Mundt <loudmax@yahoo.de>
+ *
+ * Based on YADIF (Yet Another Deinterlacing Filter)
+ * Copyright (C) 2006-2011 Michael Niedermayer <michaelni@gmx.at>
+ *               2010      James Darnley <james.darnley@gmail.com>
+ *
+ * With use of Weston 3 Field Deinterlacing Filter algorithm
+ * Copyright (C) 2012 British Broadcasting Corporation, All Rights Reserved
+ * Author of de-interlace algorithm: Jim Easterbrook for BBC R&D
+ * Based on the process described by Martin Weston for BBC R&D
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 <stdint.h>
+#include <string.h>
+
+#include "config.h"
+
+#include "bwdifdsp.h"
+#include "libavutil/attributes.h"
+#include "libavutil/common.h"
+#include "libavutil/macros.h"
+
+/*
+ * Filter coefficients coef_lf and coef_hf taken from BBC PH-2071 (Weston 3 Field Deinterlacer).
+ * Used when there is spatial and temporal interpolation.
+ * Filter coefficients coef_sp are used when there is spatial interpolation only.
+ * Adjusted for matching visual sharpness impression of spatial and temporal interpolation.
+ */
+static const uint16_t coef_lf[2] = { 4309, 213 };
+static const uint16_t coef_hf[3] = { 5570, 3801, 1016 };
+static const uint16_t coef_sp[2] = { 5077, 981 };
+
+
+#define FILTER_INTRA() \
+    for (x = 0; x < w; x++) { \
+        interpol = (coef_sp[0] * (cur[mrefs] + cur[prefs]) - coef_sp[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \
+        dst[0] = av_clip(interpol, 0, clip_max); \
+ \
+        dst++; \
+        cur++; \
+    }
+
+#define FILTER1() \
+    for (x = 0; x < w; x++) { \
+        int c = cur[mrefs]; \
+        int d = (prev2[0] + next2[0]) >> 1; \
+        int e = cur[prefs]; \
+        int temporal_diff0 = FFABS(prev2[0] - next2[0]); \
+        int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e)) >> 1; \
+        int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e)) >> 1; \
+        int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2); \
+ \
+        if (!diff) { \
+            dst[0] = d; \
+        } else {
+
+#define SPAT_CHECK() \
+            int b = ((prev2[mrefs2] + next2[mrefs2]) >> 1) - c; \
+            int f = ((prev2[prefs2] + next2[prefs2]) >> 1) - e; \
+            int dc = d - c; \
+            int de = d - e; \
+            int max = FFMAX3(de, dc, FFMIN(b, f)); \
+            int min = FFMIN3(de, dc, FFMAX(b, f)); \
+            diff = FFMAX3(diff, min, -max);
+
+#define FILTER_LINE() \
+            SPAT_CHECK() \
+            if (FFABS(c - e) > temporal_diff0) { \
+                interpol = (((coef_hf[0] * (prev2[0] + next2[0]) \
+                    - coef_hf[1] * (prev2[mrefs2] + next2[mrefs2] + prev2[prefs2] + next2[prefs2]) \
+                    + coef_hf[2] * (prev2[mrefs4] + next2[mrefs4] + prev2[prefs4] + next2[prefs4])) >> 2) \
+                    + coef_lf[0] * (c + e) - coef_lf[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \
+            } else { \
+                interpol = (coef_sp[0] * (c + e) - coef_sp[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \
+            }
+
+#define FILTER_EDGE() \
+            if (spat) { \
+                SPAT_CHECK() \
+            } \
+            interpol = (c + e) >> 1;
+
+#define FILTER2() \
+            if (interpol > d + diff) \
+                interpol = d + diff; \
+            else if (interpol < d - diff) \
+                interpol = d - diff; \
+ \
+            dst[0] = av_clip(interpol, 0, clip_max); \
+        } \
+ \
+        dst++; \
+        cur++; \
+        prev++; \
+        next++; \
+        prev2++; \
+        next2++; \
+    }
+
+void ff_bwdif_filter_intra_c(void *dst1, void *cur1, int w, int prefs, int mrefs,
+                             int prefs3, int mrefs3, int parity, int clip_max)
+{
+    uint8_t *dst = dst1;
+    uint8_t *cur = cur1;
+    int interpol, x;
+
+    FILTER_INTRA()
+}
+
+void ff_bwdif_filter_line_c(void *dst1, void *prev1, void *cur1, void *next1,
+                            int w, int prefs, int mrefs, int prefs2, int mrefs2,
+                            int prefs3, int mrefs3, int prefs4, int mrefs4,
+                            int parity, int clip_max)
+{
+    uint8_t *dst   = dst1;
+    uint8_t *prev  = prev1;
+    uint8_t *cur   = cur1;
+    uint8_t *next  = next1;
+    uint8_t *prev2 = parity ? prev : cur ;
+    uint8_t *next2 = parity ? cur  : next;
+    int interpol, x;
+
+    FILTER1()
+    FILTER_LINE()
+    FILTER2()
+}
+
+#define NEXT_LINE()\
+    dst += d_stride; \
+    prev += prefs; \
+    cur  += prefs; \
+    next += prefs;
+
+void ff_bwdif_filter_line3_c(void * dst1, int d_stride,
+                             const void * prev1, const void * cur1, const void * next1, int s_stride,
+                             int w, int parity, int clip_max)
+{
+    const int prefs = s_stride;
+    uint8_t * dst  = dst1;
+    const uint8_t * prev = prev1;
+    const uint8_t * cur  = cur1;
+    const uint8_t * next = next1;
+
+    ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w,
+                           prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max);
+    NEXT_LINE();
+    memcpy(dst, cur, w);
+    NEXT_LINE();
+    ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w,
+                           prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max);
+}
+
+void ff_bwdif_filter_edge_c(void *dst1, void *prev1, void *cur1, void *next1,
+                            int w, int prefs, int mrefs, int prefs2, int mrefs2,
+                            int parity, int clip_max, int spat)
+{
+    uint8_t *dst   = dst1;
+    uint8_t *prev  = prev1;
+    uint8_t *cur   = cur1;
+    uint8_t *next  = next1;
+    uint8_t *prev2 = parity ? prev : cur ;
+    uint8_t *next2 = parity ? cur  : next;
+    int interpol, x;
+
+    FILTER1()
+    FILTER_EDGE()
+    FILTER2()
+}
+
+static void filter_intra_16bit(void *dst1, void *cur1, int w, int prefs, int mrefs,
+                               int prefs3, int mrefs3, int parity, int clip_max)
+{
+    uint16_t *dst = dst1;
+    uint16_t *cur = cur1;
+    int interpol, x;
+
+    FILTER_INTRA()
+}
+
+static void filter_line_c_16bit(void *dst1, void *prev1, void *cur1, void *next1,
+                                int w, int prefs, int mrefs, int prefs2, int mrefs2,
+                                int prefs3, int mrefs3, int prefs4, int mrefs4,
+                                int parity, int clip_max)
+{
+    uint16_t *dst   = dst1;
+    uint16_t *prev  = prev1;
+    uint16_t *cur   = cur1;
+    uint16_t *next  = next1;
+    uint16_t *prev2 = parity ? prev : cur ;
+    uint16_t *next2 = parity ? cur  : next;
+    int interpol, x;
+
+    FILTER1()
+    FILTER_LINE()
+    FILTER2()
+}
+
+static void filter_edge_16bit(void *dst1, void *prev1, void *cur1, void *next1,
+                              int w, int prefs, int mrefs, int prefs2, int mrefs2,
+                              int parity, int clip_max, int spat)
+{
+    uint16_t *dst   = dst1;
+    uint16_t *prev  = prev1;
+    uint16_t *cur   = cur1;
+    uint16_t *next  = next1;
+    uint16_t *prev2 = parity ? prev : cur ;
+    uint16_t *next2 = parity ? cur  : next;
+    int interpol, x;
+
+    FILTER1()
+    FILTER_EDGE()
+    FILTER2()
+}
+
+av_cold void ff_bwdif_init_filter_line(BWDIFDSPContext *s, int bit_depth)
+{
+    s->filter_line3 = 0;
+    if (bit_depth > 8) {
+        s->filter_intra = filter_intra_16bit;
+        s->filter_line  = filter_line_c_16bit;
+        s->filter_edge  = filter_edge_16bit;
+    } else {
+        s->filter_intra = ff_bwdif_filter_intra_c;
+        s->filter_line  = ff_bwdif_filter_line_c;
+        s->filter_edge  = ff_bwdif_filter_edge_c;
+    }
+
+#if ARCH_X86
+    ff_bwdif_init_x86(s, bit_depth);
+#elif ARCH_AARCH64
+    ff_bwdif_init_aarch64(s, bit_depth);
+#endif
+}
diff --git a/libavfilter/vf_bwdif.c b/libavfilter/vf_bwdif.c
index 282aef5698..137cd5ef13 100644
--- a/libavfilter/vf_bwdif.c
+++ b/libavfilter/vf_bwdif.c
@@ -37,16 +37,6 @@
 #include "internal.h"
 #include "yadif.h"
 
-/*
- * Filter coefficients coef_lf and coef_hf taken from BBC PH-2071 (Weston 3 Field Deinterlacer).
- * Used when there is spatial and temporal interpolation.
- * Filter coefficients coef_sp are used when there is spatial interpolation only.
- * Adjusted for matching visual sharpness impression of spatial and temporal interpolation.
- */
-static const uint16_t coef_lf[2] = { 4309, 213 };
-static const uint16_t coef_hf[3] = { 5570, 3801, 1016 };
-static const uint16_t coef_sp[2] = { 5077, 981 };
-
 typedef struct BWDIFContext {
     YADIFContext yadif;
     BWDIFDSPContext dsp;
@@ -60,187 +50,6 @@ typedef struct ThreadData {
     int tff;
 } ThreadData;
 
-#define FILTER_INTRA() \
-    for (x = 0; x < w; x++) { \
-        interpol = (coef_sp[0] * (cur[mrefs] + cur[prefs]) - coef_sp[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \
-        dst[0] = av_clip(interpol, 0, clip_max); \
- \
-        dst++; \
-        cur++; \
-    }
-
-#define FILTER1() \
-    for (x = 0; x < w; x++) { \
-        int c = cur[mrefs]; \
-        int d = (prev2[0] + next2[0]) >> 1; \
-        int e = cur[prefs]; \
-        int temporal_diff0 = FFABS(prev2[0] - next2[0]); \
-        int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e)) >> 1; \
-        int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e)) >> 1; \
-        int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2); \
- \
-        if (!diff) { \
-            dst[0] = d; \
-        } else {
-
-#define SPAT_CHECK() \
-            int b = ((prev2[mrefs2] + next2[mrefs2]) >> 1) - c; \
-            int f = ((prev2[prefs2] + next2[prefs2]) >> 1) - e; \
-            int dc = d - c; \
-            int de = d - e; \
-            int max = FFMAX3(de, dc, FFMIN(b, f)); \
-            int min = FFMIN3(de, dc, FFMAX(b, f)); \
-            diff = FFMAX3(diff, min, -max);
-
-#define FILTER_LINE() \
-            SPAT_CHECK() \
-            if (FFABS(c - e) > temporal_diff0) { \
-                interpol = (((coef_hf[0] * (prev2[0] + next2[0]) \
-                    - coef_hf[1] * (prev2[mrefs2] + next2[mrefs2] + prev2[prefs2] + next2[prefs2]) \
-                    + coef_hf[2] * (prev2[mrefs4] + next2[mrefs4] + prev2[prefs4] + next2[prefs4])) >> 2) \
-                    + coef_lf[0] * (c + e) - coef_lf[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \
-            } else { \
-                interpol = (coef_sp[0] * (c + e) - coef_sp[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \
-            }
-
-#define FILTER_EDGE() \
-            if (spat) { \
-                SPAT_CHECK() \
-            } \
-            interpol = (c + e) >> 1;
-
-#define FILTER2() \
-            if (interpol > d + diff) \
-                interpol = d + diff; \
-            else if (interpol < d - diff) \
-                interpol = d - diff; \
- \
-            dst[0] = av_clip(interpol, 0, clip_max); \
-        } \
- \
-        dst++; \
-        cur++; \
-        prev++; \
-        next++; \
-        prev2++; \
-        next2++; \
-    }
-
-void ff_bwdif_filter_intra_c(void *dst1, void *cur1, int w, int prefs, int mrefs,
-                             int prefs3, int mrefs3, int parity, int clip_max)
-{
-    uint8_t *dst = dst1;
-    uint8_t *cur = cur1;
-    int interpol, x;
-
-    FILTER_INTRA()
-}
-
-void ff_bwdif_filter_line_c(void *dst1, void *prev1, void *cur1, void *next1,
-                            int w, int prefs, int mrefs, int prefs2, int mrefs2,
-                            int prefs3, int mrefs3, int prefs4, int mrefs4,
-                            int parity, int clip_max)
-{
-    uint8_t *dst   = dst1;
-    uint8_t *prev  = prev1;
-    uint8_t *cur   = cur1;
-    uint8_t *next  = next1;
-    uint8_t *prev2 = parity ? prev : cur ;
-    uint8_t *next2 = parity ? cur  : next;
-    int interpol, x;
-
-    FILTER1()
-    FILTER_LINE()
-    FILTER2()
-}
-
-#define NEXT_LINE()\
-    dst += d_stride; \
-    prev += prefs; \
-    cur  += prefs; \
-    next += prefs;
-
-void ff_bwdif_filter_line3_c(void * dst1, int d_stride,
-                             const void * prev1, const void * cur1, const void * next1, int s_stride,
-                             int w, int parity, int clip_max)
-{
-    const int prefs = s_stride;
-    uint8_t * dst  = dst1;
-    const uint8_t * prev = prev1;
-    const uint8_t * cur  = cur1;
-    const uint8_t * next = next1;
-
-    ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w,
-                           prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max);
-    NEXT_LINE();
-    memcpy(dst, cur, w);
-    NEXT_LINE();
-    ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w,
-                           prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max);
-}
-
-void ff_bwdif_filter_edge_c(void *dst1, void *prev1, void *cur1, void *next1,
-                            int w, int prefs, int mrefs, int prefs2, int mrefs2,
-                            int parity, int clip_max, int spat)
-{
-    uint8_t *dst   = dst1;
-    uint8_t *prev  = prev1;
-    uint8_t *cur   = cur1;
-    uint8_t *next  = next1;
-    uint8_t *prev2 = parity ? prev : cur ;
-    uint8_t *next2 = parity ? cur  : next;
-    int interpol, x;
-
-    FILTER1()
-    FILTER_EDGE()
-    FILTER2()
-}
-
-static void filter_intra_16bit(void *dst1, void *cur1, int w, int prefs, int mrefs,
-                               int prefs3, int mrefs3, int parity, int clip_max)
-{
-    uint16_t *dst = dst1;
-    uint16_t *cur = cur1;
-    int interpol, x;
-
-    FILTER_INTRA()
-}
-
-static void filter_line_c_16bit(void *dst1, void *prev1, void *cur1, void *next1,
-                                int w, int prefs, int mrefs, int prefs2, int mrefs2,
-                                int prefs3, int mrefs3, int prefs4, int mrefs4,
-                                int parity, int clip_max)
-{
-    uint16_t *dst   = dst1;
-    uint16_t *prev  = prev1;
-    uint16_t *cur   = cur1;
-    uint16_t *next  = next1;
-    uint16_t *prev2 = parity ? prev : cur ;
-    uint16_t *next2 = parity ? cur  : next;
-    int interpol, x;
-
-    FILTER1()
-    FILTER_LINE()
-    FILTER2()
-}
-
-static void filter_edge_16bit(void *dst1, void *prev1, void *cur1, void *next1,
-                              int w, int prefs, int mrefs, int prefs2, int mrefs2,
-                              int parity, int clip_max, int spat)
-{
-    uint16_t *dst   = dst1;
-    uint16_t *prev  = prev1;
-    uint16_t *cur   = cur1;
-    uint16_t *next  = next1;
-    uint16_t *prev2 = parity ? prev : cur ;
-    uint16_t *next2 = parity ? cur  : next;
-    int interpol, x;
-
-    FILTER1()
-    FILTER_EDGE()
-    FILTER2()
-}
-
 // Round job start line down to multiple of 4 so that if filter_line3 exists
 // and the frame is a multiple of 4 high then filter_line will never be called
 static inline int job_start(const int jobnr, const int nb_jobs, const int h)
@@ -394,26 +203,6 @@ static int config_props(AVFilterLink *link)
     return 0;
 }
 
-av_cold void ff_bwdif_init_filter_line(BWDIFDSPContext *s, int bit_depth)
-{
-    s->filter_line3 = 0;
-    if (bit_depth > 8) {
-        s->filter_intra = filter_intra_16bit;
-        s->filter_line  = filter_line_c_16bit;
-        s->filter_edge  = filter_edge_16bit;
-    } else {
-        s->filter_intra = ff_bwdif_filter_intra_c;
-        s->filter_line  = ff_bwdif_filter_line_c;
-        s->filter_edge  = ff_bwdif_filter_edge_c;
-    }
-
-#if ARCH_X86
-    ff_bwdif_init_x86(s, bit_depth);
-#elif ARCH_AARCH64
-    ff_bwdif_init_aarch64(s, bit_depth);
-#endif
-}
-
 
 #define OFFSET(x) offsetof(YADIFContext, x)
 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
