Moved 'deinterlace2' from -bad to -good

And remove old deinterlace plugin as deinterlace2 will
be called deinterlace in -good.
This commit is contained in:
Sebastian Dröge 2009-05-13 10:47:23 +02:00
parent 8c13566624
commit 453794d383
47 changed files with 0 additions and 8839 deletions

View file

@ -158,13 +158,6 @@ GST_CHECK_FIONREAD
dnl *** checks for structures ***
dnl *** checks for compiler characteristics ***
dnl check if we have GCC inline-asm
AS_GCC_INLINE_ASSEMBLY([HAVE_GCC_ASM=yes], [HAVE_GCC_ASM=no])
if test x$HAVE_GCC_ASM = xyes ; then
AC_DEFINE(HAVE_GCC_ASM, 1,
[Define if compiler supports gcc inline assembly])
fi
AM_CONDITIONAL(HAVE_GCC_ASM, test "x$HAVE_GCC_ASM" = "xyes")
dnl *** checks for library functions ***
AC_CHECK_FUNCS([gmtime_r])
@ -267,8 +260,6 @@ AG_GST_CHECK_PLUGIN(bayer)
AG_GST_CHECK_PLUGIN(cdxaparse)
AG_GST_CHECK_PLUGIN(dccp)
AG_GST_CHECK_PLUGIN(debugutils)
AG_GST_CHECK_PLUGIN(deinterlace)
AG_GST_CHECK_PLUGIN(deinterlace2)
AG_GST_CHECK_PLUGIN(dtmf)
AG_GST_CHECK_PLUGIN(dvdspu)
AG_GST_CHECK_PLUGIN(festival)
@ -1538,8 +1529,6 @@ gst/camerabin/Makefile
gst/cdxaparse/Makefile
gst/dccp/Makefile
gst/debugutils/Makefile
gst/deinterlace/Makefile
gst/deinterlace2/Makefile
gst/dtmf/Makefile
gst/dvdspu/Makefile
gst/festival/Makefile

View file

@ -120,8 +120,6 @@ EXTRA_HFILES = \
$(top_srcdir)/gst/amrparse/gstamrparse.h \
$(top_srcdir)/gst/autoconvert/gstautoconvert.h \
$(top_srcdir)/gst/camerabin/gstcamerabin.h \
$(top_srcdir)/gst/deinterlace/gstdeinterlace.h \
$(top_srcdir)/gst/deinterlace2/gstdeinterlace2.h \
$(top_srcdir)/gst/dccp/gstdccpclientsink.h \
$(top_srcdir)/gst/dccp/gstdccpclientsrc.h \
$(top_srcdir)/gst/dccp/gstdccpserversink.h \

View file

@ -32,8 +32,6 @@
<xi:include href="xml/element-dccpclientsrc.xml" />
<xi:include href="xml/element-dccpserversink.xml" />
<xi:include href="xml/element-dccpserversrc.xml" />
<xi:include href="xml/element-deinterlace.xml" />
<xi:include href="xml/element-deinterlace2.xml" />
<xi:include href="xml/element-dfbvideosink.xml" />
<xi:include href="xml/element-dtmfsrc.xml" />
<xi:include href="xml/element-dtsdec.xml" />
@ -104,7 +102,6 @@
<xi:include href="xml/plugin-celt.xml" />
<xi:include href="xml/plugin-dccp.xml" />
<xi:include href="xml/plugin-debugutilsbad.xml" />
<xi:include href="xml/plugin-deinterlace2.xml" />
<xi:include href="xml/plugin-dfbvideosink.xml" />
<xi:include href="xml/plugin-dirac.xml" />
<xi:include href="xml/plugin-dtmf.xml" />
@ -119,7 +116,6 @@
<xi:include href="xml/plugin-filter.xml" />
<xi:include href="xml/plugin-freeze.xml" />
<xi:include href="xml/plugin-gsm.xml" />
<xi:include href="xml/plugin-gstinterlace.xml" />
<xi:include href="xml/plugin-gstrtpmanager.xml" />
<xi:include href="xml/plugin-h264parse.xml" />
<xi:include href="xml/plugin-jack.xml" />

View file

@ -209,34 +209,6 @@ GST_TYPE_DCCP_SERVER_SRC
gst_dccp_server_src_get_type
</SECTION>
<SECTION>
<FILE>element-deinterlace</FILE>
<TITLE>deinterlace</TITLE>
GstDeinterlace
<SUBSECTION Standard>
GstDeinterlaceClass
GST_DEINTERLACE
GST_DEINTERLACE_CLASS
GST_IS_DEINTERLACE
GST_IS_DEINTERLACE_CLASS
GST_TYPE_DEINTERLACE
gst_deinterlace_get_type
</SECTION>
<SECTION>
<FILE>element-deinterlace2</FILE>
<TITLE>deinterlace2</TITLE>
GstDeinterlace2
<SUBSECTION Standard>
GstDeinterlace2Class
GST_IS_DEINTERLACE2
GST_IS_DEINTERLACE2_CLASS
GST_DEINTERLACE2
GST_DEINTERLACE2_CLASS
GST_TYPE_DEINTERLACE2
gst_deinterlace2_get_type
</SECTION>
<SECTION>
<FILE>element-dfbvideosink</FILE>
<TITLE>dfbvideosink</TITLE>

View file

@ -1,34 +0,0 @@
<plugin>
<name>deinterlace2</name>
<description>Deinterlacer</description>
<filename>../../gst/deinterlace2/.libs/libgstdeinterlace2.so</filename>
<basename>libgstdeinterlace2.so</basename>
<version>0.10.11.1</version>
<license>LGPL</license>
<source>gst-plugins-bad</source>
<package>GStreamer Bad Plug-ins CVS/prerelease</package>
<origin>Unknown package origin</origin>
<elements>
<element>
<name>deinterlace2</name>
<longname>Deinterlacer</longname>
<class>Filter/Video</class>
<description>Deinterlace Methods ported from DScaler/TvTime</description>
<author>Martin Eikermann &lt;meiker@upb.de&gt;, Sebastian Dröge &lt;slomo@circular-chaos.org&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>video/x-raw-yuv, format=(fourcc)YUY2, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-yuv, format=(fourcc)YVYU, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>video/x-raw-yuv, format=(fourcc)YUY2, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-yuv, format=(fourcc)YVYU, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
</pads>
</element>
</elements>
</plugin>

View file

@ -1,34 +0,0 @@
<plugin>
<name>gstinterlace</name>
<description>Deinterlace video</description>
<filename>../../gst/deinterlace/.libs/libgstdeinterlace.so</filename>
<basename>libgstdeinterlace.so</basename>
<version>0.10.11.1</version>
<license>LGPL</license>
<source>gst-plugins-bad</source>
<package>GStreamer Bad Plug-ins CVS/prerelease</package>
<origin>Unknown package origin</origin>
<elements>
<element>
<name>deinterlace</name>
<longname>Deinterlace</longname>
<class>Filter/Effect/Video</class>
<description>Deinterlace video</description>
<author>Wim Taymans &lt;wim.taymans@gmail.com&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>video/x-raw-yuv, format=(fourcc){ I420, Y42B }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>video/x-raw-yuv, format=(fourcc){ I420, Y42B }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
</pads>
</element>
</elements>
</plugin>

View file

@ -1,7 +0,0 @@
Makefile
Makefile.in
*.o
*.lo
*.la
.deps
.libs

View file

@ -1,12 +0,0 @@
plugin_LTLIBRARIES = libgstdeinterlace.la
libgstdeinterlace_la_SOURCES = gstdeinterlace.c
libgstdeinterlace_la_CFLAGS = \
$(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS)
libgstdeinterlace_la_LIBADD = \
$(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) $(GST_BASE_LIBS)
libgstdeinterlace_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstdeinterlace_la_LIBTOOLFLAGS = --tag=disable-static
noinst_HEADERS = gstdeinterlace.h

View file

