summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/post/deinterlace/plugins/Makefile.am15
-rw-r--r--src/post/deinterlace/plugins/greedy.c2
-rw-r--r--src/post/deinterlace/plugins/greedy2frame.c2
-rw-r--r--src/post/deinterlace/plugins/kdetv_greedyh.c2
-rw-r--r--src/post/deinterlace/plugins/kdetv_tomsmocomp.c150
-rw-r--r--src/post/deinterlace/plugins/linearblend.c4
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/SearchLoop0A.inc15
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/SearchLoopBottom.inc116
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/SearchLoopEdgeA.inc11
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/SearchLoopEdgeA8.inc12
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA.inc10
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA2.inc5
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA6.inc11
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddAH.inc10
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddAH2.inc5
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/SearchLoopTop.inc190
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/SearchLoopVA.inc6
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/SearchLoopVAH.inc6
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/StrangeBob.inc322
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/TomsMoCompAll.inc245
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/TomsMoCompAll2.inc173
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/WierdBob.inc189
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h170
-rw-r--r--src/post/deinterlace/plugins/vfir.c2
-rw-r--r--src/post/deinterlace/xine_plugin.c6
25 files changed, 1669 insertions, 10 deletions
diff --git a/src/post/deinterlace/plugins/Makefile.am b/src/post/deinterlace/plugins/Makefile.am
index 817e206cb..7c982124a 100644
--- a/src/post/deinterlace/plugins/Makefile.am
+++ b/src/post/deinterlace/plugins/Makefile.am
@@ -17,7 +17,16 @@ include $(top_srcdir)/misc/Makefile.common
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-EXTRA_DIST = greedy2frame_template.c greedyh.asm x86-64_macros.inc
+EXTRA_DIST = greedy2frame_template.c greedyh.asm \
+ tomsmocomp/SearchLoop0A.inc tomsmocomp/SearchLoopBottom.inc \
+ tomsmocomp/SearchLoopEdgeA.inc tomsmocomp/SearchLoopEdgeA8.inc \
+ tomsmocomp/SearchLoopOddA.inc tomsmocomp/SearchLoopOddA2.inc \
+ tomsmocomp/SearchLoopOddA6.inc tomsmocomp/SearchLoopOddAH.inc \
+ tomsmocomp/SearchLoopOddAH2.inc tomsmocomp/SearchLoopTop.inc \
+ tomsmocomp/SearchLoopVA.inc tomsmocomp/SearchLoopVAH.inc \
+ tomsmocomp/StrangeBob.inc tomsmocomp/TomsMoCompAll.inc \
+ tomsmocomp/TomsMoCompAll2.inc tomsmocomp/WierdBob.inc \
+ tomsmocomp/tomsmocompmacros.h x86-64_macros.inc
AM_CPPFLAGS = -I$(top_srcdir)/src/post/deinterlace
@@ -34,8 +43,8 @@ libdeinterlaceplugins_la_SOURCES = \
weave.c \
greedy2frame.c \
scalerbob.c \
- kdetv_greedyh.c
-# kdetv_tomsmocomp.c
+ kdetv_greedyh.c \
+ kdetv_tomsmocomp.c
libdeinterlaceplugins_la_LIBADD = $(XINE_LIB)
libdeinterlaceplugins_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
diff --git a/src/post/deinterlace/plugins/greedy.c b/src/post/deinterlace/plugins/greedy.c
index 8acb12c09..9f0e313b9 100644
--- a/src/post/deinterlace/plugins/greedy.c
+++ b/src/post/deinterlace/plugins/greedy.c
@@ -174,7 +174,7 @@ static void deinterlace_greedy_packed422_scanline_mmxext( uint8_t *output,
static deinterlace_method_t greedymethod =
{
- "DScaler: Greedy - Low motion",
+ "Greedy - Low motion (DScaler)",
"Greedy",
/*
"Motion Adaptive: Simple Detection",
diff --git a/src/post/deinterlace/plugins/greedy2frame.c b/src/post/deinterlace/plugins/greedy2frame.c
index 2e0f6eeb2..3b400ef1c 100644
--- a/src/post/deinterlace/plugins/greedy2frame.c
+++ b/src/post/deinterlace/plugins/greedy2frame.c
@@ -53,7 +53,7 @@ static int GreedyTwoFrameThreshold2 = 8;
static deinterlace_method_t greedy2framemethod =
{
- "Greedy - 2-frame (DScaler)",
+ "Greedy 2-frame (DScaler)",
"Greedy2Frame",
4,
MM_ACCEL_X86_MMXEXT,
diff --git a/src/post/deinterlace/plugins/kdetv_greedyh.c b/src/post/deinterlace/plugins/kdetv_greedyh.c
index dc6aafdf3..91c8fbac7 100644
--- a/src/post/deinterlace/plugins/kdetv_greedyh.c
+++ b/src/post/deinterlace/plugins/kdetv_greedyh.c
@@ -114,7 +114,7 @@ static deinterlace_method_t greedymethod =
0,
0,
deinterlace_frame_di_greedyh,
- 1,
+ 0,
{ "Uses heuristics to detect motion in the input",
"frames and reconstruct image detail where",
"possible. Use this for high quality output",
diff --git a/src/post/deinterlace/plugins/kdetv_tomsmocomp.c b/src/post/deinterlace/plugins/kdetv_tomsmocomp.c
new file mode 100644
index 000000000..d29a4ec34
--- /dev/null
+++ b/src/post/deinterlace/plugins/kdetv_tomsmocomp.c
@@ -0,0 +1,150 @@
+/**
+ * Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net>
+ *
+ * This library 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 of the License, or (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#else
+#include <stdint.h>
+#endif
+
+#include "attributes.h"
+#include "xineutils.h"
+#include "deinterlace.h"
+#include "speedtools.h"
+#include "speedy.h"
+
+#if defined (ARCH_X86) || defined (ARCH_X86_64)
+
+static int Fieldcopy(void *dest, const void *src, size_t count,
+ int rows, int dst_pitch, int src_pitch)
+{
+ unsigned char* pDest = (unsigned char*) dest;
+ unsigned char* pSrc = (unsigned char*) src;
+ int i;
+
+ for (i=0; i < rows; i++) {
+ xine_fast_memcpy(pDest, pSrc, count);
+ pSrc += src_pitch;
+ pDest += dst_pitch;
+ }
+ return 0;
+}
+
+
+#include "tomsmocomp/tomsmocompmacros.h"
+#include "x86-64_macros.inc"
+
+#define SearchEffortDefault 5
+#define UseStrangeBobDefault 0
+
+static long SearchEffort=SearchEffortDefault;
+static int UseStrangeBob=UseStrangeBobDefault;
+
+
+#define IS_MMX
+#define SSE_TYPE MMX
+#define FUNCT_NAME tomsmocomp_filter_mmx
+#include "tomsmocomp/TomsMoCompAll.inc"
+#undef IS_MMX
+#undef SSE_TYPE
+#undef FUNCT_NAME
+
+#define IS_3DNOW
+#define SSE_TYPE 3DNOW
+#define FUNCT_NAME tomsmocomp_filter_3dnow
+#include "tomsmocomp/TomsMoCompAll.inc"
+#undef IS_3DNOW
+#undef SSE_TYPE
+#undef FUNCT_NAME
+
+#define IS_SSE
+#define SSE_TYPE SSE
+#define FUNCT_NAME tomsmocomp_filter_sse
+#include "tomsmocomp/TomsMoCompAll.inc"
+#undef IS_SSE
+#undef SSE_TYPE
+#undef FUNCT_NAME
+
+#endif
+
+static void deinterlace_frame_di_tomsmocomp( uint8_t *output, int outstride,
+ deinterlace_frame_data_t *data,
+ int bottom_field, int second_field,
+ int width, int height )
+{
+#if defined (ARCH_X86) || defined (ARCH_X86_64)
+
+ if( xine_mm_accel() & MM_ACCEL_X86_MMXEXT ) {
+ tomsmocomp_filter_sse( output, outstride, data,
+ bottom_field, second_field,
+ width, height );
+ } else if( xine_mm_accel() & MM_ACCEL_X86_3DNOW ) {
+ tomsmocomp_filter_3dnow( output, outstride, data,
+ bottom_field, second_field,
+ width, height );
+ } else {
+ tomsmocomp_filter_mmx( output, outstride, data,
+ bottom_field, second_field,
+ width, height );
+ }
+
+#endif
+}
+
+static deinterlace_method_t tomsmocompmethod =
+{
+ "Tom's Motion Compensated (DScaler)",
+ "TomsMoComp",
+ /*
+ "Motion Adaptive: Motion Search",
+ "AdaptiveSearch",
+ */
+ 4,
+ MM_ACCEL_X86_MMX,
+ 0,
+ 0,
+ 0,
+ 0,
+ deinterlace_frame_di_tomsmocomp,
+ 0,
+ { "Uses heuristics to detect motion in the input",
+ "frames and reconstruct image detail where",
+ "possible. Use this for high quality output",
+ "even on monitors set to an arbitrary refresh",
+ "rate.",
+ "",
+ "Motion search mode finds and follows motion",
+ "vectors for accurate interpolation. This is",
+ "the TomsMoComp deinterlacer from DScaler.",
+ "" }
+};
+
+deinterlace_method_t *dscaler_tomsmocomp_get_method( void )
+{
+ return &tomsmocompmethod;
+}
+
diff --git a/src/post/deinterlace/plugins/linearblend.c b/src/post/deinterlace/plugins/linearblend.c
index 10cd11c3a..d8ecacefc 100644
--- a/src/post/deinterlace/plugins/linearblend.c
+++ b/src/post/deinterlace/plugins/linearblend.c
@@ -304,7 +304,7 @@ static void deinterlace_scanline_linear_blend2_mmxext( uint8_t *output,
static deinterlace_method_t linearblendmethod_mmxext =
{
- "mplayer: Linear Blend",
+ "Linear Blend (mplayer)",
"LinearBlend",
2,
MM_ACCEL_X86_MMXEXT,
@@ -330,7 +330,7 @@ static deinterlace_method_t linearblendmethod_mmxext =
static deinterlace_method_t linearblendmethod =
{
- "mplayer: Linear Blend",
+ "Linear Blend (mplayer)",
"LinearBlend",
/*
"Blur: Temporal",
diff --git a/src/post/deinterlace/plugins/tomsmocomp/SearchLoop0A.inc b/src/post/deinterlace/plugins/tomsmocomp/SearchLoop0A.inc
new file mode 100644
index 000000000..b1d9aeca7
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/SearchLoop0A.inc
@@ -0,0 +1,15 @@
+// -*- c++ -*-
+
+// Searches just the center pixel, in both the old
+// and new fields, but takes averages. This is an even
+// pixel address. Any chroma match will be used. (YUY2)
+// We best like finding 0 motion so we will bias everything we found previously
+// up by a little, and adjust later
+
+#ifdef IS_SSE2
+ "paddusb "_ONES", %%xmm7\n\t" // bias toward no motion
+#else
+ "paddusb "_ONES", %%mm7\n\t" // bias toward no motion
+#endif
+
+ MERGE4PIXavg("(%%"XDI", %%"XCX")", "(%%"XSI", %%"XCX")") // center, in old and new
diff --git a/src/post/deinterlace/plugins/tomsmocomp/SearchLoopBottom.inc b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopBottom.inc
new file mode 100644
index 000000000..4f11db4af
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopBottom.inc
@@ -0,0 +1,116 @@
+// -*- c++ -*-
+
+#ifdef IS_SSE2
+//sse2 code deleted for now
+#else
+
+// Version for non-SSE2
+
+#ifdef SKIP_SEARCH
+ "movq %%mm6, %%mm0\n\t" // just use the results of our wierd bob
+#else
+
+
+ // JA 9/Dec/2002
+ // failed experiment
+ // but leave in placeholder for me to play about
+#ifdef DONT_USE_STRANGE_BOB
+ // Use the best weave if diffs less than 10 as that
+ // means the image is still or moving cleanly
+ // if there is motion we will clip which will catch anything
+ "psubusb "_FOURS", %%mm7\n\t" // sets bits to zero if weave diff < 4
+ "pxor %%mm0, %%mm0\n\t"
+ "pcmpeqb %%mm0, %%mm7\n\t" // all ff where weave better, else 00
+ "pcmpeqb %%mm7, %%mm0\n\t" // all ff where bob better, else 00
+ "pand %%mm6, %%mm0\n\t" // use bob for these pixel values
+ "pand %%mm5, %%mm7\n\t" // use weave for these
+ "por %%mm7, %%mm0\n\t" // combine both
+#else
+ // Use the better of bob or weave
+ // pminub mm4, TENS // the most we care about
+ V_PMINUB ("%%mm4", _TENS, "%%mm0") // the most we care about
+
+ "psubusb %%mm4, %%mm7\n\t" // foregive that much from weave est?
+ "psubusb "_FOURS", %%mm7\n\t" // bias it a bit toward weave
+ "pxor %%mm0, %%mm0\n\t"
+ "pcmpeqb %%mm0, %%mm7\n\t" // all ff where weave better, else 00
+ "pcmpeqb %%mm7, %%mm0\n\t" // all ff where bob better, else 00
+ "pand %%mm6, %%mm0\n\t" // use bob for these pixel values
+ "pand %%mm5, %%mm7\n\t" // use weave for these
+ "por %%mm7, %%mm0\n\t" // combine both
+#endif
+
+
+ // pminub mm0, Max_Vals // but clip to catch the stray error
+ V_PMINUB ("%%mm0", _Max_Vals, "%%mm1") // but clip to catch the stray error
+ // pmaxub mm0, Min_Vals
+ V_PMAXUB ("%%mm0", _Min_Vals)
+
+#endif
+
+
+ MOVX" "_pDest", %%"XAX"\n\t"
+
+#ifdef USE_VERTICAL_FILTER
+ "movq %%mm0, %%mm1\n\t"
+ // pavgb mm0, qword ptr["XBX"]
+ V_PAVGB ("%%mm0", "(%%"XBX")", "%%mm2", _ShiftMask)
+ // movntq qword ptr["XAX"+"XDX"], mm0
+ V_MOVNTQ ("(%"XAX", %%"XDX")", "%%mm0")
+ // pavgb mm1, qword ptr["XBX"+"XCX"]
+ V_PAVGB ("%%mm1", "(%%"XBX", %%"XCX")", "%%mm2", _ShiftMask)
+ "addq "_dst_pitchw", %%"XBX
+ // movntq qword ptr["XAX"+"XDX"], mm1
+ V_MOVNTQ ("(%%"XAX", %%"XDX")", "%%mm1")
+#else
+
+ // movntq qword ptr["XAX"+"XDX"], mm0
+ V_MOVNTQ ("(%%"XAX", %%"XDX")", "%%mm0")
+#endif
+
+ LEAX" 8(%%"XDX"), %%"XDX"\n\t" // bump offset pointer
+ CMPX" "_Last8", %%"XDX"\n\t" // done with line?
+ "jb 1b\n\t" // y
+#endif
+
+ MOVX" "_oldbx", %%"XBX"\n\t"
+
+ : /* no outputs */
+
+ : "m"(pBob),
+ "m"(src_pitch2),
+ "m"(ShiftMask),
+ "m"(pDest),
+ "m"(dst_pitchw),
+ "m"(Last8),
+ "m"(pSrc),
+ "m"(pSrcP),
+ "m"(pBobP),
+ "m"(DiffThres),
+ "m"(Min_Vals),
+ "m"(Max_Vals),
+ "m"(FOURS),
+ "m"(TENS),
+ "m"(ONES),
+ "m"(UVMask),
+ "m"(Max_Mov),
+ "m"(YMask),
+ "m"(oldbx)
+
+ : XAX, XCX, XDX, XSI, XDI,
+#ifdef ARCH_X86
+ "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
+#endif
+ "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
+ "memory", "cc"
+ );
+
+ // adjust for next line
+ pSrc += src_pitch2;
+ pSrcP += src_pitch2;
+ pDest += dst_pitch2;
+ pBob += src_pitch2;
+ pBobP += src_pitch2;
+ }
+
+ goto end;
diff --git a/src/post/deinterlace/plugins/tomsmocomp/SearchLoopEdgeA.inc b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopEdgeA.inc
new file mode 100644
index 000000000..6208fe8c2
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopEdgeA.inc
@@ -0,0 +1,11 @@
+// -*- c++ -*-
+
+// Searches 2 pixel to the left and right, in both the old
+// and new fields, but takes averages. These are even
+// pixel addresses. Chroma match will be used. (YUY2)
+ MERGE4PIXavg("-4(%%"XDI")", "4(%%"XSI", %%"XCX", 2)") // up left, down right
+ MERGE4PIXavg("4(%%"XDI")", "-4(%%"XSI", %%"XCX", 2)") // up right, down left
+ MERGE4PIXavg("-4(%%"XDI", %%"XCX")", "4(%%"XSI", %%"XCX")") // left, right
+ MERGE4PIXavg("4(%%"XDI", %%"XCX")", "-4(%%"XSI", %%"XCX")") // right, left
+ MERGE4PIXavg("-4(%%"XDI", %%"XCX", 2)", "4(%%"XSI")") // down left, up right
+ MERGE4PIXavg("4(%%"XDI", %%"XCX", 2)", "-4(%%"XSI")") // down right, up left
diff --git a/src/post/deinterlace/plugins/tomsmocomp/SearchLoopEdgeA8.inc b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopEdgeA8.inc
new file mode 100644
index 000000000..2841c3f6d
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopEdgeA8.inc
@@ -0,0 +1,12 @@
+// -*- c++ -*-
+
+// Searches 4 pixel to the left and right, in both the old
+// and new fields, but takes averages. These are even
+// pixel addresses. Chroma match will be used. (YUY2)
+ MERGE4PIXavg("-8(%%"XDI")", "8(%%"XSI", %%"XCX", 2)") // up left, down right
+ MERGE4PIXavg("8(%%"XDI")", "-8(%%"XSI", %%"XCX", 2)") // up right, down left
+ MERGE4PIXavg("-8(%%"XDI", %%"XCX")", "8(%%"XSI", %%"XCX")") // left, right
+ MERGE4PIXavg("8(%%"XDI", %%"XCX")", "-8(%%"XSI", %%"XCX")") // right, left
+ MERGE4PIXavg("-8(%%"XDI", %%"XCX", 2)", "8(%%"XSI")") // down left, up right
+ MERGE4PIXavg("8(%%"XDI", %%"XCX", 2)", "-8(%%"XSI")") // down right, up left
+
diff --git a/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA.inc b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA.inc
new file mode 100644
index 000000000..ab5375f48
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA.inc
@@ -0,0 +1,10 @@
+// -*- c++ -*-
+
+// Searches 1 pixel to the left and right, in both the old
+// and new fields, but takes averages. These are odd
+// pixel addresses. Any chroma match will not be used. (YUY2)
+ MERGE4PIXavg("-2(%%"XDI")", "2(%%"XSI", %%"XCX", 2)") // up left, down right
+ MERGE4PIXavg("2(%%"XDI")", "-2(%%"XSI", %%"XCX", 2)") // up right, down left
+ MERGE4PIXavg("-2(%%"XDI", %%"XCX", 2)", "2(%%"XSI")") // down left, up right
+ MERGE4PIXavg("2(%%"XDI", %%"XCX", 2)", "-2(%%"XSI")") // down right, up left
+#include "SearchLoopOddA2.inc"
diff --git a/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA2.inc b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA2.inc
new file mode 100644
index 000000000..fd3f6fb0b
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA2.inc
@@ -0,0 +1,5 @@
+// Searches 1 pixel to the left and right, in both the old
+// and new fields, but takes averages. These are odd
+// pixel addresses. Any chroma match will not be used. (YUY2)
+ MERGE4PIXavg("-2(%%"XDI", %%"XCX")", "2(%%"XSI", %%"XCX")") // left, right
+ MERGE4PIXavg("2(%%"XDI", %%"XCX")", "-2(%%"XSI", %%"XCX")") // right, left
diff --git a/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA6.inc b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA6.inc
new file mode 100644
index 000000000..cbae014eb
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA6.inc
@@ -0,0 +1,11 @@
+// -*- c++ -*-
+
+// Searches 3 pixels to the left and right, in both the old
+// and new fields, but takes averages. These are odd
+// pixel addresses. Any chroma match will not be used. (YUY2)
+ MERGE4PIXavg("-6(%%"XDI")", "6(%%"XSI", %%"XCX", 2)") // up left, down right
+ MERGE4PIXavg("6(%%"XDI")", "-6(%%"XSI", %%"XCX", 2)") // up right, down left
+ MERGE4PIXavg("-6(%%"XDI", %%"XCX")", "6(%%"XSI", %%"XCX")") // left, right
+ MERGE4PIXavg("6(%%"XDI", %%"XCX")", "-6(%%"XSI", %%"XCX")") // right, left
+ MERGE4PIXavg("-6(%%"XDI", %%"XCX", 2)", "6(%%"XSI")") // down left, up right
+ MERGE4PIXavg("6(%%"XDI", %%"XCX", 2)", "-6(%%"XSI")") // down right, up left
diff --git a/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddAH.inc b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddAH.inc
new file mode 100644
index 000000000..e59e3c7e8
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddAH.inc
@@ -0,0 +1,10 @@
+// Searches 1 pixel to the left and right, in both the old
+// and new fields, but takes v-half pel averages. These are odd
+// pixel addresses. Any chroma match will not be used. (YUY2)
+ __asm
+ {
+ MERGE4PIXavgH("XDI"-2, "XDI"+"XCX"-2, "XSI"+"XCX"+2, "XSI"+2*"XCX"+2) // up left, down right
+ MERGE4PIXavgH("XDI"+2, "XDI"+"XCX"+2, "XSI"+"XCX"-2, "XSI"+2*"XCX"-2) // up right, down left
+ MERGE4PIXavgH("XDI"+2*"XCX"-2, "XDI"+"XCX"-2, "XSI"+"XCX"+2, "XSI"+2) // down left, up right
+ MERGE4PIXavgH("XDI"+2*"XCX"+2, "XDI"+"XCX"+2, "XSI"+"XCX"-2, "XSI"-2) // down right, up left
+ }
diff --git a/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddAH2.inc b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddAH2.inc
new file mode 100644
index 000000000..cd7d812a1
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddAH2.inc
@@ -0,0 +1,5 @@
+// Searches 1 pixel to the left and right, in both the old
+// and new fields, but takes vertical averages. These are odd
+// pixel addresses. Any chroma match will not be used. (YUY2)
+ MERGE4PIXavgH("-2(%%"XDI", %%"XCX")", "(%%"XDI", %%"XCX")", "(%%"XSI", %%"XCX")", "2(%%"XSI", %%"XCX")") // left, right
+ MERGE4PIXavgH("2(%%"XDI", %%"XCX")", "(%%"XDI", %%"XCX")", "(%%"XSI", %%"XCX")", "-2(%%"XSI", %%"XCX")") // right, left
diff --git a/src/post/deinterlace/plugins/tomsmocomp/SearchLoopTop.inc b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopTop.inc
new file mode 100644
index 000000000..17a3616ee
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopTop.inc
@@ -0,0 +1,190 @@
+// -*- c++ -*-
+
+unsigned char* pDest;
+const unsigned char* pSrcP;
+const unsigned char* pSrc;
+const unsigned char* pBob;
+const unsigned char* pBobP;
+
+int64_t Max_Mov = 0x0404040404040404ull;
+int64_t DiffThres = 0x0f0f0f0f0f0f0f0full;
+int64_t YMask = 0x00ff00ff00ff00ffull; // keeps only luma
+int64_t UVMask = 0xff00ff00ff00ff00ull; // keeps only chroma
+int64_t TENS = 0x0a0a0a0a0a0a0a0aull;
+int64_t FOURS = 0x0404040404040404ull;
+int64_t ONES = 0x0101010101010101ull;
+int64_t Min_Vals = 0x0000000000000000ull;
+int64_t Max_Vals = 0x0000000000000000ull;
+int64_t ShiftMask = 0xfefffefffefffeffull;
+
+// long is int32 on ARCH_368, int64 on ARCH_AMD64. Declaring it this way
+// saves a lot of xor's to delete 64bit garbage.
+
+#if defined(DBL_RESIZE) || defined(USE_FOR_DSCALER)
+long src_pitch2 = src_pitch; // even & odd lines are not longerleaved in DScaler
+#else
+long src_pitch2 = 2 * src_pitch; // even & odd lines are longerleaved in Avisynth
+#endif
+
+long dst_pitch2 = 2 * dst_pitch;
+long y;
+
+#ifdef IS_SSE2
+long Last8 = (rowsize-16); // ofs to last 16 bytes in row for SSE2
+#else
+long Last8 = (rowsize-8); // ofs to last 8 bytes in row
+#endif
+
+long dst_pitchw = dst_pitch; // local stor so asm can ref
+ pSrc = pWeaveSrc; // polongs 1 weave line above
+ pSrcP = pWeaveSrcP; // "
+
+#ifdef DBL_RESIZE
+
+#ifdef USE_VERTICAL_FILTER
+ pDest = pWeaveDest + dst_pitch2;
+#else
+ pDest = pWeaveDest + 3*dst_pitch;
+#endif
+
+#else
+
+#ifdef USE_VERTICAL_FILTER
+ pDest = pWeaveDest + dst_pitch;
+#else
+ pDest = pWeaveDest + dst_pitch2;
+#endif
+
+#endif
+
+ if (TopFirst)
+ {
+ pBob = pCopySrc + src_pitch2; // remember one weave line just copied previously
+ pBobP = pCopySrcP + src_pitch2;
+ }
+ else
+ {
+ pBob = pCopySrc;
+ pBobP = pCopySrcP;
+ }
+
+#ifndef _pBob
+#define _pBob "%0"
+#define _src_pitch2 "%1"
+#define _ShiftMask "%2"
+#define _pDest "%3"
+#define _dst_pitchw "%4"
+#define _Last8 "%5"
+#define _pSrc "%6"
+#define _pSrcP "%7"
+#define _pBobP "%8"
+#define _DiffThres "%9"
+#define _Min_Vals "%10"
+#define _Max_Vals "%11"
+#define _FOURS "%12"
+#define _TENS "%13"
+#define _ONES "%14"
+#define _UVMask "%15"
+#define _Max_Mov "%16"
+#define _YMask "%17"
+#define _oldbx "%18"
+#endif
+
+ for (y=1; y < FldHeight-1; y++)
+ {
+ // pretend it's indented -->>
+ __asm__ __volatile__
+ (
+ // Loop general reg usage
+ //
+ // XAX - pBobP, then pDest
+ // XBX - pBob
+ // XCX - src_pitch2
+ // XDX - current offset
+ // XDI - prev weave pixels, 1 line up
+ // XSI - next weave pixels, 1 line up
+
+ // Save "XBX" (-fPIC)
+ MOVX" %%"XBX", "_oldbx"\n\t"
+
+#ifdef IS_SSE2
+
+ // sse2 code deleted for now
+
+#else
+ // simple bob first 8 bytes
+ MOVX" "_pBob", %%"XBX"\n\t"
+ MOVX" "_src_pitch2", %%"XCX"\n\t"
+
+#ifdef USE_VERTICAL_FILTER
+ "movq (%%"XBX"), %%mm0\n\t"
+ "movq (%%"XBX", %%"XCX"), %%mm1\n\t" //, qword ptr["XBX"+"XCX"]
+ "movq %%mm0, %%mm2\n\t"
+ V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // halfway between
+ V_PAVGB ("%%mm0", "%%mm2", "%%mm3", _ShiftMask) // 1/4 way
+ V_PAVGB ("%%mm1", "%%mm2", "%%mm3", _ShiftMask) // 3/4 way
+ MOVX" "_pDest", %%"XDI"\n\t"
+ MOVX" "_dst_pitchw", %%"XAX"\n\t"
+ V_MOVNTQ ("(%%"XDI")", "%%mm0")
+ V_MOVNTQ ("(%%"XDI", %%"XAX")", "%%mm1") // qword ptr["XDI"+"XAX"], mm1
+
+ // simple bob last 8 bytes
+ MOVX" "_Last8", %%"XDX"\n\t"
+ LEAX" (%%"XBX", %%"XDX"), %%"XSI"\n\t" // ["XBX"+"XDX"]
+ "movq (%%"XSI"), %%mm0\n\t"
+ "movq (%%"XSI", %%"XCX"), %%mm1\n\t" // qword ptr["XSI"+"XCX"]
+ "movq %%mm0, %%mm2\n\t"
+ V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // halfway between
+ V_PAVGB ("%%mm0", "%%mm2", "%%mm3", _ShiftMask) // 1/4 way
+ V_PAVGB ("%%mm1", "%%mm2", "%%mm3", _ShiftMask) // 3/4 way
+ ADDX" %%"XDX", %%"XDI"\n\t" // last 8 bytes of dest
+ V_MOVNTQ ("%%"XDI"", "%%mm0")
+ V_MOVNTQ ("(%%"XDI", %%"XAX")", "%%mm1") // qword ptr["XDI"+"XAX"], mm1)
+
+#else
+ "movq (%%"XBX"), %%mm0\n\t"
+ // pavgb mm0, qword ptr["XBX"+"XCX"]
+ V_PAVGB ("%%mm0", "(%%"XBX", %%"XCX")", "%%mm2", _ShiftMask) // qword ptr["XBX"+"XCX"], mm2, ShiftMask)
+ MOVX" "_pDest", %%"XDI"\n\t"
+ V_MOVNTQ ("(%%"XDI")", "%%mm0")
+
+ // simple bob last 8 bytes
+ MOVX" "_Last8", %%"XDX"\n\t"
+ LEAX" (%%"XBX", %%"XDX"), %%"XSI"\n\t" //"XSI", ["XBX"+"XDX"]
+ "movq (%%"XSI"), %%mm0\n\t"
+ // pavgb mm0, qword ptr["XSI"+"XCX"]
+ V_PAVGB ("%%mm0", "(%%"XSI", %%"XCX")", "%%mm2", _ShiftMask) // qword ptr["XSI"+"XCX"], mm2, ShiftMask)
+ V_MOVNTQ ("(%%"XDI", %%"XDX")", "%%mm0") // qword ptr["XDI"+"XDX"], mm0)
+#endif
+ // now loop and get the middle qwords
+ MOVX" "_pSrc", %%"XSI"\n\t"
+ MOVX" "_pSrcP", %%"XDI"\n\t"
+ MOVX" $8, %%"XDX"\n\t" // curr offset longo all lines
+
+ "1:\n\t"
+ MOVX" "_pBobP", %%"XAX"\n\t"
+ ADDX" $8, %%"XDI"\n\t"
+ ADDX" $8, %%"XSI"\n\t"
+ ADDX" $8, %%"XBX"\n\t"
+ ADDX" %%"XDX", %%"XAX"\n\t"
+
+#ifdef USE_STRANGE_BOB
+#include "StrangeBob.inc"
+#else
+#include "WierdBob.inc"
+#endif
+
+ // For non-SSE2:
+ // through out most of the rest of this loop we will malongain
+ // mm4 our min bob value
+ // mm5 best weave pixels so far
+ // mm6 our max Bob value
+ // mm7 best weighted pixel ratings so far
+
+ // We will keep a slight bias to using the weave pixels
+ // from the current location, by rating them by the min distance
+ // from the Bob value instead of the avg distance from that value.
+ // our best and only rating so far
+ "pcmpeqb %%mm7, %%mm7\n\t" // ffff, say we didn't find anything good yet
+
+#endif
diff --git a/src/post/deinterlace/plugins/tomsmocomp/SearchLoopVA.inc b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopVA.inc
new file mode 100644
index 000000000..3e3d19b5c
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopVA.inc
@@ -0,0 +1,6 @@
+// -*- c++ -*-
+
+// Searches the center vertical line above center and below, in both the old
+// and new fields, but takes averages. These are even pixel addresses.
+ MERGE4PIXavg("(%%"XDI", %%"XCX", 2)", "(%%"XSI")") // down, up
+ MERGE4PIXavg("(%%"XDI")", "(%%"XSI", %%"XCX", 2)") // up, down
diff --git a/src/post/deinterlace/plugins/tomsmocomp/SearchLoopVAH.inc b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopVAH.inc
new file mode 100644
index 000000000..33155bc1d
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/SearchLoopVAH.inc
@@ -0,0 +1,6 @@
+// -*- c++ -*-
+
+// Searches the center vertical line above center and below, in both the old
+// and new fields, but takes averages. These are even pixel addresses.
+ MERGE4PIXavgH("(%%"XDI", %%"XCX", 2)", "(%%"XDI", %%"XCX")", "(%%"XSI", %%"XCX")", "(%%"XSI")") // down, up
+ MERGE4PIXavgH("(%%"XDI")", "(%%"XDI", %%"XCX")", "(%%"XSI", %%"XCX")", "(%%"XSI", %%"XCX", 2)") // up, down
diff --git a/src/post/deinterlace/plugins/tomsmocomp/StrangeBob.inc b/src/post/deinterlace/plugins/tomsmocomp/StrangeBob.inc
new file mode 100644
index 000000000..c1d2b5b71
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/StrangeBob.inc
@@ -0,0 +1,322 @@
+// -*- c++ -*-
+
+ // First, get and save our possible Bob values
+ // Assume our pixels are layed out as follows with x the calc'd bob value
+ // and the other pixels are from the current field
+ //
+ // j a b c k current field
+ // x calculated line
+ // m d e f n current field
+ //
+ // we calc the bob value luma value as:
+ // if |j - n| < Thres && |a - m| > Thres
+ // avg(j,n)
+ // end if
+ // if |k - m| < Thres && |c - n| > Thres
+ // avg(k,m)
+ // end if
+ // if |c - d| < Thres && |b - f| > Thres
+ // avg(c,d)
+ // end if
+ // if |a - f| < Thres && |b - d| > Thres
+ // avg(a,f)
+ // end if
+ // if |b - e| < Thres
+ // avg(b,e)
+ // end if
+ // pickup any thing not yet set with avg(b,e)
+
+ // j, n
+ "pxor %%mm5, %%mm5\n\t"
+ "pxor %%mm6, %%mm6\n\t"
+ "pxor %%mm7, %%mm7\n\t"
+
+ "movq -2(%%"XBX"), %%mm0\n\t" // value a from top left
+ "movq -4(%%"XBX", %%"XCX"), %%mm1\n\t" // value m from bottom right
+
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm3\n\t"
+ "psubusb %%mm0, %%mm1\n\t"
+ "por %%mm1, %%mm3\n\t" // abs(a,m)
+
+ "psubusb "_DiffThres", %%mm3\n\t" // nonzero where abs(a,m) > Thres else 0
+ "pxor %%mm4, %%mm4\n\t"
+ "pcmpeqb %%mm4, %%mm3\n\t" // now ff where abs(a,m) < Thres, else 00
+ "pcmpeqb %%mm3, %%mm4\n\t" // here ff where abs(a,m) > Thres, else 00
+
+
+ "movq -4(%%"XBX"), %%mm0\n\t" // value j
+ "movq 4(%%"XBX", %%"XCX"), %%mm1\n\t" // value n
+ "movq %%mm0, %%mm2\n\t"
+ "pavgb %%mm1, %%mm2\n\t" // avg(j,n)
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm0\n\t"
+ "psubusb %%mm3, %%mm1\n\t"
+ "por %%mm1, %%mm0\n\t" // abs(j,n)
+
+ "movq %%mm0, %%mm1\n\t"
+ "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(j,n) > Thres else 0
+ "pxor %%mm3, %%mm3\n\t"
+ "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(j,n) < Thres, else 00
+
+ "pand %%mm4, %%mm1\n\t"
+
+ "pand %%mm1, %%mm2\n\t"
+ "pand %%mm1, %%mm0\n\t"
+
+ "movq %%mm1, %%mm3\n\t"
+ "pxor %%mm5, %%mm3\n\t"
+ "pand %%mm3, %%mm6\n\t"
+ "pand %%mm3, %%mm7\n\t"
+ "pand %%mm3, %%mm5\n\t"
+
+ "por %%mm1, %%mm5\n\t"
+ "por %%mm2, %%mm6\n\t"
+ "por %%mm0, %%mm7\n\t"
+
+ // k & m
+ "movq 2(%%"XBX"), %%mm0\n\t" // value c from top left
+ "movq 4(%%"XBX", %%"XCX"), %%mm1\n\t" // value n from bottom right
+
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm3\n\t"
+ "psubusb %%mm0, %%mm1\n\t"
+ "por %%mm1, %%mm3\n\t" // abs(c,n)
+
+ "psubusb "_DiffThres", %%mm3\n\t" // nonzero where abs(c,n) > Thres else 0
+ "pxor %%mm4, %%mm4\n\t"
+ "pcmpeqb %%mm4, %%mm3\n\t" // now ff where abs(c,n) < Thres, else 00
+ "pcmpeqb %%mm3, %%mm4\n\t" // here ff where abs(c,n) > Thres, else 00
+
+
+ "movq 4(%%"XBX"), %%mm0\n\t" // value k
+ "movq -4(%%"XBX", %%"XCX"), %%mm1\n\t" // value m
+ "movq %%mm0, %%mm2\n\t"
+ V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(k,m)
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm0\n\t"
+ "psubusb %%mm3, %%mm1\n\t"
+ "por %%mm1, %%mm0\n\t" // abs(k,m)
+
+ "movq %%mm0, %%mm1\n\t"
+ "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(k,m) > Thres else 0
+ "pxor %%mm3, %%mm3\n\t"
+ "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(k,m) < Thres, else 00
+
+ "pand %%mm4, %%mm1\n\t"
+
+ "pand %%mm1, %%mm2\n\t"
+ "pand %%mm1, %%mm0\n\t"
+
+ "movq %%mm1, %%mm3\n\t"
+ "pxor %%mm5, %%mm3\n\t"
+ "pand %%mm3, %%mm6\n\t"
+ "pand %%mm3, %%mm7\n\t"
+ "pand %%mm3, %%mm5\n\t"
+
+ "por %%mm1, %%mm5\n\t"
+ "por %%mm2, %%mm6\n\t"
+ "por %%mm0, %%mm7\n\t"
+
+
+ // c & d
+ "movq (%%"XBX"), %%mm0\n\t" // value b from top left
+ "movq 2(%%"XBX", %%"XCX"), %%mm1\n\t" // value f from bottom right
+
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm3\n\t"
+ "psubusb %%mm0, %%mm1\n\t"
+ "por %%mm1, %%mm3\n\t" // abs(b,f)
+
+ "psubusb "_DiffThres", %%mm3\n\t" // nonzero where abs(b,f) > Thres else 0
+ "pxor %%mm4, %%mm4\n\t"
+ "pcmpeqb %%mm4, %%mm3\n\t" // now ff where abs(b,f) < Thres, else 00
+ "pcmpeqb %%mm3, %%mm4\n\t" // here ff where abs(b,f) > Thres, else 00
+
+ "movq 2(%%"XBX"), %%mm0\n\t" // value c
+ "movq -2(%%"XBX", %%"XCX"), %%mm1\n\t" // value d
+ "movq %%mm0, %%mm2\n\t"
+ V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(c,d)
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm0\n\t"
+ "psubusb %%mm3, %%mm1\n\t"
+ "por %%mm1, %%mm0\n\t" // abs(c,d)
+
+ "movq %%mm0, %%mm1\n\t"
+ "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(c,d) > Thres else 0
+ "pxor %%mm3, %%mm3\n\t"
+ "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(c,d) < Thres, else 00
+
+ "pand %%mm4, %%mm1\n\t"
+
+ "pand %%mm1, %%mm2\n\t"
+ "pand %%mm1, %%mm0\n\t"
+
+ "movq %%mm1, %%mm3\n\t"
+ "pxor %%mm5, %%mm3\n\t"
+ "pand %%mm3, %%mm6\n\t"
+ "pand %%mm3, %%mm7\n\t"
+ "pand %%mm3, %%mm5\n\t"
+
+ "por %%mm1, %%mm5\n\t"
+ "por %%mm2, %%mm6\n\t"
+ "por %%mm0, %%mm7\n\t"
+
+ // a & f
+ "movq (%%"XBX"), %%mm0\n\t" // value b from top left
+ "movq -2(%%"XBX", %%"XCX"), %%mm1\n\t" // value d from bottom right
+
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm3\n\t"
+ "psubusb %%mm0, %%mm1\n\t"
+ "por %%mm1, %%mm3\n\t" // abs(b,d)
+
+ "psubusb "_DiffThres", %%mm3\n\t" // nonzero where abs(b,d) > Thres else 0
+ "pxor %%mm4, %%mm4\n\t"
+ "pcmpeqb %%mm4, %%mm3\n\t" // now ff where abs(b,d) < Thres, else 00
+ "pcmpeqb %%mm3, %%mm4\n\t" // here ff where abs(b,d) > Thres, else 00
+
+ "movq -2(%%"XBX"), %%mm0\n\t" // value a
+ "movq 2(%%"XBX", %%"XCX"), %%mm1\n\t" // value f
+ "movq %%mm0, %%mm2\n\t"
+ V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(a,f)
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm0\n\t"
+ "psubusb %%mm3, %%mm1\n\t"
+ "por %%mm1, %%mm0\n\t" // abs(a,f)
+
+ "movq %%mm0, %%mm1\n\t"
+ "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(a,f) > Thres else 0
+ "pxor %%mm3, %%mm3\n\t"
+ "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(a,f) < Thres, else 00
+
+ "pand %%mm4, %%mm1\n\t"
+
+ "pand %%mm1, %%mm2\n\t"
+ "pand %%mm1, %%mm0\n\t"
+
+ "movq %%mm1, %%mm3\n\t"
+ "pxor %%mm5, %%mm3\n\t"
+ "pand %%mm3, %%mm6\n\t"
+ "pand %%mm3, %%mm7\n\t"
+ "pand %%mm3, %%mm5\n\t"
+
+ "por %%mm1, %%mm5\n\t"
+ "por %%mm2, %%mm6\n\t"
+ "por %%mm0, %%mm7\n\t"
+
+ "pand "_YMask", %%mm5\n\t" // mask out chroma from here
+ "pand "_YMask", %%mm6\n\t" // mask out chroma from here
+ "pand "_YMask", %%mm7\n\t" // mask out chroma from here
+
+ // b,e
+ "movq (%%"XBX"), %%mm0\n\t" // value b from top
+ "movq (%%"XBX", %%"XCX"), %%mm1\n\t" // value e from bottom
+ "movq %%mm0, %%mm2\n\t"
+ V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(b,e)
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm0\n\t"
+ "psubusb %%mm3, %%mm1\n\t"
+ "por %%mm1, %%mm0\n\t" // abs(b,e)
+
+ "movq %%mm0, %%mm1\n\t"
+ "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(b,e) > Thres else 0
+ "pxor %%mm3, %%mm3\n\t"
+ "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(b,e) < Thres, else 00
+
+ "pand %%mm1, %%mm2\n\t"
+ "pand %%mm1, %%mm0\n\t"
+
+ "movq %%mm1, %%mm3\n\t"
+ "pxor %%mm5, %%mm3\n\t"
+ "pand %%mm3, %%mm6\n\t"
+ "pand %%mm3, %%mm7\n\t"
+ "pand %%mm3, %%mm5\n\t"
+
+ "por %%mm1, %%mm5\n\t"
+ "por %%mm2, %%mm6\n\t"
+ "por %%mm0, %%mm7\n\t"
+
+ // bob in any leftovers
+ "movq (%%"XBX"), %%mm0\n\t" // value b from top
+ "movq (%%"XBX", %%"XCX"), %%mm1\n\t" // value e from bottom
+
+
+// We will also calc here the max/min values to later limit comb
+// so the max excursion will not exceed the Max_Comb constant
+
+#ifdef SKIP_SEARCH
+ "movq %%mm0, %%mm2\n\t"
+// pminub %%mm2, %%mm1
+ V_PMINUB ("%%mm2", "%%mm1", "%%mm4")
+
+// pmaxub %%mm6, %%mm2 // clip our current results so far to be above this
+ V_PMAXUB ("%%mm6", "%%mm2")
+ "movq %%mm0, %%mm2\n\t"
+ V_PMAXUB ("%%mm2", "%%mm1")
+// pminub %%mm6, %%mm2 // clip our current results so far to be below this
+ V_PMINUB ("%%mm6", "%%mm2", "%%mm4")
+
+#else
+ "movq %%mm0, %%mm2\n\t"
+ "movq (%%"XAX"), %%mm4\n\t"
+ "psubusb %%mm4, %%mm2\n\t"
+ "psubusb %%mm0, %%mm4\n\t"
+ "por %%mm2, %%mm4\n\t" // abs diff
+
+ "movq %%mm1, %%mm2\n\t"
+ "movq (%%"XAX", %%"XCX"), %%mm3\n\t"
+ "psubusb %%mm3, %%mm2\n\t"
+ "psubusb %%mm1, %%mm3\n\t"
+ "por %%mm2, %%mm3\n\t" // abs diff
+// pmaxub %%mm3, %%mm4 // top or bottom pixel moved most
+ V_PMAXUB ("%%mm3", "%%mm4") // top or bottom pixel moved most
+ "psubusb "_DiffThres", %%mm3\n\t" // moved more than allowed? or goes to 0?
+ "pxor %%mm4, %%mm4\n\t"
+ "pcmpeqb %%mm4, %%mm3\n\t" // now ff where low motion, else high motion
+
+ "movq %%mm0, %%mm2\n\t"
+// pminub %%mm2, %%mm1
+ V_PMINUB ("%%mm2", "%%mm1", "%%mm4")
+
+// pmaxub %%mm6, %%mm2 // clip our current results so far to be above this
+ V_PMAXUB ("%%mm6", "%%mm2")
+
+ "psubusb %%mm3, %%mm2\n\t" // maybe decrease it to 0000.. if no surround motion
+ "movq %%mm2, "_Min_Vals"\n\t"
+
+ "movq %%mm0, %%mm2\n\t"
+ V_PMAXUB ("%%mm2", "%%mm1")
+// pminub %%mm6, %%mm2 // clip our current results so far to be below this
+ V_PMINUB ("%%mm6", "%%mm2", "%%mm4")
+ "paddusb %%mm3, %%mm2\n\t" // maybe increase it to ffffff if no surround motion
+ "movq %%mm2, "_Max_Vals"\n\t"
+#endif
+
+ "movq %%mm0, %%mm2\n\t"
+// pavgb %%mm2, %%mm1 // avg(b,e)
+ V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(b,e)
+
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm3\n\t"
+ "psubusb %%mm0, %%mm1\n\t"
+ "por %%mm1, %%mm3\n\t" // abs(b,e)
+ "movq %%mm3, %%mm1\n\t" // keep copy of diffs
+
+ "pxor %%mm4, %%mm4\n\t"
+ "psubusb %%mm7, %%mm3\n\t" // nonzero where new weights bigger, else 0
+ "pcmpeqb %%mm4, %%mm3\n\t" // now ff where new better, else 00
+ "pcmpeqb %%mm0, %%mm0\n\t"
+ "pandn %%mm0, %%mm5\n\t"
+ "por %%mm5, %%mm3\n\t"
+ "pcmpeqb %%mm3, %%mm4\n\t" // here ff where old better, else 00
+
+ "pand %%mm3, %%mm1\n\t"
+ "pand %%mm3, %%mm2\n\t"
+
+ "pand %%mm4, %%mm6\n\t"
+ "pand %%mm4, %%mm7\n\t"
+
+ "por %%mm2, %%mm6\n\t" // our x2 value
+ "por %%mm1, %%mm7\n\t" // our x2 diffs
+ "movq %%mm7, %%mm4\n\t" // save as bob uncertainty indicator
diff --git a/src/post/deinterlace/plugins/tomsmocomp/TomsMoCompAll.inc b/src/post/deinterlace/plugins/tomsmocomp/TomsMoCompAll.inc
new file mode 100644
index 000000000..4a223138b
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/TomsMoCompAll.inc
@@ -0,0 +1,245 @@
+// -*- c++ -*-
+/////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2002 Tom Barry All rights reserved.
+/////////////////////////////////////////////////////////////////////////////
+//
+// This file is subject to the terms of the GNU General Public License as
+// published by the Free Software Foundation. A copy of this license is
+// included with this software distribution in the file COPYING. If you
+// do not have a copy, you may obtain a copy by writing to the Free
+// Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// This software 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
+//
+// Also, this program is "Philanthropy-Ware". That is, if you like it and
+// feel the need to reward or inspire the author then please feel free (but
+// not obligated) to consider joining or donating to the Electronic Frontier
+// Foundation. This will help keep cyber space free of barbed wire and bullsh*t.
+// See www.eff.org for details
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef TopFirst
+#define TopFirst IsOdd
+#endif
+
+#ifdef SEFUNC
+#undef SEFUNC
+#endif
+
+#if defined(IS_SSE)
+#define SEFUNC(x) Search_Effort_SSE_##x
+#elif defined(IS_3DNOW)
+#define SEFUNC(x) Search_Effort_3DNOW_##x
+#else
+#define SEFUNC(x) Search_Effort_MMX_##x
+#endif
+
+static void FUNCT_NAME(uint8_t *output, int outstride,
+ deinterlace_frame_data_t *data,
+ int bottom_field, int second_field, int width, int height )
+{
+ int IsOdd;
+ const unsigned char* pWeaveSrc;
+ const unsigned char* pWeaveSrcP;
+ unsigned char* pWeaveDest;
+ const unsigned char* pCopySrc;
+ const unsigned char* pCopySrcP;
+ unsigned char* pCopyDest;
+ int src_pitch;
+ int dst_pitch;
+ int rowsize;
+ int FldHeight;
+ int stride = (width*2);
+ long oldbx;
+
+
+ src_pitch = stride*2;
+ dst_pitch = outstride;
+ rowsize = stride;
+ FldHeight = height / 2;
+
+ if( second_field ) {
+ pWeaveSrc = data->f0;
+ pCopySrc = data->f0;
+ pWeaveSrcP = data->f1;
+ pCopySrcP = data->f1;
+ } else {
+ pWeaveSrc = data->f0;
+ pCopySrc = data->f1;
+ pWeaveSrcP = data->f1;
+ pCopySrcP = data->f2;
+ }
+
+ if( bottom_field ) {
+ pWeaveSrc += stride;
+ pCopySrc += 0;
+ pWeaveSrcP += stride;
+ pCopySrcP += 0;
+ } else {
+ pWeaveSrc += 0;
+ pCopySrc += stride;
+ pWeaveSrcP += 0;
+ pCopySrcP += stride;
+ }
+
+ IsOdd = bottom_field;
+
+#ifdef IS_SSE2
+// SSE2 support temporarily deleted
+
+#endif
+
+ if(IsOdd) {
+ // if we have an odd field we copy an even field and weave an odd field
+ pCopyDest = output;
+ pWeaveDest = output + dst_pitch;
+ } else {
+ // if we have an ever field we copy an odd field and weave an even field
+ pCopyDest = output + dst_pitch;
+ pWeaveDest = output;
+ }
+ // copy 1st and last weave lines
+ Fieldcopy(pWeaveDest, pCopySrc, rowsize,
+ 1, dst_pitch*2, src_pitch);
+ Fieldcopy(pWeaveDest+(FldHeight-1)*dst_pitch*2,
+ pCopySrc+(FldHeight-1)*src_pitch, rowsize,
+ 1, dst_pitch*2, src_pitch);
+
+#ifdef USE_VERTICAL_FILTER
+// Vertical Filter currently not implemented for DScaler !!
+ // copy 1st and last lines the copy field
+ Fieldcopy(pCopyDest, pCopySrc, rowsize,
+ 1, dst_pitch*2, src_pitch);
+ Fieldcopy(pCopyDest+(FldHeight-1)*dst_pitch*2,
+ pCopySrc+(FldHeight-1)*src_pitch, rowsize,
+ 1, dst_pitch*2, src_pitch);
+#else
+
+ // copy all of the copy field
+ Fieldcopy(pCopyDest, pCopySrc, rowsize,
+ FldHeight, dst_pitch*2, src_pitch);
+#endif
+ // then go fill in the hard part, being variously lazy depending upon
+ // SearchEffort
+
+ if(UseStrangeBob == 0) {
+ if (SearchEffort == 0)
+ {
+ goto SEFUNC(0);
+ }
+ else if (SearchEffort <= 1)
+ {
+ goto SEFUNC(1);
+ }
+ /* else if (SearchEffort <= 2)
+ {
+ goto SEFUNC(2);
+ }
+ */
+ else if (SearchEffort <= 3)
+ {
+ goto SEFUNC(3);
+ }
+ else if (SearchEffort <= 5)
+ {
+ goto SEFUNC(5);
+ }
+ else if (SearchEffort <= 9)
+ {
+ goto SEFUNC(9);
+ }
+ else if (SearchEffort <= 11)
+ {
+ goto SEFUNC(11);
+ }
+ else if (SearchEffort <= 13)
+ {
+ goto SEFUNC(13);
+ }
+ else if (SearchEffort <= 15)
+ {
+ goto SEFUNC(15);
+ }
+ else if (SearchEffort <= 19)
+ {
+ goto SEFUNC(19);
+ }
+ else if (SearchEffort <= 21)
+ {
+ goto SEFUNC(21);
+ }
+ else
+ {
+ goto SEFUNC(Max);
+ }
+ }
+ else
+ {
+ if (SearchEffort == 0)
+ {
+ goto SEFUNC(0_SB);
+ }
+ else if (SearchEffort <= 1)
+ {
+ goto SEFUNC(1_SB);
+ }
+ /* else if (SearchEffort <= 2)
+ {
+ goto SEFUNC(2_SB);
+ }
+ */
+ else if (SearchEffort <= 3)
+ {
+ goto SEFUNC(3_SB);
+ }
+ else if (SearchEffort <= 5)
+ {
+ goto SEFUNC(5_SB);
+ }
+ else if (SearchEffort <= 9)
+ {
+ goto SEFUNC(9_SB);
+ }
+ else if (SearchEffort <= 11)
+ {
+ goto SEFUNC(11_SB);
+ }
+ else if (SearchEffort <= 13)
+ {
+ goto SEFUNC(13_SB);
+ }
+ else if (SearchEffort <= 15)
+ {
+ goto SEFUNC(15_SB);
+ }
+ else if (SearchEffort <= 19)
+ {
+ goto SEFUNC(19_SB);
+ }
+ else if (SearchEffort <= 21)
+ {
+ goto SEFUNC(21_SB);
+ }
+ else
+ {
+ goto SEFUNC(Max_SB);
+ }
+ }
+
+end:
+#ifdef ARCH_X86
+ __asm__ __volatile__("emms");
+#endif
+ return;
+
+#include "TomsMoCompAll2.inc"
+
+#define USE_STRANGE_BOB
+
+#include "TomsMoCompAll2.inc"
+
+#undef USE_STRANGE_BOB
+}
diff --git a/src/post/deinterlace/plugins/tomsmocomp/TomsMoCompAll2.inc b/src/post/deinterlace/plugins/tomsmocomp/TomsMoCompAll2.inc
new file mode 100644
index 000000000..e9e5a081b
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/TomsMoCompAll2.inc
@@ -0,0 +1,173 @@
+// -*- c++ -*-
+
+#ifdef SEARCH_EFFORT_FUNC
+#undef SEARCH_EFFORT_FUNC
+#endif
+
+#ifdef USE_STRANGE_BOB
+#define SEARCH_EFFORT_FUNC(n) SEFUNC(n##_SB):
+#else
+#define SEARCH_EFFORT_FUNC(n) SEFUNC(n):
+#endif
+
+SEARCH_EFFORT_FUNC(0) // we don't try at all ;-)
+{
+ //see Search_Effort_Max() for comments
+#define SKIP_SEARCH
+#include "SearchLoopTop.inc"
+#include "SearchLoopBottom.inc"
+#undef SKIP_SEARCH
+}
+
+SEARCH_EFFORT_FUNC(1)
+{
+ //see Search_Effort_Max() for comments
+#include "SearchLoopTop.inc"
+ RESET_CHROMA // pretend chroma diffs was 255 each
+#include "SearchLoop0A.inc"
+#include "SearchLoopBottom.inc"
+}
+
+SEARCH_EFFORT_FUNC(3)
+{
+ //see Search_Effort_Max() for comments
+#include "SearchLoopTop.inc"
+#include "SearchLoopOddA2.inc"
+ RESET_CHROMA // pretend chroma diffs was 255 each
+#include "SearchLoop0A.inc"
+#include "SearchLoopBottom.inc"
+}
+
+SEARCH_EFFORT_FUNC(5)
+{
+ //see Search_Effort_Max() for comments
+#include "SearchLoopTop.inc"
+#include "SearchLoopOddA2.inc"
+#include "SearchLoopOddAH2.inc"
+ RESET_CHROMA // pretend chroma diffs was 255 each
+#include "SearchLoop0A.inc"
+#include "SearchLoopBottom.inc"
+}
+
+// 3x3 search
+SEARCH_EFFORT_FUNC(9)
+{
+ //see SearchEffortMax() for comments
+#include "SearchLoopTop.inc"
+#include "SearchLoopOddA.inc"
+ RESET_CHROMA // pretend chroma diffs was 255 each
+#include "SearchLoopVA.inc"
+#include "SearchLoop0A.inc"
+#include "SearchLoopBottom.inc"
+}
+
+// Search 9 with 2 H-half pels added
+SEARCH_EFFORT_FUNC(11)
+{
+ //see SearchEffortMax() for comments
+#include "SearchLoopTop.inc"
+#include "SearchLoopOddA.inc"
+#include "SearchLoopOddAH2.inc"
+ RESET_CHROMA // pretend chroma diffs was 255 each
+#include "SearchLoopVA.inc"
+#include "SearchLoop0A.inc"
+#include "SearchLoopBottom.inc"
+}
+
+// Search 11 with 2 V-half pels added
+SEARCH_EFFORT_FUNC(13)
+{
+ //see SearchEffortMax() for comments
+#include "SearchLoopTop.inc"
+#include "SearchLoopOddA.inc"
+#include "SearchLoopOddAH2.inc"
+ RESET_CHROMA // pretend chroma diffs was 255 each
+#include "SearchLoopVAH.inc"
+#include "SearchLoopVA.inc"
+#include "SearchLoop0A.inc"
+#include "SearchLoopBottom.inc"
+}
+
+// 5x3
+SEARCH_EFFORT_FUNC(15)
+{
+ //see SearchEffortMax() for comments
+#include "SearchLoopTop.inc"
+#include "SearchLoopOddA.inc"
+ RESET_CHROMA // pretend chroma diffs was 255 each
+#include "SearchLoopEdgeA.inc"
+#include "SearchLoopVA.inc"
+#include "SearchLoop0A.inc"
+#include "SearchLoopBottom.inc"
+}
+
+// 5x3 + 4 half pels
+SEARCH_EFFORT_FUNC(19)
+{
+ //see SearchEffortMax() for comments
+#include "SearchLoopTop.inc"
+#include "SearchLoopOddA.inc"
+#include "SearchLoopOddAH2.inc"
+ RESET_CHROMA // pretend chroma diffs was 255 each
+#include "SearchLoopEdgeA.inc"
+#include "SearchLoopVAH.inc"
+#include "SearchLoopVA.inc"
+#include "SearchLoop0A.inc"
+#include "SearchLoopBottom.inc"
+}
+
+// Handle one 4x1 block of pixels
+// Search a 7x3 area, no half pels
+
+SEARCH_EFFORT_FUNC(21)
+{
+ //see SearchLoopTop.inc for comments
+#include "SearchLoopTop.inc"
+
+ // odd addresses -- the pixels at odd address wouldn't generate
+ // good luma values but we will mask those off
+
+#include "SearchLoopOddA6.inc" // 4 odd v half pels, 3 to left & right
+#include "SearchLoopOddA.inc" // 6 odd pels, 1 to left & right
+
+ RESET_CHROMA // pretend chroma diffs was 255 each
+
+ // even addresses -- use both luma and chroma from these
+ // search averages of 2 pixels left and right
+#include "SearchLoopEdgeA.inc"
+ // search vertical line and averages, -1,0,+1
+#include "SearchLoopVA.inc"
+ // blend our results and loop
+#include "SearchLoop0A.inc"
+#include "SearchLoopBottom.inc"
+}
+
+// Handle one 4x1 block of pixels
+// Search a 9x3 area, no half pels
+SEARCH_EFFORT_FUNC(Max)
+{
+ //see SearchLoopTop.inc for comments
+#include "SearchLoopTop.inc"
+
+ // odd addresses -- the pixels at odd address wouldn't generate
+ // good luma values but we will mask those off
+
+#include "SearchLoopOddA6.inc" // 4 odd v half pels, 3 to left & right
+#include "SearchLoopOddA.inc" // 6 odd pels, 1 to left & right
+
+ RESET_CHROMA // pretend chroma diffs was 255 each
+
+ // even addresses -- use both luma and chroma from these
+ // search averages of 4 pixels left and right
+#include "SearchLoopEdgeA8.inc"
+ // search averages of 2 pixels left and right
+#include "SearchLoopEdgeA.inc"
+ // search vertical line and averages, -1,0,+1
+#include "SearchLoopVA.inc"
+ // blend our results and loop
+#include "SearchLoop0A.inc"
+#include "SearchLoopBottom.inc"
+}
+
+#undef SEARCH_EFFORT_FUNC
+
diff --git a/src/post/deinterlace/plugins/tomsmocomp/WierdBob.inc b/src/post/deinterlace/plugins/tomsmocomp/WierdBob.inc
new file mode 100644
index 000000000..b6a8e615f
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/WierdBob.inc
@@ -0,0 +1,189 @@
+// -*- c++ -*-
+
+ // First, get and save our possible Bob values
+ // Assume our pixels are layed out as follows with x the calc'd bob value
+ // and the other pixels are from the current field
+ //
+ // j a b c k current field
+ // x calculated line
+ // m d e f n current field
+ //
+ // we calc the bob value as:
+ // x2 = either avg(a,f), avg(c,d), avg(b,e), avg(j,n), or avg(k,m)
+
+ // selected for the smallest of abs(a,f), abs(c,d), or abs(b,e), etc.
+
+ // a,f
+ "movq -2(%%"XBX"), %%mm0\n\t" // value a from top left
+ "movq 2(%%"XBX", %%"XCX"), %%mm1\n\t" // value f from bottom right
+ "movq %%mm0, %%mm6\n\t"
+// pavgb %%mm6, %%mm1 // avg(a,f), also best so far
+ V_PAVGB ("%%mm6", "%%mm1", "%%mm7", _ShiftMask) // avg(a,f), also best so far
+ "movq %%mm0, %%mm7\n\t"
+ "psubusb %%mm1, %%mm7\n\t"
+ "psubusb %%mm0, %%mm1\n\t"
+ "por %%mm1, %%mm7\n\t" // abs diff, also best so far
+
+ // c,d
+ "movq 2(%%"XBX"), %%mm0\n\t" // value a from top left
+ "movq -2(%%"XBX", %%"XCX"), %%mm1\n\t" // value f from bottom right
+ "movq %%mm0, %%mm2\n\t"
+// pavgb %%mm2, %%mm1 // avg(c,d)
+ V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(c,d)
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm3\n\t"
+ "psubusb %%mm0, %%mm1\n\t"
+ "por %%mm1, %%mm3\n\t" // abs(c,d)
+ "movq %%mm3, %%mm1\n\t" // keep copy
+
+ "psubusb %%mm7, %%mm3\n\t" // nonzero where new weights bigger, else 0
+ "pxor %%mm4, %%mm4\n\t"
+ "pcmpeqb %%mm4, %%mm3\n\t" // now ff where new better, else 00
+ "pcmpeqb %%mm3, %%mm4\n\t" // here ff where old better, else 00
+
+ "pand %%mm3, %%mm1\n\t" // keep only better new avg and abs
+ "pand %%mm3, %%mm2\n\t"
+
+ "pand %%mm4, %%mm6\n\t"
+ "pand %%mm4, %%mm7\n\t"
+
+ "por %%mm2, %%mm6\n\t" // and merge new & old vals keeping best
+ "por %%mm1, %%mm7\n\t"
+ "por "_UVMask", %%mm7\n\t" // but we know chroma is worthless so far
+ "pand "_YMask", %%mm5\n\t" // mask out chroma from here also
+
+ // j,n
+ "movq -4(%%"XBX"), %%mm0\n\t" // value j from top left
+ "movq 4(%%"XBX", %%"XCX"), %%mm1\n\t" // value n from bottom right
+ "movq %%mm0, %%mm2\n\t"
+// pavgb %%mm2, %%mm1 // avg(j,n)
+ V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(j,n)
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm3\n\t"
+ "psubusb %%mm0, %%mm1\n\t"
+ "por %%mm1, %%mm3\n\t" // abs(j-n)
+ "movq %%mm3, %%mm1\n\t" // keep copy
+
+ "psubusb %%mm7, %%mm3\n\t" // nonzero where new weights bigger, else 0
+ "pxor %%mm4, %%mm4\n\t"
+ "pcmpeqb %%mm4, %%mm3\n\t" // now ff where new better, else 00
+ "pcmpeqb %%mm3, %%mm4\n\t" // here ff where old better, else 00
+
+ "pand %%mm3, %%mm1\n\t" // keep only better new avg and abs
+ "pand %%mm2, %%mm3\n\t"
+
+ "pand %%mm4, %%mm6\n\t"
+ "pand %%mm4, %%mm7\n\t"
+
+ "por %%mm3, %%mm6\n\t" // and merge new & old vals keeping best
+ "por %%mm1, %%mm7\n\t" // "
+
+ // k, m
+ "movq 4(%%"XBX"), %%mm0\n\t" // value k from top right
+ "movq -4(%%"XBX", %%"XCX"), %%mm1\n\t" // value n from bottom left
+ "movq %%mm0, %%mm4\n\t"
+// pavgb %%mm4, %%mm1 // avg(k,m)
+ V_PAVGB ("%%mm4", "%%mm1", "%%mm3", _ShiftMask) // avg(k,m)
+
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm3\n\t"
+ "psubusb %%mm0, %%mm1\n\t"
+ "por %%mm1, %%mm3\n\t" // abs(k,m)
+ "movq %%mm3, %%mm1\n\t" // keep copy
+
+ "movq %%mm4, %%mm2\n\t" // avg(k,m)
+
+ "psubusb %%mm7, %%mm3\n\t" // nonzero where new weights bigger, else 0
+ "pxor %%mm4, %%mm4\n\t"
+ "pcmpeqb %%mm4, %%mm3\n\t" // now ff where new better, else 00
+ "pcmpeqb %%mm3, %%mm4\n\t" // here ff where old better, else 00
+
+ "pand %%mm3, %%mm1\n\t" // keep only better new avg and abs
+ "pand %%mm2, %%mm3\n\t"
+
+ "pand %%mm4, %%mm6\n\t"
+ "pand %%mm4, %%mm7\n\t"
+
+ "por %%mm3, %%mm6\n\t" // and merge new & old vals keeping best
+ "por %%mm1, %%mm7\n\t" // "
+
+ // b,e
+ "movq (%%"XBX"), %%mm0\n\t" // value b from top
+ "movq (%%"XBX", %%"XCX"), %%mm1\n\t" // value e from bottom
+
+// We will also calc here the max/min values to later limit comb
+// so the max excursion will not exceed the Max_Comb constant
+
+#ifdef SKIP_SEARCH
+ "movq %%mm0, %%mm2\n\t"
+// pminub %%mm2, %%mm1
+ V_PMINUB ("%%mm2", "%%mm1", "%%mm4")
+
+// pmaxub %%mm6, %%mm2 // clip our current results so far to be above this
+ V_PMAXUB ("%%mm6", "%%mm2")
+ "movq %%mm0, %%mm2\n\t"
+ V_PMAXUB ("%%mm2", "%%mm1")
+// pminub %%mm6, %%mm2 // clip our current results so far to be below this
+ V_PMINUB ("%%mm6", "%%mm2", "%%mm4")
+
+#else
+ "movq %%mm0, %%mm2\n\t"
+ "movq (%%"XAX"), %%mm4\n\t"
+ "psubusb %%mm4, %%mm2\n\t"
+ "psubusb %%mm0, %%mm4\n\t"
+ "por %%mm2, %%mm4\n\t" // abs diff
+
+ "movq %%mm1, %%mm2\n\t"
+ "movq (%%"XAX", %%"XCX"), %%mm3\n\t"
+ "psubusb %%mm3, %%mm2\n\t"
+ "psubusb %%mm1, %%mm3\n\t"
+ "por %%mm2, %%mm3\n\t" // abs diff
+// pmaxub %%mm3, %%mm4 // top or bottom pixel moved most
+ V_PMAXUB ("%%mm3", "%%mm4") // top or bottom pixel moved most
+ "psubusb "_Max_Mov", %%mm3\n\t" // moved more than allowed? or goes to 0?
+ "pxor %%mm4, %%mm4\n\t"
+ "pcmpeqb %%mm4, %%mm3\n\t" // now ff where low motion, else high motion
+
+ "movq %%mm0, %%mm2\n\t"
+// pminub %%mm2, %%mm1
+ V_PMINUB ("%%mm2", "%%mm1", "%%mm4")
+
+// pmaxub %%mm6, %%mm2 // clip our current results so far to be above this
+ V_PMAXUB ("%%mm6", "%%mm2")
+
+ "psubusb %%mm3, %%mm2\n\t" // maybe decrease it to 0000.. if no surround motion
+ "movq %%mm2, "_Min_Vals"\n\t"
+
+ "movq %%mm0, %%mm2\n\t"
+ V_PMAXUB ("%%mm2", "%%mm1")
+// pminub %%mm6, %%mm2 // clip our current results so far to be below this
+ V_PMINUB ("%%mm6", "%%mm2", "%%mm4")
+ "paddusb %%mm3, %%mm2\n\t" // maybe increase it to ffffff if no surround motion
+ "movq %%mm2, "_Max_Vals"\n\t"
+#endif
+
+ "movq %%mm0, %%mm2\n\t"
+// pavgb %%mm2, %%mm1 // avg(b,e)
+ V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(b,e)
+
+ "movq %%mm0, %%mm3\n\t"
+ "psubusb %%mm1, %%mm3\n\t"
+ "psubusb %%mm0, %%mm1\n\t"
+ "por %%mm1, %%mm3\n\t" // abs(c,d)
+ "movq %%mm3, %%mm1\n\t" // keep copy of diffs
+
+ "pxor %%mm4, %%mm4\n\t"
+ "psubusb %%mm7, %%mm3\n\t" // nonzero where new weights bigger, else 0
+ "pcmpeqb %%mm4, %%mm3\n\t" // now ff where new better, else 00
+ "pcmpeqb %%mm3, %%mm4\n\t" // here ff where old better, else 00
+
+ "pand %%mm3, %%mm1\n\t"
+ "pand %%mm3, %%mm2\n\t"
+
+ "pand %%mm4, %%mm6\n\t"
+ "pand %%mm4, %%mm7\n\t"
+
+ "por %%mm2, %%mm6\n\t" // our x2 value
+ "por %%mm1, %%mm7\n\t" // our x2 diffs
+ "movq %%mm7, %%mm4\n\t" // save as bob uncertainty indicator
+
diff --git a/src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h b/src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h
new file mode 100644
index 000000000..e8e57cac5
--- /dev/null
+++ b/src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h
@@ -0,0 +1,170 @@
+#include <malloc.h>
+#include <string.h>
+#include <math.h>
+#include <malloc.h>
+
+#define USE_FOR_DSCALER
+
+#define MyMemCopy xine_fast_memcpy
+
+// Define a few macros for CPU dependent instructions.
+// I suspect I don't really understand how the C macro preprocessor works but
+// this seems to get the job done. // TRB 7/01
+
+// BEFORE USING THESE YOU MUST SET:
+
+// #define SSE_TYPE SSE (or MMX or 3DNOW)
+
+// some macros for pavgb instruction
+// V_PAVGB(mmr1, mmr2, mmr work register, smask) mmr2 may = mmrw if you can trash it
+
+#define V_PAVGB_MMX(mmr1, mmr2, mmrw, smask) \
+ "movq "mmr2", "mmrw"\n\t" \
+ "pand "smask", "mmrw"\n\t" \
+ "psrlw $1, "mmrw"\n\t" \
+ "pand "smask", "mmr1"\n\t" \
+ "psrlw $1, "mmr1"\n\t" \
+ "paddusb "mmrw", "mmr1"\n\t"
+#define V_PAVGB_SSE(mmr1, mmr2, mmrw, smask) "pavgb "mmr2", "mmr1"\n\t"
+#define V_PAVGB_3DNOW(mmr1, mmr2, mmrw, smask) "pavgusb "mmr2", "mmr1"\n\t"
+#define V_PAVGB(mmr1, mmr2, mmrw, smask) V_PAVGB2(mmr1, mmr2, mmrw, smask, SSE_TYPE)
+#define V_PAVGB2(mmr1, mmr2, mmrw, smask, ssetyp) V_PAVGB3(mmr1, mmr2, mmrw, smask, ssetyp)
+#define V_PAVGB3(mmr1, mmr2, mmrw, smask, ssetyp) V_PAVGB_##ssetyp(mmr1, mmr2, mmrw, smask)
+
+// some macros for pmaxub instruction
+#define V_PMAXUB_MMX(mmr1, mmr2) \
+ "psubusb "mmr2", "mmr1"\n\t" \
+ "paddusb "mmr2", "mmr1"\n\t"
+#define V_PMAXUB_SSE(mmr1, mmr2) "pmaxub "mmr2", "mmr1"\n\t"
+#define V_PMAXUB_3DNOW(mmr1, mmr2) V_PMAXUB_MMX(mmr1, mmr2) // use MMX version
+#define V_PMAXUB(mmr1, mmr2) V_PMAXUB2(mmr1, mmr2, SSE_TYPE)
+#define V_PMAXUB2(mmr1, mmr2, ssetyp) V_PMAXUB3(mmr1, mmr2, ssetyp)
+#define V_PMAXUB3(mmr1, mmr2, ssetyp) V_PMAXUB_##ssetyp(mmr1, mmr2)
+
+// some macros for pminub instruction
+// V_PMINUB(mmr1, mmr2, mmr work register) mmr2 may NOT = mmrw
+#define V_PMINUB_MMX(mmr1, mmr2, mmrw) \
+ "pcmpeqb "mmrw", "mmrw"\n\t" \
+ "psubusb "mmr2", "mmrw"\n\t" \
+ "paddusb "mmrw", "mmr1"\n\t" \
+ "psubusb "mmrw", "mmr1"\n\t"
+#define V_PMINUB_SSE(mmr1, mmr2, mmrw) "pminub "mmr2", "mmr1"\n\t"
+#define V_PMINUB_3DNOW(mmr1, mmr2, mmrw) V_PMINUB_MMX(mmr1, mmr2, mmrw) // use MMX version
+#define V_PMINUB(mmr1, mmr2, mmrw) V_PMINUB2(mmr1, mmr2, mmrw, SSE_TYPE)
+#define V_PMINUB2(mmr1, mmr2, mmrw, ssetyp) V_PMINUB3(mmr1, mmr2, mmrw, ssetyp)
+#define V_PMINUB3(mmr1, mmr2, mmrw, ssetyp) V_PMINUB_##ssetyp(mmr1, mmr2, mmrw)
+
+// some macros for movntq instruction
+// V_MOVNTQ(mmr1, mmr2)
+#define V_MOVNTQ_MMX(mmr1, mmr2) "movq "mmr2", "mmr1"\n\t"
+#define V_MOVNTQ_3DNOW(mmr1, mmr2) "movq "mmr2", "mmr1"\n\t"
+#define V_MOVNTQ_SSE(mmr1, mmr2) "movntq "mmr2", "mmr1"\n\t"
+#define V_MOVNTQ(mmr1, mmr2) V_MOVNTQ2(mmr1, mmr2, SSE_TYPE)
+#define V_MOVNTQ2(mmr1, mmr2, ssetyp) V_MOVNTQ3(mmr1, mmr2, ssetyp)
+#define V_MOVNTQ3(mmr1, mmr2, ssetyp) V_MOVNTQ_##ssetyp(mmr1, mmr2)
+
+// end of macros
+
+#ifdef IS_SSE2
+
+#define MERGE4PIXavg(PADDR1, PADDR2) \
+ "movdqu "PADDR1", %%xmm0\n\t" /* our 4 pixels */ \
+ "movdqu "PADDR2", %%xmm1\n\t" /* our pixel2 value */ \
+ "movdqa %%xmm0, %%xmm2\n\t" /* another copy of our pixel1 value */ \
+ "movdqa %%xmm1, %%xmm3\n\t" /* another copy of our pixel1 value */ \
+ "psubusb %%xmm1, %%xmm2\n\t" \
+ "psubusb %%xmm0, %%xmm3\n\t" \
+ "por %%xmm3, %%xmm2\n\t" \
+ "pavgb %%xmm1, %%xmm0\n\t" /* avg of 2 pixels */ \
+ "movdqa %%xmm2, %%xmm3\n\t" /* another copy of our our weights */ \
+ "pxor %%xmm1, %%xmm1\n\t" \
+ "psubusb %%xmm7, %%xmm3\n\t" /* nonzero where old weights lower, else 0 */ \
+ "pcmpeqb %%xmm1, %%xmm3\n\t" /* now ff where new better, else 00 */ \
+ "pcmpeqb %%xmm3, %%xmm1\n\t" /* here ff where old better, else 00 */ \
+ "pand %%xmm3, %%xmm0\n\t" /* keep only better new pixels */ \
+ "pand %%xmm3, %%xmm2\n\t" /* and weights */ \
+ "pand %%xmm1, %%xmm5\n\t" /* keep only better old pixels */ \
+ "pand %%xmm1, %%xmm7\n\t" \
+ "por %%xmm0, %%xmm5\n\t" /* and merge new & old vals */ \
+ "por %%xmm2, %%xmm7\n\t"
+
+#define MERGE4PIXavgH(PADDR1A, PADDR1B, PADDR2A, PADDR2B) \
+ "movdqu "PADDR1A", %%xmm0\n\t" /* our 4 pixels */ \
+ "movdqu "PADDR2A", %%xmm1\n\t" /* our pixel2 value */ \
+ "movdqu "PADDR1B", %%xmm2\n\t" /* our 4 pixels */ \
+ "movdqu "PADDR2B", %%xmm3\n\t" /* our pixel2 value */ \
+ "pavgb %%xmm2, %%xmm0\n\t" \
+ "pavgb %%xmm3, %%xmm1\n\t" \
+ "movdqa %%xmm0, %%xmm2\n\t" /* another copy of our pixel1 value */ \
+ "movdqa %%xmm1, %%xmm3\n\t" /* another copy of our pixel1 value */ \
+ "psubusb %%xmm1, %%xmm2\n\t" \
+ "psubusb %%xmm0, %%xmm3\n\t" \
+ "por %%xmm3, %%xmm2\n\t" \
+ "pavgb %%xmm1, %%xmm0\n\t" /* avg of 2 pixels */ \
+ "movdqa %%xmm2, %%xmm3\n\t" /* another copy of our our weights */ \
+ "pxor %%xmm1, %%xmm1\n\t" \
+ "psubusb %%xmm7, %%xmm3\n\t" /* nonzero where old weights lower, else 0 */ \
+ "pcmpeqb %%xmm1, %%xmm3\n\t" /* now ff where new better, else 00 */ \
+ "pcmpeqb %%xmm3, %%xmm1\n\t" /* here ff where old better, else 00 */ \
+ "pand %%xmm3, %%xmm0\n\t" /* keep only better new pixels */ \
+ "pand %%xmm3, %%xmm2\n\t" /* and weights */ \
+ "pand %%xmm1, %%xmm5\n\t" /* keep only better old pixels */ \
+ "pand %%xmm1, %%xmm7\n\t" \
+ "por %%xmm0, %%xmm5\n\t" /* and merge new & old vals */ \
+ "por %%xmm2, %%xmm7\n\t"
+
+#define RESET_CHROMA "por "_UVMask", %%xmm7\n\t"
+
+#else // ifdef IS_SSE2
+
+#define MERGE4PIXavg(PADDR1, PADDR2) \
+ "movq "PADDR1", %%mm0\n\t" /* our 4 pixels */ \
+ "movq "PADDR2", %%mm1\n\t" /* our pixel2 value */ \
+ "movq %%mm0, %%mm2\n\t" /* another copy of our pixel1 value */ \
+ "movq %%mm1, %%mm3\n\t" /* another copy of our pixel1 value */ \
+ "psubusb %%mm1, %%mm2\n\t" \
+ "psubusb %%mm0, %%mm3\n\t" \
+ "por %%mm3, %%mm2\n\t" \
+ V_PAVGB ("%%mm0", "%%mm1", "%%mm3", _ShiftMask) /* avg of 2 pixels */ \
+ "movq %%mm2, %%mm3\n\t" /* another copy of our our weights */ \
+ "pxor %%mm1, %%mm1\n\t" \
+ "psubusb %%mm7, %%mm3\n\t" /* nonzero where old weights lower, else 0 */ \
+ "pcmpeqb %%mm1, %%mm3\n\t" /* now ff where new better, else 00 */ \
+ "pcmpeqb %%mm3, %%mm1\n\t" /* here ff where old better, else 00 */ \
+ "pand %%mm3, %%mm0\n\t" /* keep only better new pixels */ \
+ "pand %%mm3, %%mm2\n\t" /* and weights */ \
+ "pand %%mm1, %%mm5\n\t" /* keep only better old pixels */ \
+ "pand %%mm1, %%mm7\n\t" \
+ "por %%mm0, %%mm5\n\t" /* and merge new & old vals */ \
+ "por %%mm2, %%mm7\n\t"
+
+#define MERGE4PIXavgH(PADDR1A, PADDR1B, PADDR2A, PADDR2B) \
+ "movq "PADDR1A", %%mm0\n\t" /* our 4 pixels */ \
+ "movq "PADDR2A", %%mm1\n\t" /* our pixel2 value */ \
+ "movq "PADDR1B", %%mm2\n\t" /* our 4 pixels */ \
+ "movq "PADDR2B", %%mm3\n\t" /* our pixel2 value */ \
+ V_PAVGB("%%mm0", "%%mm2", "%%mm2", _ShiftMask) \
+ V_PAVGB("%%mm1", "%%mm3", "%%mm3", _ShiftMask) \
+ "movq %%mm0, %%mm2\n\t" /* another copy of our pixel1 value */ \
+ "movq %%mm1, %%mm3\n\t" /* another copy of our pixel1 value */ \
+ "psubusb %%mm1, %%mm2\n\t" \
+ "psubusb %%mm0, %%mm3\n\t" \
+ "por %%mm3, %%mm2\n\t" \
+ V_PAVGB("%%mm0", "%%mm1", "%%mm3", _ShiftMask) /* avg of 2 pixels */ \
+ "movq %%mm2, %%mm3\n\t" /* another copy of our our weights */ \
+ "pxor %%mm1, %%mm1\n\t" \
+ "psubusb %%mm7, %%mm3\n\t" /* nonzero where old weights lower, else 0 */ \
+ "pcmpeqb %%mm1, %%mm3\n\t" /* now ff where new better, else 00 */ \
+ "pcmpeqb %%mm3, %%mm1\n\t" /* here ff where old better, else 00 */ \
+ "pand %%mm3, %%mm0\n\t" /* keep only better new pixels */ \
+ "pand %%mm3, %%mm2\n\t" /* and weights */ \
+ "pand %%mm1, %%mm5\n\t" /* keep only better old pixels */ \
+ "pand %%mm1, %%mm7\n\t" \
+ "por %%mm0, %%mm5\n\t" /* and merge new & old vals */ \
+ "por %%mm2, %%mm7\n\t"
+
+#define RESET_CHROMA "por "_UVMask", %%mm7\n\t"
+
+#endif
+
+
diff --git a/src/post/deinterlace/plugins/vfir.c b/src/post/deinterlace/plugins/vfir.c
index 9274a5885..6809b2244 100644
--- a/src/post/deinterlace/plugins/vfir.c
+++ b/src/post/deinterlace/plugins/vfir.c
@@ -130,7 +130,7 @@ static void copy_scanline( uint8_t *output,
static deinterlace_method_t vfirmethod =
{
- "ffmpeg: Vertical Blend",
+ "Vertical Blend (ffmpeg)",
"Vertical",
/*
"Blur: Vertical",
diff --git a/src/post/deinterlace/xine_plugin.c b/src/post/deinterlace/xine_plugin.c
index 3390040c6..e0aa6acef 100644
--- a/src/post/deinterlace/xine_plugin.c
+++ b/src/post/deinterlace/xine_plugin.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_plugin.c,v 1.41 2005/05/27 16:35:27 miguelfreitas Exp $
+ * $Id: xine_plugin.c,v 1.42 2005/05/28 02:35:57 miguelfreitas Exp $
*
* advanced video deinterlacer plugin
* Jun/2003 by Miguel Freitas
@@ -316,6 +316,7 @@ static void *deinterlace_init_plugin(xine_t *xine, void *data)
register_deinterlace_method( vfir_get_method() );
register_deinterlace_method( scalerbob_get_method() );
register_deinterlace_method( dscaler_greedyh_get_method() );
+ register_deinterlace_method( dscaler_tomsmocomp_get_method() );
filter_deinterlace_methods( config_flags, 5 /*fieldsavailable*/ );
if( !get_num_deinterlace_methods() ) {
@@ -335,7 +336,10 @@ static void *deinterlace_init_plugin(xine_t *xine, void *data)
method = get_deinterlace_method(i);
enum_methods[i+1] = (char *)method->short_name;
+ xine_buffer_strcat( help_string, "[" );
xine_buffer_strcat( help_string, (char *)method->short_name );
+ xine_buffer_strcat( help_string, "] " );
+ xine_buffer_strcat( help_string, (char *)method->name );
xine_buffer_strcat( help_string, ":\n" );
desc_len = 0;