@ -1,148 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="deinterlace"
ProjectGUID="{979C216F-0ACF-4956-AE00-055A42D678B0}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../win32/Debug"
IntermediateDirectory="../../win32/Debug"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../gstreamer/win32;../../../gstreamer;../../../gstreamer/libs;../../../glib;../../../glib/glib;../../../glib/gmodule;&quot;../../gst-libs&quot;;../../../popt/include;../../../libxml2/include/libxml2"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;deinterlace_EXPORTS;HAVE_CONFIG_H;_USE_MATH_DEFINES"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="glib-2.0.lib gmodule-2.0.lib gthread-2.0.lib gobject-2.0.lib libgstreamer.lib gstbytestream.lib iconv.lib intl.lib"
OutputFile="$(OutDir)/gstdeinterlace.dll"
LinkIncremental="2"
AdditionalLibraryDirectories="../../../gstreamer/win32/Debug;../../../glib/glib;../../../glib/gmodule;../../../glib/gthread;../../../glib/gobject;../../../gettext/lib;../../../libiconv/lib"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/deinterlace.pdb"
SubSystem="2"
OptimizeReferences="2"
ImportLibrary="$(OutDir)/gstdeinterlace.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy /Y $(TargetPath) c:\gstreamer\plugins"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../win32/Release"
IntermediateDirectory="../../win32/Release"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../gstreamer/win32;../../../gstreamer;../../../gstreamer/libs;../../../glib;../../../glib/glib;../../../glib/gmodule;&quot;../../gst-libs&quot;;../../../popt/include;../../../libxml2/include/libxml2"
PreprocessorDefinitions="WIN32;NDEBUG;GST_DISABLE_GST_DEBUG;_WINDOWS;_USRDLL;deinterlace_EXPORTS;HAVE_CONFIG_H;_USE_MATH_DEFINES"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="glib-2.0.lib gmodule-2.0.lib gthread-2.0.lib gobject-2.0.lib libgstreamer.lib gstbytestream.lib iconv.lib intl.lib"
OutputFile="$(OutDir)/gstdeinterlace.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../gstreamer/win32/Release;../../../glib/glib;../../../glib/gmodule;../../../glib/gthread;../../../glib/gobject;../../../gettext/lib;../../../libiconv/lib"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(OutDir)/gstdeinterlace.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy /Y $(TargetPath) c:\gstreamer\plugins"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\gstdeinterlace.c">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\gstdeinterlace.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -1,514 +0,0 @@
/* GStreamer simple deinterlacing plugin
* Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) 2006-2008 Tim-Philipp Müller <tim centricular net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
/* based on the Area Based Deinterlacer (for RGB frames) */
/* (a VirtualDub filter) from Gunnar Thalin <guth@home.se> */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "gstdeinterlace.h"
#include <gst/video/video.h>
/**
* SECTION:element-deinterlace
*
* Adaptively deinterlaces video frames by detecting interlacing artifacts.
* An edge detection matrix is used, with a threshold value. Pixels detected
* as 'interlaced' are replaced with pixels blended from the pixels above and
* below.
*
* <refsect2>
* <title>Example launch line</title>
* |[
* gst-launch -v videotestsrc ! deinterlace ! ffmpegcolorspace ! xvimagesink
* ]|
* </refsect2>
*/
GST_DEBUG_CATEGORY_STATIC (deinterlace_debug);
#define GST_CAT_DEFAULT deinterlace_debug
#define DEFAULT_DI_AREA_ONLY FALSE
#define DEFAULT_NI_AREA_ONLY FALSE
#define DEFAULT_BLEND FALSE
#define DEFAULT_DEINTERLACE TRUE
#define DEFAULT_THRESHOLD 20
#define DEFAULT_EDGE_DETECT 25
enum
{
ARG_0,
ARG_DI_ONLY,
ARG_NI_ONLY,
ARG_BLEND,
ARG_THRESHOLD,
ARG_EDGE_DETECT,
ARG_DEINTERLACE
};
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ I420, Y42B }"))
);
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ I420, Y42B }"))
);
GST_BOILERPLATE (GstDeinterlace, gst_deinterlace, GstBaseTransform,
GST_TYPE_BASE_TRANSFORM);
static void gst_deinterlace_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_deinterlace_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstFlowReturn gst_deinterlace_transform_ip (GstBaseTransform * trans,
GstBuffer * buf);
static gboolean gst_deinterlace_stop (GstBaseTransform * trans);
static gboolean gst_deinterlace_set_caps (GstBaseTransform * trans,
GstCaps * incaps, GstCaps * outcaps);
static GstCaps *gst_deinterlace_transform_caps (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * incaps);
static void
gst_deinterlace_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
gst_element_class_set_details_simple (element_class, "Deinterlace",
"Filter/Effect/Video", "Deinterlace video",
"Wim Taymans <wim.taymans@gmail.com>");
}
static void
gst_deinterlace_class_init (GstDeinterlaceClass * klass)
{
GObjectClass *gobject_class;
GstBaseTransformClass *basetransform_class;
gobject_class = (GObjectClass *) klass;
basetransform_class = (GstBaseTransformClass *) klass;
gobject_class->set_property = gst_deinterlace_set_property;
gobject_class->get_property = gst_deinterlace_get_property;
/**
* GstDeinterlace:deinterlace:
*
* Turn processing on/off. When false, no modification of the
* video frames occurs and they pass through intact.
*/
g_object_class_install_property (gobject_class, ARG_DEINTERLACE,
g_param_spec_boolean ("deinterlace", "deinterlace",
"turn deinterlacing on/off", DEFAULT_DEINTERLACE, G_PARAM_READWRITE));
/**
* GstDeinterlace:di-area-only:
*
* When set to true, only areas affected by the deinterlacing are output,
* making it easy to see which regions are being modified.
*
* See Also: #GstDeinterlace:ni-area-only
*/
g_object_class_install_property (gobject_class, ARG_DI_ONLY,
g_param_spec_boolean ("di-area-only", "di-area-only",
"displays deinterlaced areas only", DEFAULT_DI_AREA_ONLY,
G_PARAM_READWRITE));
/**
* GstDeinterlace:ni-area-only:
*
* When set to true, only areas unaffected by the deinterlacing are output,
* making it easy to see which regions are being preserved intact.
*
* See Also: #GstDeinterlace:di-area-only
*/
g_object_class_install_property (gobject_class, ARG_NI_ONLY,
g_param_spec_boolean ("ni-area-only", "ni-area-only",
"displays non-interlaced areas only", DEFAULT_DI_AREA_ONLY,
G_PARAM_READWRITE));
/**
* GstDeinterlace:blend:
*
* Change the blending for pixels which are detected as
* 'interlacing artifacts'. When true, the output pixel is a weighted
* average (1,2,1) of the pixel and the pixels above and below it.
* When false, the odd field lines are preserved, and the even field lines
* are averaged from the surrounding pixels above and below (the odd field).
*/
g_object_class_install_property (gobject_class, ARG_BLEND,
g_param_spec_boolean ("blend", "blend", "blend", DEFAULT_BLEND,
G_PARAM_READWRITE));
/**
* GstDeinterlace:threshold:
*
* Affects the threshold of the edge-detection function used for detecting
* interlacing artifacts.
*/
g_object_class_install_property (gobject_class, ARG_THRESHOLD,
g_param_spec_int ("threshold", "Edge-detection threshold",
"Threshold value for the interlacing artifacts in the output "
"of the edge detection", G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
/**
* GstDeinterlace:edge-detect:
*
* Affects the weighting of the edge-detection function used for detecting
* interlacing artifacts.
*/
g_object_class_install_property (gobject_class, ARG_EDGE_DETECT,
g_param_spec_int ("edge-detect", "edge detection weighting",
"Weighting value used for calculating the edge detection matrix",
G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
basetransform_class->transform_ip =
GST_DEBUG_FUNCPTR (gst_deinterlace_transform_ip);
basetransform_class->transform_caps =
GST_DEBUG_FUNCPTR (gst_deinterlace_transform_caps);
basetransform_class->stop = GST_DEBUG_FUNCPTR (gst_deinterlace_stop);
basetransform_class->set_caps = GST_DEBUG_FUNCPTR (gst_deinterlace_set_caps);
}
static void
gst_deinterlace_init (GstDeinterlace * filter, GstDeinterlaceClass * klass)
{
filter->show_deinterlaced_area_only = DEFAULT_DI_AREA_ONLY;
filter->show_noninterlaced_area_only = DEFAULT_NI_AREA_ONLY;
filter->blend = DEFAULT_BLEND;
filter->deinterlace = DEFAULT_DEINTERLACE;
filter->threshold = DEFAULT_THRESHOLD;
filter->edge_detect = DEFAULT_EDGE_DETECT;
/*filter->threshold_blend = 0; */
filter->src = NULL;
filter->picsize = 0;
}
static gboolean
gst_deinterlace_stop (GstBaseTransform * trans)
{
GstDeinterlace *filter;
filter = GST_DEINTERLACE (trans);
g_free (filter->src);
filter->src = NULL;
filter->picsize = 0;
filter->width = 0;
filter->height = 0;
return TRUE;
}
static GstCaps *
gst_deinterlace_transform_caps (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * incaps)
{
return gst_caps_ref (incaps);
}
static gboolean
gst_deinterlace_set_caps (GstBaseTransform * trans, GstCaps * incaps,
GstCaps * outcaps)
{
GstDeinterlace *filter;
GstVideoFormat fmt;
GstStructure *s;
guint32 fourcc;
gint picsize, w, h;
filter = GST_DEINTERLACE (trans);
g_assert (gst_caps_is_equal_fixed (incaps, outcaps));
s = gst_caps_get_structure (incaps, 0);
if (!gst_structure_get_int (s, "width", &w) ||
!gst_structure_get_int (s, "height", &h) ||
!gst_structure_get_fourcc (s, "format", &fourcc)) {
return FALSE;
}
filter->width = w;
filter->height = h;
filter->fourcc = fourcc;
GST_DEBUG_OBJECT (filter, "width x height = %d x %d, fourcc: %"
GST_FOURCC_FORMAT, w, h, GST_FOURCC_ARGS (fourcc));
fmt = gst_video_format_from_fourcc (fourcc);
filter->y_stride = gst_video_format_get_row_stride (fmt, 0, w);
filter->u_stride = gst_video_format_get_row_stride (fmt, 1, w);
filter->v_stride = gst_video_format_get_row_stride (fmt, 2, w);
filter->uv_height = gst_video_format_get_component_height (fmt, 1, h);
filter->y_off = gst_video_format_get_component_offset (fmt, 0, w, h);
filter->u_off = gst_video_format_get_component_offset (fmt, 1, w, h);
filter->v_off = gst_video_format_get_component_offset (fmt, 2, w, h);
picsize = gst_video_format_get_size (fmt, w, h);
if (filter->picsize != picsize) {
filter->picsize = picsize;
g_free (filter->src); /* free + alloc avoids memcpy */
filter->src = g_malloc0 (filter->picsize);
GST_LOG_OBJECT (filter, "temp buffer size %d", filter->picsize);
}
return TRUE;
}
static GstFlowReturn
gst_deinterlace_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
{
GstDeinterlace *filter;
gboolean bShowDeinterlacedAreaOnly;
gboolean bShowNoninterlacedAreaOnly;
gint y0, y1, y2, y3;
guchar *psrc1, *pdst1, *yuvptr, *src;
gint iInterlaceValue0, iInterlaceValue1, iInterlaceValue2;
gint x, y, p;
gint y_line;
guchar *y_dst, *y_src;
guchar fill_value;
gboolean bBlend;
gboolean bDeinterlace;
gint iThreshold;
gint iEdgeDetect;
gint width, height;
/* g_assert (gst_buffer_is_writable (buf)); */
filter = GST_DEINTERLACE (trans);
GST_OBJECT_LOCK (filter);
bBlend = filter->blend;
bDeinterlace = filter->deinterlace;
iThreshold = filter->threshold;
iEdgeDetect = filter->edge_detect;
bShowDeinterlacedAreaOnly = filter->show_deinterlaced_area_only;
bShowNoninterlacedAreaOnly = filter->show_noninterlaced_area_only;
GST_OBJECT_UNLOCK (filter);
src = filter->src;
yuvptr = GST_BUFFER_DATA (buf);
memcpy (filter->src, yuvptr, filter->picsize);
iThreshold = iThreshold * iThreshold * 4;
/* We don't want an integer overflow in the interlace calculation. */
if (iEdgeDetect > 180)
iEdgeDetect = 180;
iEdgeDetect = iEdgeDetect * iEdgeDetect;
for (p = 0; p < 3; p++) {
switch (p) {
case 0:
y_dst = yuvptr + filter->y_off; /* dst y pointer */
y_line = filter->y_stride;
y_src = src + filter->y_off;
width = filter->width;
height = filter->height;
fill_value = 0;
break;
case 1:
y_dst = yuvptr + filter->u_off; /* dst U pointer */
y_line = filter->u_stride;
y_src = src + filter->u_off;
width = filter->width / 2;
height = filter->uv_height;
fill_value = 128;
break;
case 2:
y_dst = yuvptr + filter->v_off; /* dst V pointer */
y_line = filter->v_stride;
y_src = src + filter->v_off;
width = filter->width / 2;
height = filter->uv_height;
fill_value = 128;
break;
default:
g_assert_not_reached ();
break;
}
for (x = 0; x < width; x++) {
pdst1 = y_dst + x;
psrc1 = y_src + x;
iInterlaceValue1 = iInterlaceValue2 = 0;
for (y = 0; y < height; y++, psrc1 += y_line, pdst1 += y_line) {
/* current line is 1 */
y0 = y1 = y2 = y3 = *psrc1;
if (y > 0)
y0 = *(psrc1 - y_line);
if (y < (height - 1))
y2 = *(psrc1 + y_line);
if (y < (height - 2))
y3 = *(psrc1 + 2 * y_line);
iInterlaceValue0 = iInterlaceValue1;
iInterlaceValue1 = iInterlaceValue2;
if (y < height - 1)
iInterlaceValue2 =
(ABS (y1 - y2) * ABS (y3 - y2) - ((iEdgeDetect * (y1 - y3) * (y1 -
y3)) >> 12)) * 10;
else
iInterlaceValue2 = 0;
if ((iInterlaceValue0 + 2 * iInterlaceValue1 + iInterlaceValue2 >
iThreshold) && (y > 0)) {
if (bShowNoninterlacedAreaOnly) {
*pdst1 = fill_value; /* blank the point and so the interlac area */
} else {
if (bDeinterlace) {
if (bBlend) {
*pdst1 = (unsigned char) ((y0 + 2 * y1 + y2) >> 2);
} else {
/* this method seems to work better than blending if the */
/* quality is pretty bad and the half pics don't fit together */
if ((y % 2) == 1) { /* if odd simply copy the value */
*pdst1 = *psrc1;
} else { /* if even interpolate the line (upper + lower)/2 */
*pdst1 = (unsigned char) ((y0 + y2) >> 1);
}
}
} else {
*pdst1 = *psrc1;
}
}
} else {
/* so we went below the treshold and therefore we don't have to */
/* change anything */
if (bShowDeinterlacedAreaOnly) {
/* this is for testing to see how we should tune the treshhold */
/* and shows as the things that haven't change because the */
/* threshold was to low?? (or shows that everything is ok :-) */
*pdst1 = fill_value; /* blank the point and so the non-interlac area */
} else {
*pdst1 = *psrc1;
}
}
}
}
}
return GST_FLOW_OK;
}
static void
gst_deinterlace_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstDeinterlace *filter;
filter = GST_DEINTERLACE (object);
GST_OBJECT_LOCK (filter);
switch (prop_id) {
case ARG_DEINTERLACE:
filter->deinterlace = g_value_get_boolean (value);
break;
case ARG_DI_ONLY:
filter->show_deinterlaced_area_only = g_value_get_boolean (value);
break;
case ARG_NI_ONLY:
filter->show_noninterlaced_area_only = g_value_get_boolean (value);
break;
case ARG_BLEND:
filter->blend = g_value_get_boolean (value);
break;
case ARG_THRESHOLD:
filter->threshold = g_value_get_int (value);
break;
case ARG_EDGE_DETECT:
filter->edge_detect = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
GST_OBJECT_UNLOCK (filter);
}
static void
gst_deinterlace_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstDeinterlace *filter;
filter = GST_DEINTERLACE (object);
GST_OBJECT_LOCK (filter);
switch (prop_id) {
case ARG_DEINTERLACE:
g_value_set_boolean (value, filter->deinterlace);
break;
case ARG_DI_ONLY:
g_value_set_boolean (value, filter->show_deinterlaced_area_only);
break;
case ARG_NI_ONLY:
g_value_set_boolean (value, filter->show_noninterlaced_area_only);
break;
case ARG_BLEND:
g_value_set_boolean (value, filter->blend);
break;
case ARG_THRESHOLD:
g_value_set_int (value, filter->threshold);
break;
case ARG_EDGE_DETECT:
g_value_set_int (value, filter->edge_detect);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
GST_OBJECT_UNLOCK (filter);
}
static gboolean
plugin_init (GstPlugin * plugin)
{
GST_DEBUG_CATEGORY_INIT (deinterlace_debug, "deinterlace", 0,
"deinterlace element");
if (!gst_element_register (plugin, "deinterlace", GST_RANK_NONE,
gst_deinterlace_get_type ()))
return FALSE;
return TRUE;
}
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstinterlace",
"Deinterlace video", plugin_init, PACKAGE_VERSION, "LGPL", GST_PACKAGE_NAME,
GST_PACKAGE_ORIGIN);

View file

@ -1,74 +0,0 @@
/* GStreamer simple deinterlacing plugin
* Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
#ifndef __GST_DEINTERLACE_H__
#define __GST_DEINTERLACE_H__
#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
G_BEGIN_DECLS
#define GST_TYPE_DEINTERLACE (gst_deinterlace_get_type())
#define GST_DEINTERLACE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DEINTERLACE,GstDeinterlace))
#define GST_DEINTERLACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DEINTERLACE,GstDeinterlaceClass))
#define GST_IS_DEINTERLACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DEINTERLACE))
#define GST_IS_DEINTERLACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DEINTERLACE))
typedef struct _GstDeinterlace GstDeinterlace;
typedef struct _GstDeinterlaceClass GstDeinterlaceClass;
struct _GstDeinterlace {
GstBaseTransform basetransform;
/*< private >*/
gint width;
gint height;
gint uv_height;
guint32 fourcc;
gboolean show_deinterlaced_area_only;
gboolean show_noninterlaced_area_only;
gboolean blend;
gboolean deinterlace;
gint threshold_blend; /* here we start blending */
gint threshold; /* here we start interpolating TODO FIXME */
gint edge_detect;
gint picsize;
gint y_stride;
gint u_stride;
gint v_stride;
gint y_off;
gint u_off;
gint v_off;
guchar *src;
};
struct _GstDeinterlaceClass {
GstBaseTransformClass basetransformclass;
};
GType gst_deinterlace_get_type (void);
G_END_DECLS
#endif /* __GST_DEINTERLACE_H__ */

View file

@ -1,48 +0,0 @@
plugin_LTLIBRARIES = libgstdeinterlace2.la
libgstdeinterlace2_la_SOURCES = \
gstdeinterlace2.c \
tvtime/greedy.c \
tvtime/greedyh.c \
tvtime/vfir.c \
tvtime/tomsmocomp.c \
tvtime/weavetff.c \
tvtime/weavebff.c \
tvtime/weave.c \
tvtime/linear.c \
tvtime/linearblend.c \
tvtime/scalerbob.c
libgstdeinterlace2_la_CFLAGS = $(GST_CFLAGS) \
$(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(LIBOIL_CFLAGS)
libgstdeinterlace2_la_LIBADD = $(GST_LIBS) \
$(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) $(GST_BASE_LIBS) $(LIBOIL_LIBS)
libgstdeinterlace2_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstdeinterlace2_la_LIBTOOLFLAGS = --tag=disable-static
noinst_HEADERS = \
gstdeinterlace2.h \
tvtime/mmx.h \
tvtime/sse.h \
tvtime/greedyh.asm \
tvtime/greedyhmacros.h \
tvtime/plugins.h \
tvtime/x86-64_macros.inc \
tvtime/tomsmocomp/SearchLoop0A.inc \
tvtime/tomsmocomp/SearchLoopBottom.inc \
tvtime/tomsmocomp/SearchLoopEdgeA8.inc \
tvtime/tomsmocomp/SearchLoopEdgeA.inc \
tvtime/tomsmocomp/SearchLoopOddA2.inc \
tvtime/tomsmocomp/SearchLoopOddA6.inc \
tvtime/tomsmocomp/SearchLoopOddAH2.inc \
tvtime/tomsmocomp/SearchLoopOddAH.inc \
tvtime/tomsmocomp/SearchLoopOddA.inc \
tvtime/tomsmocomp/SearchLoopTop.inc \
tvtime/tomsmocomp/SearchLoopVAH.inc \
tvtime/tomsmocomp/SearchLoopVA.inc \
tvtime/tomsmocomp/StrangeBob.inc \
tvtime/tomsmocomp/TomsMoCompAll2.inc \
tvtime/tomsmocomp/TomsMoCompAll.inc \
tvtime/tomsmocomp/tomsmocompmacros.h \
tvtime/tomsmocomp/WierdBob.inc

File diff suppressed because it is too large Load diff

View file

@ -1,259 +0,0 @@
/*
* GStreamer
* Copyright (C) 2005 Martin Eikermann <meiker@upb.de>
* Copyright (C) 2008-2009 Sebastian Dröge <slomo@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
#ifndef __GST_DEINTERLACE_2_H__
#define __GST_DEINTERLACE_2_H__
#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
#include <liboil/liboil.h>
#include <liboil/liboilcpu.h>
#include <liboil/liboilfunction.h>
#ifdef HAVE_GCC_ASM
#if defined(HAVE_CPU_I386) || defined(HAVE_CPU_X86_64)
#define BUILD_X86_ASM
#endif
#endif
G_BEGIN_DECLS
#define GST_TYPE_DEINTERLACE2 \
(gst_deinterlace2_get_type())
#define GST_DEINTERLACE2(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DEINTERLACE2,GstDeinterlace2))
#define GST_DEINTERLACE2_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DEINTERLACE2,GstDeinterlace2))
#define GST_IS_DEINTERLACE2(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DEINTERLACE2))
#define GST_IS_DEINTERLACE2_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DEINTERLACE2))
typedef struct _GstDeinterlace2 GstDeinterlace2;
typedef struct _GstDeinterlace2Class GstDeinterlace2Class;
#define GST_TYPE_DEINTERLACE_METHOD (gst_deinterlace_method_get_type ())
#define GST_IS_DEINTERLACE_METHOD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD))
#define GST_IS_DEINTERLACE_METHOD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD))
#define GST_DEINTERLACE_METHOD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD, GstDeinterlaceMethodClass))
#define GST_DEINTERLACE_METHOD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD, GstDeinterlaceMethod))
#define GST_DEINTERLACE_METHOD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD, GstDeinterlaceMethodClass))
#define GST_DEINTERLACE_METHOD_CAST(obj) ((GstDeinterlaceMethod*)(obj))
typedef struct _GstDeinterlaceMethod GstDeinterlaceMethod;
typedef struct _GstDeinterlaceMethodClass GstDeinterlaceMethodClass;
/*
* This structure defines the deinterlacer plugin.
*/
struct _GstDeinterlaceMethod {
GstObject parent;
};
struct _GstDeinterlaceMethodClass {
GstObjectClass parent_class;
guint fields_required;
guint latency;
void (*deinterlace_frame) (GstDeinterlaceMethod *self, GstDeinterlace2 * parent, GstBuffer *outbuf);
const gchar *name;
const gchar *nick;
};
GType gst_deinterlace_method_get_type (void);
#define GST_TYPE_DEINTERLACE_SIMPLE_METHOD (gst_deinterlace_simple_method_get_type ())
#define GST_IS_DEINTERLACE_SIMPLE_METHOD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_SIMPLE_METHOD))
#define GST_IS_DEINTERLACE_SIMPLE_METHOD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_SIMPLE_METHOD))
#define GST_DEINTERLACE_SIMPLE_METHOD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_SIMPLE_METHOD, GstDeinterlaceSimpleMethodClass))
#define GST_DEINTERLACE_SIMPLE_METHOD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_SIMPLE_METHOD, GstDeinterlaceSimpleMethod))
#define GST_DEINTERLACE_SIMPLE_METHOD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_SIMPLE_METHOD, GstDeinterlaceSimpleMethodClass))
#define GST_DEINTERLACE_SIMPLE_METHOD_CAST(obj) ((GstDeinterlaceSimpleMethod*)(obj))
typedef struct _GstDeinterlaceSimpleMethod GstDeinterlaceSimpleMethod;
typedef struct _GstDeinterlaceSimpleMethodClass GstDeinterlaceSimpleMethodClass;
typedef struct _GstDeinterlaceScanlineData GstDeinterlaceScanlineData;
/*
* This structure defines the simple deinterlacer plugin.
*/
struct _GstDeinterlaceScanlineData {
guint8 *tt0, *t0, *m0, *b0, *bb0;
guint8 *tt1, *t1, *m1, *b1, *bb1;
guint8 *tt2, *t2, *m2, *b2, *bb2;
guint8 *tt3, *t3, *m3, *b3, *bb3;
gboolean bottom_field;
};
/**
* For interpolate_scanline the input is:
*
* | t-3 t-2 t-1 t
* | Field 3 | Field 2 | Field 1 | Field 0 |
* | TT3 | | TT1 | |
* | | T2 | | T0 |
* | M3 | | M1 | |
* | | B2 | | B0 |
* | BB3 | | BB1 | |
*
* For copy_scanline the input is:
*
* | t-3 t-2 t-1 t
* | Field 3 | Field 2 | Field 1 | Field 0 |
* | | TT2 | | TT0 |
* | T3 | | T1 | |
* | | M2 | | M0 |
* | B3 | | B1 | |
* | | BB2 | | BB0 |
*
* All other values are NULL.
*/
struct _GstDeinterlaceSimpleMethod {
GstDeinterlaceMethod parent;
};
struct _GstDeinterlaceSimpleMethodClass {
GstDeinterlaceMethodClass parent_class;
void (*interpolate_scanline) (GstDeinterlaceMethod *self, GstDeinterlace2 * parent, guint8 *out, GstDeinterlaceScanlineData *scanlines, gint width);
void (*copy_scanline) (GstDeinterlaceMethod *self, GstDeinterlace2 * parent, guint8 *out, GstDeinterlaceScanlineData *scanlines, gint width);
};
GType gst_deinterlace_simple_method_get_type (void);
#define MAX_FIELD_HISTORY 10
#define PICTURE_PROGRESSIVE 0
#define PICTURE_INTERLACED_BOTTOM 1
#define PICTURE_INTERLACED_TOP 2
#define PICTURE_INTERLACED_MASK (PICTURE_INTERLACED_BOTTOM | PICTURE_INTERLACED_TOP)
typedef struct
{
/* pointer to the start of data for this field */
GstBuffer *buf;
/* see PICTURE_ flags */
guint flags;
} GstPicture;
typedef enum
{
GST_DEINTERLACE2_TOMSMOCOMP,
GST_DEINTERLACE2_GREEDY_H,
GST_DEINTERLACE2_GREEDY_L,
GST_DEINTERLACE2_VFIR,
GST_DEINTERLACE2_LINEAR,
GST_DEINTERLACE2_LINEAR_BLEND,
GST_DEINTERLACE2_SCALER_BOB,
GST_DEINTERLACE2_WEAVE,
GST_DEINTERLACE2_WEAVE_TFF,
GST_DEINTERLACE2_WEAVE_BFF
} GstDeinterlace2Methods;
typedef enum
{
GST_DEINTERLACE2_ALL, /* All (missing data is interp.) */
GST_DEINTERLACE2_TF, /* Top Fields Only */
GST_DEINTERLACE2_BF /* Bottom Fields Only */
} GstDeinterlace2Fields;
typedef enum
{
GST_DEINTERLACE2_LAYOUT_AUTO,
GST_DEINTERLACE2_LAYOUT_TFF,
GST_DEINTERLACE2_LAYOUT_BFF
} GstDeinterlace2FieldLayout;
typedef enum {
GST_DEINTERLACE2_MODE_AUTO,
GST_DEINTERLACE2_MODE_INTERLACED,
GST_DEINTERLACE2_MODE_DISABLED
} GstDeinterlace2Mode;
struct _GstDeinterlace2
{
GstElement parent;
GstPad *srcpad, *sinkpad;
/* <private> */
GstDeinterlace2Mode mode;
GstDeinterlace2FieldLayout field_layout;
guint frame_size;
gint frame_rate_n, frame_rate_d;
gboolean interlaced;
/* Duration of one field */
GstClockTime field_duration;
GstDeinterlace2Fields fields;
GstDeinterlace2Methods method_id;
GstDeinterlaceMethod *method;
/* The most recent pictures
PictureHistory[0] is always the most recent.
Pointers are NULL if the picture in question isn't valid, e.g. because
the program just started or a picture was skipped.
*/
GstPicture field_history[MAX_FIELD_HISTORY];
guint history_count;
/* Number of bytes of actual data in each scanline. May be less than
OverlayPitch since the overlay's scanlines might have alignment
requirements. Generally equal to FrameWidth * 2.
*/
guint row_stride;
/* Number of pixels in each scanline. */
gint frame_width;
/* Number of scanlines per frame. */
gint frame_height;
/* Number of scanlines per field. FrameHeight / 2, mostly for
cleanliness so we don't have to keep dividing FrameHeight by 2.
*/
gint field_height;
/* distance between lines in image
need not match the pixel width
*/
guint field_stride;
};
struct _GstDeinterlace2Class
{
GstElementClass parent_class;
};
GType gst_deinterlace2_get_type (void);
G_END_DECLS
#endif /* __GST_DEINTERLACE_2_H__ */

View file

@ -1,488 +0,0 @@
/*
*
* GStreamer
* Copyright (c) 2000 Tom Barry All rights reserved.
* mmx.h port copyright (c) 2002 Billy Biggs <vektor@dumbterm.net>.
*
* Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
/*
* Relicensed for GStreamer from GPL to LGPL with permit from Tom Barry
* and Billy Biggs.
* See: http://bugzilla.gnome.org/show_bug.cgi?id=163578
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "_stdint.h"
#include "gstdeinterlace2.h"
#include <string.h>
#define GST_TYPE_DEINTERLACE_METHOD_GREEDY_L (gst_deinterlace_method_greedy_l_get_type ())
#define GST_IS_DEINTERLACE_METHOD_GREEDY_L(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_L))
#define GST_IS_DEINTERLACE_METHOD_GREEDY_L_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_GREEDY_L))
#define GST_DEINTERLACE_METHOD_GREEDY_L_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_L, GstDeinterlaceMethodGreedyLClass))
#define GST_DEINTERLACE_METHOD_GREEDY_L(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_L, GstDeinterlaceMethodGreedyL))
#define GST_DEINTERLACE_METHOD_GREEDY_L_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_GREEDY_L, GstDeinterlaceMethodGreedyLClass))
#define GST_DEINTERLACE_METHOD_GREEDY_L_CAST(obj) ((GstDeinterlaceMethodGreedyL*)(obj))
GType gst_deinterlace_method_greedy_l_get_type (void);
typedef struct
{
GstDeinterlaceMethod parent;
guint max_comb;
} GstDeinterlaceMethodGreedyL;
typedef struct
{
GstDeinterlaceMethodClass parent_class;
void (*scanline) (GstDeinterlaceMethodGreedyL * self, uint8_t * L2,
uint8_t * L1, uint8_t * L3, uint8_t * L2P, uint8_t * Dest, int size);
} GstDeinterlaceMethodGreedyLClass;
// This is a simple lightweight DeInterlace method that uses little CPU time
// but gives very good results for low or intermedite motion.
// It defers frames by one field, but that does not seem to produce noticeable
// lip sync problems.
//
// The method used is to take either the older or newer weave pixel depending
// upon which give the smaller comb factor, and then clip to avoid large damage
// when wrong.
//
// I'd intended this to be part of a larger more elaborate method added to
// Blended Clip but this give too good results for the CPU to ignore here.
static inline void
deinterlace_greedy_packed422_scanline_c (GstDeinterlaceMethodGreedyL * self,
uint8_t * m0, uint8_t * t1,
uint8_t * b1, uint8_t * m2, uint8_t * output, int width)
{
int avg, l2_diff, lp2_diff, max, min, best;
guint max_comb = self->max_comb;
// L2 == m0
// L1 == t1
// L3 == b1
// LP2 == m2
while (width--) {
avg = (*t1 + *b1) / 2;
l2_diff = ABS (*m0 - avg);
lp2_diff = ABS (*m2 - avg);
if (l2_diff > lp2_diff)
best = *m2;
else
best = *m0;
max = MAX (*t1, *b1);
min = MIN (*t1, *b1);
if (max < 256 - max_comb)
max += max_comb;
else
max = 255;
if (min > max_comb)
min -= max_comb;
else
min = 0;
*output = CLAMP (best, min, max);
// Advance to the next set of pixels.
output += 1;
m0 += 1;
t1 += 1;
b1 += 1;
m2 += 1;
}
}
#ifdef BUILD_X86_ASM
#include "mmx.h"
static void
deinterlace_greedy_packed422_scanline_mmx (GstDeinterlaceMethodGreedyL * self,
uint8_t * m0, uint8_t * t1,
uint8_t * b1, uint8_t * m2, uint8_t * output, int width)
{
mmx_t MaxComb;
mmx_t ShiftMask;
// How badly do we let it weave? 0-255
MaxComb.ub[0] = self->max_comb;
MaxComb.ub[1] = self->max_comb;
MaxComb.ub[2] = self->max_comb;
MaxComb.ub[3] = self->max_comb;
MaxComb.ub[4] = self->max_comb;
MaxComb.ub[5] = self->max_comb;
MaxComb.ub[6] = self->max_comb;
MaxComb.ub[7] = self->max_comb;
ShiftMask.ub[0] = 0x7f;
ShiftMask.ub[1] = 0x7f;
ShiftMask.ub[2] = 0x7f;
ShiftMask.ub[3] = 0x7f;
ShiftMask.ub[4] = 0x7f;
ShiftMask.ub[5] = 0x7f;
ShiftMask.ub[6] = 0x7f;
ShiftMask.ub[7] = 0x7f;
// L2 == m0
// L1 == t1
// L3 == b1
// LP2 == m2
movq_m2r (MaxComb, mm6);
for (; width > 7; width -= 8) {
movq_m2r (*t1, mm1); // L1
movq_m2r (*m0, mm2); // L2
movq_m2r (*b1, mm3); // L3
movq_m2r (*m2, mm0); // LP2
// average L1 and L3 leave result in mm4
movq_r2r (mm1, mm4); // L1
movq_r2r (mm3, mm5); // L3
psrlw_i2r (1, mm4); // L1/2
pand_m2r (ShiftMask, mm4);
psrlw_i2r (1, mm5); // L3/2
pand_m2r (ShiftMask, mm5);
paddusb_r2r (mm5, mm4); // (L1 + L3) / 2
// get abs value of possible L2 comb
movq_r2r (mm2, mm7); // L2
psubusb_r2r (mm4, mm7); // L2 - avg
movq_r2r (mm4, mm5); // avg
psubusb_r2r (mm2, mm5); // avg - L2
por_r2r (mm7, mm5); // abs(avg-L2)
// get abs value of possible LP2 comb
movq_r2r (mm0, mm7); // LP2
psubusb_r2r (mm4, mm7); // LP2 - avg
psubusb_r2r (mm0, mm4); // avg - LP2
por_r2r (mm7, mm4); // abs(avg-LP2)
// use L2 or LP2 depending upon which makes smaller comb
psubusb_r2r (mm5, mm4); // see if it goes to zero
psubusb_r2r (mm5, mm5); // 0
pcmpeqb_r2r (mm5, mm4); // if (mm4=0) then FF else 0
pcmpeqb_r2r (mm4, mm5); // opposite of mm4
// if Comb(LP2) <= Comb(L2) then mm4=ff, mm5=0 else mm4=0, mm5 = 55
pand_r2r (mm2, mm5); // use L2 if mm5 == ff, else 0
pand_r2r (mm0, mm4); // use LP2 if mm4 = ff, else 0
por_r2r (mm5, mm4); // may the best win
// Now lets clip our chosen value to be not outside of the range
// of the high/low range L1-L3 by more than abs(L1-L3)
// This allows some comb but limits the damages and also allows more
// detail than a boring oversmoothed clip.
movq_r2r (mm1, mm2); // copy L1
psubusb_r2r (mm3, mm2); // - L3, with saturation
paddusb_r2r (mm3, mm2); // now = Max(L1,L3)
pcmpeqb_r2r (mm7, mm7); // all ffffffff
psubusb_r2r (mm1, mm7); // - L1
paddusb_r2r (mm7, mm3); // add, may sat at fff..
psubusb_r2r (mm7, mm3); // now = Min(L1,L3)
// allow the value to be above the high or below the low by amt of MaxComb
paddusb_r2r (mm6, mm2); // increase max by diff
psubusb_r2r (mm6, mm3); // lower min by diff
psubusb_r2r (mm3, mm4); // best - Min
paddusb_r2r (mm3, mm4); // now = Max(best,Min(L1,L3)
pcmpeqb_r2r (mm7, mm7); // all ffffffff
psubusb_r2r (mm4, mm7); // - Max(best,Min(best,L3)
paddusb_r2r (mm7, mm2); // add may sat at FFF..
psubusb_r2r (mm7, mm2); // now = Min( Max(best, Min(L1,L3), L2 )=L2 clipped
movq_r2m (mm2, *output); // move in our clipped best
// Advance to the next set of pixels.
output += 8;
m0 += 8;
t1 += 8;
b1 += 8;
m2 += 8;
}
emms ();
if (width > 0)
deinterlace_greedy_packed422_scanline_c (self, m0, t1, b1, m2, output,
width);
}
#include "sse.h"
static void
deinterlace_greedy_packed422_scanline_mmxext (GstDeinterlaceMethodGreedyL *
self, uint8_t * m0, uint8_t * t1, uint8_t * b1, uint8_t * m2,
uint8_t * output, int width)
{
mmx_t MaxComb;
// How badly do we let it weave? 0-255
MaxComb.ub[0] = self->max_comb;
MaxComb.ub[1] = self->max_comb;
MaxComb.ub[2] = self->max_comb;
MaxComb.ub[3] = self->max_comb;
MaxComb.ub[4] = self->max_comb;
MaxComb.ub[5] = self->max_comb;
MaxComb.ub[6] = self->max_comb;
MaxComb.ub[7] = self->max_comb;
// L2 == m0
// L1 == t1
// L3 == b1
// LP2 == m2
movq_m2r (MaxComb, mm6);
for (; width > 7; width -= 8) {
movq_m2r (*t1, mm1); // L1
movq_m2r (*m0, mm2); // L2
movq_m2r (*b1, mm3); // L3
movq_m2r (*m2, mm0); // LP2
// average L1 and L3 leave result in mm4
movq_r2r (mm1, mm4); // L1
pavgb_r2r (mm3, mm4); // (L1 + L3)/2
// get abs value of possible L2 comb
movq_r2r (mm2, mm7); // L2
psubusb_r2r (mm4, mm7); // L2 - avg
movq_r2r (mm4, mm5); // avg
psubusb_r2r (mm2, mm5); // avg - L2
por_r2r (mm7, mm5); // abs(avg-L2)
// get abs value of possible LP2 comb
movq_r2r (mm0, mm7); // LP2
psubusb_r2r (mm4, mm7); // LP2 - avg
psubusb_r2r (mm0, mm4); // avg - LP2
por_r2r (mm7, mm4); // abs(avg-LP2)
// use L2 or LP2 depending upon which makes smaller comb
psubusb_r2r (mm5, mm4); // see if it goes to zero
pxor_r2r (mm5, mm5); // 0
pcmpeqb_r2r (mm5, mm4); // if (mm4=0) then FF else 0
pcmpeqb_r2r (mm4, mm5); // opposite of mm4
// if Comb(LP2) <= Comb(L2) then mm4=ff, mm5=0 else mm4=0, mm5 = 55
pand_r2r (mm2, mm5); // use L2 if mm5 == ff, else 0
pand_r2r (mm0, mm4); // use LP2 if mm4 = ff, else 0
por_r2r (mm5, mm4); // may the best win
// Now lets clip our chosen value to be not outside of the range
// of the high/low range L1-L3 by more than abs(L1-L3)
// This allows some comb but limits the damages and also allows more
// detail than a boring oversmoothed clip.
movq_r2r (mm1, mm2); // copy L1
pmaxub_r2r (mm3, mm2); // now = Max(L1,L3)
pminub_r2r (mm1, mm3); // now = Min(L1,L3)
// allow the value to be above the high or below the low by amt of MaxComb
paddusb_r2r (mm6, mm2); // increase max by diff
psubusb_r2r (mm6, mm3); // lower min by diff
pmaxub_r2r (mm3, mm4); // now = Max(best,Min(L1,L3)
pminub_r2r (mm4, mm2); // now = Min( Max(best, Min(L1,L3)), L2 )=L2 clipped
movq_r2m (mm2, *output); // move in our clipped best
// Advance to the next set of pixels.
output += 8;
m0 += 8;
t1 += 8;
b1 += 8;
m2 += 8;
}
emms ();
if (width > 0)
deinterlace_greedy_packed422_scanline_c (self, m0, t1, b1, m2, output,
width);
}
#endif
static void
deinterlace_frame_di_greedy (GstDeinterlaceMethod * d_method,
GstDeinterlace2 * object, GstBuffer * outbuf)
{
GstDeinterlaceMethodGreedyL *self =
GST_DEINTERLACE_METHOD_GREEDY_L (d_method);
GstDeinterlaceMethodGreedyLClass *klass =
GST_DEINTERLACE_METHOD_GREEDY_L_GET_CLASS (self);
int InfoIsOdd = 0;
int Line;
unsigned int Pitch = object->field_stride;
unsigned char *L1; // ptr to Line1, of 3
unsigned char *L2; // ptr to Line2, the weave line
unsigned char *L3; // ptr to Line3
unsigned char *L2P; // ptr to prev Line2
unsigned char *Dest = GST_BUFFER_DATA (outbuf);
// copy first even line no matter what, and the first odd line if we're
// processing an EVEN field. (note diff from other deint rtns.)
if (object->field_history[object->history_count - 1].flags ==
PICTURE_INTERLACED_BOTTOM) {
InfoIsOdd = 1;
L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
L2 = GST_BUFFER_DATA (object->field_history[object->history_count - 1].buf);
L3 = L1 + Pitch;
L2P =
GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf);
// copy first even line
oil_memcpy (Dest, L1, object->row_stride);
Dest += object->row_stride;
} else {
InfoIsOdd = 0;
L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
L2 = GST_BUFFER_DATA (object->field_history[object->history_count -
1].buf) + Pitch;
L3 = L1 + Pitch;
L2P =
GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf) +
Pitch;
// copy first even line
oil_memcpy (Dest, GST_BUFFER_DATA (object->field_history[0].buf),
object->row_stride);
Dest += object->row_stride;
// then first odd line
oil_memcpy (Dest, L1, object->row_stride);
Dest += object->row_stride;
}
for (Line = 0; Line < (object->field_height - 1); ++Line) {
klass->scanline (self, L2, L1, L3, L2P, Dest, object->row_stride);
Dest += object->row_stride;
oil_memcpy (Dest, L3, object->row_stride);
Dest += object->row_stride;
L1 += Pitch;
L2 += Pitch;
L3 += Pitch;
L2P += Pitch;
}
if (InfoIsOdd) {
oil_memcpy (Dest, L2, object->row_stride);
}
}
G_DEFINE_TYPE (GstDeinterlaceMethodGreedyL, gst_deinterlace_method_greedy_l,
GST_TYPE_DEINTERLACE_METHOD);
enum
{
ARG_0,
ARG_MAX_COMB
};
static void
gst_deinterlace_method_greedy_l_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstDeinterlaceMethodGreedyL *self = GST_DEINTERLACE_METHOD_GREEDY_L (object);
switch (prop_id) {
case ARG_MAX_COMB:
self->max_comb = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gst_deinterlace_method_greedy_l_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstDeinterlaceMethodGreedyL *self = GST_DEINTERLACE_METHOD_GREEDY_L (object);
switch (prop_id) {
case ARG_MAX_COMB:
g_value_set_uint (value, self->max_comb);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gst_deinterlace_method_greedy_l_class_init (GstDeinterlaceMethodGreedyLClass *
klass)
{
GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
GObjectClass *gobject_class = (GObjectClass *) klass;
#ifdef BUILD_X86_ASM
guint cpu_flags = oil_cpu_get_flags ();
#endif
gobject_class->set_property = gst_deinterlace_method_greedy_l_set_property;
gobject_class->get_property = gst_deinterlace_method_greedy_l_get_property;
g_object_class_install_property (gobject_class, ARG_MAX_COMB,
g_param_spec_uint ("max-comb",
"Max comb",
"Max Comb", 0, 255, 15, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
);
dim_class->fields_required = 4;
dim_class->deinterlace_frame = deinterlace_frame_di_greedy;
dim_class->name = "Motion Adaptive: Simple Detection";
dim_class->nick = "greedyl";
dim_class->latency = 1;
#ifdef BUILD_X86_ASM
if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) {
klass->scanline = deinterlace_greedy_packed422_scanline_mmxext;
} else if (cpu_flags & OIL_IMPL_FLAG_MMX) {
klass->scanline = deinterlace_greedy_packed422_scanline_mmx;
} else {
klass->scanline = deinterlace_greedy_packed422_scanline_c;
}
#else
klass->scanline = deinterlace_greedy_packed422_scanline_c;
#endif
}
static void
gst_deinterlace_method_greedy_l_init (GstDeinterlaceMethodGreedyL * self)
{
self->max_comb = 15;
}

View file

@ -1,250 +0,0 @@
/*
*
* GStreamer
* Copyright (c) 2001 Tom Barry. All rights reserved.
* Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
/*
* Relicensed for GStreamer from GPL to LGPL with permit from Tom Barry.
* See: http://bugzilla.gnome.org/show_bug.cgi?id=163578
*/
#include "x86-64_macros.inc"
void
FUNCT_NAME (GstDeinterlaceMethodGreedyH *self, uint8_t * L1, uint8_t * L2, uint8_t * L3, uint8_t * L2P,
uint8_t * Dest, int size)
{
// in tight loop some vars are accessed faster in local storage
int64_t YMask = 0x00ff00ff00ff00ffull; // to keep only luma
int64_t UVMask = 0xff00ff00ff00ff00ull; // to keep only chroma
int64_t ShiftMask = 0xfefefefefefefefeull; // to avoid shifting chroma to luma
int64_t QW256 = 0x0100010001000100ull; // 4 256's
int64_t MaxComb;
int64_t MotionThreshold;
int64_t MotionSense;
int64_t i;
long LoopCtr;
long oldbx;
int64_t QW256B;
int64_t LastAvg = 0; //interp value from left qword
// FIXME: Use C implementation if the width is not a multiple of 4
// Do something more optimal later
if (size % 8 != 0)
greedyDScaler_C (self, L1, L2, L3, L2P, Dest, size);
// Set up our two parms that are actually evaluated for each pixel
i = self->max_comb;
MaxComb =
i << 56 | i << 48 | i << 40 | i << 32 | i << 24 | i << 16 | i << 8 | i;
i = self->motion_threshold; // scale to range of 0-257
MotionThreshold = i << 48 | i << 32 | i << 16 | i | UVMask;
i = self->motion_sense; // scale to range of 0-257
MotionSense = i << 48 | i << 32 | i << 16 | i;
i = 0xffffffff - 256;
QW256B = i << 48 | i << 32 | i << 16 | i; // save a couple instr on PMINSW instruct.
LoopCtr = size / 8 - 1; // there are LineLength / 8 qwords per line but do 1 less, adj at end of loop
// For ease of reading, the comments below assume that we're operating on an odd
// field (i.e., that InfoIsOdd is true). Assume the obvious for even lines..
__asm__ __volatile__ (
// save ebx (-fPIC)
MOVX " %%" XBX ", %[oldbx]\n\t"
MOVX " %[L1], %%" XAX "\n\t"
LEAX " 8(%%" XAX "), %%" XBX "\n\t" // next qword needed by DJR
MOVX " %[L3], %%" XCX "\n\t"
SUBX " %%" XAX ", %%" XCX "\n\t" // carry L3 addr as an offset
MOVX " %[L2P], %%" XDX "\n\t"
MOVX " %[L2], %%" XSI "\n\t"
MOVX " %[Dest], %%" XDI "\n\t" // DL1 if Odd or DL2 if Even
".align 8\n\t"
"1:\n\t"
"movq (%%" XSI "), %%mm0\n\t" // L2 - the newest weave pixel value
"movq (%%" XAX "), %%mm1\n\t" // L1 - the top pixel
"movq (%%" XDX "), %%mm2\n\t" // L2P - the prev weave pixel
"movq (%%" XAX ", %%" XCX "), %%mm3\n\t" // L3, next odd row
"movq %%mm1, %%mm6\n\t" // L1 - get simple single pixel interp
// pavgb mm6, mm3 // use macro below
V_PAVGB ("%%mm6", "%%mm3", "%%mm4", "%[ShiftMask]")
// DJR - Diagonal Jaggie Reduction
// In the event that we are going to use an average (Bob) pixel we do not want a jagged
// stair step effect. To combat this we avg in the 2 horizontally adjacen pixels into the
// interpolated Bob mix. This will do horizontal smoothing for only the Bob'd pixels.
"movq %[LastAvg], %%mm4\n\t" // the bob value from prev qword in row
"movq %%mm6, %[LastAvg]\n\t" // save for next pass
"psrlq $48, %%mm4\n\t" // right justify 1 pixel
"movq %%mm6, %%mm7\n\t" // copy of simple bob pixel
"psllq $16, %%mm7\n\t" // left justify 3 pixels
"por %%mm7, %%mm4\n\t" // and combine
"movq (%%" XBX "), %%mm5\n\t" // next horiz qword from L1
// pavgb mm5, qword ptr[ebx+ecx] // next horiz qword from L3, use macro below
V_PAVGB ("%%mm5", "(%%" XBX ",%%" XCX ")", "%%mm7", "%[ShiftMask]")
"psllq $48, %%mm5\n\t" // left just 1 pixel
"movq %%mm6, %%mm7\n\t" // another copy of simple bob pixel
"psrlq $16, %%mm7\n\t" // right just 3 pixels
"por %%mm7, %%mm5\n\t" // combine
// pavgb mm4, mm5 // avg of forward and prev by 1 pixel, use macro
V_PAVGB ("%%mm4", "%%mm5", "%%mm5", "%[ShiftMask]") // mm5 gets modified if MMX
// pavgb mm6, mm4 // avg of center and surround interp vals, use macro
V_PAVGB ("%%mm6", "%%mm4", "%%mm7", "%[ShiftMask]")
// Don't do any more averaging than needed for mmx. It hurts performance and causes rounding errors.
#ifndef IS_MMX
// pavgb mm4, mm6 // 1/4 center, 3/4 adjacent
V_PAVGB ("%%mm4", "%%mm6", "%%mm7", "%[ShiftMask]")
// pavgb mm6, mm4 // 3/8 center, 5/8 adjacent
V_PAVGB ("%%mm6", "%%mm4", "%%mm7", "%[ShiftMask]")
#endif
// get abs value of possible L2 comb
"movq %%mm6, %%mm4\n\t" // work copy of interp val
"movq %%mm2, %%mm7\n\t" // L2
"psubusb %%mm4, %%mm7\n\t" // L2 - avg
"movq %%mm4, %%mm5\n\t" // avg
"psubusb %%mm2, %%mm5\n\t" // avg - L2
"por %%mm7, %%mm5\n\t" // abs(avg-L2)
// get abs value of possible L2P comb
"movq %%mm0, %%mm7\n\t" // L2P
"psubusb %%mm4, %%mm7\n\t" // L2P - avg
"psubusb %%mm0, %%mm4\n\t" // avg - L2P
"por %%mm7, %%mm4\n\t" // abs(avg-L2P)
// use L2 or L2P depending upon which makes smaller comb
"psubusb %%mm5, %%mm4\n\t" // see if it goes to zero
"psubusb %%mm5, %%mm5\n\t" // 0
"pcmpeqb %%mm5, %%mm4\n\t" // if (mm4=0) then FF else 0
"pcmpeqb %%mm4, %%mm5\n\t" // opposite of mm4
// if Comb(L2P) <= Comb(L2) then mm4=ff, mm5=0 else mm4=0, mm5 = 55
"pand %%mm2, %%mm5\n\t" // use L2 if mm5 == ff, else 0
"pand %%mm0, %%mm4\n\t" // use L2P if mm4 = ff, else 0
"por %%mm5, %%mm4\n\t" // may the best win
// Inventory: at this point we have the following values:
// mm0 = L2P (or L2)
// mm1 = L1
// mm2 = L2 (or L2P)
// mm3 = L3
// mm4 = the best of L2,L2P weave pixel, base upon comb
// mm6 = the avg interpolated value, if we need to use it
// Let's measure movement, as how much the weave pixel has changed
"movq %%mm2, %%mm7\n\t"
"psubusb %%mm0, %%mm2\n\t"
"psubusb %%mm7, %%mm0\n\t"
"por %%mm2, %%mm0\n\t" // abs value of change, used later
// Now lets clip our chosen value to be not outside of the range
// of the high/low range L1-L3 by more than MaxComb.
// This allows some comb but limits the damages and also allows more
// detail than a boring oversmoothed clip.
"movq %%mm1, %%mm2\n\t" // copy L1
// pmaxub mm2, mm3 // use macro
V_PMAXUB ("%%mm2", "%%mm3") // now = Max(L1,L3)
"movq %%mm1, %%mm5\n\t" // copy L1
// pminub mm5, mm3 // now = Min(L1,L3), use macro
V_PMINUB ("%%mm5", "%%mm3", "%%mm7")
// allow the value to be above the high or below the low by amt of MaxComb
"psubusb %[MaxComb], %%mm5\n\t" // lower min by diff
"paddusb %[MaxComb], %%mm2\n\t" // increase max by diff
// pmaxub mm4, mm5 // now = Max(best,Min(L1,L3) use macro
V_PMAXUB ("%%mm4", "%%mm5")
// pminub mm4, mm2 // now = Min( Max(best, Min(L1,L3), L2 )=L2 clipped
V_PMINUB ("%%mm4", "%%mm2", "%%mm7")
// Blend weave pixel with bob pixel, depending on motion val in mm0
"psubusb %[MotionThreshold], %%mm0\n\t" // test Threshold, clear chroma change >>>??
"pmullw %[MotionSense], %%mm0\n\t" // mul by user factor, keep low 16 bits
"movq %[QW256], %%mm7\n\t"
#ifdef IS_MMXEXT
"pminsw %%mm7, %%mm0\n\t" // max = 256
#else
"paddusw %[QW256B], %%mm0\n\t" // add, may sat at fff..
"psubusw %[QW256B], %%mm0\n\t" // now = Min(L1,256)
#endif
"psubusw %%mm0, %%mm7\n\t" // so the 2 sum to 256, weighted avg
"movq %%mm4, %%mm2\n\t" // save weave chroma info before trashing
"pand %[YMask], %%mm4\n\t" // keep only luma from calc'd value
"pmullw %%mm7, %%mm4\n\t" // use more weave for less motion
"pand %[YMask], %%mm6\n\t" // keep only luma from calc'd value
"pmullw %%mm0, %%mm6\n\t" // use more bob for large motion
"paddusw %%mm6, %%mm4\n\t" // combine
"psrlw $8, %%mm4\n\t" // div by 256 to get weighted avg
// chroma comes from weave pixel
"pand %[UVMask], %%mm2\n\t" // keep chroma
"por %%mm4, %%mm2\n\t" // and combine
V_MOVNTQ ("(%%" XDI ")", "%%mm2") // move in our clipped best, use macro
// bump ptrs and loop
LEAX " 8(%%" XAX "), %%" XAX "\n\t"
LEAX " 8(%%" XBX "), %%" XBX "\n\t"
LEAX " 8(%%" XDX "), %%" XDX "\n\t"
LEAX " 8(%%" XDI "), %%" XDI "\n\t"
LEAX " 8(%%" XSI "), %%" XSI "\n\t"
DECX " %[LoopCtr]\n\t"
"jg 1b\n\t" // loop if not to last line
// note P-III default assumes backward branches taken
"jl 1f\n\t" // done
MOVX " %%" XAX ", %%" XBX "\n\t" // sharpness lookahead 1 byte only, be wrong on 1
"jmp 1b\n\t"
"1:\n\t"
MOVX " %[oldbx], %%" XBX "\n\t"
"emms\n\t": /* no outputs */
:[LastAvg] "m" (LastAvg),
[L1] "m" (L1),
[L3] "m" (L3),
[L2P] "m" (L2P),
[L2] "m" (L2),
[Dest] "m" (Dest),
[ShiftMask] "m" (ShiftMask),
[MaxComb] "m" (MaxComb),
[MotionThreshold] "m" (MotionThreshold),
[MotionSense] "m" (MotionSense),
[QW256B] "m" (QW256B),
[YMask] "m" (YMask),
[UVMask] "m" (UVMask),
[LoopCtr] "m" (LoopCtr),
[QW256] "m" (QW256),
[oldbx] "m" (oldbx)
: XAX, XCX, XDX, XSI, XDI,
"st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
#ifdef __MMX__
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
#endif
"memory", "cc");
}

View file

@ -1,420 +0,0 @@
/*
*
* GStreamer
* Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net>
* Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
/*
* Relicensed for GStreamer from GPL to LGPL with permit from Billy Biggs.
* See: http://bugzilla.gnome.org/show_bug.cgi?id=163578
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "greedyhmacros.h"
#include <stdlib.h>
#include "_stdint.h"
#include <string.h>
#include "gst/gst.h"
#include "plugins.h"
#include "gstdeinterlace2.h"
#define GST_TYPE_DEINTERLACE_METHOD_GREEDY_H (gst_deinterlace_method_greedy_h_get_type ())
#define GST_IS_DEINTERLACE_METHOD_GREEDY_H(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H))
#define GST_IS_DEINTERLACE_METHOD_GREEDY_H_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H))
#define GST_DEINTERLACE_METHOD_GREEDY_H_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H, GstDeinterlaceMethodGreedyHClass))
#define GST_DEINTERLACE_METHOD_GREEDY_H(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H, GstDeinterlaceMethodGreedyH))
#define GST_DEINTERLACE_METHOD_GREEDY_H_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H, GstDeinterlaceMethodGreedyHClass))
#define GST_DEINTERLACE_METHOD_GREEDY_H_CAST(obj) ((GstDeinterlaceMethodGreedyH*)(obj))
GType gst_deinterlace_method_greedy_h_get_type (void);
typedef struct
{
GstDeinterlaceMethod parent;
guint max_comb, motion_threshold, motion_sense;
} GstDeinterlaceMethodGreedyH;
typedef struct
{
GstDeinterlaceMethodClass parent_class;
void (*scanline) (GstDeinterlaceMethodGreedyH * self, uint8_t * L2,
uint8_t * L1, uint8_t * L3, uint8_t * L2P, uint8_t * Dest, int size);
} GstDeinterlaceMethodGreedyHClass;
void
greedyDScaler_C (GstDeinterlaceMethodGreedyH * self, uint8_t * L1, uint8_t * L2,
uint8_t * L3, uint8_t * L2P, uint8_t * Dest, int size)
{
int Pos;
uint8_t l1_l, l1_1_l, l3_l, l3_1_l;
uint8_t l1_c, l1_1_c, l3_c, l3_1_c;
uint8_t avg_l, avg_c, avg_l_1, avg_c_1;
uint8_t avg_l__1 = 0, avg_c__1 = 0;
uint8_t avg_s_l, avg_s_c;
uint8_t avg_sc_l, avg_sc_c;
uint8_t best_l, best_c;
uint16_t mov_l;
uint8_t out_l, out_c;
uint8_t l2_l, l2_c, lp2_l, lp2_c;
uint8_t l2_l_diff, l2_c_diff, lp2_l_diff, lp2_c_diff;
uint8_t min_l, min_c, max_l, max_c;
guint max_comb = self->max_comb;
guint motion_sense = self->motion_sense;
guint motion_threshold = self->motion_threshold;
for (Pos = 0; Pos < size; Pos += 2) {
l1_l = L1[0];
l1_c = L1[1];
l3_l = L3[0];
l3_c = L3[1];
if (Pos == size - 1) {
l1_1_l = l1_l;
l1_1_c = l1_c;
l3_1_l = l3_l;
l3_1_c = l3_c;
} else {
l1_1_l = L1[2];
l1_1_c = L1[3];
l3_1_l = L3[2];
l3_1_c = L3[3];
}
/* Average of L1 and L3 */
avg_l = (l1_l + l3_l) / 2;
avg_c = (l1_c + l3_c) / 2;
if (Pos == 0) {
avg_l__1 = avg_l;
avg_c__1 = avg_c;
}
/* Average of next L1 and next L3 */
avg_l_1 = (l1_1_l + l3_1_l) / 2;
avg_c_1 = (l1_1_c + l3_1_c) / 2;
/* Calculate average of one pixel forward and previous */
avg_s_l = (avg_l__1 + avg_l_1) / 2;
avg_s_c = (avg_c__1 + avg_c_1) / 2;
/* Calculate average of center and surrounding pixels */
avg_sc_l = (avg_l + avg_s_l) / 2;
avg_sc_c = (avg_c + avg_s_c) / 2;
/* move forward */
avg_l__1 = avg_l;
avg_c__1 = avg_c;
/* Get best L2/L2P, i.e. least diff from above average */
l2_l = L2[0];
l2_c = L2[1];
lp2_l = L2P[0];
lp2_c = L2P[1];
l2_l_diff = ABS (l2_l - avg_sc_l);
l2_c_diff = ABS (l2_c - avg_sc_c);
lp2_l_diff = ABS (lp2_l - avg_sc_l);
lp2_c_diff = ABS (lp2_c - avg_sc_c);
if (l2_l_diff > lp2_l_diff)
best_l = lp2_l;
else
best_l = l2_l;
if (l2_c_diff > lp2_c_diff)
best_c = lp2_c;
else
best_c = l2_c;
/* Clip this best L2/L2P by L1/L3 and allow to differ by GreedyMaxComb */
max_l = MAX (l1_l, l3_l);
min_l = MIN (l1_l, l3_l);
if (max_l < 256 - max_comb)
max_l += max_comb;
else
max_l = 255;
if (min_l > max_comb)
min_l -= max_comb;
else
min_l = 0;
max_c = MAX (l1_c, l3_c);
min_c = MIN (l1_c, l3_c);
if (max_c < 256 - max_comb)
max_c += max_comb;
else
max_c = 255;
if (min_c > max_comb)
min_c -= max_comb;
else
min_c = 0;
out_l = CLAMP (best_l, min_l, max_l);
out_c = CLAMP (best_c, min_c, max_c);
/* Do motion compensation for luma, i.e. how much
* the weave pixel differs */
mov_l = ABS (l2_l - lp2_l);
if (mov_l > motion_threshold)
mov_l -= motion_threshold;
else
mov_l = 0;
mov_l = mov_l * motion_sense;
if (mov_l > 256)
mov_l = 256;
/* Weighted sum on clipped weave pixel and average */
out_l = (out_l * (256 - mov_l) + avg_sc_l * mov_l) / 256;
Dest[0] = out_l;
Dest[1] = out_c;
Dest += 2;
L1 += 2;
L2 += 2;
L3 += 2;
L2P += 2;
}
}
#ifdef BUILD_X86_ASM
#define IS_MMXEXT
#define SIMD_TYPE MMXEXT
#define FUNCT_NAME greedyDScaler_MMXEXT
#include "greedyh.asm"
#undef SIMD_TYPE
#undef IS_MMXEXT
#undef FUNCT_NAME
#define IS_3DNOW
#define SIMD_TYPE 3DNOW
#define FUNCT_NAME greedyDScaler_3DNOW
#include "greedyh.asm"
#undef SIMD_TYPE
#undef IS_3DNOW
#undef FUNCT_NAME
#define IS_MMX
#define SIMD_TYPE MMX
#define FUNCT_NAME greedyDScaler_MMX
#include "greedyh.asm"
#undef SIMD_TYPE
#undef IS_MMX
#undef FUNCT_NAME
#endif
static void
deinterlace_frame_di_greedyh (GstDeinterlaceMethod * d_method,
GstDeinterlace2 * object, GstBuffer * outbuf)
{
GstDeinterlaceMethodGreedyH *self =
GST_DEINTERLACE_METHOD_GREEDY_H (d_method);
GstDeinterlaceMethodGreedyHClass *klass =
GST_DEINTERLACE_METHOD_GREEDY_H_GET_CLASS (self);
int InfoIsOdd = 0;
int Line;
unsigned int Pitch = object->field_stride;
unsigned char *L1; // ptr to Line1, of 3
unsigned char *L2; // ptr to Line2, the weave line
unsigned char *L3; // ptr to Line3
unsigned char *L2P; // ptr to prev Line2
unsigned char *Dest = GST_BUFFER_DATA (outbuf);
// copy first even line no matter what, and the first odd line if we're
// processing an EVEN field. (note diff from other deint rtns.)
if (object->field_history[object->history_count - 1].flags ==
PICTURE_INTERLACED_BOTTOM) {
InfoIsOdd = 1;
L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
L2 = GST_BUFFER_DATA (object->field_history[object->history_count - 1].buf);
L3 = L1 + Pitch;
L2P =
GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf);
// copy first even line
oil_memcpy (Dest, L1, object->row_stride);
Dest += object->row_stride;
} else {
InfoIsOdd = 0;
L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
L2 = GST_BUFFER_DATA (object->field_history[object->history_count -
1].buf) + Pitch;
L3 = L1 + Pitch;
L2P =
GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf) +
Pitch;
// copy first even line
oil_memcpy (Dest, GST_BUFFER_DATA (object->field_history[0].buf),
object->row_stride);
Dest += object->row_stride;
// then first odd line
oil_memcpy (Dest, L1, object->row_stride);
Dest += object->row_stride;
}
for (Line = 0; Line < (object->field_height - 1); ++Line) {
klass->scanline (self, L1, L2, L3, L2P, Dest, object->row_stride);
Dest += object->row_stride;
oil_memcpy (Dest, L3, object->row_stride);
Dest += object->row_stride;
L1 += Pitch;
L2 += Pitch;
L3 += Pitch;
L2P += Pitch;
}
if (InfoIsOdd) {
oil_memcpy (Dest, L2, object->row_stride);
}
}
G_DEFINE_TYPE (GstDeinterlaceMethodGreedyH, gst_deinterlace_method_greedy_h,
GST_TYPE_DEINTERLACE_METHOD);
enum
{
ARG_0,
ARG_MAX_COMB,
ARG_MOTION_THRESHOLD,
ARG_MOTION_SENSE
};
static void
gst_deinterlace_method_greedy_h_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (object);
switch (prop_id) {
case ARG_MAX_COMB:
self->max_comb = g_value_get_uint (value);
break;
case ARG_MOTION_THRESHOLD:
self->motion_threshold = g_value_get_uint (value);
break;
case ARG_MOTION_SENSE:
self->motion_sense = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gst_deinterlace_method_greedy_h_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (object);
switch (prop_id) {
case ARG_MAX_COMB:
g_value_set_uint (value, self->max_comb);
break;
case ARG_MOTION_THRESHOLD:
g_value_set_uint (value, self->motion_threshold);
break;
case ARG_MOTION_SENSE:
g_value_set_uint (value, self->motion_sense);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gst_deinterlace_method_greedy_h_class_init (GstDeinterlaceMethodGreedyHClass *
klass)
{
GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
GObjectClass *gobject_class = (GObjectClass *) klass;
#ifdef BUILD_X86_ASM
guint cpu_flags = oil_cpu_get_flags ();
#endif
gobject_class->set_property = gst_deinterlace_method_greedy_h_set_property;
gobject_class->get_property = gst_deinterlace_method_greedy_h_get_property;
g_object_class_install_property (gobject_class, ARG_MAX_COMB,
g_param_spec_uint ("max-comb",
"Max comb",
"Max Comb", 0, 255, 5, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
);
g_object_class_install_property (gobject_class, ARG_MOTION_THRESHOLD,
g_param_spec_uint ("motion-threshold",
"Motion Threshold",
"Motion Threshold",
0, 255, 25, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
);
g_object_class_install_property (gobject_class, ARG_MOTION_SENSE,
g_param_spec_uint ("motion-sense",
"Motion Sense",
"Motion Sense",
0, 255, 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
);
dim_class->fields_required = 4;
dim_class->deinterlace_frame = deinterlace_frame_di_greedyh;
dim_class->name = "Motion Adaptive: Advanced Detection";
dim_class->nick = "greedyh";
dim_class->latency = 1;
#ifdef BUILD_X86_ASM
if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) {
klass->scanline = greedyDScaler_MMXEXT;
} else if (cpu_flags & OIL_IMPL_FLAG_3DNOW) {
klass->scanline = greedyDScaler_3DNOW;
} else if (cpu_flags & OIL_IMPL_FLAG_MMX) {
klass->scanline = greedyDScaler_MMX;
} else {
klass->scanline = greedyDScaler_C;
}
#else
klass->scanline = greedyDScaler_C;
#endif
}
static void
gst_deinterlace_method_greedy_h_init (GstDeinterlaceMethodGreedyH * self)
{
self->max_comb = 5;
self->motion_threshold = 25;
self->motion_sense = 30;
}

View file

@ -1,75 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2001 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
//
/////////////////////////////////////////////////////////////////////////////
// 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 SIMD_TYPE MMXEXT (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_MMXEXT(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, SIMD_TYPE)
#define V_PAVGB2(mmr1, mmr2, mmrw, smask, simd_type) V_PAVGB3(mmr1, mmr2, mmrw, smask, simd_type)
#define V_PAVGB3(mmr1, mmr2, mmrw, smask, simd_type) V_PAVGB_##simd_type(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_MMXEXT(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, SIMD_TYPE)
#define V_PMAXUB2(mmr1, mmr2, simd_type) V_PMAXUB3(mmr1, mmr2, simd_type)
#define V_PMAXUB3(mmr1, mmr2, simd_type) V_PMAXUB_##simd_type(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_MMXEXT(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, SIMD_TYPE)
#define V_PMINUB2(mmr1, mmr2, mmrw, simd_type) V_PMINUB3(mmr1, mmr2, mmrw, simd_type)
#define V_PMINUB3(mmr1, mmr2, mmrw, simd_type) V_PMINUB_##simd_type(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_MMXEXT(mmr1, mmr2) "movntq "mmr2", "mmr1"\n\t"
#define V_MOVNTQ(mmr1, mmr2) V_MOVNTQ2(mmr1, mmr2, SIMD_TYPE)
#define V_MOVNTQ2(mmr1, mmr2, simd_type) V_MOVNTQ3(mmr1, mmr2, simd_type)
#define V_MOVNTQ3(mmr1, mmr2, simd_type) V_MOVNTQ_##simd_type(mmr1, mmr2)
// end of macros

View file

@ -1,214 +0,0 @@
/**
* Copyright (C) 2002 Billy Biggs <vektor@dumbterm.net>.
* Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
*
* 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 "_stdint.h"
#include "gstdeinterlace2.h"
#include <string.h>
#define GST_TYPE_DEINTERLACE_METHOD_LINEAR (gst_deinterlace_method_linear_get_type ())
#define GST_IS_DEINTERLACE_METHOD_LINEAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_LINEAR))
#define GST_IS_DEINTERLACE_METHOD_LINEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_LINEAR))
#define GST_DEINTERLACE_METHOD_LINEAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_LINEAR, GstDeinterlaceMethodLinearClass))
#define GST_DEINTERLACE_METHOD_LINEAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_LINEAR, GstDeinterlaceMethodLinear))
#define GST_DEINTERLACE_METHOD_LINEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_LINEAR, GstDeinterlaceMethodLinearClass))
#define GST_DEINTERLACE_METHOD_LINEAR_CAST(obj) ((GstDeinterlaceMethodLinear*)(obj))
GType gst_deinterlace_method_linear_get_type (void);
typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodLinear;
typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodLinearClass;
static void
deinterlace_scanline_linear_c (GstDeinterlaceMethod * self,
GstDeinterlace2 * parent, guint8 * out,
GstDeinterlaceScanlineData * scanlines, gint width)
{
gint i;
width *= 2;
for (i = 0; i < width; i++)
out[i] = (scanlines->t0[i] + scanlines->b0[i]) / 2;
}
#ifdef BUILD_X86_ASM
#include "mmx.h"
static void
deinterlace_scanline_linear_mmx (GstDeinterlaceMethod * self,
GstDeinterlace2 * parent, guint8 * out,
GstDeinterlaceScanlineData * scanlines, gint width)
{
const mmx_t shiftmask = { 0xfefffefffefffeffULL }; /* To avoid shifting chroma to luma. */
int i;
guint8 *bot = scanlines->b0, *top = scanlines->t0;
for (i = width / 16; i; --i) {
movq_m2r (*bot, mm0);
movq_m2r (*top, mm1);
movq_m2r (*(bot + 8), mm2);
movq_m2r (*(top + 8), mm3);
movq_m2r (*(bot + 16), mm4);
movq_m2r (*(top + 16), mm5);
movq_m2r (*(bot + 24), mm6);
movq_m2r (*(top + 24), mm7);
pand_m2r (shiftmask, mm0);
pand_m2r (shiftmask, mm1);
pand_m2r (shiftmask, mm2);
pand_m2r (shiftmask, mm3);
pand_m2r (shiftmask, mm4);
pand_m2r (shiftmask, mm5);
pand_m2r (shiftmask, mm6);
pand_m2r (shiftmask, mm7);
psrlw_i2r (1, mm0);
psrlw_i2r (1, mm1);
psrlw_i2r (1, mm2);
psrlw_i2r (1, mm3);
psrlw_i2r (1, mm4);
psrlw_i2r (1, mm5);
psrlw_i2r (1, mm6);
psrlw_i2r (1, mm7);
paddb_r2r (mm1, mm0);
paddb_r2r (mm3, mm2);
paddb_r2r (mm5, mm4);
paddb_r2r (mm7, mm6);
movq_r2m (mm0, *out);
movq_r2m (mm2, *(out + 8));
movq_r2m (mm4, *(out + 16));
movq_r2m (mm6, *(out + 24));
out += 32;
top += 32;
bot += 32;
}
width = (width & 0xf);
for (i = width / 4; i; --i) {
movq_m2r (*bot, mm0);
movq_m2r (*top, mm1);
pand_m2r (shiftmask, mm0);
pand_m2r (shiftmask, mm1);
psrlw_i2r (1, mm0);
psrlw_i2r (1, mm1);
paddb_r2r (mm1, mm0);
movq_r2m (mm0, *out);
out += 8;
top += 8;
bot += 8;
}
width = width & 0x7;
/* Handle last few pixels. */
for (i = width * 2; i; --i) {
*out++ = ((*top++) + (*bot++)) >> 1;
}
emms ();
}
#include "sse.h"
static void
deinterlace_scanline_linear_mmxext (GstDeinterlaceMethod * self,
GstDeinterlace2 * parent, guint8 * out,
GstDeinterlaceScanlineData * scanlines, gint width)
{
gint i;
guint8 *bot = scanlines->b0, *top = scanlines->t0;
for (i = width / 16; i; --i) {
movq_m2r (*bot, mm0);
movq_m2r (*top, mm1);
movq_m2r (*(bot + 8), mm2);
movq_m2r (*(top + 8), mm3);
movq_m2r (*(bot + 16), mm4);
movq_m2r (*(top + 16), mm5);
movq_m2r (*(bot + 24), mm6);
movq_m2r (*(top + 24), mm7);
pavgb_r2r (mm1, mm0);
pavgb_r2r (mm3, mm2);
pavgb_r2r (mm5, mm4);
pavgb_r2r (mm7, mm6);
movntq_r2m (mm0, *out);
movntq_r2m (mm2, *(out + 8));
movntq_r2m (mm4, *(out + 16));
movntq_r2m (mm6, *(out + 24));
out += 32;
top += 32;
bot += 32;
}
width = (width & 0xf);
for (i = width / 4; i; --i) {
movq_m2r (*bot, mm0);
movq_m2r (*top, mm1);
pavgb_r2r (mm1, mm0);
movntq_r2m (mm0, *out);
out += 8;
top += 8;
bot += 8;
}
width = width & 0x7;
/* Handle last few pixels. */
for (i = width * 2; i; --i) {
*out++ = ((*top++) + (*bot++)) >> 1;
}
emms ();
}
#endif
G_DEFINE_TYPE (GstDeinterlaceMethodLinear, gst_deinterlace_method_linear,
GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
static void
gst_deinterlace_method_linear_class_init (GstDeinterlaceMethodLinearClass *
klass)
{
GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
GstDeinterlaceSimpleMethodClass *dism_class =
(GstDeinterlaceSimpleMethodClass *) klass;
#ifdef BUILD_X86_ASM
guint cpu_flags = oil_cpu_get_flags ();
#endif
dim_class->fields_required = 1;
dim_class->name = "Television: Full resolution";
dim_class->nick = "linear";
dim_class->latency = 0;
dism_class->interpolate_scanline = deinterlace_scanline_linear_c;
#ifdef BUILD_X86_ASM
if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) {
dism_class->interpolate_scanline = deinterlace_scanline_linear_mmxext;
} else if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) {
dism_class->interpolate_scanline = deinterlace_scanline_linear_mmx;
}
#endif
}
static void
gst_deinterlace_method_linear_init (GstDeinterlaceMethodLinear * self)
{
}

View file

@ -1,231 +0,0 @@
/**
* Linear blend deinterlacing plugin. The idea for this algorithm came
* from the linear blend deinterlacer which originated in the mplayer
* sources.
*
* Copyright (C) 2002 Billy Biggs <vektor@dumbterm.net>.
* Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
*
* 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 "_stdint.h"
#include "gstdeinterlace2.h"
#include <string.h>
#define GST_TYPE_DEINTERLACE_METHOD_LINEAR_BLEND (gst_deinterlace_method_linear_blend_get_type ())
#define GST_IS_DEINTERLACE_METHOD_LINEAR_BLEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_LINEAR_BLEND))
#define GST_IS_DEINTERLACE_METHOD_LINEAR_BLEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_LINEAR_BLEND))
#define GST_DEINTERLACE_METHOD_LINEAR_BLEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_LINEAR_BLEND, GstDeinterlaceMethodLinearBlendClass))
#define GST_DEINTERLACE_METHOD_LINEAR_BLEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_LINEAR_BLEND, GstDeinterlaceMethodLinearBlend))
#define GST_DEINTERLACE_METHOD_LINEAR_BLEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_LINEAR_BLEND, GstDeinterlaceMethodLinearBlendClass))
#define GST_DEINTERLACE_METHOD_LINEAR_BLEND_CAST(obj) ((GstDeinterlaceMethodLinearBlend*)(obj))
GType gst_deinterlace_method_linear_blend_get_type (void);
typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodLinearBlend;
typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodLinearBlendClass;
static inline void
deinterlace_scanline_linear_blend_c (GstDeinterlaceMethod * self,
GstDeinterlace2 * parent, guint8 * out,
GstDeinterlaceScanlineData * scanlines, gint width)
{
guint8 *t0 = scanlines->t0;
guint8 *b0 = scanlines->b0;
guint8 *m1 = scanlines->m1;
width *= 2;
while (width--) {
*out++ = (*t0++ + *b0++ + (*m1++ << 1)) >> 2;
}
}
static inline void
deinterlace_scanline_linear_blend2_c (GstDeinterlaceMethod * self,
GstDeinterlace2 * parent, guint8 * out,
GstDeinterlaceScanlineData * scanlines, gint width)
{
guint8 *m0 = scanlines->m0;
guint8 *t1 = scanlines->t1;
guint8 *b1 = scanlines->b1;
width *= 2;
while (width--) {
*out++ = (*t1++ + *b1++ + (*m0++ << 1)) >> 2;
}
}
#ifdef BUILD_X86_ASM
#include "mmx.h"
static inline void
deinterlace_scanline_linear_blend_mmx (GstDeinterlaceMethod * self,
GstDeinterlace2 * parent, guint8 * out,
GstDeinterlaceScanlineData * scanlines, gint width)
{
guint8 *t0 = scanlines->t0;
guint8 *b0 = scanlines->b0;
guint8 *m1 = scanlines->m1;
gint i;
// Get width in bytes.
width *= 2;
i = width / 8;
width -= i * 8;
pxor_r2r (mm7, mm7);
while (i--) {
movd_m2r (*t0, mm0);
movd_m2r (*b0, mm1);
movd_m2r (*m1, mm2);
movd_m2r (*(t0 + 4), mm3);
movd_m2r (*(b0 + 4), mm4);
movd_m2r (*(m1 + 4), mm5);
punpcklbw_r2r (mm7, mm0);
punpcklbw_r2r (mm7, mm1);
punpcklbw_r2r (mm7, mm2);
punpcklbw_r2r (mm7, mm3);
punpcklbw_r2r (mm7, mm4);
punpcklbw_r2r (mm7, mm5);
psllw_i2r (1, mm2);
psllw_i2r (1, mm5);
paddw_r2r (mm0, mm2);
paddw_r2r (mm3, mm5);
paddw_r2r (mm1, mm2);
paddw_r2r (mm4, mm5);
psrlw_i2r (2, mm2);
psrlw_i2r (2, mm5);
packuswb_r2r (mm2, mm2);
packuswb_r2r (mm5, mm5);
movd_r2m (mm2, *out);
movd_r2m (mm5, *(out + 4));
out += 8;
t0 += 8;
b0 += 8;
m1 += 8;
}
while (width--) {
*out++ = (*t0++ + *b0++ + (*m1++ << 1)) >> 2;
}
emms ();
}
static inline void
deinterlace_scanline_linear_blend2_mmx (GstDeinterlaceMethod * self,
GstDeinterlace2 * parent, guint8 * out,
GstDeinterlaceScanlineData * scanlines, gint width)
{
guint8 *m0 = scanlines->m0;
guint8 *t1 = scanlines->t1;
guint8 *b1 = scanlines->b1;
gint i;
// Get width in bytes.
width *= 2;
i = width / 8;
width -= i * 8;
pxor_r2r (mm7, mm7);
while (i--) {
movd_m2r (*t1, mm0);
movd_m2r (*b1, mm1);
movd_m2r (*m0, mm2);
movd_m2r (*(t1 + 4), mm3);
movd_m2r (*(b1 + 4), mm4);
movd_m2r (*(m0 + 4), mm5);
punpcklbw_r2r (mm7, mm0);
punpcklbw_r2r (mm7, mm1);
punpcklbw_r2r (mm7, mm2);
punpcklbw_r2r (mm7, mm3);
punpcklbw_r2r (mm7, mm4);
punpcklbw_r2r (mm7, mm5);
psllw_i2r (1, mm2);
psllw_i2r (1, mm5);
paddw_r2r (mm0, mm2);
paddw_r2r (mm3, mm5);
paddw_r2r (mm1, mm2);
paddw_r2r (mm4, mm5);
psrlw_i2r (2, mm2);
psrlw_i2r (2, mm5);
packuswb_r2r (mm2, mm2);
packuswb_r2r (mm5, mm5);
movd_r2m (mm2, *out);
movd_r2m (mm5, *(out + 4));
out += 8;
t1 += 8;
b1 += 8;
m0 += 8;
}
while (width--) {
*out++ = (*t1++ + *b1++ + (*m0++ << 1)) >> 2;
}
emms ();
}
#endif
G_DEFINE_TYPE (GstDeinterlaceMethodLinearBlend,
gst_deinterlace_method_linear_blend, GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
static void
gst_deinterlace_method_linear_blend_class_init
(GstDeinterlaceMethodLinearBlendClass * klass)
{
GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
GstDeinterlaceSimpleMethodClass *dism_class =
(GstDeinterlaceSimpleMethodClass *) klass;
#ifdef BUILD_X86_ASM
guint cpu_flags = oil_cpu_get_flags ();
#endif
dim_class->fields_required = 2;
dim_class->name = "Blur: Temporal";
dim_class->nick = "linearblend";
dim_class->latency = 0;
dism_class->interpolate_scanline = deinterlace_scanline_linear_blend_c;
dism_class->copy_scanline = deinterlace_scanline_linear_blend2_c;
#ifdef BUILD_X86_ASM
if (cpu_flags & OIL_IMPL_FLAG_MMX) {
dism_class->interpolate_scanline = deinterlace_scanline_linear_blend_mmx;
dism_class->copy_scanline = deinterlace_scanline_linear_blend2_mmx;
}
#endif
}
static void
gst_deinterlace_method_linear_blend_init (GstDeinterlaceMethodLinearBlend *
self)
{
}

View file

@ -1,723 +0,0 @@
/* mmx.h
MultiMedia eXtensions GCC interface library for IA32.
To use this library, simply include this header file
and compile with GCC. You MUST have inlining enabled
in order for mmx_ok() to work; this can be done by
simply using -O on the GCC command line.
Compiling with -DMMX_TRACE will cause detailed trace
output to be sent to stderr for each mmx operation.
This adds lots of code, and obviously slows execution to
a crawl, but can be very useful for debugging.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR ANY PARTICULAR PURPOSE.
1997-98 by H. Dietz and R. Fisher
History:
97-98* R.Fisher Early versions
980501 R.Fisher Original Release
980611* H.Dietz Rewrite, correctly implementing inlines, and
R.Fisher including direct register accesses.
980616 R.Fisher Release of 980611 as 980616.
980714 R.Fisher Minor corrections to Makefile, etc.
980715 R.Fisher mmx_ok() now prevents optimizer from using
clobbered values.
mmx_ok() now checks if cpuid instruction is
available before trying to use it.
980726* R.Fisher mm_support() searches for AMD 3DNow, Cyrix
Extended MMX, and standard MMX. It returns a
value which is positive if any of these are
supported, and can be masked with constants to
see which. mmx_ok() is now a call to this
980726* R.Fisher Added i2r support for shift functions
980919 R.Fisher Fixed AMD extended feature recognition bug.
980921 R.Fisher Added definition/check for _MMX_H.
Added "float s[2]" to mmx_t for use with
3DNow and EMMX. So same mmx_t can be used.
981013 R.Fisher Fixed cpuid function 1 bug (looked at wrong reg)
Fixed psllq_i2r error in mmxtest.c
* Unreleased (internal or interim) versions
Notes:
It appears that the latest gas has the pand problem fixed, therefore
I'll undefine BROKEN_PAND by default.
String compares may be quicker than the multiple test/jumps in vendor
test sequence in mmx_ok(), but I'm not concerned with that right now.
Acknowledgments:
Jussi Laako for pointing out the errors ultimately found to be
connected to the failure to notify the optimizer of clobbered values.
Roger Hardiman for reminding us that CPUID isn't everywhere, and that
someone may actually try to use this on a machine without CPUID.
Also for suggesting code for checking this.
Robert Dale for pointing out the AMD recognition bug.
Jimmy Mayfield and Carl Witty for pointing out the Intel recognition
bug.
Carl Witty for pointing out the psllq_i2r test bug.
*/
#ifndef _MMX_H
#define _MMX_H
/*#define MMX_TRACE */
/* Warning: at this writing, the version of GAS packaged
with most Linux distributions does not handle the
parallel AND operation mnemonic correctly. If the
symbol BROKEN_PAND is defined, a slower alternative
coding will be used. If execution of mmxtest results
in an illegal instruction fault, define this symbol.
*/
#undef BROKEN_PAND
/* The type of an value that fits in an MMX register
(note that long long constant values MUST be suffixed
by LL and unsigned long long values by ULL, lest
they be truncated by the compiler)
*/
typedef union {
long long q; /* Quadword (64-bit) value */
unsigned long long uq; /* Unsigned Quadword */
int d[2]; /* 2 Doubleword (32-bit) values */
unsigned int ud[2]; /* 2 Unsigned Doubleword */
short w[4]; /* 4 Word (16-bit) values */
unsigned short uw[4]; /* 4 Unsigned Word */
char b[8]; /* 8 Byte (8-bit) values */
unsigned char ub[8]; /* 8 Unsigned Byte */
float s[2]; /* Single-precision (32-bit) value */
} mmx_t;
/* Function to test if multimedia instructions are supported...
*/
inline extern int
mm_support(void)
{
/* Returns 1 if MMX instructions are supported,
3 if Cyrix MMX and Extended MMX instructions are supported
5 if AMD MMX and 3DNow! instructions are supported
0 if hardware does not support any of these
*/
register int rval = 0;
__asm__ __volatile__ (
/* See if CPUID instruction is supported ... */
/* ... Get copies of EFLAGS into eax and ecx */
"pushf\n\t"
"popl %%eax\n\t"
"movl %%eax, %%ecx\n\t"
/* ... Toggle the ID bit in one copy and store */
/* to the EFLAGS reg */
"xorl $0x200000, %%eax\n\t"
"push %%eax\n\t"
"popf\n\t"
/* ... Get the (hopefully modified) EFLAGS */
"pushf\n\t"
"popl %%eax\n\t"
/* ... Compare and test result */
"xorl %%eax, %%ecx\n\t"
"testl $0x200000, %%ecx\n\t"
"jz NotSupported1\n\t" /* Nothing supported */
/* Get standard CPUID information, and
go to a specific vendor section */
"movl $0, %%eax\n\t"
"cpuid\n\t"
/* Check for Intel */
"cmpl $0x756e6547, %%ebx\n\t"
"jne TryAMD\n\t"
"cmpl $0x49656e69, %%edx\n\t"
"jne TryAMD\n\t"
"cmpl $0x6c65746e, %%ecx\n"
"jne TryAMD\n\t"
"jmp Intel\n\t"
/* Check for AMD */
"\nTryAMD:\n\t"
"cmpl $0x68747541, %%ebx\n\t"
"jne TryCyrix\n\t"
"cmpl $0x69746e65, %%edx\n\t"
"jne TryCyrix\n\t"
"cmpl $0x444d4163, %%ecx\n"
"jne TryCyrix\n\t"
"jmp AMD\n\t"
/* Check for Cyrix */
"\nTryCyrix:\n\t"
"cmpl $0x69727943, %%ebx\n\t"
"jne NotSupported2\n\t"
"cmpl $0x736e4978, %%edx\n\t"
"jne NotSupported3\n\t"
"cmpl $0x64616574, %%ecx\n\t"
"jne NotSupported4\n\t"
/* Drop through to Cyrix... */
/* Cyrix Section */
/* See if extended CPUID is supported */
"movl $0x80000000, %%eax\n\t"
"cpuid\n\t"
"cmpl $0x80000000, %%eax\n\t"
"jl MMXtest\n\t" /* Try standard CPUID instead */
/* Extended CPUID supported, so get extended features */
"movl $0x80000001, %%eax\n\t"
"cpuid\n\t"
"testl $0x00800000, %%eax\n\t" /* Test for MMX */
"jz NotSupported5\n\t" /* MMX not supported */
"testl $0x01000000, %%eax\n\t" /* Test for Ext'd MMX */
"jnz EMMXSupported\n\t"
"movl $1, %0:\n\n\t" /* MMX Supported */
"jmp Return\n\n"
"EMMXSupported:\n\t"
"movl $3, %0:\n\n\t" /* EMMX and MMX Supported */
"jmp Return\n\t"
/* AMD Section */
"AMD:\n\t"
/* See if extended CPUID is supported */
"movl $0x80000000, %%eax\n\t"
"cpuid\n\t"
"cmpl $0x80000000, %%eax\n\t"
"jl MMXtest\n\t" /* Try standard CPUID instead */
/* Extended CPUID supported, so get extended features */
"movl $0x80000001, %%eax\n\t"
"cpuid\n\t"
"testl $0x00800000, %%edx\n\t" /* Test for MMX */
"jz NotSupported6\n\t" /* MMX not supported */
"testl $0x80000000, %%edx\n\t" /* Test for 3DNow! */
"jnz ThreeDNowSupported\n\t"
"movl $1, %0:\n\n\t" /* MMX Supported */
"jmp Return\n\n"
"ThreeDNowSupported:\n\t"
"movl $5, %0:\n\n\t" /* 3DNow! and MMX Supported */
"jmp Return\n\t"
/* Intel Section */
"Intel:\n\t"
/* Check for MMX */
"MMXtest:\n\t"
"movl $1, %%eax\n\t"
"cpuid\n\t"
"testl $0x00800000, %%edx\n\t" /* Test for MMX */
"jz NotSupported7\n\t" /* MMX Not supported */
"movl $1, %0:\n\n\t" /* MMX Supported */
"jmp Return\n\t"
/* Nothing supported */
"\nNotSupported1:\n\t"
"#movl $101, %0:\n\n\t"
"\nNotSupported2:\n\t"
"#movl $102, %0:\n\n\t"
"\nNotSupported3:\n\t"
"#movl $103, %0:\n\n\t"
"\nNotSupported4:\n\t"
"#movl $104, %0:\n\n\t"
"\nNotSupported5:\n\t"
"#movl $105, %0:\n\n\t"
"\nNotSupported6:\n\t"
"#movl $106, %0:\n\n\t"
"\nNotSupported7:\n\t"
"#movl $107, %0:\n\n\t"
"movl $0, %0:\n\n\t"
"Return:\n\t"
: "=a" (rval)
: /* no input */
: "eax", "ebx", "ecx", "edx"
);
/* Return */
return(rval);
}
/* Function to test if mmx instructions are supported...
*/
inline extern int
mmx_ok(void)
{
/* Returns 1 if MMX instructions are supported, 0 otherwise */
return ( mm_support() & 0x1 );
}
/* Helper functions for the instruction macros that follow...
(note that memory-to-register, m2r, instructions are nearly
as efficient as register-to-register, r2r, instructions;
however, memory-to-memory instructions are really simulated
as a convenience, and are only 1/3 as efficient)
*/
#ifdef MMX_TRACE
/* Include the stuff for printing a trace to stderr...
*/
#include <stdio.h>
#define mmx_i2r(op, imm, reg) \
{ \
mmx_t mmx_trace; \
mmx_trace = (imm); \
fprintf(stderr, #op "_i2r(" #imm "=0x%016llx, ", mmx_trace.q); \
__asm__ __volatile__ ("movq %%" #reg ", %0" \
: "=X" (mmx_trace) \
: /* nothing */ ); \
fprintf(stderr, #reg "=0x%016llx) => ", mmx_trace.q); \
__asm__ __volatile__ (#op " %0, %%" #reg \
: /* nothing */ \
: "X" (imm)); \
__asm__ __volatile__ ("movq %%" #reg ", %0" \
: "=X" (mmx_trace) \
: /* nothing */ ); \
fprintf(stderr, #reg "=0x%016llx\n", mmx_trace.q); \
}
#define mmx_m2r(op, mem, reg) \
{ \
mmx_t mmx_trace; \
mmx_trace = (mem); \
fprintf(stderr, #op "_m2r(" #mem "=0x%016llx, ", mmx_trace.q); \
__asm__ __volatile__ ("movq %%" #reg ", %0" \
: "=X" (mmx_trace) \
: /* nothing */ ); \
fprintf(stderr, #reg "=0x%016llx) => ", mmx_trace.q); \
__asm__ __volatile__ (#op " %0, %%" #reg \
: /* nothing */ \
: "X" (mem)); \
__asm__ __volatile__ ("movq %%" #reg ", %0" \
: "=X" (mmx_trace) \
: /* nothing */ ); \
fprintf(stderr, #reg "=0x%016llx\n", mmx_trace.q); \
}
#define mmx_r2m(op, reg, mem) \
{ \
mmx_t mmx_trace; \
__asm__ __volatile__ ("movq %%" #reg ", %0" \
: "=X" (mmx_trace) \
: /* nothing */ ); \
fprintf(stderr, #op "_r2m(" #reg "=0x%016llx, ", mmx_trace.q); \
mmx_trace = (mem); \
fprintf(stderr, #mem "=0x%016llx) => ", mmx_trace.q); \
__asm__ __volatile__ (#op " %%" #reg ", %0" \
: "=X" (mem) \
: /* nothing */ ); \
mmx_trace = (mem); \
fprintf(stderr, #mem "=0x%016llx\n", mmx_trace.q); \
}
#define mmx_r2r(op, regs, regd) \
{ \
mmx_t mmx_trace; \
__asm__ __volatile__ ("movq %%" #regs ", %0" \
: "=X" (mmx_trace) \
: /* nothing */ ); \
fprintf(stderr, #op "_r2r(" #regs "=0x%016llx, ", mmx_trace.q); \
__asm__ __volatile__ ("movq %%" #regd ", %0" \
: "=X" (mmx_trace) \
: /* nothing */ ); \
fprintf(stderr, #regd "=0x%016llx) => ", mmx_trace.q); \
__asm__ __volatile__ (#op " %" #regs ", %" #regd); \
__asm__ __volatile__ ("movq %%" #regd ", %0" \
: "=X" (mmx_trace) \
: /* nothing */ ); \
fprintf(stderr, #regd "=0x%016llx\n", mmx_trace.q); \
}
#define mmx_m2m(op, mems, memd) \
{ \
mmx_t mmx_trace; \
mmx_trace = (mems); \
fprintf(stderr, #op "_m2m(" #mems "=0x%016llx, ", mmx_trace.q); \
mmx_trace = (memd); \
fprintf(stderr, #memd "=0x%016llx) => ", mmx_trace.q); \
__asm__ __volatile__ ("movq %0, %%mm0\n\t" \
#op " %1, %%mm0\n\t" \
"movq %%mm0, %0" \
: "=X" (memd) \
: "X" (mems)); \
mmx_trace = (memd); \
fprintf(stderr, #memd "=0x%016llx\n", mmx_trace.q); \
}
#else
/* These macros are a lot simpler without the tracing...
*/
#define mmx_i2r(op, imm, reg) \
__asm__ __volatile__ (#op " $" #imm ", %%" #reg \
: /* nothing */ \
: /* nothing */);
#define mmx_m2r(op, mem, reg) \
__asm__ __volatile__ (#op " %0, %%" #reg \
: /* nothing */ \
: "m" (mem))
#define mmx_r2m(op, reg, mem) \
__asm__ __volatile__ (#op " %%" #reg ", %0" \
: "=m" (mem) \
: /* nothing */ )
#define mmx_r2r(op, regs, regd) \
__asm__ __volatile__ (#op " %" #regs ", %" #regd)
#define mmx_m2m(op, mems, memd) \
__asm__ __volatile__ ("movq %0, %%mm0\n\t" \
#op " %1, %%mm0\n\t" \
"movq %%mm0, %0" \
: "=m" (memd) \
: "m" (mems))
#endif
/* 1x64 MOVe Quadword
(this is both a load and a store...
in fact, it is the only way to store)
*/
#define movq_m2r(var, reg) mmx_m2r(movq, var, reg)
#define movq_r2m(reg, var) mmx_r2m(movq, reg, var)
#define movq_r2r(regs, regd) mmx_r2r(movq, regs, regd)
#define movq(vars, vard) \
__asm__ __volatile__ ("movq %1, %%mm0\n\t" \
"movq %%mm0, %0" \
: "=X" (vard) \
: "X" (vars))
/* 1x32 MOVe Doubleword
(like movq, this is both load and store...
but is most useful for moving things between
mmx registers and ordinary registers)
*/
#define movd_m2r(var, reg) mmx_m2r(movd, var, reg)
#define movd_r2m(reg, var) mmx_r2m(movd, reg, var)
#define movd_r2r(regs, regd) mmx_r2r(movd, regs, regd)
#define movd(vars, vard) \
__asm__ __volatile__ ("movd %1, %%mm0\n\t" \
"movd %%mm0, %0" \
: "=X" (vard) \
: "X" (vars))
/* 2x32, 4x16, and 8x8 Parallel ADDs
*/
#define paddd_m2r(var, reg) mmx_m2r(paddd, var, reg)
#define paddd_r2r(regs, regd) mmx_r2r(paddd, regs, regd)
#define paddd(vars, vard) mmx_m2m(paddd, vars, vard)
#define paddw_m2r(var, reg) mmx_m2r(paddw, var, reg)
#define paddw_r2r(regs, regd) mmx_r2r(paddw, regs, regd)
#define paddw(vars, vard) mmx_m2m(paddw, vars, vard)
#define paddb_m2r(var, reg) mmx_m2r(paddb, var, reg)
#define paddb_r2r(regs, regd) mmx_r2r(paddb, regs, regd)
#define paddb(vars, vard) mmx_m2m(paddb, vars, vard)
/* 4x16 and 8x8 Parallel ADDs using Saturation arithmetic
*/
#define paddsw_m2r(var, reg) mmx_m2r(paddsw, var, reg)
#define paddsw_r2r(regs, regd) mmx_r2r(paddsw, regs, regd)
#define paddsw(vars, vard) mmx_m2m(paddsw, vars, vard)
#define paddsb_m2r(var, reg) mmx_m2r(paddsb, var, reg)
#define paddsb_r2r(regs, regd) mmx_r2r(paddsb, regs, regd)
#define paddsb(vars, vard) mmx_m2m(paddsb, vars, vard)
/* 4x16 and 8x8 Parallel ADDs using Unsigned Saturation arithmetic
*/
#define paddusw_m2r(var, reg) mmx_m2r(paddusw, var, reg)
#define paddusw_r2r(regs, regd) mmx_r2r(paddusw, regs, regd)
#define paddusw(vars, vard) mmx_m2m(paddusw, vars, vard)
#define paddusb_m2r(var, reg) mmx_m2r(paddusb, var, reg)
#define paddusb_r2r(regs, regd) mmx_r2r(paddusb, regs, regd)
#define paddusb(vars, vard) mmx_m2m(paddusb, vars, vard)
/* 2x32, 4x16, and 8x8 Parallel SUBs
*/
#define psubd_m2r(var, reg) mmx_m2r(psubd, var, reg)
#define psubd_r2r(regs, regd) mmx_r2r(psubd, regs, regd)
#define psubd(vars, vard) mmx_m2m(psubd, vars, vard)
#define psubw_m2r(var, reg) mmx_m2r(psubw, var, reg)
#define psubw_r2r(regs, regd) mmx_r2r(psubw, regs, regd)
#define psubw(vars, vard) mmx_m2m(psubw, vars, vard)
#define psubb_m2r(var, reg) mmx_m2r(psubb, var, reg)
#define psubb_r2r(regs, regd) mmx_r2r(psubb, regs, regd)
#define psubb(vars, vard) mmx_m2m(psubb, vars, vard)
/* 4x16 and 8x8 Parallel SUBs using Saturation arithmetic
*/
#define psubsw_m2r(var, reg) mmx_m2r(psubsw, var, reg)
#define psubsw_r2r(regs, regd) mmx_r2r(psubsw, regs, regd)
#define psubsw(vars, vard) mmx_m2m(psubsw, vars, vard)
#define psubsb_m2r(var, reg) mmx_m2r(psubsb, var, reg)
#define psubsb_r2r(regs, regd) mmx_r2r(psubsb, regs, regd)
#define psubsb(vars, vard) mmx_m2m(psubsb, vars, vard)
/* 4x16 and 8x8 Parallel SUBs using Unsigned Saturation arithmetic
*/
#define psubusw_m2r(var, reg) mmx_m2r(psubusw, var, reg)
#define psubusw_r2r(regs, regd) mmx_r2r(psubusw, regs, regd)
#define psubusw(vars, vard) mmx_m2m(psubusw, vars, vard)
#define psubusb_m2r(var, reg) mmx_m2r(psubusb, var, reg)
#define psubusb_r2r(regs, regd) mmx_r2r(psubusb, regs, regd)
#define psubusb(vars, vard) mmx_m2m(psubusb, vars, vard)
/* 4x16 Parallel MULs giving Low 4x16 portions of results
*/
#define pmullw_m2r(var, reg) mmx_m2r(pmullw, var, reg)
#define pmullw_r2r(regs, regd) mmx_r2r(pmullw, regs, regd)
#define pmullw(vars, vard) mmx_m2m(pmullw, vars, vard)
/* 4x16 Parallel MULs giving High 4x16 portions of results
*/
#define pmulhw_m2r(var, reg) mmx_m2r(pmulhw, var, reg)
#define pmulhw_r2r(regs, regd) mmx_r2r(pmulhw, regs, regd)
#define pmulhw(vars, vard) mmx_m2m(pmulhw, vars, vard)
/* 4x16->2x32 Parallel Mul-ADD
(muls like pmullw, then adds adjacent 16-bit fields
in the multiply result to make the final 2x32 result)
*/
#define pmaddwd_m2r(var, reg) mmx_m2r(pmaddwd, var, reg)
#define pmaddwd_r2r(regs, regd) mmx_r2r(pmaddwd, regs, regd)
#define pmaddwd(vars, vard) mmx_m2m(pmaddwd, vars, vard)
/* 1x64 bitwise AND
*/
#ifdef BROKEN_PAND
#define pand_m2r(var, reg) \
{ \
mmx_m2r(pandn, (mmx_t) -1LL, reg); \
mmx_m2r(pandn, var, reg); \
}
#define pand_r2r(regs, regd) \
{ \
mmx_m2r(pandn, (mmx_t) -1LL, regd); \
mmx_r2r(pandn, regs, regd); \
}
#define pand(vars, vard) \
{ \
movq_m2r(vard, mm0); \
mmx_m2r(pandn, (mmx_t) -1LL, mm0); \
mmx_m2r(pandn, vars, mm0); \
movq_r2m(mm0, vard); \
}
#else
#define pand_m2r(var, reg) mmx_m2r(pand, var, reg)
#define pand_r2r(regs, regd) mmx_r2r(pand, regs, regd)
#define pand(vars, vard) mmx_m2m(pand, vars, vard)
#endif
/* 1x64 bitwise AND with Not the destination
*/
#define pandn_m2r(var, reg) mmx_m2r(pandn, var, reg)
#define pandn_r2r(regs, regd) mmx_r2r(pandn, regs, regd)
#define pandn(vars, vard) mmx_m2m(pandn, vars, vard)
/* 1x64 bitwise OR
*/
#define por_m2r(var, reg) mmx_m2r(por, var, reg)
#define por_r2r(regs, regd) mmx_r2r(por, regs, regd)
#define por(vars, vard) mmx_m2m(por, vars, vard)
/* 1x64 bitwise eXclusive OR
*/
#define pxor_m2r(var, reg) mmx_m2r(pxor, var, reg)
#define pxor_r2r(regs, regd) mmx_r2r(pxor, regs, regd)
#define pxor(vars, vard) mmx_m2m(pxor, vars, vard)
/* 2x32, 4x16, and 8x8 Parallel CoMPare for EQuality
(resulting fields are either 0 or -1)
*/
#define pcmpeqd_m2r(var, reg) mmx_m2r(pcmpeqd, var, reg)
#define pcmpeqd_r2r(regs, regd) mmx_r2r(pcmpeqd, regs, regd)
#define pcmpeqd(vars, vard) mmx_m2m(pcmpeqd, vars, vard)
#define pcmpeqw_m2r(var, reg) mmx_m2r(pcmpeqw, var, reg)
#define pcmpeqw_r2r(regs, regd) mmx_r2r(pcmpeqw, regs, regd)
#define pcmpeqw(vars, vard) mmx_m2m(pcmpeqw, vars, vard)
#define pcmpeqb_m2r(var, reg) mmx_m2r(pcmpeqb, var, reg)
#define pcmpeqb_r2r(regs, regd) mmx_r2r(pcmpeqb, regs, regd)
#define pcmpeqb(vars, vard) mmx_m2m(pcmpeqb, vars, vard)
/* 2x32, 4x16, and 8x8 Parallel CoMPare for Greater Than
(resulting fields are either 0 or -1)
*/
#define pcmpgtd_m2r(var, reg) mmx_m2r(pcmpgtd, var, reg)
#define pcmpgtd_r2r(regs, regd) mmx_r2r(pcmpgtd, regs, regd)
#define pcmpgtd(vars, vard) mmx_m2m(pcmpgtd, vars, vard)
#define pcmpgtw_m2r(var, reg) mmx_m2r(pcmpgtw, var, reg)
#define pcmpgtw_r2r(regs, regd) mmx_r2r(pcmpgtw, regs, regd)
#define pcmpgtw(vars, vard) mmx_m2m(pcmpgtw, vars, vard)
#define pcmpgtb_m2r(var, reg) mmx_m2r(pcmpgtb, var, reg)
#define pcmpgtb_r2r(regs, regd) mmx_r2r(pcmpgtb, regs, regd)
#define pcmpgtb(vars, vard) mmx_m2m(pcmpgtb, vars, vard)
/* 1x64, 2x32, and 4x16 Parallel Shift Left Logical
*/
#define psllq_i2r(imm, reg) mmx_i2r(psllq, imm, reg)
#define psllq_m2r(var, reg) mmx_m2r(psllq, var, reg)
#define psllq_r2r(regs, regd) mmx_r2r(psllq, regs, regd)
#define psllq(vars, vard) mmx_m2m(psllq, vars, vard)
#define pslld_i2r(imm, reg) mmx_i2r(pslld, imm, reg)
#define pslld_m2r(var, reg) mmx_m2r(pslld, var, reg)
#define pslld_r2r(regs, regd) mmx_r2r(pslld, regs, regd)
#define pslld(vars, vard) mmx_m2m(pslld, vars, vard)
#define psllw_i2r(imm, reg) mmx_i2r(psllw, imm, reg)
#define psllw_m2r(var, reg) mmx_m2r(psllw, var, reg)
#define psllw_r2r(regs, regd) mmx_r2r(psllw, regs, regd)
#define psllw(vars, vard) mmx_m2m(psllw, vars, vard)
/* 1x64, 2x32, and 4x16 Parallel Shift Right Logical
*/
#define psrlq_i2r(imm, reg) mmx_i2r(psrlq, imm, reg)
#define psrlq_m2r(var, reg) mmx_m2r(psrlq, var, reg)
#define psrlq_r2r(regs, regd) mmx_r2r(psrlq, regs, regd)
#define psrlq(vars, vard) mmx_m2m(psrlq, vars, vard)
#define psrld_i2r(imm, reg) mmx_i2r(psrld, imm, reg)
#define psrld_m2r(var, reg) mmx_m2r(psrld, var, reg)
#define psrld_r2r(regs, regd) mmx_r2r(psrld, regs, regd)
#define psrld(vars, vard) mmx_m2m(psrld, vars, vard)
#define psrlw_i2r(imm, reg) mmx_i2r(psrlw, imm, reg)
#define psrlw_m2r(var, reg) mmx_m2r(psrlw, var, reg)
#define psrlw_r2r(regs, regd) mmx_r2r(psrlw, regs, regd)
#define psrlw(vars, vard) mmx_m2m(psrlw, vars, vard)
/* 2x32 and 4x16 Parallel Shift Right Arithmetic
*/
#define psrad_i2r(imm, reg) mmx_i2r(psrad, imm, reg)
#define psrad_m2r(var, reg) mmx_m2r(psrad, var, reg)
#define psrad_r2r(regs, regd) mmx_r2r(psrad, regs, regd)
#define psrad(vars, vard) mmx_m2m(psrad, vars, vard)
#define psraw_i2r(imm, reg) mmx_i2r(psraw, imm, reg)
#define psraw_m2r(var, reg) mmx_m2r(psraw, var, reg)
#define psraw_r2r(regs, regd) mmx_r2r(psraw, regs, regd)
#define psraw(vars, vard) mmx_m2m(psraw, vars, vard)
/* 2x32->4x16 and 4x16->8x8 PACK and Signed Saturate
(packs source and dest fields into dest in that order)
*/
#define packssdw_m2r(var, reg) mmx_m2r(packssdw, var, reg)
#define packssdw_r2r(regs, regd) mmx_r2r(packssdw, regs, regd)
#define packssdw(vars, vard) mmx_m2m(packssdw, vars, vard)
#define packsswb_m2r(var, reg) mmx_m2r(packsswb, var, reg)
#define packsswb_r2r(regs, regd) mmx_r2r(packsswb, regs, regd)
#define packsswb(vars, vard) mmx_m2m(packsswb, vars, vard)
/* 4x16->8x8 PACK and Unsigned Saturate
(packs source and dest fields into dest in that order)
*/
#define packuswb_m2r(var, reg) mmx_m2r(packuswb, var, reg)
#define packuswb_r2r(regs, regd) mmx_r2r(packuswb, regs, regd)
#define packuswb(vars, vard) mmx_m2m(packuswb, vars, vard)
/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK Low
(interleaves low half of dest with low half of source
as padding in each result field)
*/
#define punpckldq_m2r(var, reg) mmx_m2r(punpckldq, var, reg)
#define punpckldq_r2r(regs, regd) mmx_r2r(punpckldq, regs, regd)
#define punpckldq(vars, vard) mmx_m2m(punpckldq, vars, vard)
#define punpcklwd_m2r(var, reg) mmx_m2r(punpcklwd, var, reg)
#define punpcklwd_r2r(regs, regd) mmx_r2r(punpcklwd, regs, regd)
#define punpcklwd(vars, vard) mmx_m2m(punpcklwd, vars, vard)
#define punpcklbw_m2r(var, reg) mmx_m2r(punpcklbw, var, reg)
#define punpcklbw_r2r(regs, regd) mmx_r2r(punpcklbw, regs, regd)
#define punpcklbw(vars, vard) mmx_m2m(punpcklbw, vars, vard)
/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK High
(interleaves high half of dest with high half of source
as padding in each result field)
*/
#define punpckhdq_m2r(var, reg) mmx_m2r(punpckhdq, var, reg)
#define punpckhdq_r2r(regs, regd) mmx_r2r(punpckhdq, regs, regd)
#define punpckhdq(vars, vard) mmx_m2m(punpckhdq, vars, vard)
#define punpckhwd_m2r(var, reg) mmx_m2r(punpckhwd, var, reg)
#define punpckhwd_r2r(regs, regd) mmx_r2r(punpckhwd, regs, regd)
#define punpckhwd(vars, vard) mmx_m2m(punpckhwd, vars, vard)
#define punpckhbw_m2r(var, reg) mmx_m2r(punpckhbw, var, reg)
#define punpckhbw_r2r(regs, regd) mmx_r2r(punpckhbw, regs, regd)
#define punpckhbw(vars, vard) mmx_m2m(punpckhbw, vars, vard)
/* Empty MMx State
(used to clean-up when going from mmx to float use
of the registers that are shared by both; note that
there is no float-to-mmx operation needed, because
only the float tag word info is corruptible)
*/
#ifdef MMX_TRACE
#define emms() \
{ \
fprintf(stderr, "emms()\n"); \
__asm__ __volatile__ ("emms"); \
}
#else
#define emms() __asm__ __volatile__ ("emms")
#endif
#endif

View file

@ -1,54 +0,0 @@
/*
*
* GStreamer
* Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net>
* Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
/*
* Relicensed for GStreamer from GPL to LGPL with permit from Billy Biggs.
* See: http://bugzilla.gnome.org/show_bug.cgi?id=163578
*/
#ifndef TVTIME_PLUGINS_H_INCLUDED
#define TVTIME_PLUGINS_H_INCLUDED
#define GST_TYPE_DEINTERLACE_TOMSMOCOMP (gst_deinterlace_method_tomsmocomp_get_type ())
#define GST_TYPE_DEINTERLACE_GREEDY_H (gst_deinterlace_method_greedy_h_get_type ())
#define GST_TYPE_DEINTERLACE_GREEDY_L (gst_deinterlace_method_greedy_l_get_type ())
#define GST_TYPE_DEINTERLACE_VFIR (gst_deinterlace_method_vfir_get_type ())
#define GST_TYPE_DEINTERLACE_LINEAR (gst_deinterlace_method_linear_get_type ())
#define GST_TYPE_DEINTERLACE_LINEAR_BLEND (gst_deinterlace_method_linear_blend_get_type ())
#define GST_TYPE_DEINTERLACE_SCALER_BOB (gst_deinterlace_method_scaler_bob_get_type ())
#define GST_TYPE_DEINTERLACE_WEAVE (gst_deinterlace_method_weave_get_type ())
#define GST_TYPE_DEINTERLACE_WEAVE_TFF (gst_deinterlace_method_weave_tff_get_type ())
#define GST_TYPE_DEINTERLACE_WEAVE_BFF (gst_deinterlace_method_weave_bff_get_type ())
GType gst_deinterlace_method_tomsmocomp_get_type (void);
GType gst_deinterlace_method_greedy_h_get_type (void);
GType gst_deinterlace_method_greedy_l_get_type (void);
GType gst_deinterlace_method_vfir_get_type (void);
GType gst_deinterlace_method_linear_get_type (void);
GType gst_deinterlace_method_linear_blend_get_type (void);
GType gst_deinterlace_method_scaler_bob_get_type (void);
GType gst_deinterlace_method_weave_get_type (void);
GType gst_deinterlace_method_weave_tff_get_type (void);
GType gst_deinterlace_method_weave_bff_get_type (void);
#endif /* TVTIME_PLUGINS_H_INCLUDED */

View file

@ -1,74 +0,0 @@
/**
* Double lines
* Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* 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 "_stdint.h"
#include "gstdeinterlace2.h"
#include <string.h>
#define GST_TYPE_DEINTERLACE_METHOD_SCALER_BOB (gst_deinterlace_method_scaler_bob_get_type ())
#define GST_IS_DEINTERLACE_METHOD_SCALER_BOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_SCALER_BOB))
#define GST_IS_DEINTERLACE_METHOD_SCALER_BOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_SCALER_BOB))
#define GST_DEINTERLACE_METHOD_SCALER_BOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_SCALER_BOB, GstDeinterlaceMethodScalerBobClass))
#define GST_DEINTERLACE_METHOD_SCALER_BOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_SCALER_BOB, GstDeinterlaceMethodScalerBob))
#define GST_DEINTERLACE_METHOD_SCALER_BOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_SCALER_BOB, GstDeinterlaceMethodScalerBobClass))
#define GST_DEINTERLACE_METHOD_SCALER_BOB_CAST(obj) ((GstDeinterlaceMethodScalerBob*)(obj))
GType gst_deinterlace_method_scaler_bob_get_type (void);
typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodScalerBob;
typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodScalerBobClass;
static void
deinterlace_scanline_scaler_bob (GstDeinterlaceMethod * self,
GstDeinterlace2 * parent, guint8 * out,
GstDeinterlaceScanlineData * scanlines, gint width)
{
oil_memcpy (out, scanlines->t0, parent->row_stride);
}
G_DEFINE_TYPE (GstDeinterlaceMethodScalerBob, gst_deinterlace_method_scaler_bob,
GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
static void
gst_deinterlace_method_scaler_bob_class_init (GstDeinterlaceMethodScalerBobClass
* klass)
{
GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
GstDeinterlaceSimpleMethodClass *dism_class =
(GstDeinterlaceSimpleMethodClass *) klass;
dim_class->fields_required = 1;
dim_class->name = "Double lines";
dim_class->nick = "scalerbob";
dim_class->latency = 0;
dism_class->interpolate_scanline = deinterlace_scanline_scaler_bob;
}
static void
gst_deinterlace_method_scaler_bob_init (GstDeinterlaceMethodScalerBob * self)
{
}

View file

@ -1,992 +0,0 @@
/* sse.h
Streaming SIMD Extenstions (a.k.a. Katmai New Instructions)
GCC interface library for IA32.
To use this library, simply include this header file
and compile with GCC. You MUST have inlining enabled
in order for sse_ok() to work; this can be done by
simply using -O on the GCC command line.
Compiling with -DSSE_TRACE will cause detailed trace
output to be sent to stderr for each sse operation.
This adds lots of code, and obviously slows execution to
a crawl, but can be very useful for debugging.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR ANY PARTICULAR PURPOSE.
1999 by R. Fisher
Based on libmmx by H. Dietz and R. Fisher
Notes:
This is still extremely alpha.
Because this library depends on an assembler which understands the
SSE opcodes, you probably won't be able to use this yet.
For now, do not use TRACE versions. These both make use
of the MMX registers, not the SSE registers. This will be resolved
at a later date.
ToDo:
Rewrite TRACE macros
Major Debugging Work
*/
#ifndef _SSE_H
#define _SSE_H
/* The type of an value that fits in an SSE register
(note that long long constant values MUST be suffixed
by LL and unsigned long long values by ULL, lest
they be truncated by the compiler)
*/
typedef union {
float sf[4]; /* Single-precision (32-bit) value */
} __attribute__ ((aligned (16))) sse_t; /* On a 16 byte (128-bit) boundary */
#if 0
/* Function to test if multimedia instructions are supported...
*/
inline extern int
mm_support(void)
{
/* Returns 1 if MMX instructions are supported,
3 if Cyrix MMX and Extended MMX instructions are supported
5 if AMD MMX and 3DNow! instructions are supported
9 if MMX and SSE instructions are supported
0 if hardware does not support any of these
*/
register int rval = 0;
__asm__ __volatile__ (
/* See if CPUID instruction is supported ... */
/* ... Get copies of EFLAGS into eax and ecx */
"pushf\n\t"
"popl %%eax\n\t"
"movl %%eax, %%ecx\n\t"
/* ... Toggle the ID bit in one copy and store */
/* to the EFLAGS reg */
"xorl $0x200000, %%eax\n\t"
"push %%eax\n\t"
"popf\n\t"
/* ... Get the (hopefully modified) EFLAGS */
"pushf\n\t"
"popl %%eax\n\t"
/* ... Compare and test result */
"xorl %%eax, %%ecx\n\t"
"testl $0x200000, %%ecx\n\t"
"jz NotSupported1\n\t" /* CPUID not supported */
/* Get standard CPUID information, and
go to a specific vendor section */
"movl $0, %%eax\n\t"
"cpuid\n\t"
/* Check for Intel */
"cmpl $0x756e6547, %%ebx\n\t"
"jne TryAMD\n\t"
"cmpl $0x49656e69, %%edx\n\t"
"jne TryAMD\n\t"
"cmpl $0x6c65746e, %%ecx\n"
"jne TryAMD\n\t"
"jmp Intel\n\t"
/* Check for AMD */
"\nTryAMD:\n\t"
"cmpl $0x68747541, %%ebx\n\t"
"jne TryCyrix\n\t"
"cmpl $0x69746e65, %%edx\n\t"
"jne TryCyrix\n\t"
"cmpl $0x444d4163, %%ecx\n"
"jne TryCyrix\n\t"
"jmp AMD\n\t"
/* Check for Cyrix */
"\nTryCyrix:\n\t"
"cmpl $0x69727943, %%ebx\n\t"
"jne NotSupported2\n\t"
"cmpl $0x736e4978, %%edx\n\t"
"jne NotSupported3\n\t"
"cmpl $0x64616574, %%ecx\n\t"
"jne NotSupported4\n\t"
/* Drop through to Cyrix... */
/* Cyrix Section */
/* See if extended CPUID level 80000001 is supported */
/* The value of CPUID/80000001 for the 6x86MX is undefined
according to the Cyrix CPU Detection Guide (Preliminary
Rev. 1.01 table 1), so we'll check the value of eax for
CPUID/0 to see if standard CPUID level 2 is supported.
According to the table, the only CPU which supports level
2 is also the only one which supports extended CPUID levels.
*/
"cmpl $0x2, %%eax\n\t"
"jne MMXtest\n\t" /* Use standard CPUID instead */
/* Extended CPUID supported (in theory), so get extended
features */
"movl $0x80000001, %%eax\n\t"
"cpuid\n\t"
"testl $0x00800000, %%eax\n\t" /* Test for MMX */
"jz NotSupported5\n\t" /* MMX not supported */
"testl $0x01000000, %%eax\n\t" /* Test for Ext'd MMX */
"jnz EMMXSupported\n\t"
"movl $1, %0:\n\n\t" /* MMX Supported */
"jmp Return\n\n"
"EMMXSupported:\n\t"
"movl $3, %0:\n\n\t" /* EMMX and MMX Supported */
"jmp Return\n\t"
/* AMD Section */
"AMD:\n\t"
/* See if extended CPUID is supported */
"movl $0x80000000, %%eax\n\t"
"cpuid\n\t"
"cmpl $0x80000000, %%eax\n\t"
"jl MMXtest\n\t" /* Use standard CPUID instead */
/* Extended CPUID supported, so get extended features */
"movl $0x80000001, %%eax\n\t"
"cpuid\n\t"
"testl $0x00800000, %%edx\n\t" /* Test for MMX */
"jz NotSupported6\n\t" /* MMX not supported */
"testl $0x80000000, %%edx\n\t" /* Test for 3DNow! */
"jnz ThreeDNowSupported\n\t"
"movl $1, %0:\n\n\t" /* MMX Supported */
"jmp Return\n\n"
"ThreeDNowSupported:\n\t"
"movl $5, %0:\n\n\t" /* 3DNow! and MMX Supported */
"jmp Return\n\t"
/* Intel Section */
"Intel:\n\t"
/* Check for SSE */
"SSEtest:\n\t"
"movl $1, %%eax\n\t"
"cpuid\n\t"
"testl $0x02000000, %%edx\n\t" /* Test for SSE */
"jz MMXtest\n\t" /* SSE Not supported */
"movl $9, %0:\n\n\t" /* SSE Supported */
"jmp Return\n\t"
/* Check for MMX */
"MMXtest:\n\t"
"movl $1, %%eax\n\t"
"cpuid\n\t"
"testl $0x00800000, %%edx\n\t" /* Test for MMX */
"jz NotSupported7\n\t" /* MMX Not supported */
"movl $1, %0:\n\n\t" /* MMX Supported */
"jmp Return\n\t"
/* Nothing supported */
"\nNotSupported1:\n\t"
"#movl $101, %0:\n\n\t"
"\nNotSupported2:\n\t"
"#movl $102, %0:\n\n\t"
"\nNotSupported3:\n\t"
"#movl $103, %0:\n\n\t"
"\nNotSupported4:\n\t"
"#movl $104, %0:\n\n\t"
"\nNotSupported5:\n\t"
"#movl $105, %0:\n\n\t"
"\nNotSupported6:\n\t"
"#movl $106, %0:\n\n\t"
"\nNotSupported7:\n\t"
"#movl $107, %0:\n\n\t"
"movl $0, %0:\n\n\t"
"Return:\n\t"
: "=a" (rval)
: /* no input */
: "eax", "ebx", "ecx", "edx"
);
/* Return */
return(rval);
}
/* Function to test if sse instructions are supported...
*/
inline extern int
sse_ok(void)
{
/* Returns 1 if SSE instructions are supported, 0 otherwise */
return ( (mm_support() & 0x8) >> 3 );
}
#endif
/* Helper functions for the instruction macros that follow...
(note that memory-to-register, m2r, instructions are nearly
as efficient as register-to-register, r2r, instructions;
however, memory-to-memory instructions are really simulated
as a convenience, and are only 1/3 as efficient)
*/
#ifdef SSE_TRACE
/* Include the stuff for printing a trace to stderr...
*/
#include <stdio.h>
#define sse_i2r(op, imm, reg) \
{ \
sse_t sse_trace; \
sse_trace.uq = (imm); \
fprintf(stderr, #op "_i2r(" #imm "=0x%08x%08x, ", \
sse_trace.d[1], sse_trace.d[0]); \
__asm__ __volatile__ ("movq %%" #reg ", %0" \
: "=X" (sse_trace) \
: /* nothing */ ); \
fprintf(stderr, #reg "=0x%08x%08x) => ", \
sse_trace.d[1], sse_trace.d[0]); \
__asm__ __volatile__ (#op " %0, %%" #reg \
: /* nothing */ \
: "X" (imm)); \
__asm__ __volatile__ ("movq %%" #reg ", %0" \
: "=X" (sse_trace) \
: /* nothing */ ); \
fprintf(stderr, #reg "=0x%08x%08x\n", \
sse_trace.d[1], sse_trace.d[0]); \
}
#define sse_m2r(op, mem, reg) \
{ \
sse_t sse_trace; \
sse_trace = (mem); \
fprintf(stderr, #op "_m2r(" #mem "=0x%08x%08x, ", \
sse_trace.d[1], sse_trace.d[0]); \
__asm__ __volatile__ ("movq %%" #reg ", %0" \
: "=X" (sse_trace) \
: /* nothing */ ); \
fprintf(stderr, #reg "=0x%08x%08x) => ", \
sse_trace.d[1], sse_trace.d[0]); \
__asm__ __volatile__ (#op " %0, %%" #reg \
: /* nothing */ \
: "X" (mem)); \
__asm__ __volatile__ ("movq %%" #reg ", %0" \
: "=X" (sse_trace) \
: /* nothing */ ); \
fprintf(stderr, #reg "=0x%08x%08x\n", \
sse_trace.d[1], sse_trace.d[0]); \
}
#define sse_r2m(op, reg, mem) \
{ \
sse_t sse_trace; \
__asm__ __volatile__ ("movq %%" #reg ", %0" \
: "=X" (sse_trace) \
: /* nothing */ ); \
fprintf(stderr, #op "_r2m(" #reg "=0x%08x%08x, ", \
sse_trace.d[1], sse_trace.d[0]); \
sse_trace = (mem); \
fprintf(stderr, #mem "=0x%08x%08x) => ", \
sse_trace.d[1], sse_trace.d[0]); \
__asm__ __volatile__ (#op " %%" #reg ", %0" \
: "=X" (mem) \
: /* nothing */ ); \
sse_trace = (mem); \
fprintf(stderr, #mem "=0x%08x%08x\n", \
sse_trace.d[1], sse_trace.d[0]); \
}
#define sse_r2r(op, regs, regd) \
{ \
sse_t sse_trace; \
__asm__ __volatile__ ("movq %%" #regs ", %0" \
: "=X" (sse_trace) \
: /* nothing */ ); \
fprintf(stderr, #op "_r2r(" #regs "=0x%08x%08x, ", \
sse_trace.d[1], sse_trace.d[0]); \
__asm__ __volatile__ ("movq %%" #regd ", %0" \
: "=X" (sse_trace) \
: /* nothing */ ); \
fprintf(stderr, #regd "=0x%08x%08x) => ", \
sse_trace.d[1], sse_trace.d[0]); \
__asm__ __volatile__ (#op " %" #regs ", %" #regd); \
__asm__ __volatile__ ("movq %%" #regd ", %0" \
: "=X" (sse_trace) \
: /* nothing */ ); \
fprintf(stderr, #regd "=0x%08x%08x\n", \
sse_trace.d[1], sse_trace.d[0]); \
}
#define sse_m2m(op, mems, memd) \
{ \
sse_t sse_trace; \
sse_trace = (mems); \
fprintf(stderr, #op "_m2m(" #mems "=0x%08x%08x, ", \
sse_trace.d[1], sse_trace.d[0]); \
sse_trace = (memd); \
fprintf(stderr, #memd "=0x%08x%08x) => ", \
sse_trace.d[1], sse_trace.d[0]); \
__asm__ __volatile__ ("movq %0, %%mm0\n\t" \
#op " %1, %%mm0\n\t" \
"movq %%mm0, %0" \
: "=X" (memd) \
: "X" (mems)); \
sse_trace = (memd); \
fprintf(stderr, #memd "=0x%08x%08x\n", \
sse_trace.d[1], sse_trace.d[0]); \
}
#else
/* These macros are a lot simpler without the tracing...
*/
#define sse_i2r(op, imm, reg) \
__asm__ __volatile__ (#op " %0, %%" #reg \
: /* nothing */ \
: "X" (imm) )
#define sse_m2r(op, mem, reg) \
__asm__ __volatile__ (#op " %0, %%" #reg \
: /* nothing */ \
: "X" (mem))
#define sse_r2m(op, reg, mem) \
__asm__ __volatile__ (#op " %%" #reg ", %0" \
: "=X" (mem) \
: /* nothing */ )
#define sse_r2r(op, regs, regd) \
__asm__ __volatile__ (#op " %" #regs ", %" #regd)
#define sse_r2ri(op, regs, regd, imm) \
__asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
: /* nothing */ \
: "X" (imm) )
/* Load data from mems to xmmreg, operate on xmmreg, and store data to memd */
#define sse_m2m(op, mems, memd, xmmreg) \
__asm__ __volatile__ ("movups %0, %%xmm0\n\t" \
#op " %1, %%xmm0\n\t" \
"movups %%mm0, %0" \
: "=X" (memd) \
: "X" (mems))
#define sse_m2ri(op, mem, reg, subop) \
__asm__ __volatile__ (#op " %0, %%" #reg ", " #subop \
: /* nothing */ \
: "X" (mem))
#define sse_m2mi(op, mems, memd, xmmreg, subop) \
__asm__ __volatile__ ("movups %0, %%xmm0\n\t" \
#op " %1, %%xmm0, " #subop "\n\t" \
"movups %%mm0, %0" \
: "=X" (memd) \
: "X" (mems))
#endif
/* 1x128 MOVe Aligned four Packed Single-fp
*/
#define movaps_m2r(var, reg) sse_m2r(movaps, var, reg)
#define movaps_r2m(reg, var) sse_r2m(movaps, reg, var)
#define movaps_r2r(regs, regd) sse_r2r(movaps, regs, regd)
#define movaps(vars, vard) \
__asm__ __volatile__ ("movaps %1, %%mm0\n\t" \
"movaps %%mm0, %0" \
: "=X" (vard) \
: "X" (vars))
/* 1x128 MOVe aligned Non-Temporal four Packed Single-fp
*/
#define movntps_r2m(xmmreg, var) sse_r2m(movntps, xmmreg, var)
/* 1x64 MOVe Non-Temporal Quadword
*/
#define movntq_r2m(mmreg, var) sse_r2m(movntq, mmreg, var)
/* 1x128 MOVe Unaligned four Packed Single-fp
*/
#define movups_m2r(var, reg) sse_m2r(movups, var, reg)
#define movups_r2m(reg, var) sse_r2m(movups, reg, var)
#define movups_r2r(regs, regd) sse_r2r(movups, regs, regd)
#define movups(vars, vard) \
__asm__ __volatile__ ("movups %1, %%mm0\n\t" \
"movups %%mm0, %0" \
: "=X" (vard) \
: "X" (vars))
/* MOVe High to Low Packed Single-fp
high half of 4x32f (x) -> low half of 4x32f (y)
*/
#define movhlps_r2r(regs, regd) sse_r2r(movhlps, regs, regd)
/* MOVe Low to High Packed Single-fp
low half of 4x32f (x) -> high half of 4x32f (y)
*/
#define movlhps_r2r(regs, regd) sse_r2r(movlhps, regs, regd)
/* MOVe High Packed Single-fp
2x32f -> high half of 4x32f
*/
#define movhps_m2r(var, reg) sse_m2r(movhps, var, reg)
#define movhps_r2m(reg, var) sse_r2m(movhps, reg, var)
#define movhps(vars, vard) \
__asm__ __volatile__ ("movhps %1, %%mm0\n\t" \
"movhps %%mm0, %0" \
: "=X" (vard) \
: "X" (vars))
/* MOVe Low Packed Single-fp
2x32f -> low half of 4x32f
*/
#define movlps_m2r(var, reg) sse_m2r(movlps, var, reg)
#define movlps_r2m(reg, var) sse_r2m(movlps, reg, var)
#define movlps(vars, vard) \
__asm__ __volatile__ ("movlps %1, %%mm0\n\t" \
"movlps %%mm0, %0" \
: "=X" (vard) \
: "X" (vars))
/* MOVe Scalar Single-fp
lowest field of 4x32f (x) -> lowest field of 4x32f (y)
*/
#define movss_m2r(var, reg) sse_m2r(movss, var, reg)
#define movss_r2m(reg, var) sse_r2m(movss, reg, var)
#define movss_r2r(regs, regd) sse_r2r(movss, regs, regd)
#define movss(vars, vard) \
__asm__ __volatile__ ("movss %1, %%mm0\n\t" \
"movss %%mm0, %0" \
: "=X" (vard) \
: "X" (vars))
/* 4x16 Packed SHUFfle Word
*/
#define pshufw_m2r(var, reg, index) sse_m2ri(pshufw, var, reg, index)
#define pshufw_r2r(regs, regd, index) sse_r2ri(pshufw, regs, regd, index)
/* 1x128 SHUFfle Packed Single-fp
*/
#define shufps_m2r(var, reg, index) sse_m2ri(shufps, var, reg, index)
#define shufps_r2r(regs, regd, index) sse_r2ri(shufps, regs, regd, index)
/* ConVerT Packed signed Int32 to(2) Packed Single-fp
*/
#define cvtpi2ps_m2r(var, xmmreg) sse_m2r(cvtpi2ps, var, xmmreg)
#define cvtpi2ps_r2r(mmreg, xmmreg) sse_r2r(cvtpi2ps, mmreg, xmmreg)
/* ConVerT Packed Single-fp to(2) Packed signed Int32
*/
#define cvtps2pi_m2r(var, mmreg) sse_m2r(cvtps2pi, var, mmreg)
#define cvtps2pi_r2r(xmmreg, mmreg) sse_r2r(cvtps2pi, mmreg, xmmreg)
/* ConVerT with Truncate Packed Single-fp to(2) Packed Int32
*/
#define cvttps2pi_m2r(var, mmreg) sse_m2r(cvttps2pi, var, mmreg)
#define cvttps2pi_r2r(xmmreg, mmreg) sse_r2r(cvttps2pi, mmreg, xmmreg)
/* ConVerT Signed Int32 to(2) Single-fp (Scalar)
*/
#define cvtsi2ss_m2r(var, xmmreg) sse_m2r(cvtsi2ss, var, xmmreg)
#define cvtsi2ss_r2r(reg, xmmreg) sse_r2r(cvtsi2ss, reg, xmmreg)
/* ConVerT Scalar Single-fp to(2) Signed Int32
*/
#define cvtss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg)
#define cvtss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg)
/* ConVerT with Truncate Scalar Single-fp to(2) Signed Int32
*/
#define cvttss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg)
#define cvttss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg)
/* Parallel EXTRact Word from 4x16
*/
#define pextrw_r2r(mmreg, reg, field) sse_r2ri(pextrw, mmreg, reg, field)
/* Parallel INSeRt Word from 4x16
*/
#define pinsrw_r2r(reg, mmreg, field) sse_r2ri(pinsrw, reg, mmreg, field)
/* MOVe MaSK from Packed Single-fp
*/
#ifdef SSE_TRACE
#define movmskps(xmmreg, reg) \
{ \
fprintf(stderr, "movmskps()\n"); \
__asm__ __volatile__ ("movmskps %" #xmmreg ", %" #reg) \
}
#else
#define movmskps(xmmreg, reg) \
__asm__ __volatile__ ("movmskps %" #xmmreg ", %" #reg)
#endif
/* Parallel MOVe MaSK from mmx reg to 32-bit reg
*/
#ifdef SSE_TRACE
#define pmovmskb(mmreg, reg) \
{ \
fprintf(stderr, "movmskps()\n"); \
__asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg) \
}
#else
#define pmovmskb(mmreg, reg) \
__asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
#endif
/* MASKed MOVe from 8x8 to memory pointed to by (e)di register
*/
#define maskmovq(mmregs, fieldreg) sse_r2ri(maskmovq, mmregs, fieldreg)
/* 4x32f Parallel ADDs
*/
#define addps_m2r(var, reg) sse_m2r(addps, var, reg)
#define addps_r2r(regs, regd) sse_r2r(addps, regs, regd)
#define addps(vars, vard, xmmreg) sse_m2m(addps, vars, vard, xmmreg)
/* Lowest Field of 4x32f Parallel ADDs
*/
#define addss_m2r(var, reg) sse_m2r(addss, var, reg)
#define addss_r2r(regs, regd) sse_r2r(addss, regs, regd)
#define addss(vars, vard, xmmreg) sse_m2m(addss, vars, vard, xmmreg)
/* 4x32f Parallel SUBs
*/
#define subps_m2r(var, reg) sse_m2r(subps, var, reg)
#define subps_r2r(regs, regd) sse_r2r(subps, regs, regd)
#define subps(vars, vard, xmmreg) sse_m2m(subps, vars, vard, xmmreg)
/* Lowest Field of 4x32f Parallel SUBs
*/
#define subss_m2r(var, reg) sse_m2r(subss, var, reg)
#define subss_r2r(regs, regd) sse_r2r(subss, regs, regd)
#define subss(vars, vard, xmmreg) sse_m2m(subss, vars, vard, xmmreg)
/* 8x8u -> 4x16u Packed Sum of Absolute Differences
*/
#define psadbw_m2r(var, reg) sse_m2r(psadbw, var, reg)
#define psadbw_r2r(regs, regd) sse_r2r(psadbw, regs, regd)
#define psadbw(vars, vard, mmreg) sse_m2m(psadbw, vars, vard, mmreg)
/* 4x16u Parallel MUL High Unsigned
*/
#define pmulhuw_m2r(var, reg) sse_m2r(pmulhuw, var, reg)
#define pmulhuw_r2r(regs, regd) sse_r2r(pmulhuw, regs, regd)
#define pmulhuw(vars, vard, mmreg) sse_m2m(pmulhuw, vars, vard, mmreg)
/* 4x32f Parallel MULs
*/
#define mulps_m2r(var, reg) sse_m2r(mulps, var, reg)
#define mulps_r2r(regs, regd) sse_r2r(mulps, regs, regd)
#define mulps(vars, vard, xmmreg) sse_m2m(mulps, vars, vard, xmmreg)
/* Lowest Field of 4x32f Parallel MULs
*/
#define mulss_m2r(var, reg) sse_m2r(mulss, var, reg)
#define mulss_r2r(regs, regd) sse_r2r(mulss, regs, regd)
#define mulss(vars, vard, xmmreg) sse_m2m(mulss, vars, vard, xmmreg)
/* 4x32f Parallel DIVs
*/
#define divps_m2r(var, reg) sse_m2r(divps, var, reg)
#define divps_r2r(regs, regd) sse_r2r(divps, regs, regd)
#define divps(vars, vard, xmmreg) sse_m2m(divps, vars, vard, xmmreg)
/* Lowest Field of 4x32f Parallel DIVs
*/
#define divss_m2r(var, reg) sse_m2r(divss, var, reg)
#define divss_r2r(regs, regd) sse_r2r(divss, regs, regd)
#define divss(vars, vard, xmmreg) sse_m2m(divss, vars, vard, xmmreg)
/* 4x32f Parallel Reciprocals
*/
#define rcpps_m2r(var, reg) sse_m2r(rcpps, var, reg)
#define rcpps_r2r(regs, regd) sse_r2r(rcpps, regs, regd)
#define rcpps(vars, vard, xmmreg) sse_m2m(rcpps, vars, vard, xmmreg)
/* Lowest Field of 4x32f Parallel Reciprocals
*/
#define rcpss_m2r(var, reg) sse_m2r(rcpss, var, reg)
#define rcpss_r2r(regs, regd) sse_r2r(rcpss, regs, regd)
#define rcpss(vars, vard, xmmreg) sse_m2m(rcpss, vars, vard, xmmreg)
/* 4x32f Parallel Square Root of Reciprocals
*/
#define rsqrtps_m2r(var, reg) sse_m2r(rsqrtps, var, reg)
#define rsqrtps_r2r(regs, regd) sse_r2r(rsqrtps, regs, regd)
#define rsqrtps(vars, vard, xmmreg) sse_m2m(rsqrtps, vars, vard, xmmreg)
/* Lowest Field of 4x32f Parallel Square Root of Reciprocals
*/
#define rsqrtss_m2r(var, reg) sse_m2r(rsqrtss, var, reg)
#define rsqrtss_r2r(regs, regd) sse_r2r(rsqrtss, regs, regd)
#define rsqrtss(vars, vard, xmmreg) sse_m2m(rsqrtss, vars, vard, xmmreg)
/* 4x32f Parallel Square Roots
*/
#define sqrtps_m2r(var, reg) sse_m2r(sqrtps, var, reg)
#define sqrtps_r2r(regs, regd) sse_r2r(sqrtps, regs, regd)
#define sqrtps(vars, vard, xmmreg) sse_m2m(sqrtps, vars, vard, xmmreg)
/* Lowest Field of 4x32f Parallel Square Roots
*/
#define sqrtss_m2r(var, reg) sse_m2r(sqrtss, var, reg)
#define sqrtss_r2r(regs, regd) sse_r2r(sqrtss, regs, regd)
#define sqrtss(vars, vard, xmmreg) sse_m2m(sqrtss, vars, vard, xmmreg)
/* 8x8u and 4x16u Parallel AVeraGe
*/
#define pavgb_m2r(var, reg) sse_m2r(pavgb, var, reg)
#define pavgb_r2r(regs, regd) sse_r2r(pavgb, regs, regd)
#define pavgb(vars, vard, mmreg) sse_m2m(pavgb, vars, vard, mmreg)
#define pavgw_m2r(var, reg) sse_m2r(pavgw, var, reg)
#define pavgw_r2r(regs, regd) sse_r2r(pavgw, regs, regd)
#define pavgw(vars, vard, mmreg) sse_m2m(pavgw, vars, vard, mmreg)
/* 1x128 bitwise AND
*/
#define andps_m2r(var, reg) sse_m2r(andps, var, reg)
#define andps_r2r(regs, regd) sse_r2r(andps, regs, regd)
#define andps(vars, vard, xmmreg) sse_m2m(andps, vars, vard, xmmreg)
/* 1x128 bitwise AND with Not the destination
*/
#define andnps_m2r(var, reg) sse_m2r(andnps, var, reg)
#define andnps_r2r(regs, regd) sse_r2r(andnps, regs, regd)
#define andnps(vars, vard, xmmreg) sse_m2m(andnps, vars, vard, xmmreg)
/* 1x128 bitwise OR
*/
#define orps_m2r(var, reg) sse_m2r(orps, var, reg)
#define orps_r2r(regs, regd) sse_r2r(orps, regs, regd)
#define orps(vars, vard, xmmreg) sse_m2m(orps, vars, vard, xmmreg)
/* 1x128 bitwise eXclusive OR
*/
#define xorps_m2r(var, reg) sse_m2r(xorps, var, reg)
#define xorps_r2r(regs, regd) sse_r2r(xorps, regs, regd)
#define xorps(vars, vard, xmmreg) sse_m2m(xorps, vars, vard, xmmreg)
/* 8x8u, 4x16, and 4x32f Parallel Maximum
*/
#define pmaxub_m2r(var, reg) sse_m2r(pmaxub, var, reg)
#define pmaxub_r2r(regs, regd) sse_r2r(pmaxub, regs, regd)
#define pmaxub(vars, vard, mmreg) sse_m2m(pmaxub, vars, vard, mmreg)
#define pmaxsw_m2r(var, reg) sse_m2r(pmaxsw, var, reg)
#define pmaxsw_r2r(regs, regd) sse_r2r(pmaxsw, regs, regd)
#define pmaxsw(vars, vard, mmreg) sse_m2m(pmaxsw, vars, vard, mmreg)
#define maxps_m2r(var, reg) sse_m2r(maxps, var, reg)
#define maxps_r2r(regs, regd) sse_r2r(maxps, regs, regd)
#define maxps(vars, vard, xmmreg) sse_m2m(maxps, vars, vard, xmmreg)
/* Lowest Field of 4x32f Parallel Maximum
*/
#define maxss_m2r(var, reg) sse_m2r(maxss, var, reg)
#define maxss_r2r(regs, regd) sse_r2r(maxss, regs, regd)
#define maxss(vars, vard, xmmreg) sse_m2m(maxss, vars, vard, xmmreg)
/* 8x8u, 4x16, and 4x32f Parallel Minimum
*/
#define pminub_m2r(var, reg) sse_m2r(pminub, var, reg)
#define pminub_r2r(regs, regd) sse_r2r(pminub, regs, regd)
#define pminub(vars, vard, mmreg) sse_m2m(pminub, vars, vard, mmreg)
#define pminsw_m2r(var, reg) sse_m2r(pminsw, var, reg)
#define pminsw_r2r(regs, regd) sse_r2r(pminsw, regs, regd)
#define pminsw(vars, vard, mmreg) sse_m2m(pminsw, vars, vard, mmreg)
#define minps_m2r(var, reg) sse_m2r(minps, var, reg)
#define minps_r2r(regs, regd) sse_r2r(minps, regs, regd)
#define minps(vars, vard, xmmreg) sse_m2m(minps, vars, vard, xmmreg)
/* Lowest Field of 4x32f Parallel Minimum
*/
#define minss_m2r(var, reg) sse_m2r(minss, var, reg)
#define minss_r2r(regs, regd) sse_r2r(minss, regs, regd)
#define minss(vars, vard, xmmreg) sse_m2m(minss, vars, vard, xmmreg)
/* 4x32f Parallel CoMPares
(resulting fields are either 0 or -1)
*/
#define cmpps_m2r(var, reg, op) sse_m2ri(cmpps, var, reg, op)
#define cmpps_r2r(regs, regd, op) sse_r2ri(cmpps, regs, regd, op)
#define cmpps(vars, vard, op, xmmreg) sse_m2mi(cmpps, vars, vard, xmmreg, op)
#define cmpeqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 0)
#define cmpeqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 0)
#define cmpeqps(vars, vard, xmmreg) sse_m2mi(cmpps, vars, vard, xmmreg, 0)
#define cmpltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 1)
#define cmpltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 1)
#define cmpltps(vars, vard, xmmreg) sse_m2mi(cmpps, vars, vard, xmmreg, 1)
#define cmpleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 2)
#define cmpleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 2)
#define cmpleps(vars, vard, xmmreg) sse_m2mi(cmpps, vars, vard, xmmreg, 2)
#define cmpunordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 3)
#define cmpunordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 3)
#define cmpunordps(vars, vard, xmmreg) sse_m2mi(cmpps, vars, vard, xmmreg, 3)
#define cmpneqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 4)
#define cmpneqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 4)
#define cmpneqps(vars, vard, xmmreg) sse_m2mi(cmpps, vars, vard, xmmreg, 4)
#define cmpnltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 5)
#define cmpnltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 5)
#define cmpnltps(vars, vard, xmmreg) sse_m2mi(cmpps, vars, vard, xmmreg, 5)
#define cmpnleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 6)
#define cmpnleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 6)
#define cmpnleps(vars, vard, xmmreg) sse_m2mi(cmpps, vars, vard, xmmreg, 6)
#define cmpordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 7)
#define cmpordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 7)
#define cmpordps(vars, vard, xmmreg) sse_m2mi(cmpps, vars, vard, xmmreg, 7)
/* Lowest Field of 4x32f Parallel CoMPares
(resulting fields are either 0 or -1)
*/
#define cmpss_m2r(var, reg, op) sse_m2ri(cmpss, var, reg, op)
#define cmpss_r2r(regs, regd, op) sse_r2ri(cmpss, regs, regd, op)
#define cmpss(vars, vard, op, xmmreg) sse_m2mi(cmpss, vars, vard, xmmreg, op)
#define cmpeqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 0)
#define cmpeqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 0)
#define cmpeqss(vars, vard, xmmreg) sse_m2mi(cmpss, vars, vard, xmmreg, 0)
#define cmpltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 1)
#define cmpltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 1)
#define cmpltss(vars, vard, xmmreg) sse_m2mi(cmpss, vars, vard, xmmreg, 1)
#define cmpless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 2)
#define cmpless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 2)
#define cmpless(vars, vard, xmmreg) sse_m2mi(cmpss, vars, vard, xmmreg, 2)
#define cmpunordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 3)
#define cmpunordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 3)
#define cmpunordss(vars, vard, xmmreg) sse_m2mi(cmpss, vars, vard, xmmreg, 3)
#define cmpneqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 4)
#define cmpneqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 4)
#define cmpneqss(vars, vard, xmmreg) sse_m2mi(cmpss, vars, vard, xmmreg, 4)
#define cmpnltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 5)
#define cmpnltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 5)
#define cmpnltss(vars, vard, xmmreg) sse_m2mi(cmpss, vars, vard, xmmreg, 5)
#define cmpnless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 6)
#define cmpnless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 6)
#define cmpnless(vars, vard, xmmreg) sse_m2mi(cmpss, vars, vard, xmmreg, 6)
#define cmpordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 7)
#define cmpordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 7)
#define cmpordss(vars, vard, xmmreg) sse_m2mi(cmpss, vars, vard, xmmreg, 7)
/* Lowest Field of 4x32f Parallel CoMPares to set EFLAGS
(resulting fields are either 0 or -1)
*/
#define comiss_m2r(var, reg) sse_m2r(comiss, var, reg)
#define comiss_r2r(regs, regd) sse_r2r(comiss, regs, regd)
#define comiss(vars, vard, xmmreg) sse_m2m(comiss, vars, vard, xmmreg)
/* Lowest Field of 4x32f Unordered Parallel CoMPares to set EFLAGS
(resulting fields are either 0 or -1)
*/
#define ucomiss_m2r(var, reg) sse_m2r(ucomiss, var, reg)
#define ucomiss_r2r(regs, regd) sse_r2r(ucomiss, regs, regd)
#define ucomiss(vars, vard, xmmreg) sse_m2m(ucomiss, vars, vard, xmmreg)
/* 2-(4x32f) -> 4x32f UNPaCK Low Packed Single-fp
(interleaves low half of dest with low half of source
as padding in each result field)
*/
#define unpcklps_m2r(var, reg) sse_m2r(unpcklps, var, reg)
#define unpcklps_r2r(regs, regd) sse_r2r(unpcklps, regs, regd)
/* 2-(4x32f) -> 4x32f UNPaCK High Packed Single-fp
(interleaves high half of dest with high half of source
as padding in each result field)
*/
#define unpckhps_m2r(var, reg) sse_m2r(unpckhps, var, reg)
#define unpckhps_r2r(regs, regd) sse_r2r(unpckhps, regs, regd)
/* Fp and mmX ReSTORe state
*/
#ifdef SSE_TRACE
#define fxrstor(mem) \
{ \
fprintf(stderr, "fxrstor()\n"); \
__asm__ __volatile__ ("fxrstor %0" \
: /* nothing */ \
: "X" (mem)) \
}
#else
#define fxrstor(mem) \
__asm__ __volatile__ ("fxrstor %0" \
: /* nothing */ \
: "X" (mem))
#endif
/* Fp and mmX SAVE state
*/
#ifdef SSE_TRACE
#define fxsave(mem) \
{ \
fprintf(stderr, "fxsave()\n"); \
__asm__ __volatile__ ("fxsave %0" \
: /* nothing */ \
: "X" (mem)) \
}
#else
#define fxsave(mem) \
__asm__ __volatile__ ("fxsave %0" \
: /* nothing */ \
: "X" (mem))
#endif
/* STore streaMing simd eXtensions Control/Status Register
*/
#ifdef SSE_TRACE
#define stmxcsr(mem) \
{ \
fprintf(stderr, "stmxcsr()\n"); \
__asm__ __volatile__ ("stmxcsr %0" \
: /* nothing */ \
: "X" (mem)) \
}
#else
#define stmxcsr(mem) \
__asm__ __volatile__ ("stmxcsr %0" \
: /* nothing */ \
: "X" (mem))
#endif
/* LoaD streaMing simd eXtensions Control/Status Register
*/
#ifdef SSE_TRACE
#define ldmxcsr(mem) \
{ \
fprintf(stderr, "ldmxcsr()\n"); \
__asm__ __volatile__ ("ldmxcsr %0" \
: /* nothing */ \
: "X" (mem)) \
}
#else
#define ldmxcsr(mem) \
__asm__ __volatile__ ("ldmxcsr %0" \
: /* nothing */ \
: "X" (mem))
#endif
/* Store FENCE - enforce ordering of stores before fence vs. stores
occuring after fence in source code.
*/
#ifdef SSE_TRACE
#define sfence() \
{ \
fprintf(stderr, "sfence()\n"); \
__asm__ __volatile__ ("sfence\n\t") \
}
#else
#define sfence() \
__asm__ __volatile__ ("sfence\n\t")
#endif
/* PREFETCH data using T0, T1, T2, or NTA hint
T0 = Prefetch into all cache levels
T1 = Prefetch into all cache levels except 0th level
T2 = Prefetch into all cache levels except 0th and 1st levels
NTA = Prefetch data into non-temporal cache structure
*/
#ifdef SSE_TRACE
#else
#define prefetch(mem, hint) \
__asm__ __volatile__ ("prefetch" #hint " %0" \
: /* nothing */ \
: "X" (mem))
#define prefetcht0(mem) prefetch(mem, t0)
#define prefetcht1(mem) prefetch(mem, t1)
#define prefetcht2(mem) prefetch(mem, t2)
#define prefetchnta(mem) prefetch(mem, nta)
#endif
#endif

View file

@ -1,211 +0,0 @@
/**
* Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net>
* Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
*
* This program 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, or (at your option)
* any later version.
*
* This program 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 this program; 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 <stdlib.h>
#include "_stdint.h"
#include <string.h>
#include "gst/gst.h"
#include "gstdeinterlace2.h"
#include "plugins.h"
#define GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP (gst_deinterlace_method_tomsmocomp_get_type ())
#define GST_IS_DEINTERLACE_METHOD_TOMSMOCOMP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP))
#define GST_IS_DEINTERLACE_METHOD_TOMSMOCOMP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP))
#define GST_DEINTERLACE_METHOD_TOMSMOCOMP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP, GstDeinterlaceMethodTomsMoCompClass))
#define GST_DEINTERLACE_METHOD_TOMSMOCOMP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP, GstDeinterlaceMethodTomsMoComp))
#define GST_DEINTERLACE_METHOD_TOMSMOCOMP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP, GstDeinterlaceMethodTomsMoCompClass))
#define GST_DEINTERLACE_METHOD_TOMSMOCOMP_CAST(obj) ((GstDeinterlaceMethodTomsMoComp*)(obj))
GType gst_deinterlace_method_tomsmocomp_get_type (void);
typedef struct
{
GstDeinterlaceMethod parent;
guint search_effort;
gboolean strange_bob;
} GstDeinterlaceMethodTomsMoComp;
typedef struct
{
GstDeinterlaceMethodClass parent_class;
} GstDeinterlaceMethodTomsMoCompClass;
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++) {
oil_memcpy (pDest, pSrc, count);
pSrc += src_pitch;
pDest += dst_pitch;
}
return 0;
}
#define USE_FOR_DSCALER
#define IS_C
#define SIMD_TYPE C
#define FUNCT_NAME tomsmocompDScaler_C
#include "tomsmocomp/TomsMoCompAll.inc"
#undef IS_C
#undef SIMD_TYPE
#undef FUNCT_NAME
#ifdef BUILD_X86_ASM
#include "tomsmocomp/tomsmocompmacros.h"
#include "x86-64_macros.inc"
#define IS_MMX
#define SIMD_TYPE MMX
#define FUNCT_NAME tomsmocompDScaler_MMX
#include "tomsmocomp/TomsMoCompAll.inc"
#undef IS_MMX
#undef SIMD_TYPE
#undef FUNCT_NAME
#define IS_3DNOW
#define SIMD_TYPE 3DNOW
#define FUNCT_NAME tomsmocompDScaler_3DNOW
#include "tomsmocomp/TomsMoCompAll.inc"
#undef IS_3DNOW
#undef SIMD_TYPE
#undef FUNCT_NAME
#define IS_MMXEXT
#define SIMD_TYPE MMXEXT
#define FUNCT_NAME tomsmocompDScaler_MMXEXT
#include "tomsmocomp/TomsMoCompAll.inc"
#undef IS_MMXEXT
#undef SIMD_TYPE
#undef FUNCT_NAME
#endif
G_DEFINE_TYPE (GstDeinterlaceMethodTomsMoComp,
gst_deinterlace_method_tomsmocomp, GST_TYPE_DEINTERLACE_METHOD);
enum
{
ARG_0,
ARG_SEARCH_EFFORT,
ARG_STRANGE_BOB
};
static void
gst_deinterlace_method_tomsmocomp_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstDeinterlaceMethodTomsMoComp *self =
GST_DEINTERLACE_METHOD_TOMSMOCOMP (object);
switch (prop_id) {
case ARG_SEARCH_EFFORT:
self->search_effort = g_value_get_uint (value);
break;
case ARG_STRANGE_BOB:
self->strange_bob = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gst_deinterlace_method_tomsmocomp_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstDeinterlaceMethodTomsMoComp *self =
GST_DEINTERLACE_METHOD_TOMSMOCOMP (object);
switch (prop_id) {
case ARG_SEARCH_EFFORT:
g_value_set_uint (value, self->search_effort);
break;
case ARG_STRANGE_BOB:
g_value_set_boolean (value, self->strange_bob);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gst_deinterlace_method_tomsmocomp_class_init
(GstDeinterlaceMethodTomsMoCompClass * klass)
{
GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
GObjectClass *gobject_class = (GObjectClass *) klass;
#ifdef BUILD_X86_ASM
guint cpu_flags = oil_cpu_get_flags ();
#endif
gobject_class->set_property = gst_deinterlace_method_tomsmocomp_set_property;
gobject_class->get_property = gst_deinterlace_method_tomsmocomp_get_property;
g_object_class_install_property (gobject_class, ARG_SEARCH_EFFORT,
g_param_spec_uint ("search-effort",
"Search Effort",
"Search Effort", 0, 27, 5, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
);
g_object_class_install_property (gobject_class, ARG_STRANGE_BOB,
g_param_spec_boolean ("strange-bob",
"Strange Bob",
"Use strange bob", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
);
dim_class->fields_required = 4;
dim_class->name = "Motion Adaptive: Motion Search";
dim_class->nick = "tomsmocomp";
dim_class->latency = 1;
#ifdef BUILD_X86_ASM
if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) {
dim_class->deinterlace_frame = tomsmocompDScaler_MMXEXT;
} else if (cpu_flags & OIL_IMPL_FLAG_3DNOW) {
dim_class->deinterlace_frame = tomsmocompDScaler_3DNOW;
} else if (cpu_flags & OIL_IMPL_FLAG_MMX) {
dim_class->deinterlace_frame = tomsmocompDScaler_MMX;
} else {
dim_class->deinterlace_frame = tomsmocompDScaler_C;
}
#else
dim_class->deinterlace_frame = tomsmocompDScaler_C;
#endif
}
static void
gst_deinterlace_method_tomsmocomp_init (GstDeinterlaceMethodTomsMoComp * self)
{
self->search_effort = 5;
self->strange_bob = FALSE;
}

View file

@ -1,15 +0,0 @@
// -*- 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

View file

@ -1,174 +0,0 @@
// -*- c++ -*-
// Version for non-SSE2
#ifndef IS_C
#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)
//FIXME: XDX or XAX!!
"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
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,
"st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
#ifdef __MMX__
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
#endif
"memory", "cc"
);
// adjust for next line
pSrc += src_pitch2;
pSrcP += src_pitch2;
pDest += dst_pitch2;
pBob += src_pitch2;
pBobP += src_pitch2;
}
return 0;
#else
#ifdef SKIP_SEARCH
out[0] = best[0]; // just use the results of our wierd bob
out[1] = best[1];
#else
diff[0] = diff[0] - MIN (diff[0], 10) - 4;
diff[1] = diff[1] - MIN (diff[1] - 10) - 4;
if (diff[0] < 0)
out[0] = weave[0];
else
out[0] = best[0];
if (diff[1] < 0)
out[1] = weave[1];
else
out[1] = best[1];
out[0] = CLAMP (out[0], MinVals[0], MaxVals[0]);
out[1] = CLAMP (out[1], MinVals[1], MaxVals[1]);
#endif
#ifdef USE_VERTICAL_FILTER
pDest[x] = (out[0] + pBob[0]) / 2;
pDest[x + dst_pitchw] = (pBob[src_pitch2] + out[0]) / 2;
pDest[x + 1] = (out[1] + pBob[1]) / 2;
pDest[x + 1 + dst_pitchw] = (pBob[src_pitch2 + 1] + out[1]) / 2;
#else
pDest[x] = out[0];
pDest[x+1] = out[1];
#endif
pBob += 2;
pBobP += 2;
pSrc += 2;
pSrcP += 2;
}
// adjust for next line
pSrc = src_pitch2 * (y+1) + pWeaveSrc;
pSrcP = src_pitch2 * (y+1) + pWeaveSrcP;
pDest = dst_pitch2 * (y+1) + pWeaveDest + dst_pitch2;
if (TopFirst)
{
pBob = pCopySrc + src_pitch2;
pBobP = pCopySrcP + src_pitch2;
}
else
{
pBob = pCopySrc;
pBobP = pCopySrcP;
}
pBob += src_pitch2 * (y+1);
pBobP += src_pitch2 * (y+1);
}
return 0;
#endif

View file

@ -1,11 +0,0 @@
// -*- 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

View file

@ -1,12 +0,0 @@
// -*- 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

View file

@ -1,10 +0,0 @@
// -*- 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"

View file

@ -1,5 +0,0 @@
// 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

View file

@ -1,11 +0,0 @@
// -*- 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

View file

@ -1,10 +0,0 @@
// 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
}

View file

@ -1,5 +0,0 @@
// 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

View file

@ -1,254 +0,0 @@
// -*- c++ -*-
unsigned char* pDest;
const unsigned char* pSrcP;
const unsigned char* pSrc;
const unsigned char* pBob;
const unsigned char* pBobP;
// 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 interleaved in DScaler
#else
long src_pitch2 = 2 * src_pitch; // even & odd lines are interleaved in Avisynth
#endif
long dst_pitch2 = 2 * dst_pitch;
long y;
long Last8;
pSrc = pWeaveSrc; // points 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 IS_C
#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
Last8 = (rowsize-8);
for (y=1; y < FldHeight-1; y++)
{
long dst_pitchw = dst_pitch; // local stor so asm can ref
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 oldbx;
// 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"
// 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 maintain
// 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
#else
Last8 = (rowsize - 4);
for (y=1; y < FldHeight-1; y++)
{
#ifdef USE_STRANGE_BOB
long DiffThres = 0x0f;
#endif
#ifndef SKIP_SEARCH
long weave[2], MaxVals[2], MinVals[2];
#endif
long diff[2], best[2], avg[2], diff2[2], out[2], x;
#ifdef USE_VERTICAL_FILTER
pDest[0] = (3 * pBob[0] + pBob[src_pitch2]) / 4;
pDest[1] = (3 * pBob[1] + pBob[src_pitch2 + 1]) / 4;
pDest[2] = (3 * pBob[2] + pBob[src_pitch2 + 2]) / 4;
pDest[3] = (3 * pBob[3] + pBob[src_pitch2 + 3]) / 4;
pDest[dst_pitchw] = (pBob[0] + 3 * pBob[src_pitch2]) / 4;
pDest[dst_pitchw + 1] = (pBob[1] + 3 * pBob[src_pitch2 + 1]) / 4;
pDest[dst_pitchw + 2] = (pBob[2] + 3 * pBob[src_pitch2 + 2]) / 4;
pDest[dst_pitchw + 3] = (pBob[3] + 3 * pBob[src_pitch2 + 3]) / 4;
// simple bob last byte
pDest[Last8] = (3 * pBob[Last8] + pBob[Last8 + src_pitch2]) / 4;
pDest[Last8 + 1] = (3 * pBob[Last8 + 1] + pBob[Last8 + src_pitch2 + 1]) / 4;
pDest[Last8 + 2] = (3 * pBob[Last8 + 2] + pBob[Last8 + src_pitch2 + 2]) / 4;
pDest[Last8 + 3] = (3 * pBob[Last8 + 3] + pBob[Last8 + src_pitch2 + 3]) / 4;
pDest[Last8 + src_pitch2] = (pBob[Last8] + 3 * pBob[Last8 + src_pitch2]) / 4;
pDest[Last8 + src_pitch2 + 1] = (pBob[Last8 + 1] + 3 * pBob[Last8 + src_pitch2 + 1]) / 4;
pDest[Last8 + src_pitch2 + 2] = (pBob[Last8 + 2] + 3 * pBob[Last8 + src_pitch2 + 2]) / 4;
pDest[Last8 + src_pitch2 + 3] = (pBob[Last8 + 3] + 3 * pBob[Last8 + src_pitch2 + 3]) / 4;
#else
pDest[0] = (pBob[0] + pBob[src_pitch2 + 1]) / 2;
pDest[1] = (pBob[1] + pBob[src_pitch2 + 1]) / 2;
pDest[2] = (pBob[2] + pBob[src_pitch2 + 2]) / 2;
pDest[3] = (pBob[3] + pBob[src_pitch2 + 3]) / 2;
// simple bob last byte
pDest[Last8] = (pBob[Last8] + pBob[Last8 + src_pitch2]) / 2;
pDest[Last8 + 1] = (pBob[Last8 + 1] + pBob[Last8 + src_pitch2 + 1]) / 2;
pDest[Last8 + 2] = (pBob[Last8 + 2] + pBob[Last8 + src_pitch2 + 2]) / 2;
pDest[Last8 + 3] = (pBob[Last8 + 3] + pBob[Last8 + src_pitch2 + 3]) / 2;
#endif
pBob += 4;
pBobP += 4;
pSrc += 4;
pSrcP += 4;
for (x=4; x < Last8; x += 2) {
#ifdef USE_STRANGE_BOB
#include "StrangeBob.inc"
#else
#include "WierdBob.inc"
#endif
// 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
diff[0] = diff[1] = 255;
#endif

View file

@ -1,6 +0,0 @@
// -*- 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

View file

@ -1,6 +0,0 @@
// -*- 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

View file

@ -1,435 +0,0 @@
// -*- 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)
#ifndef IS_C
// 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"
V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // 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
#else
diff[0] = -1;
diff[1] = -1;
best[0] = 0;
best[1] = 0;
// j, n
if (ABS (pBob[-2] - pBob[src_pitch2 - 4]) < DiffThres &&
ABS (pBob[-4] - pBob[src_pitch2 + 4]) > DiffThres) {
best[0] = (pBob[-2] + pBob[src_pitch2 - 4]) / 2;
diff[0] = ABS (pBob[-2] - pBob[src_pitch2 - 4]);
}
if (ABS (pBob[-1] - pBob[src_pitch2 - 3]) < DiffThres &&
ABS (pBob[-3] - pBob[src_pitch2 + 5]) > DiffThres) {
best[1] = (pBob[-1] + pBob[src_pitch2 - 3]) / 2;
diff[1] = ABS (pBob[-1] - pBob[src_pitch2 - 3]);
}
// k & m
if (ABS (pBob[2] - pBob[src_pitch2 + 4]) < DiffThres &&
ABS (pBob[4] - pBob[src_pitch2 - 4]) > DiffThres) {
best[0] = (pBob[4] + pBob[src_pitch2 - 4]) / 2;
diff[0] = ABS (pBob[4] - pBob[src_pitch2 - 4]);
}
if (ABS (pBob[3] - pBob[src_pitch2 + 5]) < DiffThres &&
ABS (pBob[5] - pBob[src_pitch2 - 3]) > DiffThres) {
best[1] = (pBob[5] + pBob[src_pitch2 - 3]) / 2;
diff[1] = ABS (pBob[5] - pBob[src_pitch2 - 3]);
}
// c & d
if (ABS (pBob[0] - pBob[src_pitch2 + 2]) < DiffThres &&
ABS (pBob[2] - pBob[src_pitch2 - 2]) > DiffThres) {
best[0] = (pBob[2] + pBob[src_pitch2 - 2]) / 2;
diff[0] = ABS (pBob[2] - pBob[src_pitch2 - 2]);
}
if (ABS (pBob[1] - pBob[src_pitch2 + 3]) < DiffThres &&
ABS (pBob[3] - pBob[src_pitch2 - 1]) > DiffThres) {
best[1] = (pBob[3] + pBob[src_pitch2 - 1]) / 2;
diff[1] = ABS (pBob[3] - pBob[src_pitch2 - 1]);
}
// a & f
if (ABS (pBob[0] - pBob[src_pitch2 - 2]) < DiffThres &&
ABS (pBob[-2] - pBob[src_pitch2 + 2]) > DiffThres) {
best[0] = (pBob[-2] + pBob[src_pitch2 + 2]) / 2;
diff[0] = ABS (pBob[-2] - pBob[src_pitch2 + 2]);
}
if (ABS (pBob[1] - pBob[src_pitch2 - 1]) < DiffThres &&
ABS (pBob[-1] - pBob[src_pitch2 + 3]) > DiffThres) {
best[1] = (pBob[-1] + pBob[src_pitch2 + 3]) / 2;
diff[1] = ABS (pBob[-1] - pBob[src_pitch2 + 3]);
}
// b,e
if (ABS (pBob[0] - pBob[src_pitch2]) < DiffThres) {
best[0] = (pBob[0] + pBob[src_pitch2]) / 2;
diff[0] = ABS (pBob[0] - pBob[src_pitch2]);
}
if (ABS (pBob[1] - pBob[src_pitch2 + 1]) < DiffThres) {
best[1] = (pBob[1] + pBob[src_pitch2 + 1]) / 2;
diff[1] = ABS (pBob[1] - pBob[src_pitch2 + 1]);
}
// 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
best[0] = CLAMP (best[0], MIN (pBob[src_pitch2], pBob[0]), MAX (pBob[src_pitch2], pBob[0]));
best[1] = CLAMP (best[1], MIN (pBob[src_pitch2 + 1], pBob[1]), MAX (pBob[src_pitch2 + 1], pBob[1]));
#else
mov[0] = MAX (ABS (pBob[0] - pBobP[0]), ABS (pBob[src_pitch2] - pBobP[src_pitch2]));
mov[1] = MAX (ABS (pBob[1] - pBobP[1]), ABS (pBob[src_pitch2 + 1] - pBobP[src_pitch2 + 1]));
MinVals[0] = 0;
MinVals[1] = 0;
MaxVals[0] = 255;
MaxVals[1] = 255;
if (mov[0] > DiffThres) {
MinVals[0] = MAX (MIN (pBob[0], pBob[src_pitch2]), best[0]);
MaxVals[0] = MIN (MAX (pBob[0], pBob[src_pitch2]), best[0]);
}
if (mov[1] > DiffThres) {
MinVals[1] = MAX (MIN (pBob[1], pBob[src_pitch2+1]), best[1]);
MaxVals[1] = MIN (MAX (pBob[1], pBob[src_pitch2+1]), best[1]);
}
best[0] = CLAMP (best[0], MIN (pBob[src_pitch2], pBob[0]), MAX (pBob[src_pitch2], pBob[0]));
best[1] = CLAMP (best[1], MIN (pBob[src_pitch2 + 1], pBob[1]), MAX (pBob[src_pitch2 + 1], pBob[1]));
#endif
avg[0] = (pBob[src_pitch2] + pBob[0]) / 2;
avg[1] = (pBob[src_pitch2 + 1] + pBob[1]) / 2;
diff2[0] = ABS (pBob[src_pitch2 + 1] - pBob[1]);
diff2[1] = ABS (pBob[src_pitch2 + 1] - pBob[1]);
if (diff[0] == -1 || diff2[0] < diff[0]) {
best[0] = avg[0];
diff[0] = diff2[0];
}
if (diff[1] == -1 || diff2[1] < diff[1]) {
best[1] = avg[1];
diff[1] = diff2[1];
}
#endif

View file

@ -1,241 +0,0 @@
/*
* GStreamer
* Copyright (c) 2002 Tom Barry All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
/*
* Relicensed for GStreamer from GPL to LGPL with permit from Tom Barry.
* See: http://bugzilla.gnome.org/show_bug.cgi?id=163578
*/
#ifndef TopFirst
#define TopFirst IsOdd
#endif
#ifdef SEFUNC
#undef SEFUNC
#endif
#if defined(IS_MMXEXT)
#define SEFUNC(x) Search_Effort_MMXEXT_##x(int src_pitch, int dst_pitch, int rowsize, const unsigned char *pWeaveSrc, const unsigned char *pWeaveSrcP, unsigned char *pWeaveDest, int IsOdd, const unsigned char *pCopySrc, const unsigned char *pCopySrcP, int FldHeight)
#elif defined(IS_3DNOW)
#define SEFUNC(x) Search_Effort_3DNOW_##x(int src_pitch, int dst_pitch, int rowsize, const unsigned char *pWeaveSrc, const unsigned char *pWeaveSrcP, unsigned char *pWeaveDest, int IsOdd, const unsigned char *pCopySrc, const unsigned char *pCopySrcP, int FldHeight)
#elif defined(IS_MMX)
#define SEFUNC(x) Search_Effort_MMX_##x(int src_pitch, int dst_pitch, int rowsize, const unsigned char *pWeaveSrc, const unsigned char *pWeaveSrcP, unsigned char *pWeaveDest, int IsOdd, const unsigned char *pCopySrc, const unsigned char *pCopySrcP, int FldHeight)
#else
#define SEFUNC(x) Search_Effort_C_##x(int src_pitch, int dst_pitch, int rowsize, const unsigned char *pWeaveSrc, const unsigned char *pWeaveSrcP, unsigned char *pWeaveDest, int IsOdd, const unsigned char *pCopySrc, const unsigned char *pCopySrcP, int FldHeight)
#endif
#include "TomsMoCompAll2.inc"
#define USE_STRANGE_BOB
#include "TomsMoCompAll2.inc"
#undef USE_STRANGE_BOB
#undef SEFUNC
#if defined(IS_MMXEXT)
#define SEFUNC(x) Search_Effort_MMXEXT_##x(src_pitch, dst_pitch, rowsize, pWeaveSrc, pWeaveSrcP, pWeaveDest, IsOdd, pCopySrc, pCopySrcP, FldHeight)
#elif defined(IS_3DNOW)
#define SEFUNC(x) Search_Effort_3DNOW_##x(src_pitch, dst_pitch, rowsize, pWeaveSrc, pWeaveSrcP, pWeaveDest, IsOdd, pCopySrc, pCopySrcP, FldHeight)
#elif defined(IS_MMX)
#define SEFUNC(x) Search_Effort_MMX_##x(src_pitch, dst_pitch, rowsize, pWeaveSrc, pWeaveSrcP, pWeaveDest, IsOdd, pCopySrc, pCopySrcP, FldHeight)
#else
#define SEFUNC(x) Search_Effort_C_##x(src_pitch, dst_pitch, rowsize, pWeaveSrc, pWeaveSrcP, pWeaveDest, IsOdd, pCopySrc, pCopySrcP, FldHeight)
#endif
void FUNCT_NAME(GstDeinterlaceMethod *d_method, GstDeinterlace2* object, GstBuffer *outbuf)
{
GstDeinterlaceMethodTomsMoComp *self = GST_DEINTERLACE_METHOD_TOMSMOCOMP (d_method);
long SearchEffort = self->search_effort;
int UseStrangeBob = self->strange_bob;
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;
/* double stride do address just every odd/even scanline */
src_pitch = object->field_stride;
dst_pitch = object->row_stride;
rowsize = object->row_stride;
FldHeight = object->field_height;
pCopySrc = GST_BUFFER_DATA(object->field_history[object->history_count-1].buf);
pCopySrcP = GST_BUFFER_DATA(object->field_history[object->history_count-3].buf);
pWeaveSrc = GST_BUFFER_DATA(object->field_history[object->history_count-2].buf);
pWeaveSrcP = GST_BUFFER_DATA(object->field_history[object->history_count-4].buf);
/* use bottom field and interlace top field */
if (object->field_history[object->history_count-2].flags == PICTURE_INTERLACED_BOTTOM) {
IsOdd = 1;
// if we have an odd field we copy an even field and weave an odd field
pCopyDest = GST_BUFFER_DATA(outbuf);
pWeaveDest = pCopyDest + dst_pitch;
}
/* do it vice verca */
else {
IsOdd = 0;
// if we have an even field we copy an odd field and weave an even field
pCopyDest = GST_BUFFER_DATA(outbuf) + dst_pitch;
pWeaveDest = GST_BUFFER_DATA(outbuf);
}
// 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) {
if (SearchEffort == 0)
{
SEFUNC(0);
}
else if (SearchEffort <= 1)
{
SEFUNC(1);
}
/* else if (SearchEffort <= 2)
{
SEFUNC(2);
}
*/
else if (SearchEffort <= 3)
{
SEFUNC(3);
}
else if (SearchEffort <= 5)
{
SEFUNC(5);
}
else if (SearchEffort <= 9)
{
SEFUNC(9);
}
else if (SearchEffort <= 11)
{
SEFUNC(11);
}
else if (SearchEffort <= 13)
{
SEFUNC(13);
}
else if (SearchEffort <= 15)
{
SEFUNC(15);
}
else if (SearchEffort <= 19)
{
SEFUNC(19);
}
else if (SearchEffort <= 21)
{
SEFUNC(21);
}
else
{
SEFUNC(Max);
}
}
else
{
if (SearchEffort == 0)
{
SEFUNC(0SB);
}
else if (SearchEffort <= 1)
{
SEFUNC(1SB);
}
/* else if (SearchEffort <= 2)
{
SEFUNC(2SB);
}
*/
else if (SearchEffort <= 3)
{
SEFUNC(3SB);
}
else if (SearchEffort <= 5)
{
SEFUNC(5SB);
}
else if (SearchEffort <= 9)
{
SEFUNC(9SB);
}
else if (SearchEffort <= 11)
{
SEFUNC(11SB);
}
else if (SearchEffort <= 13)
{
SEFUNC(13SB);
}
else if (SearchEffort <= 15)
{
SEFUNC(15SB);
}
else if (SearchEffort <= 19)
{
SEFUNC(19SB);
}
else if (SearchEffort <= 21)
{
SEFUNC(21SB);
}
else
{
SEFUNC(MaxSB);
}
}
#if defined(BUILD_X86_ASM) && !defined(IS_C)
__asm__ __volatile__("emms");
#endif
}

View file

@ -1,243 +0,0 @@
// -*- 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
static inline int 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
}
static inline int SEARCH_EFFORT_FUNC(1)
{
#ifdef IS_C
#define SKIP_SEARCH
#include "SearchLoopTop.inc"
#include "SearchLoopBottom.inc"
#undef SKIP_SEARCH
#else
//see Search_Effort_Max() for comments
#include "SearchLoopTop.inc"
RESET_CHROMA // pretend chroma diffs was 255 each
#include "SearchLoop0A.inc"
#include "SearchLoopBottom.inc"
#endif
}
static inline int SEARCH_EFFORT_FUNC(3)
{
#ifdef IS_C
#define SKIP_SEARCH
#include "SearchLoopTop.inc"
#include "SearchLoopBottom.inc"
#undef SKIP_SEARCH
#else
//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"
#endif
}
static inline int SEARCH_EFFORT_FUNC(5)
{
#ifdef IS_C
#define SKIP_SEARCH
#include "SearchLoopTop.inc"
#include "SearchLoopBottom.inc"
#undef SKIP_SEARCH
#else
//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"
#endif
}
// 3x3 search
static inline int SEARCH_EFFORT_FUNC(9)
{
#ifdef IS_C
#define SKIP_SEARCH
#include "SearchLoopTop.inc"
#include "SearchLoopBottom.inc"
#undef SKIP_SEARCH
#else
//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"
#endif
}
// Search 9 with 2 H-half pels added
static inline int SEARCH_EFFORT_FUNC(11)
{
#ifdef IS_C
#define SKIP_SEARCH
#include "SearchLoopTop.inc"
#include "SearchLoopBottom.inc"
#undef SKIP_SEARCH
#else
//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"
#endif
}
// Search 11 with 2 V-half pels added
static inline int SEARCH_EFFORT_FUNC(13)
{
#ifdef IS_C
#define SKIP_SEARCH
#include "SearchLoopTop.inc"
#include "SearchLoopBottom.inc"
#undef SKIP_SEARCH
#else
//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"
#endif
}
// 5x3
static inline int SEARCH_EFFORT_FUNC(15)
{
#ifdef IS_C
#define SKIP_SEARCH
#include "SearchLoopTop.inc"
#include "SearchLoopBottom.inc"
#undef SKIP_SEARCH
#else
//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"
#endif
}
// 5x3 + 4 half pels
static inline int SEARCH_EFFORT_FUNC(19)
{
#ifdef IS_C
#define SKIP_SEARCH
#include "SearchLoopTop.inc"
#include "SearchLoopBottom.inc"
#undef SKIP_SEARCH
#else
//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"
#endif
}
// Handle one 4x1 block of pixels
// Search a 7x3 area, no half pels
static inline int SEARCH_EFFORT_FUNC(21)
{
#ifdef IS_C
#define SKIP_SEARCH
#include "SearchLoopTop.inc"
#include "SearchLoopBottom.inc"
#undef SKIP_SEARCH
#else
//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"
#endif
}
// Handle one 4x1 block of pixels
// Search a 9x3 area, no half pels
static inline int SEARCH_EFFORT_FUNC(Max)
{
#ifdef IS_C
#define SKIP_SEARCH
#include "SearchLoopTop.inc"
#include "SearchLoopBottom.inc"
#undef SKIP_SEARCH
#else
//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"
#endif
}
#undef SEARCH_EFFORT_FUNC

View file

@ -1,286 +0,0 @@
// -*- 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.
#ifndef IS_C
// 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
#else
// a,f
best[0] = (pBob[-2] + pBob[src_pitch2 + 2]) / 2;
diff[0] = ABS (pBob[-2] - pBob[src_pitch2 + 2]);
best[1] = (pBob[-1] + pBob[src_pitch2 + 3]) / 2;
diff[1] = ABS (pBob[-1] - pBob[src_pitch2 + 3]);
// c,d
if (ABS (pBob[2] - pBob[src_pitch2 - 2]) < diff[0]) {
best[0] = (pBob[2] + pBob[src_pitch2 - 2]) / 2;
diff[0] = ABS (pBob[2] - pBob[src_pitch2 - 2]);
}
if (ABS (pBob[3] - pBob[src_pitch2 - 1]) < diff[1]) {
best[1] = (pBob[3] + pBob[src_pitch2 - 1]) / 2;
diff[1] = ABS (pBob[3] - pBob[src_pitch2 - 1]);
}
// j,n
if (ABS (pBob[-4] - pBob[src_pitch2 + 4]) < diff[0]) {
best[0] = (pBob[-4] + pBob[src_pitch2 + 4]) / 2;
diff[0] = ABS (pBob[-4] - pBob[src_pitch2 + 4]);
}
if (ABS (pBob[-3] - pBob[src_pitch2 + 5]) < diff[1]) {
best[1] = (pBob[-3] + pBob[src_pitch2 + 5]) / 2;
diff[1] = ABS (pBob[-3] - pBob[src_pitch2 + 5]);
}
// k,m
if (ABS (pBob[4] - pBob[src_pitch2 - 4]) < diff[0]) {
best[0] = (pBob[4] + pBob[src_pitch2 - 4]) / 2;
diff[0] = ABS (pBob[-4] - pBob[src_pitch2 - 4]);
}
if (ABS (pBob[5] - pBob[src_pitch2 - 3]) < diff[1]) {
best[1] = (pBob[5] + pBob[src_pitch2 - 3]) / 2;
diff[1] = ABS (pBob[-3] - pBob[src_pitch2 - 3]);
}
// k,m
if (ABS (pBob[4] - pBob[src_pitch2 - 4]) < diff[0]) {
best[0] = (pBob[4] + pBob[src_pitch2 - 4]) / 2;
diff[0] = ABS (pBob[-4] - pBob[src_pitch2 - 4]);
}
if (ABS (pBob[5] - pBob[src_pitch2 - 3]) < diff[1]) {
best[1] = (pBob[5] + pBob[src_pitch2 - 3]) / 2;
diff[1] = ABS (pBob[-3] - pBob[src_pitch2 - 3]);
}
// 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
best[0] = CLAMP (best[0], MIN (pBob[src_pitch2], pBob[0]), MAX (pBob[src_pitch2], pBob[0]));
best[1] = CLAMP (best[1], MIN (pBob[src_pitch2 + 1], pBob[1]), MAX (pBob[src_pitch2 + 1], pBob[1]));
#else
mov[0] = MAX (ABS (pBob[0] - pBobP[0]), ABS (pBob[src_pitch2] - pBobP[src_pitch2]));
mov[1] = MAX (ABS (pBob[1] - pBobP[1]), ABS (pBob[src_pitch2 + 1] - pBobP[src_pitch2 + 1]));
MinVals[0] = 0;
MinVals[1] = 0;
MaxVals[0] = 255;
MaxVals[1] = 255;
if (mov[0] > Max_Mov[0]) {
MinVals[0] = MAX (MIN (pBob[0], pBob[src_pitch2]), best[0]);
MaxVals[0] = MIN (MAX (pBob[0], pBob[src_pitch2]), best[0]);
}
if (mov[1] > Max_Mov[1]) {
MinVals[1] = MAX (MIN (pBob[1], pBob[src_pitch2 + 1]), best[1]);
MaxVals[1] = MIN (MAX (pBob[1], pBob[src_pitch2 + 1]), best[1]);
}
best[0] = CLAMP (best[0], MIN (pBob[src_pitch2], pBob[0]), MAX (pBob[src_pitch2], pBob[0]));
best[1] = CLAMP (best[1], MIN (pBob[src_pitch2 + 1], pBob[1]), MAX (pBob[src_pitch2 + 1], pBob[1]));
#endif
avg[0] = (pBob[src_pitch2] + pBob[0]) / 2;
avg[1] = (pBob[src_pitch2 + 1] + pBob[1]) / 2;
diff2[0] = ABS (pBob[src_pitch2] - pBob[0]);
diff2[1] = ABS (pBob[src_pitch2 + 1] - pBob[1]);
if (diff2[0] < diff[0]) {
best[0] = avg[0];
diff[0] = diff2[0];
}
if (diff2[1] < diff[1]) {
best[1] = avg[1];
diff[1] = diff2[1];
}
#endif

View file

@ -1,164 +0,0 @@
#include <string.h>
#include <math.h>
// 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 SIMD_TYPE MMXEXT (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_MMXEXT(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, SIMD_TYPE)
#define V_PAVGB2(mmr1, mmr2, mmrw, smask, simd_type) V_PAVGB3(mmr1, mmr2, mmrw, smask, simd_type)
#define V_PAVGB3(mmr1, mmr2, mmrw, smask, simd_type) V_PAVGB_##simd_type(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_MMXEXT(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, SIMD_TYPE)
#define V_PMAXUB2(mmr1, mmr2, simd_type) V_PMAXUB3(mmr1, mmr2, simd_type)
#define V_PMAXUB3(mmr1, mmr2, simd_type) V_PMAXUB_##simd_type(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_MMXEXT(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, SIMD_TYPE)
#define V_PMINUB2(mmr1, mmr2, mmrw, simd_type) V_PMINUB3(mmr1, mmr2, mmrw, simd_type)
#define V_PMINUB3(mmr1, mmr2, mmrw, simd_type) V_PMINUB_##simd_type(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_MMXEXT(mmr1, mmr2) "movntq "mmr2", "mmr1"\n\t"
#define V_MOVNTQ(mmr1, mmr2) V_MOVNTQ2(mmr1, mmr2, SIMD_TYPE)
#define V_MOVNTQ2(mmr1, mmr2, simd_type) V_MOVNTQ3(mmr1, mmr2, simd_type)
#define V_MOVNTQ3(mmr1, mmr2, simd_type) V_MOVNTQ_##simd_type(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

View file

@ -1,187 +0,0 @@
/*
*
* GStreamer
* Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net>
* Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
* Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
/*
* This file contains code from ffmpeg, see http://ffmpeg.org/ (LGPL)
* and modifications by Billy Biggs.
*
* Relicensed for GStreamer from GPL to LGPL with permit from Billy Biggs.
* See: http://bugzilla.gnome.org/show_bug.cgi?id=163578
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "_stdint.h"
#include "gstdeinterlace2.h"
#include <string.h>
#define GST_TYPE_DEINTERLACE_METHOD_VFIR (gst_deinterlace_method_vfir_get_type ())
#define GST_IS_DEINTERLACE_METHOD_VFIR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_VFIR))
#define GST_IS_DEINTERLACE_METHOD_VFIR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_VFIR))
#define GST_DEINTERLACE_METHOD_VFIR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_VFIR, GstDeinterlaceMethodVFIRClass))
#define GST_DEINTERLACE_METHOD_VFIR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_VFIR, GstDeinterlaceMethodVFIR))
#define GST_DEINTERLACE_METHOD_VFIR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_VFIR, GstDeinterlaceMethodVFIRClass))
#define GST_DEINTERLACE_METHOD_VFIR_CAST(obj) ((GstDeinterlaceMethodVFIR*)(obj))
GType gst_deinterlace_method_vfir_get_type (void);
typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodVFIR;
typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodVFIRClass;
/*
* The MPEG2 spec uses a slightly harsher filter, they specify
* [-1 8 2 8 -1]. ffmpeg uses a similar filter but with more of
* a tendancy to blur than to use the local information. The
* filter taps here are: [-1 4 2 4 -1].
*/
/**
* C implementation.
*/
static inline void
deinterlace_line_c (GstDeinterlaceMethod * self, GstDeinterlace2 * parent,
guint8 * dst, GstDeinterlaceScanlineData * scanlines, gint width)
{
gint sum;
guint8 *lum_m4 = scanlines->tt1;
guint8 *lum_m3 = scanlines->t0;
guint8 *lum_m2 = scanlines->m1;
guint8 *lum_m1 = scanlines->b0;
guint8 *lum = scanlines->bb1;
gint size = width * 2;
for (; size >= 0; size--) {
sum = -lum_m4[0];
sum += lum_m3[0] << 2;
sum += lum_m2[0] << 1;
sum += lum_m1[0] << 2;
sum += -lum[0];
dst[0] = (sum + 4) >> 3; // This needs to be clipped at 0 and 255: cm[(sum + 4) >> 3];
lum_m4++;
lum_m3++;
lum_m2++;
lum_m1++;
lum++;
dst++;
}
}
#ifdef BUILD_X86_ASM
#include "mmx.h"
static void
deinterlace_line_mmx (GstDeinterlaceMethod * self, GstDeinterlace2 * parent,
guint8 * dst, GstDeinterlaceScanlineData * scanlines, gint width)
{
mmx_t rounder;
guint8 *lum_m4 = scanlines->tt1;
guint8 *lum_m3 = scanlines->t0;
guint8 *lum_m2 = scanlines->m1;
guint8 *lum_m1 = scanlines->b0;
guint8 *lum = scanlines->bb1;
rounder.uw[0] = 4;
rounder.uw[1] = 4;
rounder.uw[2] = 4;
rounder.uw[3] = 4;
pxor_r2r (mm7, mm7);
movq_m2r (rounder, mm6);
for (; width > 1; width -= 2) {
movd_m2r (*lum_m4, mm0);
movd_m2r (*lum_m3, mm1);
movd_m2r (*lum_m2, mm2);
movd_m2r (*lum_m1, mm3);
movd_m2r (*lum, mm4);
punpcklbw_r2r (mm7, mm0);
punpcklbw_r2r (mm7, mm1);
punpcklbw_r2r (mm7, mm2);
punpcklbw_r2r (mm7, mm3);
punpcklbw_r2r (mm7, mm4);
paddw_r2r (mm3, mm1);
psllw_i2r (1, mm2);
paddw_r2r (mm4, mm0);
psllw_i2r (2, mm1); // 2
paddw_r2r (mm6, mm2);
paddw_r2r (mm2, mm1);
psubusw_r2r (mm0, mm1);
psrlw_i2r (3, mm1); // 3
packuswb_r2r (mm7, mm1);
movd_r2m (mm1, *dst);
lum_m4 += 4;
lum_m3 += 4;
lum_m2 += 4;
lum_m1 += 4;
lum += 4;
dst += 4;
}
emms ();
/* Handle odd widths */
if (width > 0) {
scanlines->tt1 = lum_m4;
scanlines->t0 = lum_m3;
scanlines->m1 = lum_m2;
scanlines->b0 = lum_m1;
scanlines->bb1 = lum;
deinterlace_line_c (self, parent, dst, scanlines, width);
}
}
#endif
G_DEFINE_TYPE (GstDeinterlaceMethodVFIR, gst_deinterlace_method_vfir,
GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
static void
gst_deinterlace_method_vfir_class_init (GstDeinterlaceMethodVFIRClass * klass)
{
GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
GstDeinterlaceSimpleMethodClass *dism_class =
(GstDeinterlaceSimpleMethodClass *) klass;
#ifdef BUILD_X86_ASM
guint cpu_flags = oil_cpu_get_flags ();
#endif
dim_class->fields_required = 2;
dim_class->name = "Blur Vertical";
dim_class->nick = "vfir";
dim_class->latency = 0;
#ifdef BUILD_X86_ASM
if (cpu_flags & OIL_IMPL_FLAG_MMX) {
dism_class->interpolate_scanline = deinterlace_line_mmx;
} else {
dism_class->interpolate_scanline = deinterlace_line_c;
}
#else
dism_class->interpolate_scanline = deinterlace_line_c;
#endif
}
static void
gst_deinterlace_method_vfir_init (GstDeinterlaceMethodVFIR * self)
{
}

View file

@ -1,82 +0,0 @@
/**
* Weave frames
* Copyright (C) 2002 Billy Biggs <vektor@dumbterm.net>.
* Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* 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 "_stdint.h"
#include "gstdeinterlace2.h"
#include <string.h>
#define GST_TYPE_DEINTERLACE_METHOD_WEAVE (gst_deinterlace_method_weave_get_type ())
#define GST_IS_DEINTERLACE_METHOD_WEAVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_WEAVE))
#define GST_IS_DEINTERLACE_METHOD_WEAVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_WEAVE))
#define GST_DEINTERLACE_METHOD_WEAVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_WEAVE, GstDeinterlaceMethodWeaveClass))
#define GST_DEINTERLACE_METHOD_WEAVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_WEAVE, GstDeinterlaceMethodWeave))
#define GST_DEINTERLACE_METHOD_WEAVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_WEAVE, GstDeinterlaceMethodWeaveClass))
#define GST_DEINTERLACE_METHOD_WEAVE_CAST(obj) ((GstDeinterlaceMethodWeave*)(obj))
GType gst_deinterlace_method_weave_get_type (void);
typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodWeave;
typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodWeaveClass;
static void
deinterlace_scanline_weave (GstDeinterlaceMethod * self,
GstDeinterlace2 * parent, guint8 * out,
GstDeinterlaceScanlineData * scanlines, gint width)
{
oil_memcpy (out, scanlines->m1, parent->row_stride);
}
static void
copy_scanline (GstDeinterlaceMethod * self, GstDeinterlace2 * parent,
guint8 * out, GstDeinterlaceScanlineData * scanlines, gint width)
{
oil_memcpy (out, scanlines->m0, parent->row_stride);
}
G_DEFINE_TYPE (GstDeinterlaceMethodWeave, gst_deinterlace_method_weave,
GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
static void
gst_deinterlace_method_weave_class_init (GstDeinterlaceMethodWeaveClass * klass)
{
GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
GstDeinterlaceSimpleMethodClass *dism_class =
(GstDeinterlaceSimpleMethodClass *) klass;
dim_class->fields_required = 2;
dim_class->name = "Weave";
dim_class->nick = "weave";
dim_class->latency = 0;
dism_class->interpolate_scanline = deinterlace_scanline_weave;
dism_class->copy_scanline = copy_scanline;
}
static void
gst_deinterlace_method_weave_init (GstDeinterlaceMethodWeave * self)
{
}

View file

@ -1,88 +0,0 @@
/**
* Weave frames, bottom-field-first.
* Copyright (C) 2003 Billy Biggs <vektor@dumbterm.net>.
* Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* 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 "_stdint.h"
#include "gstdeinterlace2.h"
#include <string.h>
#define GST_TYPE_DEINTERLACE_METHOD_WEAVE_BFF (gst_deinterlace_method_weave_bff_get_type ())
#define GST_IS_DEINTERLACE_METHOD_WEAVE_BFF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_WEAVE_BFF))
#define GST_IS_DEINTERLACE_METHOD_WEAVE_BFF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_WEAVE_BFF))
#define GST_DEINTERLACE_METHOD_WEAVE_BFF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_WEAVE_BFF, GstDeinterlaceMethodWeaveBFFClass))
#define GST_DEINTERLACE_METHOD_WEAVE_BFF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_WEAVE_BFF, GstDeinterlaceMethodWeaveBFF))
#define GST_DEINTERLACE_METHOD_WEAVE_BFF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_WEAVE_BFF, GstDeinterlaceMethodWeaveBFFClass))
#define GST_DEINTERLACE_METHOD_WEAVE_BFF_CAST(obj) ((GstDeinterlaceMethodWeaveBFF*)(obj))
GType gst_deinterlace_method_weave_bff_get_type (void);
typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodWeaveBFF;
typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodWeaveBFFClass;
static void
deinterlace_scanline_weave (GstDeinterlaceMethod * self,
GstDeinterlace2 * parent, guint8 * out,
GstDeinterlaceScanlineData * scanlines, gint width)
{
oil_memcpy (out, scanlines->m1, parent->row_stride);
}
static void
copy_scanline (GstDeinterlaceMethod * self, GstDeinterlace2 * parent,
guint8 * out, GstDeinterlaceScanlineData * scanlines, gint width)
{
/* FIXME: original code used m2 and m0 but this looks really bad */
if (scanlines->bottom_field) {
oil_memcpy (out, scanlines->bb2, parent->row_stride);
} else {
oil_memcpy (out, scanlines->bb0, parent->row_stride);
}
}
G_DEFINE_TYPE (GstDeinterlaceMethodWeaveBFF, gst_deinterlace_method_weave_bff,
GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
static void
gst_deinterlace_method_weave_bff_class_init (GstDeinterlaceMethodWeaveBFFClass *
klass)
{
GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
GstDeinterlaceSimpleMethodClass *dism_class =
(GstDeinterlaceSimpleMethodClass *) klass;
dim_class->fields_required = 3;
dim_class->name = "Progressive: Bottom Field First";
dim_class->nick = "weavebff";
dim_class->latency = 0;
dism_class->interpolate_scanline = deinterlace_scanline_weave;
dism_class->copy_scanline = copy_scanline;
}
static void
gst_deinterlace_method_weave_bff_init (GstDeinterlaceMethodWeaveBFF * self)
{
}

View file

@ -1,88 +0,0 @@
/**
* Weave frames, top-field-first.
* Copyright (C) 2003 Billy Biggs <vektor@dumbterm.net>.
* Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* 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 "_stdint.h"
#include "gstdeinterlace2.h"
#include <string.h>
#define GST_TYPE_DEINTERLACE_METHOD_WEAVE_TFF (gst_deinterlace_method_weave_tff_get_type ())
#define GST_IS_DEINTERLACE_METHOD_WEAVE_TFF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_WEAVE_TFF))
#define GST_IS_DEINTERLACE_METHOD_WEAVE_TFF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_WEAVE_TFF))
#define GST_DEINTERLACE_METHOD_WEAVE_TFF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_WEAVE_TFF, GstDeinterlaceMethodWeaveTFFClass))
#define GST_DEINTERLACE_METHOD_WEAVE_TFF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_WEAVE_TFF, GstDeinterlaceMethodWeaveTFF))
#define GST_DEINTERLACE_METHOD_WEAVE_TFF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_WEAVE_TFF, GstDeinterlaceMethodWeaveTFFClass))
#define GST_DEINTERLACE_METHOD_WEAVE_TFF_CAST(obj) ((GstDeinterlaceMethodWeaveTFF*)(obj))
GType gst_deinterlace_method_weave_tff_get_type (void);
typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodWeaveTFF;
typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodWeaveTFFClass;
static void
deinterlace_scanline_weave (GstDeinterlaceMethod * self,
GstDeinterlace2 * parent, guint8 * out,
GstDeinterlaceScanlineData * scanlines, gint width)
{
oil_memcpy (out, scanlines->m1, parent->row_stride);
}
static void
copy_scanline (GstDeinterlaceMethod * self, GstDeinterlace2 * parent,
guint8 * out, GstDeinterlaceScanlineData * scanlines, gint width)
{
/* FIXME: original code used m2 and m0 but this looks really bad */
if (scanlines->bottom_field) {
oil_memcpy (out, scanlines->bb0, parent->row_stride);
} else {
oil_memcpy (out, scanlines->bb2, parent->row_stride);
}
}
G_DEFINE_TYPE (GstDeinterlaceMethodWeaveTFF, gst_deinterlace_method_weave_tff,
GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
static void
gst_deinterlace_method_weave_tff_class_init (GstDeinterlaceMethodWeaveTFFClass *
klass)
{
GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
GstDeinterlaceSimpleMethodClass *dism_class =
(GstDeinterlaceSimpleMethodClass *) klass;
dim_class->fields_required = 3;
dim_class->name = "Progressive: Top Field First";
dim_class->nick = "weavetff";
dim_class->latency = 0;
dism_class->interpolate_scanline = deinterlace_scanline_weave;
dism_class->copy_scanline = copy_scanline;
}
static void
gst_deinterlace_method_weave_tff_init (GstDeinterlaceMethodWeaveTFF * self)
{
}

View file

@ -1,82 +0,0 @@
/*
*
* GStreamer
* Copyright (C) 2004 Dirk Ziegelmeier <dziegel@gmx.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
/*
*
* See: http://bugzilla.gnome.org/show_bug.cgi?id=163578
*/
/*
* This file is copied from TVTIME's sources.
* Original author: Achim Schneider <batchall@mordor.ch>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef XAX
#if defined (HAVE_CPU_I386) && !defined(HAVE_CPU_X86_64)
#define XAX "eax"
#define XBX "ebx"
#define XCX "ecx"
#define XDX "edx"
#define XSI "esi"
#define XDI "edi"
#define XSP "esp"
#define MOVX "movl"
#define LEAX "leal"
#define DECX "decl"
#define PUSHX "pushl"
#define POPX "popl"
#define CMPX "cmpl"
#define ADDX "addl"
#define SHLX "shll"
#define SHRX "shrl"
#define SUBX "subl"
#elif defined (HAVE_CPU_X86_64)
#define XAX "rax"
#define XBX "rbx"
#define XCX "rcx"
#define XDX "rdx"
#define XSI "rsi"
#define XDI "rdi"
#define XSP "rsp"
#define MOVX "movq"
#define LEAX "leaq"
#define DECX "decq"
#define PUSHX "pushq"
#define POPX "popq"
#define CMPX "cmpq"
#define ADDX "addq"
#define SHLX "shlq"
#define SHRX "shrq"
#define SUBX "subq"
#else
#error Undefined architecture. Define either ARCH_X86 or ARCH_X86_64.
#endif
#endif