[packages/vid.stab] - new, with update from git

qboosh qboosh at pld-linux.org
Tue Jul 16 16:22:42 CEST 2013


commit ca14007dbc5cc183b5dbeaa0abe448178f6b3234
Author: Jakub Bogusz <qboosh at pld-linux.org>
Date:   Tue Jul 16 16:22:31 2013 +0200

    - new, with update from git

 vid.stab-git.patch | 8669 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 vid.stab.spec      |   72 +
 2 files changed, 8741 insertions(+)
---
diff --git a/vid.stab.spec b/vid.stab.spec
new file mode 100644
index 0000000..60d2a43
--- /dev/null
+++ b/vid.stab.spec
@@ -0,0 +1,72 @@
+#
+# Conditional build:
+%bcond_with	sse2	# use SSE2 instructions
+#
+%ifarch pentium4 %{x8664}
+%define	with_sse2	1
+%endif
+Summary:	Vid.Stab - video stabilization library
+Summary(pl.UTF-8):	Vid.Stab - biblioteka do stabilizacji obrazu
+Name:		vid.stab
+Version:	0.96
+Release:	1
+License:	GPL v2+
+Group:		Libraries
+#Source0Download: http://public.hronopik.de/vid.stab/download.php
+Source0:	https://github.com/georgmartius/vid.stab/tarball/release-%{version}?/%{name}-%{version}.tar.gz
+# Source0-md5:	3dda75371b71e0e695cb1f679691c23c
+Patch0:		%{name}-git.patch
+URL:		http://public.hronopik.de/vid.stab/
+BuildRequires:	cmake >= 2.6
+BuildRoot:	%{tmpdir}/%{name}-%{version}-root-%(id -u -n)
+
+%description
+Vid.Stab is a library for stabilizing video clips.
+
+%description -l pl.UTF-8
+Vid.Stab to biblioteka do stabilizacji filmów.
+
+%package devel
+Summary:	Header files for vid.stab library
+Summary(pl.UTF-8):	Pliki nagłówkowe biblioteki vid.stab
+Group:		Development/Libraries
+Requires:	%{name} = %{version}-%{release}
+
+%description devel
+Header files for vid.stab library.
+
+%description devel -l pl.UTF-8
+Pliki nagłówkowe biblioteki vid.stab.
+
+%prep
+%setup -q -n georgmartius-%{name}-254ee37
+%patch0 -p1
+
+%build
+cd src
+%cmake . \
+	%{!?with_sse:-DSSE2_FOUND=OFF}
+%{__make}
+
+%install
+rm -rf $RPM_BUILD_ROOT
+
+%{__make} -C src install \
+	DESTDIR=$RPM_BUILD_ROOT
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post	-p /sbin/ldconfig
+%postun	-p /sbin/ldconfig
+
+%files
+%defattr(644,root,root,755)
+%doc Changelog LICENSE README Todo
+%attr(755,root,root) %{_libdir}/libvidstab.so.0.9
+
+%files devel
+%defattr(644,root,root,755)
+%attr(755,root,root) %{_libdir}/libvidstab.so
+%{_includedir}/vid.stab
+%{_pkgconfigdir}/vidstab.pc
diff --git a/vid.stab-git.patch b/vid.stab-git.patch
new file mode 100644
index 0000000..4bc7801
--- /dev/null
+++ b/vid.stab-git.patch
@@ -0,0 +1,8669 @@
+diff --git a/CMakeModules/FindSSE.cmake b/CMakeModules/FindSSE.cmake
+new file mode 100644
+index 0000000..6ece876
+--- /dev/null
++++ b/CMakeModules/FindSSE.cmake
+@@ -0,0 +1,104 @@
++# Check if SSE instructions are available on the machine where 
++# the project is compiled.
++
++IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
++   EXEC_PROGRAM(cat ARGS "/proc/cpuinfo" OUTPUT_VARIABLE CPUINFO)
++
++   STRING(REGEX REPLACE "^.*(sse2).*$" "\\1" SSE_THERE ${CPUINFO})
++   STRING(COMPARE EQUAL "sse2" "${SSE_THERE}" SSE2_TRUE)
++   IF (SSE2_TRUE)
++      set(SSE2_FOUND true CACHE BOOL "SSE2 available on host")
++   ELSE (SSE2_TRUE)
++      set(SSE2_FOUND false CACHE BOOL "SSE2 available on host")
++   ENDIF (SSE2_TRUE)
++
++   # /proc/cpuinfo apparently omits sse3 :(
++   STRING(REGEX REPLACE "^.*[^s](sse3).*$" "\\1" SSE_THERE ${CPUINFO})
++   STRING(COMPARE EQUAL "sse3" "${SSE_THERE}" SSE3_TRUE)
++   IF (NOT SSE3_TRUE)
++      STRING(REGEX REPLACE "^.*(T2300).*$" "\\1" SSE_THERE ${CPUINFO})
++      STRING(COMPARE EQUAL "T2300" "${SSE_THERE}" SSE3_TRUE)
++   ENDIF (NOT SSE3_TRUE)
++
++   STRING(REGEX REPLACE "^.*(ssse3).*$" "\\1" SSE_THERE ${CPUINFO})
++   STRING(COMPARE EQUAL "ssse3" "${SSE_THERE}" SSSE3_TRUE)
++   IF (SSE3_TRUE OR SSSE3_TRUE)
++      set(SSE3_FOUND true CACHE BOOL "SSE3 available on host")
++   ELSE (SSE3_TRUE OR SSSE3_TRUE)
++      set(SSE3_FOUND false CACHE BOOL "SSE3 available on host")
++   ENDIF (SSE3_TRUE OR SSSE3_TRUE)
++   IF (SSSE3_TRUE)
++      set(SSSE3_FOUND true CACHE BOOL "SSSE3 available on host")
++   ELSE (SSSE3_TRUE)
++      set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host")
++   ENDIF (SSSE3_TRUE)
++
++   STRING(REGEX REPLACE "^.*(sse4_1).*$" "\\1" SSE_THERE ${CPUINFO})
++   STRING(COMPARE EQUAL "sse4_1" "${SSE_THERE}" SSE41_TRUE)
++   IF (SSE41_TRUE)
++      set(SSE4_1_FOUND true CACHE BOOL "SSE4.1 available on host")
++   ELSE (SSE41_TRUE)
++      set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
++   ENDIF (SSE41_TRUE)
++ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
++   EXEC_PROGRAM("/usr/sbin/sysctl -n machdep.cpu.features" OUTPUT_VARIABLE
++      CPUINFO)
++
++   STRING(REGEX REPLACE "^.*[^S](SSE2).*$" "\\1" SSE_THERE ${CPUINFO})
++   STRING(COMPARE EQUAL "SSE2" "${SSE_THERE}" SSE2_TRUE)
++   IF (SSE2_TRUE)
++      set(SSE2_FOUND true CACHE BOOL "SSE2 available on host")
++   ELSE (SSE2_TRUE)
++      set(SSE2_FOUND false CACHE BOOL "SSE2 available on host")
++   ENDIF (SSE2_TRUE)
++
++   STRING(REGEX REPLACE "^.*[^S](SSE3).*$" "\\1" SSE_THERE ${CPUINFO})
++   STRING(COMPARE EQUAL "SSE3" "${SSE_THERE}" SSE3_TRUE)
++   IF (SSE3_TRUE)
++      set(SSE3_FOUND true CACHE BOOL "SSE3 available on host")
++   ELSE (SSE3_TRUE)
++      set(SSE3_FOUND false CACHE BOOL "SSE3 available on host")
++   ENDIF (SSE3_TRUE)
++
++   STRING(REGEX REPLACE "^.*(SSSE3).*$" "\\1" SSE_THERE ${CPUINFO})
++   STRING(COMPARE EQUAL "SSSE3" "${SSE_THERE}" SSSE3_TRUE)
++   IF (SSSE3_TRUE)
++      set(SSSE3_FOUND true CACHE BOOL "SSSE3 available on host")
++   ELSE (SSSE3_TRUE)
++      set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host")
++   ENDIF (SSSE3_TRUE)
++
++   STRING(REGEX REPLACE "^.*(SSE4.1).*$" "\\1" SSE_THERE ${CPUINFO})
++   STRING(COMPARE EQUAL "SSE4.1" "${SSE_THERE}" SSE41_TRUE)
++   IF (SSE41_TRUE)
++      set(SSE4_1_FOUND true CACHE BOOL "SSE4.1 available on host")
++   ELSE (SSE41_TRUE)
++      set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
++   ENDIF (SSE41_TRUE)
++ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Windows")
++   # TODO
++   set(SSE2_FOUND   true  CACHE BOOL "SSE2 available on host")
++   set(SSE3_FOUND   false CACHE BOOL "SSE3 available on host")
++   set(SSSE3_FOUND  false CACHE BOOL "SSSE3 available on host")
++   set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
++ELSE(CMAKE_SYSTEM_NAME MATCHES "Linux")
++   set(SSE2_FOUND   true  CACHE BOOL "SSE2 available on host")
++   set(SSE3_FOUND   false CACHE BOOL "SSE3 available on host")
++   set(SSSE3_FOUND  false CACHE BOOL "SSSE3 available on host")
++   set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
++ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
++
++if(NOT SSE2_FOUND)
++      MESSAGE(STATUS "Could not find hardware support for SSE2 on this machine.")
++endif(NOT SSE2_FOUND)
++if(NOT SSE3_FOUND)
++      MESSAGE(STATUS "Could not find hardware support for SSE3 on this machine.")
++endif(NOT SSE3_FOUND)
++if(NOT SSSE3_FOUND)
++      MESSAGE(STATUS "Could not find hardware support for SSSE3 on this machine.")
++endif(NOT SSSE3_FOUND)
++if(NOT SSE4_1_FOUND)
++      MESSAGE(STATUS "Could not find hardware support for SSE4.1 on this machine.")
++endif(NOT SSE4_1_FOUND)
++
++mark_as_advanced(SSE2_FOUND SSE3_FOUND SSSE3_FOUND SSE4_1_FOUND)
+diff --git a/CMakeModules/WritePgkConfig.cmake b/CMakeModules/WritePgkConfig.cmake
+new file mode 100644
+index 0000000..caf9499
+--- /dev/null
++++ b/CMakeModules/WritePgkConfig.cmake
+@@ -0,0 +1,25 @@
++#
++# Write a pkg-config pc file for given "name" with "decription"
++# Arguments:
++#   name: a library name (without "lib" prefix and "so" suffixes
++#   desc: a desription string
++#
++macro (create_pkgconfig_file name desc)
++    set(_pkgfname "${CMAKE_CURRENT_BINARY_DIR}/${name}.pc")
++    message(STATUS "${name}: writing pkgconfig file ${_pkgfname}")
++
++    file(WRITE "${_pkgfname}" "# file generated by razor-qt cmake build
++prefix=${CMAKE_INSTALL_PREFIX}
++libdir=\${prefix}/lib${LIB_SUFFIX}
++includedir=\${prefix}/include
++
++Name: ${name}
++Description: ${desc}
++Version: ${VIDSTAB_VERSION}
++Libs: -L\${libdir} -l${name}
++Cflags: -I\${includedir}
++
++")
++
++    install(FILES ${_pkgfname} DESTINATION lib${LIB_SUFFIX}/pkgconfig)
++endmacro()
+\ No newline at end of file
+diff --git a/CMakeModules/create_pkgconfig_file.cmake b/CMakeModules/create_pkgconfig_file.cmake
+new file mode 100644
+index 0000000..c941f09
+--- /dev/null
++++ b/CMakeModules/create_pkgconfig_file.cmake
+@@ -0,0 +1,25 @@
++#
++# Write a pkg-config pc file for given "name" with "decription"
++# Arguments:
++#   name: a library name (without "lib" prefix and "so" suffixes
++#   desc: a desription string
++#
++macro (create_pkgconfig_file name desc)
++    set(_pkgfname "${CMAKE_CURRENT_BINARY_DIR}/${name}.pc")
++    message(STATUS "${name}: writing pkgconfig file ${_pkgfname}")
++
++    file(WRITE "${_pkgfname}" "# file generated by vid.stab cmake build
++prefix=${CMAKE_INSTALL_PREFIX}
++libdir=\${prefix}/lib${LIB_SUFFIX}
++includedir=\${prefix}/include
++
++Name: ${name}
++Description: ${desc}
++Version: ${VIDSTAB_VERSION}
++Libs: -L\${libdir} -l${name}
++Cflags: -I\${includedir}
++
++")
++
++    install(FILES ${_pkgfname} DESTINATION lib/pkgconfig)
++endmacro()
+\ No newline at end of file
+diff --git a/Install b/Install
+new file mode 100644
+index 0000000..15d5eee
+--- /dev/null
++++ b/Install
+@@ -0,0 +1,31 @@
++***  LIBRARY ***
++To compile the library do:
++
++cd src/cmake
++
++cmake ../
++make
++sudo make install
++
++To customize the installation prefix use
++cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local
++
++
++*** TRANSCODE plugins ***
++
++You need to have the transcode sources installed. The best
++choice it to download the same version you have in your distribution.
++Youi don't need to compile transcode itself.
++Download from http://tcforge.berlios.de/ or
++ http://developer.berlios.de/project/showfiles.php?group_id=10094.
++Then you need to adapt the transcode/CMakeLists.txt and change
++ the variable
++> set(TRANSCODE_ROOT path/to/transcode)
++
++cd transcode/cmake
++make
++. install.sh
++
++*** FFMPEG ***
++
++You need to configure ffmpeg with --enable-vidstab
+\ No newline at end of file
+diff --git a/README b/README
+index 467c5f3..c688a84 100644
+--- a/README
++++ b/README
+@@ -1,3 +1,5 @@
++Video stabilization library with plugins for transcode and ffmpeg.
++
+ See Install
+ 
+ please visit
+diff --git a/Todo b/Todo
+index 073dbdc..f386dd9 100644
+--- a/Todo
++++ b/Todo
+@@ -6,7 +6,3 @@ Some things that could be done
+ 
+ - make transform stage work with fifo file for transforms, such that streaming is also possible with 2-stage version.
+ 
+-- write full motion detection to file and delegate final transformation detection to snd-phase
+-
+-
+-- frei0r plugin
+\ No newline at end of file
+diff --git a/libavfilter/README b/libavfilter/README
+index 9dad132..fef17db 100644
+--- a/libavfilter/README
++++ b/libavfilter/README
+@@ -1,35 +1,7 @@
+-These are filters for the libavfilter framework.
+-
+-Hopefully they get integrated into ffmpeg but until then you have
+- to do the following to get it working:
+-link the files to your
+-ffmpeg/libavfilter/
+-
+-also link the vid.stab source directory
+-ln -s ...../vid.stab/src ffmpeg/libavfilter/
+-
+-(for now, to find the include files
+-later we have to make an own lib with header files and so on)
+-
+-add the following lines to the files in libavfilter/
+-allfilters.c
+-
+-    REGISTER_FILTER (STABILIZE,   stabilize,   vf);
+-    REGISTER_FILTER (TRANSFORM,   transform,   vf);
+-
+-Makefile
+-
+-to OBJS = .... optstr.o
+-
+-and further down
+-OBJS-$(CONFIG_STABILIZE_FILTER)              += vf_stabilize.o
+-OBJS-$(CONFIG_TRANSFORM_FILTER)              += vf_transform.o
+-
+-and
+-configure ffmpeg with
+-
+---extra-libs="-L/path/to/vidstab/src/cmake -lvidstab"
++These files are now in the ffmpeg source tree (as of 25.04.2013). They will be removed here at some point.
+ 
++Make sure you configure ffmpeg with
++--enable-vidstab
+ 
+ 
+ 
+diff --git a/libavfilter/git-workflow.txt b/libavfilter/git-workflow.txt
+new file mode 100644
+index 0000000..4d786f5
+--- /dev/null
++++ b/libavfilter/git-workflow.txt
+@@ -0,0 +1,20 @@
++
++#How to work in the ffmpeg git (or in any other one actually)
++#Create a new branch
++git branch "BRANCHNAME"
++git checkout "BRANCHNAME"
++#do you stuff
++git commit
++#rebase to master such that your changes only against the master branch and can be squashed
++git rebase -i master
++#or if merged in between then
++git log
++# or to find original branch point:
++diff -u <(git rev-list --first-parent BRANCHNAME)              <(git rev-list --first-parent master) |      sed -ne 's/^ //p' | head -1
++
++git rebase -i 39423.....
++
++git format-patch -s 3969b4b861ce8152e3195e8f8c3437abd2..
++
++
++007989c7a2215f54aeaf2393ab3aff0c208e862f
+diff --git a/libavfilter/optstr.c b/libavfilter/optstr.c
+deleted file mode 100644
+index ddd4439..0000000
+--- a/libavfilter/optstr.c
++++ /dev/null
+@@ -1,145 +0,0 @@
+-/*
+- *  optstr.c
+- *
+- *  This is a shortened version of the optstr.c file from transcode
+- *  Copyright (C) Tilmann Bitterberg 2003
+- *
+- *  Description: A general purpose option string parser
+- *
+- *  Usage: see optstr.h, please
+- *
+- *  This file is part of transcode, a video stream processing tool
+- *
+- *  transcode 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.
+- *
+- *  transcode 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 GNU Make; see the file COPYING.  If not, write to
+- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+- *
+- */
+-
+-#ifdef HAVE_CONFIG_H
+-# include "config.h"
+-#endif
+-
+-/* for vsscanf */
+-#ifdef HAVE_VSSCANF
+-#  define _GNU_SOURCE
+-#endif
+-
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#include <stdarg.h>
+-#include "optstr.h"
+-
+-
+-// take from transcode
+-const char* optstr_lookup(const char *haystack, const char *needle)
+-{
+-    const char *ch = haystack;
+-    int found = 0;
+-    size_t len = strlen(needle);
+-
+-    while (!found) {
+-        ch = strstr(ch, needle);
+-
+-        /* not in string */
+-        if (!ch) {
+-            break;
+-        }
+-
+-        /* do we want this hit? ie is it exact? */
+-        if (ch[len] == '\0' || ch[len] == '=' || ch[len] == ARG_SEP) {
+-            found = 1;
+-        } else {
+-            /* go a little further */
+-            ch++;
+-        }
+-    }
+-
+-    return ch;
+-}
+-
+-int optstr_get(const char *options, const char *name, const char *fmt, ...)
+-{
+-    va_list ap;     /* points to each unnamed arg in turn */
+-    int num_args = 0, n = 0;
+-    size_t pos, fmt_len = strlen(fmt);
+-    const char *ch = NULL;
+-
+-#ifndef HAVE_VSSCANF
+-    void *temp[ARG_MAXIMUM];
+-#endif
+-
+-    ch = optstr_lookup(options, name);
+-    if (!ch) {
+-        return -1;
+-    }
+-
+-    /* name IS in options */
+-
+-    /* Find how many arguments we expect */
+-    for (pos = 0; pos < fmt_len; pos++) {
+-        if (fmt[pos] == '%') {
+-            ++num_args;
+-            /* is this one quoted  with '%%' */
+-            if (pos + 1 < fmt_len && fmt[pos + 1] == '%') {
+-                --num_args;
+-                ++pos;
+-            }
+-        }
+-    }
+-
+-#ifndef HAVE_VSSCANF
+-    if (num_args > ARG_MAXIMUM) {
+-        fprintf (stderr,
+-            "(%s:%d) Internal Overflow; redefine ARG_MAXIMUM (%d) to something higher\n",
+-            __FILE__, __LINE__, ARG_MAXIMUM);
+-        return -2;
+-    }
+-#endif
+-
+-    n = num_args;
+-    /* Bool argument */
+-    if (num_args <= 0) {
+-        return 0;
+-    }
+-
+-    /* skip the `=' (if it is one) */
+-    ch += strlen( name );
+-    if( *ch == '=' )
+-        ch++;
+-
+-    if( !*ch )
+-        return 0;
+-
+-    va_start(ap, fmt);
+-
+-#ifndef HAVE_VSSCANF
+-    while (--n >= 0) {
+-        temp[num_args - n - 1] = va_arg(ap, void *);
+-    }
+-
+-    n = sscanf(ch, fmt,
+-            temp[0],  temp[1],  temp[2],  temp[3]);
+-
+-#else
+-    /* this would be very nice instead of the above,
+-     * but it does not seem portable
+-     */
+-     n = vsscanf(ch, fmt, ap);
+-#endif
+-
+-    va_end(ap);
+-
+-    return n;
+-}
+diff --git a/libavfilter/optstr.h b/libavfilter/optstr.h
+deleted file mode 100644
+index 64cb483..0000000
+--- a/libavfilter/optstr.h
++++ /dev/null
+@@ -1,57 +0,0 @@
+-#ifndef OPTSTR_H
+-#define OPTSTR_H
+-
+-#define ARG_MAXIMUM (4)
+-#define ARG_SEP ':'
+-#define ARG_CONFIG_LEN 8192
+-
+-/*
+- * optstr_lookup:
+- *     Finds the _exact_ 'needle' in 'haystack' (naming intentionally 
+- *     identical to the 'strstr' (3) linux man page)
+- *
+- * Parameters:
+- *     needle: substring to be searched
+- *     haystack: string which is supposed to contain the substring
+- * Return Value:
+- *     constant pointer to first substring found, or NULL if substring
+- *     isn't found.
+- * Side effects:
+- *     none
+- * Preconditions:
+- *     none
+- * Postconditions:
+- *     none
+- */
+-const char * optstr_lookup(const char *haystack, const char *needle);
+-
+-/*
+- * optstr_get:
+- *     extract values from option string
+- *
+- * Parameters:
+- *     options: a null terminated string of options to parse,
+- *              syntax is "opt1=val1:opt_bool:opt2=val1-val2"
+- *              where ':' is the seperator.
+- *     name: the name to look for in options; eg "opt2"
+- *     fmt: the format to scan values (printf format); eg "%d-%d"
+- *     (...): variables to assign; eg &lower, &upper
+- * Return value:
+- *     -2 internal error
+- *     -1 `name' is not in `options'
+- *     0  `name' is in `options'
+- *     >0 number of arguments assigned
+- * Side effects:
+- *     none
+- * Preconditions:
+- *     none
+- * Postconditions:
+- *     none
+- */
+-int optstr_get(const char *options, const char *name, const char *fmt, ...)
+-#ifdef HAVE_GCC_ATTRIBUTES
+-__attribute__((format(scanf,3,4)))
+-#endif
+-;
+-
+-#endif /* OPTSTR_H */
+diff --git a/libavfilter/vf_stabilize.c b/libavfilter/vf_stabilize.c
+deleted file mode 100644
+index 6596d8d..0000000
+--- a/libavfilter/vf_stabilize.c
++++ /dev/null
+@@ -1,328 +0,0 @@
+-/*
+- *  vf_stabilize.c
+- *
+- *  Copyright (C) Georg Martius - Jan 2012
+- *   georg dot martius at web dot de
+- *
+- *  This file is part of vid.stab, video deshaking lib
+- *
+- *  vid.stab 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.
+- *
+- *  vid.stab 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 GNU Make; see the file COPYING.  If not, write to
+- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+- *
+- */
+-
+-/* Typical call:
+- *  ffmpeg -i input -vf stabilize=shakiness=5:show=1 dummy.avi
+- *  all parameters are optional
+- */
+-
+-
+-/*
+-  TODO: check AVERROR  codes
+-*/
+-
+-#define DEFAULT_TRANS_FILE_NAME     "transforms.dat"
+-#define VS_INPUT_MAXLEN 1024
+-
+-#include <math.h> //?
+-#include <libgen.h> //?
+-
+-#include "libavutil/avstring.h"
+-#include "libavutil/common.h"
+-#include "libavutil/mem.h"
+-#include "libavutil/pixdesc.h"
+-#include "libavutil/pixfmt.h"
+-#include "libavutil/imgutils.h"
+-#include "libavcodec/dsputil.h"
+-#include "avfilter.h"
+-#include "formats.h"
+-#include "internal.h"
+-#include "video.h"
+-
+-
+-#include "optstr.h"
+-#include "vid.stab/libvidstab.h"
+-
+-/* private date structure of this filter*/
+-typedef struct _stab_data {
+-    AVClass av_class;
+-
+-    MotionDetect md;
+-    AVFilterBufferRef *ref;    ///< Previous frame
+-    char* options;
+-
+-    char* result;
+-    FILE* f;
+-
+-} StabData;
+-
+-static PixelFormat AV2OurPixelFormat(AVFilterContext *ctx, enum AVPixelFormat pf){
+-	switch(pf){
+-    case AV_PIX_FMT_YUV420P:  return PF_YUV420P;
+-		case AV_PIX_FMT_YUV422P:	return PF_YUV422P;
+-		case AV_PIX_FMT_YUV444P:	return PF_YUV444P;
+-		case AV_PIX_FMT_YUV410P:	return PF_YUV410P;
+-		case AV_PIX_FMT_YUV411P:	return PF_YUV411P;
+-		case AV_PIX_FMT_YUV440P:	return PF_YUV440P;
+-		case AV_PIX_FMT_YUVA420P: return PF_YUVA420P;
+-		case AV_PIX_FMT_GRAY8:		return PF_GRAY8;
+-		case AV_PIX_FMT_RGB24:		return PF_RGB24;
+-		case AV_PIX_FMT_BGR24:		return PF_BGR24;
+-		case AV_PIX_FMT_RGBA:		  return PF_RGBA;
+-	default:
+-		av_log(ctx, AV_LOG_ERROR, "cannot deal with pixel format %i!\n", pf);
+-		return PF_NONE;
+-	}
+-}
+-
+-
+-/*************************************************************************/
+-
+-/* Module interface routines and data. */
+-
+-/*************************************************************************/
+-
+-static av_cold int init(AVFilterContext *ctx, const char *args)
+-{
+-
+-    StabData* sd = ctx->priv;
+-
+-    if (!sd) {
+-        av_log(ctx, AV_LOG_INFO, "init: out of memory!\n");
+-        return AVERROR(EINVAL);
+-    }
+-
+-    av_log(ctx, AV_LOG_INFO, "Stabilize: init %s\n", LIBVIDSTAB_VERSION);
+-    if(args)
+-        sd->options=av_strdup(args);
+-    else
+-        sd->options=0;
+-
+-
+-    return 0;
+-}
+-
+-///1
+-static av_cold void uninit(AVFilterContext *ctx)
+-{
+-    StabData *sd = ctx->priv;
+-
+-    //  avfilter_unref_buffer(sd->ref);
+-
+-    MotionDetect* md = &(sd->md);
+-    if (sd->f) {
+-        fclose(sd->f);
+-        sd->f = NULL;
+-    }
+-
+-    cleanupMotionDetection(md);
+-    if (sd->result) {
+-        av_free(sd->result);
+-        sd->result = NULL;
+-    }
+-    if(sd->options) av_free(sd->options);
+-}
+-
+-// AVFILTER_DEFINE_CLASS(stabilize);
+-
+-static int query_formats(AVFilterContext *ctx)
+-{
+-    static const enum AVPixelFormat pix_fmts[] = {
+-        AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
+-        AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA420P,
+-        AV_PIX_FMT_YUV440P,  AV_PIX_FMT_GRAY8,
+-        AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, AV_PIX_FMT_RGBA,
+-        AV_PIX_FMT_NONE
+-    };
+-
+-    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+-    return 0;
+-}
+-
+-
+-
+-
+-static int config_input(AVFilterLink *inlink)
+-{
+-    AVFilterContext *ctx = inlink->dst;
+-    StabData *sd = ctx->priv;
+-//    char* filenamecopy, *filebasename;
+-
+-    MotionDetect* md = &(sd->md);
+-    VSFrameInfo fi;
+-    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[inlink->format];
+-
+-    initFrameInfo(&fi,inlink->w, inlink->h, AV2OurPixelFormat(ctx, inlink->format));
+-    // check
+-    if(fi.bytesPerPixel != av_get_bits_per_pixel(desc)/8)
+-        av_log(ctx, AV_LOG_ERROR, "pixel-format error: wrong bits/per/pixel");
+-    if(fi.log2ChromaW != desc->log2_chroma_w)
+-        av_log(ctx, AV_LOG_ERROR, "pixel-format error: log2_chroma_w");
+-    if(fi.log2ChromaH != desc->log2_chroma_h)
+-        av_log(ctx, AV_LOG_ERROR, "pixel-format error: log2_chroma_h");
+-
+-    if(initMotionDetect(md, &fi, "stabilize") != VS_OK){
+-        av_log(ctx, AV_LOG_ERROR, "initialization of Motion Detection failed");
+-        return AVERROR(EINVAL);
+-    }
+-
+-    /// TODO: find out input name
+-    sd->result = av_malloc(VS_INPUT_MAXLEN);
+-//    filenamecopy = strndup(sd->vob->video_in_file);
+-//    filebasename = basename(filenamecopy);
+-//    if (strlen(filebasename) < VS_INPUT_MAXLEN - 4) {
+-//        snprintf(sd->result, VS_INPUT_MAXLEN, "%s.trf", filebasename);
+-//} else {
+-//    av_log(ctx, AV_LOG_WARN, "input name too long, using default `%s'",
+-//                    DEFAULT_TRANS_FILE_NAME);
+-    snprintf(sd->result, VS_INPUT_MAXLEN, DEFAULT_TRANS_FILE_NAME);
+-//    }
+-
+-    if (sd->options != NULL) {
+-        if(optstr_lookup(sd->options, "help")) {
+-            av_log(ctx, AV_LOG_INFO, motiondetect_help);
+-            return AVERROR(EINVAL);
+-        }
+-
+-        optstr_get(sd->options, "result",     "%[^:]", sd->result);
+-        optstr_get(sd->options, "shakiness",  "%d", &md->shakiness);
+-        optstr_get(sd->options, "accuracy",   "%d", &md->accuracy);
+-        optstr_get(sd->options, "stepsize",   "%d", &md->stepSize);
+-        optstr_get(sd->options, "algo",       "%d", &md->algo);
+-        optstr_get(sd->options, "mincontrast","%lf",&md->contrastThreshold);
+-        optstr_get(sd->options, "show",       "%d", &md->show);
+-    }
+-
+-    if(configureMotionDetect(md)!= VS_OK){
+-    	av_log(ctx, AV_LOG_ERROR, "configuration of Motion Detection failed\n");
+-        return AVERROR(EINVAL);
+-    }
+-
+-    av_log(ctx, AV_LOG_INFO, "Image Stabilization Settings:\n");
+-    av_log(ctx, AV_LOG_INFO, "     shakiness = %d\n", md->shakiness);
+-    av_log(ctx, AV_LOG_INFO, "      accuracy = %d\n", md->accuracy);
+-    av_log(ctx, AV_LOG_INFO, "      stepsize = %d\n", md->stepSize);
+-    av_log(ctx, AV_LOG_INFO, "          algo = %d\n", md->algo);
+-    av_log(ctx, AV_LOG_INFO, "   mincontrast = %f\n", md->contrastThreshold);
+-    av_log(ctx, AV_LOG_INFO, "          show = %d\n", md->show);
+-    av_log(ctx, AV_LOG_INFO, "        result = %s\n", sd->result);
+-
+-    sd->f = fopen(sd->result, "w");
+-    if (sd->f == NULL) {
+-        av_log(ctx, AV_LOG_ERROR, "cannot open transform file %s!\n", sd->result);
+-        return AVERROR(EINVAL);
+-    }else{
+-        if(prepareFile(md, sd->f) != VS_OK){
+-            av_log(ctx, AV_LOG_ERROR, "cannot write to transform file %s!\n", sd->result);
+-            return AVERROR(EINVAL);
+-        }
+-    }
+-    return 0;
+-}
+-
+-
+-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
+-{
+-    AVFilterContext *ctx = inlink->dst;
+-    StabData *sd = ctx->priv;
+-    MotionDetect* md = &(sd->md);
+-    LocalMotions localmotions;
+-
+-
+-    AVFilterLink *outlink = inlink->dst->outputs[0];
+-    //const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+-    //int hsub0 = desc->log2_chroma_w;
+-    //int vsub0 = desc->log2_chroma_h;
+-    int direct = 0;
+-    AVFilterBufferRef *out;
+-    VSFrame frame;
+-    int plane;
+-
+-    if (in->perms & AV_PERM_WRITE) {
+-        direct = 1;
+-        out = in;
+-    } else {
+-        out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+-        if (!out) {
+-            avfilter_unref_bufferp(&in);
+-            return AVERROR(ENOMEM);
+-        }
+-        avfilter_copy_buffer_ref_props(out, in);
+-    }
+-
+-    for(plane=0; plane < md->fi.planes; plane++){
+-        frame.data[plane] = in->data[plane];
+-        frame.linesize[plane] = in->linesize[plane];
+-    }
+-    if(motionDetection(md, &localmotions, &frame) !=  VS_OK){
+-        av_log(ctx, AV_LOG_ERROR, "motion detection failed");
+-        return AVERROR(AVERROR_EXTERNAL);
+-    } else {
+-        if(writeToFile(md, sd->f, &localmotions) != VS_OK){
+-            av_log(ctx, AV_LOG_ERROR, "cannot write to transform file!");
+-            return AVERROR(EPERM);
+-        }
+-        vs_vector_del(&localmotions);
+-    }
+-    if(md->show>0 && !direct){
+-        // copy
+-        av_image_copy(out->data, out->linesize,
+-                      (void*)in->data, in->linesize,
+-                      in->format, in->video->w, in->video->h);
+-    }
+-
+-    if (!direct)
+-        avfilter_unref_bufferp(&in);
+-
+-    return ff_filter_frame(outlink, out);
+-}
+-
+-
+-AVFilter avfilter_vf_stabilize = {
+-    .name      = "stabilize",
+-    .description = NULL_IF_CONFIG_SMALL("extracts relative transformations of \n\
+-    subsequent frames (used for stabilization together with the\n\
+-    transform filter in a second pass)."),
+-
+-    .priv_size = sizeof(StabData),
+-
+-    .init   = init,
+-    .uninit = uninit,
+-    .query_formats = query_formats,
+-
+-    .inputs    = (const AVFilterPad[]) {{ .name       = "default",
+-                                    .type             = AVMEDIA_TYPE_VIDEO,
+-                                    .get_video_buffer = ff_null_get_video_buffer,
+-                                    .filter_frame     = filter_frame,
+-                                    .config_props     = config_input,
+-                                    .min_perms        = AV_PERM_READ, },
+-                                  { .name = NULL}},
+-    .outputs   = (const AVFilterPad[]) {{ .name       = "default",
+-                                    .type             = AVMEDIA_TYPE_VIDEO, },
+-                                  { .name = NULL}},
+-};
+-
+-
+-
+-/*************************************************************************/
+-
+-/*
+- * Local variables:
+- *   c-file-style: "stroustrup"
+- *   c-file-offsets: ((case-label . *) (statement-case-intro . *))
+- *   indent-tabs-mode: nil
+- * End:
+- *
+- * vim: expandtab shiftwidth=4:
+- */
+diff --git a/libavfilter/vf_transform.c b/libavfilter/vf_transform.c
+deleted file mode 100644
+index d8a7d99..0000000
+--- a/libavfilter/vf_transform.c
++++ /dev/null
+@@ -1,349 +0,0 @@
+-/*
+- *  vf_transform.c
+- *
+- *  Copyright (C) Georg Martius - Jan 2012
+- *   georg dot martius at web dot de
+- *
+- *  This file is part of vid.stab, video deshaking lib
+- *
+- *  vid.stab 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.
+- *
+- *  vid.stab 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 GNU Make; see the file COPYING.  If not, write to
+- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+- *
+- */
+-
+-/* Typical call:
+- *  ffmpeg -i inp.mpeg ffmpeg -vf transform inp_s.mpeg
+- *  all parameters are optional
+- */
+-
+-/*
+-  TODO: check AVERROR  codes
+-*/
+-
+-#define DEFAULT_TRANS_FILE_NAME     "transforms.dat"
+-
+-#include "libavutil/common.h"
+-#include "libavutil/mem.h"
+-#include "libavutil/pixdesc.h"
+-#include "libavutil/pixfmt.h"
+-#include "libavcodec/dsputil.h"
+-#include "avfilter.h"
+-#include "formats.h"
+-#include "internal.h"
+-#include "video.h"
+-
+-#include "optstr.h"
+-
+-#include "vid.stab/libvidstab.h"
+-
+-#define VS_INPUT_MAXLEN 1024
+-
+-/* private date structure of this filter*/
+-typedef struct {
+-    TransformData td;
+-
+-    Transformations trans; // transformations
+-    char* options;
+-    char input[VS_INPUT_MAXLEN];
+-} FilterData;
+-
+-
+-static PixelFormat AV2OurPixelFormat(AVFilterContext *ctx, enum AVPixelFormat pf){
+-	switch(pf){
+-    case AV_PIX_FMT_YUV420P: return PF_YUV420P;
+-		case AV_PIX_FMT_RGB24:		return PF_RGB24;
+-		case AV_PIX_FMT_BGR24:		return PF_BGR24;
+-		case AV_PIX_FMT_YUV422P:	return PF_YUV422P;
+-		case AV_PIX_FMT_YUV444P:	return PF_YUV444P;
+-		case AV_PIX_FMT_YUV410P:	return PF_YUV410P;
+-		case AV_PIX_FMT_YUV411P:	return PF_YUV411P;
+-		case AV_PIX_FMT_GRAY8:		return PF_GRAY8;
+-		case AV_PIX_FMT_YUVA420P:return PF_YUVA420P;
+-		case AV_PIX_FMT_RGBA:		return PF_RGBA;
+-	default:
+-		av_log(ctx, AV_LOG_ERROR, "cannot deal with pixel format %i!\n", pf);
+-		return PF_NONE;
+-	}
+-}
+-
+-
+-/*************************************************************************/
+-
+-/* Module interface routines and data. */
+-
+-/*************************************************************************/
+-
+-static av_cold int init(AVFilterContext *ctx, const char *args)
+-{
+-
+-    FilterData* fd = ctx->priv;
+-
+-    if (!fd) {
+-        av_log(ctx, AV_LOG_INFO, "init: out of memory!\n");
+-        return AVERROR(EINVAL);
+-    }
+-
+-    av_log(ctx, AV_LOG_INFO, "Transform filter: init %s\n", LIBVIDSTAB_VERSION);
+-
+-    if(args)
+-        fd->options=av_strdup(args);
+-
+-    return 0;
+-}
+-
+-static av_cold void uninit(AVFilterContext *ctx)
+-{
+-    FilterData *fd = ctx->priv;
+-
+-    //  avfilter_unref_buffer(fd->ref);
+-
+-    cleanupTransformData(&fd->td);
+-    cleanupTransformations(&fd->trans);
+-
+-    if(fd->options) av_free(fd->options);
+-}
+-
+-
+-static int query_formats(AVFilterContext *ctx)
+-{
+-    static const enum AVPixelFormat pix_fmts[] = {
+-        AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
+-        AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA420P,
+-        AV_PIX_FMT_YUV440P,  AV_PIX_FMT_GRAY8,
+-        AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, AV_PIX_FMT_RGBA,
+-        AV_PIX_FMT_NONE
+-    };
+-
+-    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+-    return 0;
+-}
+-
+-
+-static int config_input(AVFilterLink *inlink)
+-{
+-    AVFilterContext *ctx = inlink->dst;
+-    FilterData *fd = ctx->priv;
+-    FILE* f;
+-//    char* filenamecopy, *filebasename;
+-
+-    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[inlink->format];
+-
+-    TransformData* td = &(fd->td);
+-
+-    VSFrameInfo fi_src;
+-    VSFrameInfo fi_dest;
+-    if(!initFrameInfo(&fi_src, inlink->w, inlink->h,
+-                      AV2OurPixelFormat(ctx,inlink->format)) ||
+-       !initFrameInfo(&fi_dest, inlink->w, inlink->h,
+-                      AV2OurPixelFormat(ctx, inlink->format))){
+-        av_log(ctx, AV_LOG_ERROR, "unknown pixel format: %i (%s)",
+-               inlink->format, desc->name);
+-        return AVERROR(EINVAL);
+-    }
+-
+-    // check
+-    if(fi_src.bytesPerPixel != av_get_bits_per_pixel(desc)/8 ||
+-       fi_src.log2ChromaW != desc->log2_chroma_w ||
+-       fi_src.log2ChromaH != desc->log2_chroma_h){
+-        av_log(ctx, AV_LOG_ERROR, "pixel-format error: bpp %i<>%i  ",
+-               fi_src.bytesPerPixel, av_get_bits_per_pixel(desc)/8);
+-        av_log(ctx, AV_LOG_ERROR, "chroma_subsampl: w: %i<>%i  h: %i<>%i\n",
+-               fi_src.log2ChromaW, desc->log2_chroma_w,
+-               fi_src.log2ChromaH, desc->log2_chroma_h);
+-        return AVERROR(EINVAL);
+-    }
+-
+-    if(initTransformData(td, &fi_src, &fi_dest, "transform") != VS_OK){
+-        av_log(ctx, AV_LOG_ERROR, "initialization of TransformData failed\n");
+-        return AVERROR(EINVAL);
+-    }
+-    td->verbose=1; // TODO: get from somewhere
+-
+-
+-    /// TODO: find out input name
+-//    fd->input = (char*)av_malloc(VS_INPUT_MAXLEN);
+-
+-//    filenamecopy = strndup(fd->vob->video_in_file);
+-//    filebasename = basename(filenamecopy);
+-//    if (strlen(filebasename) < VS_INPUT_MAXLEN - 4) {
+-//        snprintf(fd->result, VS_INPUT_MAXLEN, "%s.trf", filebasename);
+-//} else {
+-//    av_log(ctx, AV_LOG_WARN, "input name too long, using default `%s'",
+-//                    DEFAULT_TRANS_FILE_NAME);
+-    snprintf(fd->input, VS_INPUT_MAXLEN, DEFAULT_TRANS_FILE_NAME);
+-//    }
+-
+-    if (fd->options != NULL) {
+-        if(optstr_lookup(fd->options, "help")) {
+-            av_log(ctx, AV_LOG_INFO, transform_help);
+-            return AVERROR(EINVAL);
+-        }
+-
+-        optstr_get(fd->options, "input",     "%[^:]", fd->input);
+-        optstr_get(fd->options, "maxshift",  "%d", &td->maxShift);
+-        optstr_get(fd->options, "maxangle",  "%lf", &td->maxAngle);
+-        optstr_get(fd->options, "smoothing", "%d", &td->smoothing);
+-        optstr_get(fd->options, "crop"     , "%d", &td->crop);
+-        optstr_get(fd->options, "invert"   , "%d", &td->invert);
+-        optstr_get(fd->options, "relative" , "%d", &td->relative);
+-        optstr_get(fd->options, "zoom"     , "%lf",&td->zoom);
+-        optstr_get(fd->options, "optzoom"  , "%d", &td->optZoom);
+-        optstr_get(fd->options, "interpol" , "%d", (int*)(&td->interpolType));
+-        optstr_get(fd->options, "sharpen"  , "%lf",&td->sharpen);
+-        if(optstr_lookup(fd->options, "tripod")){
+-            av_log(ctx,AV_LOG_INFO, "Virtual tripod mode: relative=False, smoothing=0");
+-            td->relative=0;
+-            td->smoothing=0;
+-        }
+-    }
+-
+-    if(configureTransformData(td)!= VS_OK){
+-    	av_log(ctx, AV_LOG_ERROR, "configuration of Tranform failed\n");
+-        return AVERROR(EINVAL);
+-    }
+-
+-    av_log(ctx, AV_LOG_INFO, "Image Transformation/Stabilization Settings:\n");
+-    av_log(ctx, AV_LOG_INFO, "    input     = %s\n", fd->input);
+-    av_log(ctx, AV_LOG_INFO, "    smoothing = %d\n", td->smoothing);
+-    av_log(ctx, AV_LOG_INFO, "    maxshift  = %d\n", td->maxShift);
+-    av_log(ctx, AV_LOG_INFO, "    maxangle  = %f\n", td->maxAngle);
+-    av_log(ctx, AV_LOG_INFO, "    crop      = %s\n", td->crop ? "Black" : "Keep");
+-    av_log(ctx, AV_LOG_INFO, "    relative  = %s\n", td->relative ? "True": "False");
+-    av_log(ctx, AV_LOG_INFO, "    invert    = %s\n", td->invert ? "True" : "False");
+-    av_log(ctx, AV_LOG_INFO, "    zoom      = %f\n", td->zoom);
+-    av_log(ctx, AV_LOG_INFO, "    optzoom   = %s\n", td->optZoom ? "On" : "Off");
+-    av_log(ctx, AV_LOG_INFO, "    interpol  = %s\n", interpolTypes[td->interpolType]);
+-    av_log(ctx, AV_LOG_INFO, "    sharpen   = %f\n", td->sharpen);
+-
+-    f = fopen(fd->input, "r");
+-    if (f == NULL) {
+-        av_log(ctx, AV_LOG_ERROR, "cannot open input file %s!\n", fd->input);
+-    } else {
+-        ManyLocalMotions mlms;
+-        if(readLocalMotionsFile(f,&mlms)==VS_OK){
+-            // calculate the actual transforms from the localmotions
+-            if(localmotions2TransformsSimple(td, &mlms,&fd->trans)!=VS_OK)
+-                av_log(ctx, AV_LOG_ERROR, "calculating transformations failed!\n");
+-        }else{ // try to read old format
+-            if (!readOldTransforms(td, f, &fd->trans)) { /* read input file */
+-                av_log(ctx, AV_LOG_ERROR, "error parsing input file %s!\n", fd->input);
+-            }
+-        }
+-    }
+-    fclose(f);
+-
+-    if (preprocessTransforms(td, &fd->trans)!= VS_OK ) {
+-        av_log(ctx, AV_LOG_ERROR, "error while preprocessing transforms\n");
+-        return AVERROR(EINVAL);
+-    }
+-
+-    // TODO: add sharpening
+-    return 0;
+-}
+-
+-
+-static int filter_frame(AVFilterLink *inlink,  AVFilterBufferRef *in)
+-{
+-    AVFilterContext *ctx = inlink->dst;
+-    FilterData *fd = ctx->priv;
+-    TransformData* td = &(fd->td);
+-
+-    AVFilterLink *outlink = inlink->dst->outputs[0];
+-    //const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+-    //int hsub0 = desc->log2_chroma_w;
+-    //int vsub0 = desc->log2_chroma_h;
+-    int direct = 0;
+-    AVFilterBufferRef *out;
+-    VSFrame inframe;
+-    VSFrame outframe;
+-    int plane;
+-
+-    if (in->perms & AV_PERM_WRITE) {
+-        direct = 1;
+-        out = in;
+-    } else {
+-        out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+-        if (!out) {
+-            avfilter_unref_bufferp(&in);
+-            return AVERROR(ENOMEM);
+-        }
+-        avfilter_copy_buffer_ref_props(out, in);
+-    }
+-
+-    for(plane=0; plane < td->fiSrc.planes; plane++){
+-        inframe.data[plane] = in->data[plane];
+-        inframe.linesize[plane] = in->linesize[plane];
+-    }
+-    for(plane=0; plane < td->fiDest.planes; plane++){
+-        outframe.data[plane] = out->data[plane];
+-        outframe.linesize[plane] = out->linesize[plane];
+-    }
+-
+-
+-    transformPrepare(td, &inframe, &outframe);
+-
+-    if (fd->td.fiSrc.pFormat > PF_PACKED) {
+-        transformRGB(td, getNextTransform(td, &fd->trans));
+-    } else {
+-        transformYUV(td, getNextTransform(td, &fd->trans));
+-    }
+-    transformFinish(td);
+-
+-    if (!direct)
+-        avfilter_unref_bufferp(&in);
+-
+-    return ff_filter_frame(outlink, out);
+-}
+-
+-
+-AVFilter avfilter_vf_transform = {
+-    .name      = "transform",
+-    .description = NULL_IF_CONFIG_SMALL("transforms each frame according to transformations\n\
+- given in an input file (e.g. translation, rotate) see also filter stabilize."),
+-
+-    .priv_size = sizeof(FilterData),
+-
+-    .init = init,
+-    .uninit = uninit,
+-    .query_formats = query_formats,
+-
+-    .inputs    = (const AVFilterPad[]) {
+-        { .name       = "default",
+-          .type             = AVMEDIA_TYPE_VIDEO,
+-          .get_video_buffer = ff_null_get_video_buffer,
+-          .filter_frame     = filter_frame,
+-          .config_props     = config_input,
+-          .min_perms        = AV_PERM_READ | AV_PERM_WRITE,
+-        },
+-        { .name = NULL}},
+-    .outputs   = (const AVFilterPad[]) {
+-        { .name             = "default",
+-          .type             = AVMEDIA_TYPE_VIDEO, },
+-        { .name = NULL}
+-    },
+-};
+-
+-
+-
+-/*************************************************************************/
+-
+-/*
+- * Local variables:
+- *   c-file-style: "stroustrup"
+- *   c-file-offsets: ((case-label . *) (statement-case-intro . *))
+- *   indent-tabs-mode: nil
+- * End:
+- *
+- * vim: expandtab shiftwidth=4:
+- */
+diff --git a/libavfilter/vf_vidstabdetect.c b/libavfilter/vf_vidstabdetect.c
+new file mode 100644
+index 0000000..d96ca8e
+--- /dev/null
++++ b/libavfilter/vf_vidstabdetect.c
+@@ -0,0 +1,218 @@
++/*
++ * Copyright (c) 2013 Georg Martius <georg dot martius at web dot de>
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#define DEFAULT_RESULT_NAME     "transforms.trf"
++
++#include <vid.stab/libvidstab.h>
++
++#include "libavutil/common.h"
++#include "libavutil/opt.h"
++#include "libavutil/imgutils.h"
++#include "avfilter.h"
++#include "internal.h"
++
++#include "vidstabutils.h"
++
++typedef struct {
++    const AVClass *class;
++
++    VSMotionDetect md;
++    VSMotionDetectConfig conf;
++
++    char *result;
++    FILE *f;
++} StabData;
++
++
++#define OFFSET(x) offsetof(StabData, x)
++#define OFFSETC(x) (offsetof(StabData, conf)+offsetof(VSMotionDetectConfig, x))
++#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
++
++static const AVOption vidstabdetect_options[] = {
++    {"result",      "path to the file used to write the transforms",                 OFFSET(result),             AV_OPT_TYPE_STRING, {.str = DEFAULT_RESULT_NAME}, .flags = FLAGS},
++    {"shakiness",   "how shaky is the video and how quick is the camera?"
++                    " 1: little (fast) 10: very strong/quick (slow)",                OFFSETC(shakiness),         AV_OPT_TYPE_INT,    {.i64 = 5},      1,  10, FLAGS},
++    {"accuracy",    "(>=shakiness) 1: low 15: high (slow)",                          OFFSETC(accuracy),          AV_OPT_TYPE_INT,    {.i64 = 9},      1,  15, FLAGS},
++    {"stepsize",    "region around minimum is scanned with 1 pixel resolution",      OFFSETC(stepSize),          AV_OPT_TYPE_INT,    {.i64 = 6},      1,  32, FLAGS},
++    {"mincontrast", "below this contrast a field is discarded (0-1)",                OFFSETC(contrastThreshold), AV_OPT_TYPE_DOUBLE, {.dbl = 0.25}, 0.0, 1.0, FLAGS},
++    {"show",        "0: draw nothing; 1,2: show fields and transforms",              OFFSETC(show),              AV_OPT_TYPE_INT,    {.i64 = 0},      0,   2, FLAGS},
++    {"tripod",      "virtual tripod mode (if >0): motion is compared to a reference"
++                    " reference frame (frame # is the value)",                       OFFSETC(virtualTripod),     AV_OPT_TYPE_INT,    {.i64 = 0}, 0, INT_MAX, FLAGS},
++    {NULL}
++};
++
++AVFILTER_DEFINE_CLASS(vidstabdetect);
++
++static av_cold int init(AVFilterContext *ctx)
++{
++    StabData *sd = ctx->priv;
++    vs_set_mem_and_log_functions();
++    sd->class = &vidstabdetect_class;
++    av_log(ctx, AV_LOG_VERBOSE, "vidstabdetect filter: init %s\n", LIBVIDSTAB_VERSION);
++    return 0;
++}
++
++static av_cold void uninit(AVFilterContext *ctx)
++{
++    StabData *sd = ctx->priv;
++    VSMotionDetect *md = &(sd->md);
++
++    if (sd->f) {
++        fclose(sd->f);
++        sd->f = NULL;
++    }
++
++    vsMotionDetectionCleanup(md);
++}
++
++static int query_formats(AVFilterContext *ctx)
++{
++    // If you add something here also add it in vidstabutils.c
++    static const enum AVPixelFormat pix_fmts[] = {
++        AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
++        AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA420P,
++        AV_PIX_FMT_YUV440P,  AV_PIX_FMT_GRAY8,
++        AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, AV_PIX_FMT_RGBA,
++        AV_PIX_FMT_NONE
++    };
++
++    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
++    return 0;
++}
++
++static int config_input(AVFilterLink *inlink)
++{
++    AVFilterContext *ctx = inlink->dst;
++    StabData *sd = ctx->priv;
++
++    VSMotionDetect* md = &(sd->md);
++    VSFrameInfo fi;
++    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
++
++    vsFrameInfoInit(&fi, inlink->w, inlink->h, av_2_vs_pixel_format(ctx, inlink->format));
++    if (fi.bytesPerPixel != av_get_bits_per_pixel(desc)/8) {
++        av_log(ctx, AV_LOG_ERROR, "pixel-format error: wrong bits/per/pixel, please report a BUG");
++        return AVERROR(EINVAL);
++    }
++    if (fi.log2ChromaW != desc->log2_chroma_w) {
++        av_log(ctx, AV_LOG_ERROR, "pixel-format error: log2_chroma_w, please report a BUG");
++        return AVERROR(EINVAL);
++    }
++
++    if (fi.log2ChromaH != desc->log2_chroma_h) {
++        av_log(ctx, AV_LOG_ERROR, "pixel-format error: log2_chroma_h, please report a BUG");
++        return AVERROR(EINVAL);
++    }
++
++    // set values that are not initialized by the options
++    sd->conf.algo     = 1;
++    sd->conf.modName  = "vidstabdetect";
++    if (vsMotionDetectInit(md, &sd->conf, &fi) != VS_OK) {
++        av_log(ctx, AV_LOG_ERROR, "initialization of Motion Detection failed, please report a BUG");
++        return AVERROR(EINVAL);
++    }
++
++    vsMotionDetectGetConfig(&sd->conf, md);
++    av_log(ctx, AV_LOG_INFO, "Video stabilization settings (pass 1/2):\n");
++    av_log(ctx, AV_LOG_INFO, "     shakiness = %d\n", sd->conf.shakiness);
++    av_log(ctx, AV_LOG_INFO, "      accuracy = %d\n", sd->conf.accuracy);
++    av_log(ctx, AV_LOG_INFO, "      stepsize = %d\n", sd->conf.stepSize);
++    av_log(ctx, AV_LOG_INFO, "   mincontrast = %f\n", sd->conf.contrastThreshold);
++    av_log(ctx, AV_LOG_INFO, "          show = %d\n", sd->conf.show);
++    av_log(ctx, AV_LOG_INFO, "        result = %s\n", sd->result);
++
++    sd->f = fopen(sd->result, "w");
++    if (sd->f == NULL) {
++        av_log(ctx, AV_LOG_ERROR, "cannot open transform file %s\n", sd->result);
++        return AVERROR(EINVAL);
++    } else {
++        if (vsPrepareFile(md, sd->f) != VS_OK) {
++            av_log(ctx, AV_LOG_ERROR, "cannot write to transform file %s\n", sd->result);
++            return AVERROR(EINVAL);
++        }
++    }
++    return 0;
++}
++
++
++static int filter_frame(AVFilterLink *inlink, AVFrame *in)
++{
++    AVFilterContext *ctx = inlink->dst;
++    StabData *sd = ctx->priv;
++    VSMotionDetect *md = &(sd->md);
++    LocalMotions localmotions;
++
++    AVFilterLink *outlink = inlink->dst->outputs[0];
++    VSFrame frame;
++    int plane;
++
++    if (sd->conf.show > 0 && !av_frame_is_writable(in))
++        av_frame_make_writable(in);
++
++    for (plane = 0; plane < md->fi.planes; plane++) {
++        frame.data[plane] = in->data[plane];
++        frame.linesize[plane] = in->linesize[plane];
++    }
++    if (vsMotionDetection(md, &localmotions, &frame) != VS_OK) {
++        av_log(ctx, AV_LOG_ERROR, "motion detection failed");
++        return AVERROR(AVERROR_EXTERNAL);
++    } else {
++        if (vsWriteToFile(md, sd->f, &localmotions) != VS_OK) {
++            av_log(ctx, AV_LOG_ERROR, "cannot write to transform file");
++            return AVERROR(errno);
++        }
++        vs_vector_del(&localmotions);
++    }
++
++    return ff_filter_frame(outlink, in);
++}
++
++static const AVFilterPad avfilter_vf_vidstabdetect_inputs[] = {
++    {
++        .name             = "default",
++        .type             = AVMEDIA_TYPE_VIDEO,
++        .filter_frame     = filter_frame,
++        .config_props     = config_input,
++    },
++    { NULL }
++};
++
++static const AVFilterPad avfilter_vf_vidstabdetect_outputs[] = {
++    {
++        .name             = "default",
++        .type             = AVMEDIA_TYPE_VIDEO,
++    },
++    { NULL }
++};
++
++AVFilter avfilter_vf_vidstabdetect = {
++    .name          = "vidstabdetect",
++    .description   = NULL_IF_CONFIG_SMALL("Extract relative transformations, "
++                                          "pass 1 of 2 for stabilization "
++                                          "(see vidstabtransform for pass 2)."),
++    .priv_size     = sizeof(StabData),
++    .init          = init,
++    .uninit        = uninit,
++    .query_formats = query_formats,
++
++    .inputs        = avfilter_vf_vidstabdetect_inputs,
++    .outputs       = avfilter_vf_vidstabdetect_outputs,
++    .priv_class    = &vidstabdetect_class,
++};
+diff --git a/libavfilter/vf_vidstabtransform.c b/libavfilter/vf_vidstabtransform.c
+new file mode 100644
+index 0000000..eee3da7
+--- /dev/null
++++ b/libavfilter/vf_vidstabtransform.c
+@@ -0,0 +1,292 @@
++/*
++ * Copyright (c) 2013 Georg Martius <georg dot martius at web dot de>
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#define DEFAULT_INPUT_NAME     "transforms.trf"
++
++#include <vid.stab/libvidstab.h>
++
++#include "libavutil/common.h"
++#include "libavutil/opt.h"
++#include "libavutil/imgutils.h"
++#include "avfilter.h"
++#include "internal.h"
++
++#include "vidstabutils.h"
++
++typedef struct {
++    const AVClass *class;
++
++    VSTransformData td;
++    VSTransformConfig conf;
++
++    VSTransformations trans;    // transformations
++    char *input;                // name of transform file
++    int tripod;
++} TransformContext;
++
++#define OFFSET(x) offsetof(TransformContext, x)
++#define OFFSETC(x) (offsetof(TransformContext, conf)+offsetof(VSTransformConfig, x))
++#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
++
++static const AVOption vidstabtransform_options[] = {
++    {"input",     "path to the file storing the transforms",                        OFFSET(input),
++                   AV_OPT_TYPE_STRING, {.str = DEFAULT_INPUT_NAME}, .flags = FLAGS },
++    {"smoothing", "number of frames*2 + 1 used for lowpass filtering",              OFFSETC(smoothing),
++                   AV_OPT_TYPE_INT,    {.i64 = 10},       1, 1000, FLAGS},
++    {"maxshift",  "maximal number of pixels to translate image",                    OFFSETC(maxShift),
++                   AV_OPT_TYPE_INT,    {.i64 = -1},      -1, 500,  FLAGS},
++    {"maxangle",  "maximal angle in rad to rotate image",                           OFFSETC(maxAngle),
++                   AV_OPT_TYPE_DOUBLE, {.dbl = -1.0},  -1.0, 3.14, FLAGS},
++    {"crop",      "set cropping mode",                                              OFFSETC(crop),
++                   AV_OPT_TYPE_INT,    {.i64 = 0},        0, 1,    FLAGS, "crop"},
++    {  "keep",    "keep border",                                                    0,
++                   AV_OPT_TYPE_CONST,  {.i64 = VSKeepBorder }, 0, 0, FLAGS, "crop"},
++    {  "black",   "black border",                                                   0,
++                   AV_OPT_TYPE_CONST,  {.i64 = VSCropBorder }, 0, 0, FLAGS, "crop"},
++    {"invert",    "1: invert transforms",                                           OFFSETC(invert),
++                   AV_OPT_TYPE_INT,    {.i64 = 0},        0, 1,    FLAGS},
++    {"relative",  "consider transforms as 0: absolute, 1: relative",                OFFSETC(relative),
++                   AV_OPT_TYPE_INT,    {.i64 = 1},        0, 1,    FLAGS},
++    {"zoom",      "percentage to zoom >0: zoom in, <0 zoom out",                    OFFSETC(zoom),
++                   AV_OPT_TYPE_DOUBLE, {.dbl = 0},        0, 100,  FLAGS},
++    {"optzoom",   "0: nothing, 1: determine optimal zoom (added to 'zoom')",        OFFSETC(optZoom),
++                   AV_OPT_TYPE_INT,    {.i64 = 1},        0, 1,    FLAGS},
++    {"interpol",  "type of interpolation",                                          OFFSETC(interpolType),
++                   AV_OPT_TYPE_INT,    {.i64 = 2},        0, 3,    FLAGS, "interpol"},
++    {  "no",      "no interpolation",                                               0,
++                   AV_OPT_TYPE_CONST,  {.i64 = VS_Zero  },  0, 0,  FLAGS, "interpol"},
++    {  "linear",  "linear (horizontal)",                                            0,
++                   AV_OPT_TYPE_CONST,  {.i64 = VS_Linear }, 0, 0,  FLAGS, "interpol"},
++    {  "bilinear","bi-linear",                                                      0,
++                   AV_OPT_TYPE_CONST,  {.i64 = VS_BiLinear},0, 0,  FLAGS, "interpol"},
++    {  "bicubic", "bi-cubic",                                                       0,
++                   AV_OPT_TYPE_CONST,  {.i64 = VS_BiCubic },0, 0,  FLAGS, "interpol"},
++    {"tripod",    "if 1: virtual tripod mode (equiv. to relative=0:smoothing=0)",   OFFSET(tripod),
++                   AV_OPT_TYPE_INT,    {.i64 = 0},        0, 1,    FLAGS},
++    {NULL}
++};
++
++AVFILTER_DEFINE_CLASS(vidstabtransform);
++
++static av_cold int init(AVFilterContext *ctx)
++{
++    TransformContext *tc = ctx->priv;
++    vs_set_mem_and_log_functions();
++    tc->class = &vidstabtransform_class;
++    av_log(ctx, AV_LOG_VERBOSE, "vidstabtransform filter: init %s\n", LIBVIDSTAB_VERSION);
++    return 0;
++}
++
++static av_cold void uninit(AVFilterContext *ctx)
++{
++    TransformContext *tc = ctx->priv;
++
++    vsTransformDataCleanup(&tc->td);
++    vsTransformationsCleanup(&tc->trans);
++}
++
++static int query_formats(AVFilterContext *ctx)
++{
++    // If you add something here also add it in vidstabutils.c
++    static const enum AVPixelFormat pix_fmts[] = {
++        AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
++        AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA420P,
++        AV_PIX_FMT_YUV440P,  AV_PIX_FMT_GRAY8,
++        AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, AV_PIX_FMT_RGBA,
++        AV_PIX_FMT_NONE
++    };
++
++    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
++    return 0;
++}
++
++
++static int config_input(AVFilterLink *inlink)
++{
++    AVFilterContext *ctx = inlink->dst;
++    TransformContext *tc = ctx->priv;
++    FILE *f;
++
++    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
++
++    VSTransformData *td = &(tc->td);
++
++    VSFrameInfo fi_src;
++    VSFrameInfo fi_dest;
++
++    if (!vsFrameInfoInit(&fi_src, inlink->w, inlink->h,
++                         av_2_vs_pixel_format(ctx, inlink->format)) ||
++        !vsFrameInfoInit(&fi_dest, inlink->w, inlink->h,
++                         av_2_vs_pixel_format(ctx, inlink->format))) {
++        av_log(ctx, AV_LOG_ERROR, "unknown pixel format: %i (%s)",
++               inlink->format, desc->name);
++        return AVERROR(EINVAL);
++    }
++
++    if (fi_src.bytesPerPixel != av_get_bits_per_pixel(desc)/8 ||
++        fi_src.log2ChromaW != desc->log2_chroma_w ||
++        fi_src.log2ChromaH != desc->log2_chroma_h) {
++        av_log(ctx, AV_LOG_ERROR, "pixel-format error: bpp %i<>%i  ",
++               fi_src.bytesPerPixel, av_get_bits_per_pixel(desc)/8);
++        av_log(ctx, AV_LOG_ERROR, "chroma_subsampl: w: %i<>%i  h: %i<>%i\n",
++               fi_src.log2ChromaW, desc->log2_chroma_w,
++               fi_src.log2ChromaH, desc->log2_chroma_h);
++        return AVERROR(EINVAL);
++    }
++
++    // set values that are not initializes by the options
++    tc->conf.modName = "vidstabtransform";
++    tc->conf.verbose =1;
++    if (tc->tripod) {
++        av_log(ctx, AV_LOG_INFO, "Virtual tripod mode: relative=0, smoothing=0");
++        tc->conf.relative  = 0;
++        tc->conf.smoothing = 0;
++    }
++
++    if (vsTransformDataInit(td, &tc->conf, &fi_src, &fi_dest) != VS_OK) {
++        av_log(ctx, AV_LOG_ERROR, "initialization of vid.stab transform failed, please report a BUG\n");
++        return AVERROR(EINVAL);
++    }
++
++    vsTransformGetConfig(&tc->conf, td);
++    av_log(ctx, AV_LOG_INFO, "Video transformation/stabilization settings (pass 2/2):\n");
++    av_log(ctx, AV_LOG_INFO, "    input     = %s\n", tc->input);
++    av_log(ctx, AV_LOG_INFO, "    smoothing = %d\n", tc->conf.smoothing);
++    av_log(ctx, AV_LOG_INFO, "    maxshift  = %d\n", tc->conf.maxShift);
++    av_log(ctx, AV_LOG_INFO, "    maxangle  = %f\n", tc->conf.maxAngle);
++    av_log(ctx, AV_LOG_INFO, "    crop      = %s\n", tc->conf.crop ? "Black" : "Keep");
++    av_log(ctx, AV_LOG_INFO, "    relative  = %s\n", tc->conf.relative ? "True": "False");
++    av_log(ctx, AV_LOG_INFO, "    invert    = %s\n", tc->conf.invert ? "True" : "False");
++    av_log(ctx, AV_LOG_INFO, "    zoom      = %f\n", tc->conf.zoom);
++    av_log(ctx, AV_LOG_INFO, "    optzoom   = %s\n", tc->conf.optZoom ? "On" : "Off");
++    av_log(ctx, AV_LOG_INFO, "    interpol  = %s\n", getInterpolationTypeName(tc->conf.interpolType));
++
++    f = fopen(tc->input, "r");
++    if (f == NULL) {
++        av_log(ctx, AV_LOG_ERROR, "cannot open input file %s\n", tc->input);
++        return AVERROR(errno);
++    } else {
++        VSManyLocalMotions mlms;
++        if (vsReadLocalMotionsFile(f, &mlms) == VS_OK) {
++            // calculate the actual transforms from the local motions
++            if (vsLocalmotions2TransformsSimple(td, &mlms, &tc->trans) != VS_OK) {
++                av_log(ctx, AV_LOG_ERROR, "calculating transformations failed\n");
++                return AVERROR(EINVAL);
++            }
++        } else { // try to read old format
++            if (!vsReadOldTransforms(td, f, &tc->trans)) { /* read input file */
++                av_log(ctx, AV_LOG_ERROR, "error parsing input file %s\n", tc->input);
++                return AVERROR(EINVAL);
++            }
++        }
++    }
++    fclose(f);
++
++    if (vsPreprocessTransforms(td, &tc->trans) != VS_OK ) {
++        av_log(ctx, AV_LOG_ERROR, "error while preprocessing transforms\n");
++        return AVERROR(EINVAL);
++    }
++
++    // TODO: add sharpening, so far the user needs to call the unsharp filter manually
++    return 0;
++}
++
++
++static int filter_frame(AVFilterLink *inlink, AVFrame *in)
++{
++    AVFilterContext *ctx = inlink->dst;
++    TransformContext *tc = ctx->priv;
++    VSTransformData* td = &(tc->td);
++
++    AVFilterLink *outlink = inlink->dst->outputs[0];
++    int direct = 0;
++    AVFrame *out;
++    VSFrame inframe;
++    int plane;
++
++    if (av_frame_is_writable(in)) {
++        direct = 1;
++        out = in;
++    } else {
++        out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
++        if (!out) {
++            av_frame_free(&in);
++            return AVERROR(ENOMEM);
++        }
++        av_frame_copy_props(out, in);
++    }
++
++    for (plane = 0; plane < vsTransformGetSrcFrameInfo(td)->planes; plane++) {
++        inframe.data[plane] = in->data[plane];
++        inframe.linesize[plane] = in->linesize[plane];
++    }
++    if (direct) {
++        vsTransformPrepare(td, &inframe, &inframe);
++    } else { // separate frames
++        VSFrame outframe;
++        for (plane = 0; plane < vsTransformGetDestFrameInfo(td)->planes; plane++) {
++            outframe.data[plane] = out->data[plane];
++            outframe.linesize[plane] = out->linesize[plane];
++        }
++        vsTransformPrepare(td, &inframe, &outframe);
++    }
++
++    vsDoTransform(td, vsGetNextTransform(td, &tc->trans));
++
++    vsTransformFinish(td);
++
++    if (!direct)
++        av_frame_free(&in);
++
++    return ff_filter_frame(outlink, out);
++}
++
++static const AVFilterPad avfilter_vf_vidstabtransform_inputs[] = {
++    {
++        .name             = "default",
++        .type             = AVMEDIA_TYPE_VIDEO,
++        .filter_frame     = filter_frame,
++        .config_props     = config_input,
++    },
++    { NULL }
++};
++
++static const AVFilterPad avfilter_vf_vidstabtransform_outputs[] = {
++    {
++        .name             = "default",
++        .type             = AVMEDIA_TYPE_VIDEO,
++    },
++    { NULL }
++};
++
++AVFilter avfilter_vf_vidstabtransform = {
++    .name          = "vidstabtransform",
++    .description   = NULL_IF_CONFIG_SMALL("Transform the frames, "
++                                          "pass 2 of 2 for stabilization "
++                                          "(see vidstabdetect for pass 1)."),
++    .priv_size     = sizeof(TransformContext),
++    .init          = init,
++    .uninit        = uninit,
++    .query_formats = query_formats,
++
++    .inputs        = avfilter_vf_vidstabtransform_inputs,
++    .outputs       = avfilter_vf_vidstabtransform_outputs,
++    .priv_class    = &vidstabtransform_class,
++};
+diff --git a/libavfilter/vidstabutils.c b/libavfilter/vidstabutils.c
+new file mode 100644
+index 0000000..dd6486d
+--- /dev/null
++++ b/libavfilter/vidstabutils.c
+@@ -0,0 +1,85 @@
++/*
++ * Copyright (c) 2013 Georg Martius <georg dot martius at web dot de>
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "vidstabutils.h"
++
++/** convert AV's pixelformat to vid.stab pixelformat */
++VSPixelFormat av_2_vs_pixel_format(AVFilterContext *ctx, enum AVPixelFormat pf)
++{
++    switch (pf) {
++    case AV_PIX_FMT_YUV420P:  return PF_YUV420P;
++    case AV_PIX_FMT_YUV422P:  return PF_YUV422P;
++    case AV_PIX_FMT_YUV444P:  return PF_YUV444P;
++    case AV_PIX_FMT_YUV410P:  return PF_YUV410P;
++    case AV_PIX_FMT_YUV411P:  return PF_YUV411P;
++    case AV_PIX_FMT_YUV440P:  return PF_YUV440P;
++    case AV_PIX_FMT_YUVA420P: return PF_YUVA420P;
++    case AV_PIX_FMT_GRAY8:    return PF_GRAY8;
++    case AV_PIX_FMT_RGB24:    return PF_RGB24;
++    case AV_PIX_FMT_BGR24:    return PF_BGR24;
++    case AV_PIX_FMT_RGBA:     return PF_RGBA;
++    default:
++        av_log(ctx, AV_LOG_ERROR, "cannot deal with pixel format %i\n", pf);
++        return PF_NONE;
++    }
++}
++
++/** struct to hold a valid context for logging from within vid.stab lib */
++typedef struct {
++    const AVClass *class;
++} VS2AVLogCtx;
++
++/** wrapper to log vs_log into av_log */
++static int vs_2_av_log_wrapper(int type, const char *tag, const char *format, ...)
++{
++    va_list ap;
++    VS2AVLogCtx ctx;
++    AVClass class = {
++      .class_name = tag,
++      .item_name  = av_default_item_name,
++      .option     = 0,
++      .version    = LIBAVUTIL_VERSION_INT,
++      .category   = AV_CLASS_CATEGORY_FILTER,
++    };
++    ctx.class = &class;
++    va_start(ap, format);
++    av_vlog(&ctx, type, format, ap);
++    va_end(ap);
++    return VS_OK;
++}
++
++/** sets the memory allocation function and logging constants to av versions */
++void vs_set_mem_and_log_functions(void)
++{
++    vs_malloc  = av_malloc;
++    vs_zalloc  = av_mallocz;
++    vs_realloc = av_realloc;
++    vs_free    = av_free;
++
++    VS_ERROR_TYPE = AV_LOG_ERROR;
++    VS_WARN_TYPE  = AV_LOG_WARNING;
++    VS_INFO_TYPE  = AV_LOG_INFO;
++    VS_MSG_TYPE   = AV_LOG_VERBOSE;
++
++    vs_log   = vs_2_av_log_wrapper;
++
++    VS_ERROR = 0;
++    VS_OK    = 1;
++}
+diff --git a/libavfilter/vidstabutils.h b/libavfilter/vidstabutils.h
+new file mode 100644
+index 0000000..f1c20e6
+--- /dev/null
++++ b/libavfilter/vidstabutils.h
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (c) 2013 Georg Martius <georg dot martius at web dot de>
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#ifndef AVFILTER_VIDSTABUTILS_H
++#define AVFILTER_VIDSTABUTILS_H
++
++#include <vid.stab/libvidstab.h>
++
++#include "avfilter.h"
++
++/* ** some conversions from avlib to vid.stab constants and functions *** */
++
++/** converts the pixelformat of avlib into the one of the vid.stab library */
++VSPixelFormat av_2_vs_pixel_format(AVFilterContext *ctx, enum AVPixelFormat pf);
++
++/** sets the memory allocation function and logging constants to av versions */
++void vs_set_mem_and_log_functions(void);
++
++#endif
+diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
+index 819e91b..1d10db3 100644
+--- a/src/CMakeLists.txt
++++ b/src/CMakeLists.txt
+@@ -5,12 +5,20 @@ SET(CMAKE_BUILTTYPE None)
+ 
+ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/../CMakeModules/")
+ 
+-#add_definitions( -Wall -O3 -Wno-pointer-sign -DTESTING )
+-add_definitions( -Wall -O3 -Wno-pointer-sign)
+-#add_definitions(  -Wall -O0 -g -Wno-pointer-sign )
++include (FindSSE)
++
++set(MAJOR_VERSION 0)
++set(MINOR_VERSION 9)
++set(PATCH_VERSION 6)
++set(VIDSTAB_VERSION ${MAJOR_VERSION}.${MINOR_VERSION}${PATCH_VERSION})
++
++add_definitions( -Wall -O3 -g -Wno-pointer-sign -fPIC )
++# add_definitions(  -Wall -O0 -g -Wno-pointer-sign )
++
++### ORC is not used in any active code at the moment  ###
+ # I tried it with 0.4.14
+ #  0.4.10 did not work (not all opcode implemented)
+-# find_package(Orc)  // it actually not used by any active code
++# find_package(Orc)
+ if(ORC_FOUND)
+ add_definitions( -DUSE_ORC ${ORC_DEFINITIONS} )
+ include_directories( ${ORC_INCLUDE_DIRS} )
+@@ -20,15 +28,25 @@ endif()
+ 
+ # here we should check for SSE2
+ # our  -DUSE_SSE2_ASM code does not work with fpic
+-add_definitions( -fPIC -DUSE_SSE2 -msse2 -ffast-math )
++if(SSE2_FOUND)
++add_definitions( -DUSE_SSE2 -msse2 -ffast-math )
++endif()
+ 
+-# Create the vidstab library
+-add_library (vidstab STATIC
+-  frameinfo.c transformtype.c libvidstab.c transform.c transformfixedpoint.c
++set(SOURCES frameinfo.c transformtype.c libvidstab.c transform.c transformfixedpoint.c
+   motiondetect.c motiondetect_opt.c serialize.c
+-	localmotion2transform.c
+-	boxblur.c vsvector.c orc/motiondetectorc.c)
+-#  orc/transformorc.c
++	localmotion2transform.c boxblur.c vsvector.c orc/motiondetectorc.c)
++
++set(HEADERS frameinfo.h transformtype.h libvidstab.h transform.h
++  motiondetect.h serialize.h localmotion2transform.h boxblur.h vsvector.h )
++
++
++# Create the vidstab library
++# add_library (vidstab STATIC ${SOURCES})
++add_library (vidstab SHARED ${SOURCES})
++
++#set version of lib
++set_target_properties(vidstab PROPERTIES SOVERSION ${MAJOR_VERSION}.${MINOR_VERSION})
++
+ 
+ target_link_libraries(vidstab m)
+ if(ORC_FOUND)
+@@ -37,3 +55,18 @@ endif()
+ if(USE_OMP)
+ target_link_libraries(vidstab gomp)
+ endif()
++
++
++#if(!NOHEADERS)
++FILE(GLOB HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/*.h")
++INSTALL(FILES ${HEADERS} DESTINATION include/vid.stab)
++#endif()
++
++INSTALL(TARGETS vidstab
++  RUNTIME DESTINATION bin
++  LIBRARY DESTINATION lib
++  ARCHIVE DESTINATION lib
++)
++
++include(create_pkgconfig_file)
++create_pkgconfig_file(vidstab "Vid.Stab, a library for stabilizing video clips")
+diff --git a/src/boxblur.c b/src/boxblur.c
+index b7a1488..db376fe 100644
+--- a/src/boxblur.c
++++ b/src/boxblur.c
+@@ -27,9 +27,9 @@
+ 
+ 
+ void boxblur_hori_C(unsigned char* dest, const unsigned char* src,
+-										int width, int height, int dest_strive, int src_strive, int size);
++                    int width, int height, int dest_strive, int src_strive, int size);
+ void boxblur_vert_C(unsigned char* dest, const unsigned char* src,
+-										int width, int height, int dest_strive, int src_strive, int size);
++                    int width, int height, int dest_strive, int src_strive, int size);
+ 
+ /*
+   The algorithm:
+@@ -43,74 +43,74 @@ void boxblur_vert_C(unsigned char* dest, const unsigned char* src,
+   accumulator: acc = acc + new - old, pixel = acc/size
+ */
+ 
+-void boxblurYUV(VSFrame* dest, const VSFrame* src,
+-		VSFrame* buffer, const VSFrameInfo* fi,
+-		unsigned int size, BoxBlurColorMode colormode){
++void boxblurPlanar(VSFrame* dest, const VSFrame* src,
++    VSFrame* buffer, const VSFrameInfo* fi,
++    unsigned int size, BoxBlurColorMode colormode){
+   int localbuffer=0;
+   int size2;
+   if(size<2){
+     if(dest!=src)
+-      copyFrame(dest,src,fi);
++      vsFrameCopy(dest,src,fi);
+     return;
+   }
+-	VSFrame buf;
++  VSFrame buf;
+   if(buffer==0){
+-		allocateFrame(&buf,fi);
+-		localbuffer=1;
++    vsFrameAllocate(&buf,fi);
++    localbuffer=1;
+   }else{
+-		buf = *buffer;
+-	}
++    buf = *buffer;
++  }
+   // odd and larger than 2 and maximally half of smaller image dimension
+   size  = VS_CLAMP((size/2)*2+1,3,VS_MIN(fi->height/2,fi->width/2));
+   //printf("%i\n",size);
+ 
+   // luminance
+   boxblur_hori_C(buf.data[0],  src->data[0],
+-								 fi->width, fi->height, buf.linesize[0],src->linesize[0], size);
++                 fi->width, fi->height, buf.linesize[0],src->linesize[0], size);
+   boxblur_vert_C(dest->data[0], buf.data[0],
+-								 fi->width, fi->height, dest->linesize[0], buf.linesize[0], size);
+-
+-	size2 = size/2+1; 	// odd and larger than 0
+-	int plane;
+-	switch (colormode){
+-	case BoxBlurColor:
+-		// color
+-		if(size2>1){
+-			for(plane=1; plane<fi->planes; plane++){
+-				boxblur_hori_C(buf.data[plane], src->data[plane],
+-											 fi->width  >> getPlaneWidthSubS(fi,plane),
+-											 fi->height >> getPlaneHeightSubS(fi,plane),
+-											 buf.linesize[plane], src->linesize[plane], size2);
+-				boxblur_vert_C(dest->data[plane], buf.data[plane],
+-											 fi->width  >> getPlaneWidthSubS(fi,plane),
+-											 fi->height >> getPlaneHeightSubS(fi,plane),
+-											 dest->linesize[plane], buf.linesize[plane], size2);
+-			}
+-		}
+-		break;
+-	case BoxBlurKeepColor:
+-		// copy both color channels
+-		for(plane=1; plane<fi->planes; plane++){
+-			copyFramePlane(dest, src, fi, plane);
+-		}
+-	case BoxBlurNoColor: // do nothing
+-	default:
+-		break;
+-	}
++                 fi->width, fi->height, dest->linesize[0], buf.linesize[0], size);
++
++  size2 = size/2+1;   // odd and larger than 0
++  int plane;
++  switch (colormode){
++  case BoxBlurColor:
++    // color
++    if(size2>1){
++      for(plane=1; plane<fi->planes; plane++){
++        boxblur_hori_C(buf.data[plane], src->data[plane],
++                       fi->width  >> vsGetPlaneWidthSubS(fi,plane),
++                       fi->height >> vsGetPlaneHeightSubS(fi,plane),
++                       buf.linesize[plane], src->linesize[plane], size2);
++        boxblur_vert_C(dest->data[plane], buf.data[plane],
++                       fi->width  >> vsGetPlaneWidthSubS(fi,plane),
++                       fi->height >> vsGetPlaneHeightSubS(fi,plane),
++                       dest->linesize[plane], buf.linesize[plane], size2);
++      }
++    }
++    break;
++  case BoxBlurKeepColor:
++    // copy both color channels
++    for(plane=1; plane<fi->planes; plane++){
++      vsFrameCopyPlane(dest, src, fi, plane);
++    }
++  case BoxBlurNoColor: // do nothing
++  default:
++    break;
++  }
+ 
+   if(localbuffer)
+-    freeFrame(&buf);
++    vsFrameFree(&buf);
+ }
+ 
+ /* /\* */
+ /*   The algorithm: */
+-/*   see boxblurYUV but here we for RGB */
++/*   see boxblurPlanar but here we for Packed */
+ 
+ /*   we add the 3 bytes of one pixel as if they where one number */
+ /* *\/ */
+-/* void boxblurRGB(const unsigned char* src, unsigned char* dest,  */
+-/* 		unsigned char* buffer, const VSFrameInfo* fi,  */
+-/* 		unsigned int size){ */
++/* void boxblurPacked(const unsigned char* src, unsigned char* dest,  */
++/*     unsigned char* buffer, const VSFrameInfo* fi,  */
++/*     unsigned int size){ */
+ /*   int localbuffer=0; */
+ /*   if(buffer==0){ */
+ /*     buffer=(unsigned char*) vs_malloc(fi->framesize); */
+@@ -120,7 +120,7 @@ void boxblurYUV(VSFrame* dest, const VSFrame* src,
+ /*   //  (and not larger than 256, because otherwise we can get an overflow) */
+ /*   size  = VS_CLAMP((size/2)*2+1,3,VS_MIN(256,VS_MIN(fi->height/2,fi->width/2)));  */
+ 
+-/*   // we need a different version of these functions for RGB */
++/*   // we need a different version of these functions for Packed */
+ /*   boxblur_hori_C(src, buffer, fi->width, fi->height, fi->strive, size);   */
+ /*   boxblur_vert_C(buffer, dest, fi->width, fi->height, fi->strive, size); */
+ 
+@@ -130,7 +130,7 @@ void boxblurYUV(VSFrame* dest, const VSFrame* src,
+ 
+ 
+ void boxblur_hori_C(unsigned char* dest, const unsigned char* src,
+-										int width, int height, int dest_strive, int src_strive, int size){
++                    int width, int height, int dest_strive, int src_strive, int size){
+ 
+   int i,j,k;
+   unsigned int acc;
+@@ -160,7 +160,7 @@ void boxblur_hori_C(unsigned char* dest, const unsigned char* src,
+ }
+ 
+ void boxblur_vert_C(unsigned char* dest, const unsigned char* src,
+-		    int width, int height, int dest_strive, int src_strive, int size){
++        int width, int height, int dest_strive, int src_strive, int size){
+ 
+   int i,j,k;
+   int acc;
+diff --git a/src/boxblur.h b/src/boxblur.h
+index b341589..3f8fac0 100644
+--- a/src/boxblur.h
++++ b/src/boxblur.h
+@@ -39,8 +39,8 @@ typedef enum _BoxBlurColorMode { BoxBlurColor, BoxBlurKeepColor, BoxBlurNoColor}
+  * @param size of bluring kernel, (min 3 and it is made odd)
+  * @param onlyLumincance if true color planes stay untouched
+  */
+-void boxblurYUV(VSFrame* dest, const VSFrame* src,
+-		VSFrame* buffer, const VSFrameInfo* fi,
+-		unsigned int size, BoxBlurColorMode colormode);
++void boxblurPlanar(VSFrame* dest, const VSFrame* src,
++    VSFrame* buffer, const VSFrameInfo* fi,
++    unsigned int size, BoxBlurColorMode colormode);
+ 
+ #endif
+diff --git a/src/frameinfo.c b/src/frameinfo.c
+index 9580d74..36a2c44 100644
+--- a/src/frameinfo.c
++++ b/src/frameinfo.c
+@@ -25,8 +25,9 @@
+ #include "frameinfo.h"
+ #include "vidstabdefines.h"
+ #include <assert.h>
++#include <string.h>
+ 
+-int initFrameInfo(VSFrameInfo* fi, int width, int height, PixelFormat pFormat){
++int vsFrameInfoInit(VSFrameInfo* fi, int width, int height, VSPixelFormat pFormat){
+   fi->pFormat=pFormat;
+   fi->width = width;
+   fi->height = height;
+@@ -82,36 +83,36 @@ int initFrameInfo(VSFrameInfo* fi, int width, int height, PixelFormat pFormat){
+   return 1;
+ }
+ 
+-int getPlaneWidthSubS(const VSFrameInfo* fi, int plane){
+-	return plane == 1 || plane == 2 ? fi->log2ChromaW : 0;
++int vsGetPlaneWidthSubS(const VSFrameInfo* fi, int plane){
++  return plane == 1 || plane == 2 ? fi->log2ChromaW : 0;
+ }
+ 
+-int getPlaneHeightSubS(const VSFrameInfo* fi, int plane){
+-	return  plane == 1 || plane == 2 ? fi->log2ChromaH : 0;
++int vsGetPlaneHeightSubS(const VSFrameInfo* fi, int plane){
++  return  plane == 1 || plane == 2 ? fi->log2ChromaH : 0;
+ }
+ 
+-int isNullFrame(const VSFrame* frame) {
+-	return frame==0 || frame->data[0]==0;
++int vsFrameIsNull(const VSFrame* frame) {
++  return frame==0 || frame->data[0]==0;
+ }
+ 
+ 
+-int equalFrames(const VSFrame* frame1,const VSFrame* frame2){
+-	return frame1 && frame2 && (frame1==frame2 || frame1->data[0] == frame2->data[0]);
++int vsFramesEqual(const VSFrame* frame1,const VSFrame* frame2){
++  return frame1 && frame2 && (frame1==frame2 || frame1->data[0] == frame2->data[0]);
+ }
+ 
+-void nullFrame(VSFrame* frame){
+-	memset(frame->data,0,sizeof(uint8_t*)*4);
+-	memset(frame->linesize,0,sizeof(int)*4);
++void vsFrameNull(VSFrame* frame){
++  memset(frame->data,0,sizeof(uint8_t*)*4);
++  memset(frame->linesize,0,sizeof(int)*4);
+ }
+ 
+-void allocateFrame(VSFrame* frame, const VSFrameInfo* fi){
+-	nullFrame(frame);
++void vsFrameAllocate(VSFrame* frame, const VSFrameInfo* fi){
++  vsFrameNull(frame);
+   if(fi->pFormat<PF_PACKED){
+     int i;
+     assert(fi->planes > 0 && fi->planes <= 4);
+     for (i=0; i< fi->planes; i++){
+-      int w = fi->width  >> getPlaneWidthSubS(fi, i);
+-      int h = fi->height >> getPlaneHeightSubS(fi, i);
++      int w = fi->width  >> vsGetPlaneWidthSubS(fi, i);
++      int h = fi->height >> vsGetPlaneHeightSubS(fi, i);
+       frame->data[i] = vs_zalloc(w * h * sizeof(uint8_t));
+       frame->linesize[i] = w;
+       if(frame->data[i]==0)
+@@ -128,53 +129,53 @@ void allocateFrame(VSFrame* frame, const VSFrameInfo* fi){
+   }
+ }
+ 
+-void copyFramePlane(VSFrame* dest, const VSFrame* src,
+-										const VSFrameInfo* fi, int plane){
+-	assert(src->data[plane]);
+-	int h = fi->height >> getPlaneHeightSubS(fi, plane);
+-	if(src->linesize[plane] == dest->linesize[plane])
+-		memcpy(dest->data[plane], src->data[plane], src->linesize[plane] *  h * sizeof(uint8_t));
+-	else {
+-		uint8_t* d = dest->data[plane];
+-		const uint8_t* s = src->data[plane];
+-		int w = fi->width  >> getPlaneWidthSubS(fi, plane);
+-		for (; h>0; h++) {
+-			memcpy(d,s,sizeof(uint8_t) * w);
+-			d += dest->linesize[plane];
+-			s += src ->linesize[plane];
+-		}
+-	}
++void vsFrameCopyPlane(VSFrame* dest, const VSFrame* src,
++                    const VSFrameInfo* fi, int plane){
++  assert(src->data[plane]);
++  int h = fi->height >> vsGetPlaneHeightSubS(fi, plane);
++  if(src->linesize[plane] == dest->linesize[plane])
++    memcpy(dest->data[plane], src->data[plane], src->linesize[plane] *  h * sizeof(uint8_t));
++  else {
++    uint8_t* d = dest->data[plane];
++    const uint8_t* s = src->data[plane];
++    int w = fi->width  >> vsGetPlaneWidthSubS(fi, plane);
++    for (; h>0; h--) {
++      memcpy(d,s,sizeof(uint8_t) * w);
++      d += dest->linesize[plane];
++      s += src ->linesize[plane];
++    }
++  }
+ }
+ 
+-void copyFrame(VSFrame* dest, const VSFrame* src, const VSFrameInfo* fi){
+-	int plane;
+-	assert(fi->planes > 0 && fi->planes <= 4);
+-	for (plane=0; plane< fi->planes; plane++){
+-		copyFramePlane(dest,src,fi,plane);
+-	}
++void vsFrameCopy(VSFrame* dest, const VSFrame* src, const VSFrameInfo* fi){
++  int plane;
++  assert(fi->planes > 0 && fi->planes <= 4);
++  for (plane=0; plane< fi->planes; plane++){
++    vsFrameCopyPlane(dest,src,fi,plane);
++  }
+ }
+ 
+-void fillFrameFromBuffer(VSFrame* frame, uint8_t* img, const VSFrameInfo* fi){
++void vsFrameFillFromBuffer(VSFrame* frame, uint8_t* img, const VSFrameInfo* fi){
+   assert(fi->planes > 0 && fi->planes <= 4);
+-  nullFrame(frame);
++  vsFrameNull(frame);
+   long int offset = 0;
+   int i;
+   for (i=0; i< fi->planes; i++){
+-    int w = fi->width  >> getPlaneWidthSubS(fi, i);
+-    int h = fi->height >> getPlaneHeightSubS(fi, i);
++    int w = fi->width  >> vsGetPlaneWidthSubS(fi, i);
++    int h = fi->height >> vsGetPlaneHeightSubS(fi, i);
+     frame->data[i] = img + offset;
+     frame->linesize[i] = w*fi->bytesPerPixel;
+     offset += h * w*fi->bytesPerPixel;
+   }
+ }
+ 
+-void freeFrame(VSFrame* frame){
+-	int plane;
+-	for (plane=0; plane< 4; plane++){
+-		if(frame->data[plane]) vs_free(frame->data[plane]);
+-		frame->data[plane]=0;
+-		frame->linesize[plane]=0;
+-	}
++void vsFrameFree(VSFrame* frame){
++  int plane;
++  for (plane=0; plane< 4; plane++){
++    if(frame->data[plane]) vs_free(frame->data[plane]);
++    frame->data[plane]=0;
++    frame->linesize[plane]=0;
++  }
+ }
+ 
+ 
+diff --git a/src/frameinfo.h b/src/frameinfo.h
+index 76a2d61..f48e92e 100644
+--- a/src/frameinfo.h
++++ b/src/frameinfo.h
+@@ -43,7 +43,7 @@ typedef enum {PF_NONE = -1,
+               PF_BGR24,     ///< packed RGB 8:8:8, 24bpp, BGRBGR...
+               PF_RGBA,      ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
+               PF_NUMBER     ///< number of pixel formats
+-} PixelFormat;
++} VSPixelFormat;
+ 
+ /** frame information for deshaking lib
+     This only works for planar image formats
+@@ -53,7 +53,7 @@ typedef struct vsframeinfo {
+   int planes;        // number of planes (1 luma, 2,3 chroma, 4 alpha)
+   int log2ChromaW; // subsampling of width in chroma planes
+   int log2ChromaH; // subsampling of height in chroma planes
+-  PixelFormat pFormat;
++  VSPixelFormat pFormat;
+   int bytesPerPixel; // number of bytes per pixel (for packed formats)
+ } VSFrameInfo;
+ 
+@@ -68,43 +68,43 @@ typedef struct vsframe {
+ #define CHROMA_SIZE(width,log2sub)  (-(-(width) >> (log2sub)))
+ 
+ /// initializes the frameinfo for the given format
+-int initFrameInfo(VSFrameInfo* fi, int width, int height, PixelFormat pFormat);
++int vsFrameInfoInit(VSFrameInfo* fi, int width, int height, VSPixelFormat pFormat);
+ 
+ 
+ /// returns the subsampling shift amount, horizonatally for the given plane
+-int getPlaneWidthSubS(const VSFrameInfo* fi, int plane);
++int vsGetPlaneWidthSubS(const VSFrameInfo* fi, int plane);
+ 
+ /// returns the subsampling shift amount, vertically for the given plane
+-int getPlaneHeightSubS(const VSFrameInfo* fi, int plane);
++int vsGetPlaneHeightSubS(const VSFrameInfo* fi, int plane);
+ 
+ /// zero initialization
+-void nullFrame(VSFrame* frame);
++void vsFrameNull(VSFrame* frame);
+ 
+ /// returns true if frame is null (data[0]==0)
+-int isNullFrame(const VSFrame* frame);
++int vsFrameIsNull(const VSFrame* frame);
+ 
+ /// compares two frames for identity (based in data[0])
+-int equalFrames(const VSFrame* frame1,const VSFrame* frame2);
++int vsFramesEqual(const VSFrame* frame1,const VSFrame* frame2);
+ 
+ /// allocates memory for a frame
+-void allocateFrame(VSFrame* frame, const VSFrameInfo* fi);
++void vsFrameAllocate(VSFrame* frame, const VSFrameInfo* fi);
+ 
+ 
+ /// copies the given plane number from src to dest
+-void copyFramePlane(VSFrame* dest, const VSFrame* src,
+-										const VSFrameInfo* fi, int plane);
++void vsFrameCopyPlane(VSFrame* dest, const VSFrame* src,
++                    const VSFrameInfo* fi, int plane);
+ 
+ /// copies src to dest
+-void copyFrame(VSFrame* dest, const VSFrame* src, const VSFrameInfo* fi);
++void vsFrameCopy(VSFrame* dest, const VSFrame* src, const VSFrameInfo* fi);
+ 
+ /** fills the data pointer so that it corresponds to the img saved in the linear buffer.
+     No copying is performed.
+-    Do not call freeFrame() on it.
++    Do not call vsFrameFree() on it.
+  */
+-void fillFrameFromBuffer(VSFrame* frame, uint8_t* img, const VSFrameInfo* fi);
++void vsFrameFillFromBuffer(VSFrame* frame, uint8_t* img, const VSFrameInfo* fi);
+ 
+ /// frees memory
+-void freeFrame(VSFrame* frame);
++void vsFrameFree(VSFrame* frame);
+ 
+ #endif  /* FRAMEINFO_H */
+ 
+diff --git a/src/libvidstab.c b/src/libvidstab.c
+index b804f3a..263093b 100644
+--- a/src/libvidstab.c
++++ b/src/libvidstab.c
+@@ -24,6 +24,50 @@
+ 
+ #include "libvidstab.h"
+ 
++#include <string.h>
++#include <stdio.h>
++#include <stdarg.h>
++
++/**** default values for memory and logging ****/
++
++/// memory allocation with zero initialization
++void* _zalloc(size_t size){
++    return memset(malloc(size),0,size);
++}
++
++/// logging function
++int _vs_log(int type, const char* tag, const char* format, ...){
++    fprintf(stderr,"%s (%s):",
++            type == VS_ERROR_TYPE ? "Error: " :
++            type == VS_WARN_TYPE  ? "Warn:  " :
++            type == VS_INFO_TYPE  ? "Info:  " :
++            type == VS_MSG_TYPE   ? "Msg:   " : "Unknown",
++            tag);
++    va_list ap;
++    va_start (ap, format);
++    vfprintf (stderr, format, ap);
++    va_end (ap);
++    fprintf(stderr,"\n");
++    return 0;
++}
++
++
++vs_malloc_t vs_malloc   = malloc;
++vs_realloc_t vs_realloc = realloc;
++vs_free_t vs_free       = free;
++vs_zalloc_t vs_zalloc   = _zalloc;
++
++vs_strdup_t vs_strdup   = strdup;
++vs_strndup_t vs_strndup = strndup;
++
++vs_log_t vs_log         = _vs_log;
++int VS_ERROR_TYPE = 0;
++int VS_WARN_TYPE  = 1;
++int VS_INFO_TYPE  = 2;
++int VS_MSG_TYPE   = 3;
++
++int VS_ERROR     = -1;
++int VS_OK        = 0;
+ 
+ /*
+  * Local variables:
+diff --git a/src/libvidstab.h b/src/libvidstab.h
+index 88d960f..8debdf0 100644
+--- a/src/libvidstab.h
++++ b/src/libvidstab.h
+@@ -25,21 +25,15 @@
+ #ifndef LIBVIDSTAB_H
+ #define LIBVIDSTAB_H
+ 
+-#define LIBVIDSTAB_VERSION "v0.96 (2013-02-19)"
++#define LIBVIDSTAB_VERSION "v0.961 (2013-04-16)"
+ 
+ #include "frameinfo.h"
+ #include "motiondetect.h"
+ #include "transform.h"
+-#include "boxblur.h"
+ #include "vsvector.h"
+ #include "serialize.h"
+ #include "localmotion2transform.h"
+ 
+-#include "transformfixedpoint.h"
+-#ifdef TESTING
+-#include "transformfloat.h"
+-#endif
+-
+ #endif  /* LIBVIDSTAB_H_ */
+ 
+ /*
+@@ -47,6 +41,8 @@
+  *   c-file-style: "stroustrup"
+  *   c-file-offsets: ((case-label . *) (statement-case-intro . *))
+  *   indent-tabs-mode: nil
++ *   c-basic-offset: 2 t
+  * End:
+  *
++ * vim: expandtab shiftwidth=2:
+  */
+diff --git a/src/localmotion2transform.c b/src/localmotion2transform.c
+index 601e1ad..4637235 100644
+--- a/src/localmotion2transform.c
++++ b/src/localmotion2transform.c
+@@ -23,29 +23,30 @@
+  */
+ 
+ #include "localmotion2transform.h"
++#include "transformtype_operations.h"
+ #include <assert.h>
+ 
+-int localmotions2TransformsSimple(TransformData* td,
+-																	const ManyLocalMotions* motions,
+-																	Transformations* trans ){
+-	int i;
+-	int len = vs_vector_size(motions);
+-	assert(trans->len==0 && trans->ts == 0);
+-	trans->ts = vs_malloc(sizeof(Transform)*len );
+-	for(i=0; i< vs_vector_size(motions); i++) {
+-		trans->ts[i]=simpleMotionsToTransform(td,MLMGet(motions,i));
+-		//    storeLocalmotions(stderr,MLMGet(motions,i));
+-		//		storeTransform(stderr,&trans->ts[i]);
+-	}
+-	trans->len=len;
+-	return VS_OK;
++int vsLocalmotions2TransformsSimple(VSTransformData* td,
++                                  const VSManyLocalMotions* motions,
++                                  VSTransformations* trans ){
++  int i;
++  int len = vs_vector_size(motions);
++  assert(trans->len==0 && trans->ts == 0);
++  trans->ts = vs_malloc(sizeof(VSTransform)*len );
++  for(i=0; i< vs_vector_size(motions); i++) {
++    trans->ts[i]=vsSimpleMotionsToTransform(td,VSMLMGet(motions,i));
++    //    vsStoreLocalmotions(stderr,VSMLMGet(motions,i));
++    //    storeTransform(stderr,&trans->ts[i]);
++  }
++  trans->len=len;
++  return VS_OK;
+ }
+ 
+ 
+ /* calculates rotation angle for the given transform and
+  * field with respect to the given center-point
+  */
+-double calcAngle(const LocalMotion* lm, int center_x, int center_y){
++double vsCalcAngle(const LocalMotion* lm, int center_x, int center_y){
+   // we better ignore fields that are to close to the rotation center
+   if (abs(lm->f.x - center_x) + abs(lm->f.y - center_y) < lm->f.size*2) {
+     return 0;
+@@ -56,16 +57,16 @@ double calcAngle(const LocalMotion* lm, int center_x, int center_y){
+                       lm->f.x - center_x + lm->v.x);
+     double diff = a2 - a1;
+     return (diff > M_PI) ? diff - 2 * M_PI : ((diff < -M_PI) ? diff + 2
+-					      * M_PI : diff);
++                * M_PI : diff);
+   }
+ }
+ 
+ 
+-Transform simpleMotionsToTransform(TransformData* td,
++VSTransform vsSimpleMotionsToTransform(VSTransformData* td,
+                                    const LocalMotions* motions){
+   int center_x = 0;
+   int center_y = 0;
+-	Transform t = null_transform();
++  VSTransform t = null_transform();
+   if(motions==0) return t;
+   int num_motions=vs_vector_size(motions);
+   double *angles = (double*) vs_malloc(sizeof(double) * num_motions);
+@@ -93,14 +94,14 @@ Transform simpleMotionsToTransform(TransformData* td,
+     for (i = 0; i < num_motions; i++) {
+       // substract avg and calc angle
+       LocalMotion m = sub_localmotion(LMGet(motions,i),&meanmotion);
+-      angles[i] = calcAngle(&m, center_x, center_y);
++      angles[i] = vsCalcAngle(&m, center_x, center_y);
+     }
+     double min, max;
+     t.alpha = -cleanmean(angles, num_motions, &min, &max);
+     if (max - min > td->maxAngleVariation) {
+       t.alpha = 0;
+-      vs_log_info(td->modName, "too large variation in angle(%f)\n",
+-		  max-min);
++      vs_log_info(td->conf.modName, "too large variation in angle(%f)\n",
++      max-min);
+     }
+   }
+   vs_free(angles);
+diff --git a/src/localmotion2transform.h b/src/localmotion2transform.h
+index cd6b173..6a41e30 100644
+--- a/src/localmotion2transform.h
++++ b/src/localmotion2transform.h
+@@ -33,21 +33,21 @@
+ 
+ /** converts for each frame the localmotions into a transform
+  */
+-int localmotions2TransformsSimple(TransformData* td,
+-																	const ManyLocalMotions* motions,
+-																	Transformations* trans );
++int vsLocalmotions2TransformsSimple(VSTransformData* td,
++                                  const VSManyLocalMotions* motions,
++                                  VSTransformations* trans );
+ 
+ 
+ /** calculates rotation angle for the given transform and
+  * field with respect to the given center-point
+  */
+-double calcAngle(const LocalMotion* lm, int center_x, int center_y);
++double vsCalcAngle(const LocalMotion* lm, int center_x, int center_y);
+ 
+ /** calculates the transformation that caused the observed motions.
+     Using a simple cleaned-means approach to eliminate outliers.
+     translation and rotation is calculated.
+ */
+-Transform simpleMotionsToTransform(TransformData* td,
++VSTransform vsSimpleMotionsToTransform(VSTransformData* td,
+                                    const LocalMotions* motions);
+ 
+ #endif
+diff --git a/src/motiondetect.c b/src/motiondetect.c
+index 749a93e..921230a 100644
+--- a/src/motiondetect.c
++++ b/src/motiondetect.c
+@@ -25,6 +25,7 @@
+  *
+  */
+ #include "motiondetect.h"
++#include "motiondetect_internal.h"
+ #include "motiondetect_opt.h"
+ #include <math.h>
+ #include <limits.h>
+@@ -39,6 +40,10 @@
+ #include "boxblur.h"
+ #include "vidstabdefines.h"
+ #include "localmotion2transform.h"
++#include "transformtype_operations.h"
++
++#define USE_SPIRAL_FIELD_CALC
++
+ 
+ /* internal data structures */
+ 
+@@ -48,104 +53,111 @@ typedef struct _contrast_idx {
+   int index;
+ } contrast_idx;
+ 
+-int initMotionDetect(MotionDetect* md, const VSFrameInfo* fi,
+-		     const char* modName) {
++
++VSMotionDetectConfig vsMotionDetectGetDefaulfConfig(const char* modName){
++  VSMotionDetectConfig conf;
++  conf.stepSize          = 6;
++  conf.algo              = 1;
++  conf.accuracy          = 9;
++  conf.shakiness         = 5;
++  conf.virtualTripod     = 0;
++  conf.contrastThreshold = 0.25;
++  conf.show              = 0;
++  conf.modName           = modName;
++  return conf;
++}
++
++void vsMotionDetectGetConfig(VSMotionDetectConfig* conf, const VSMotionDetect* md){
++  if(md && conf)
++    *conf = md->conf;
++}
++
++const VSFrameInfo* vsMotionDetectGetFrameInfo(const VSMotionDetect* md){
++  return &md->fi;
++}
++
++
++int vsMotionDetectInit(VSMotionDetect* md, const VSMotionDetectConfig* conf, const VSFrameInfo* fi){
+   assert(md && fi);
++  md->conf = *conf;
+   md->fi = *fi;
+-  md->modName = modName;
+ 
+   if(fi->pFormat<=PF_NONE ||  fi->pFormat==PF_PACKED || fi->pFormat>=PF_NUMBER) {
+-    vs_log_warn(md->modName, "unsupported Pixel Format (%i)\n",
++    vs_log_warn(md->conf.modName, "unsupported Pixel Format (%i)\n",
+                 md->fi.pFormat);
+     return VS_ERROR;
+   }
+ 
+-  allocateFrame(&md->prev, &md->fi);
+-  if (isNullFrame(&md->prev)) {
+-    vs_log_error(md->modName, "malloc failed");
++  vsFrameAllocate(&md->prev, &md->fi);
++  if (vsFrameIsNull(&md->prev)) {
++    vs_log_error(md->conf.modName, "malloc failed");
+     return VS_ERROR;
+   }
+ 
+-  nullFrame(&md->curr);
+-  nullFrame(&md->currorig);
+-  nullFrame(&md->currtmp);
++  vsFrameNull(&md->curr);
++  vsFrameNull(&md->currorig);
++  vsFrameNull(&md->currtmp);
+   md->hasSeenOneFrame = 0;
+   md->frameNum = 0;
+ 
+-  // Options
+-  md->stepSize  = 6;
+-  md->allowMax  = 0;
+-  md->algo      = 1;
+-  md->accuracy  = 9;
+-  md->shakiness = 5;
+   md->fieldSize = VS_MIN(md->fi.width, md->fi.height) / 12;
+-  md->virtualTripod = 0;
+-  md->show = 0;
+-  md->contrastThreshold = 0.25;
+-  md->initialized = 1;
+-  return VS_OK;
+-}
+-
+-int configureMotionDetect(MotionDetect* md) {
+-  if (md->initialized != 1)
+-    return VS_ERROR;
++  md->allowMax  = 0;
++  md->fieldNum  = 0; // will be set in initFields()
+ 
+-  md->shakiness = VS_MIN(10,VS_MAX(1,md->shakiness));
+-  md->accuracy = VS_MIN(15,VS_MAX(1,md->accuracy));
+-  if (md->accuracy < md->shakiness / 2) {
+-    vs_log_info(md->modName, "Accuracy should not be lower than shakiness/2 -- fixed");
+-    md->accuracy = md->shakiness / 2;
++  md->conf.shakiness = VS_MIN(10,VS_MAX(1,md->conf.shakiness));
++  md->conf.accuracy = VS_MIN(15,VS_MAX(1,md->conf.accuracy));
++  if (md->conf.accuracy < md->conf.shakiness / 2) {
++    vs_log_info(md->conf.modName, "Accuracy should not be lower than shakiness/2 -- fixed");
++    md->conf.accuracy = md->conf.shakiness / 2;
+   }
+-  if (md->accuracy > 9 && md->stepSize > 6) {
+-    vs_log_info(md->modName, "For high accuracy use lower stepsize  -- set to 6 now");
+-    md->stepSize = 6; // maybe 4
++  if (md->conf.accuracy > 9 && md->conf.stepSize > 6) {
++    vs_log_info(md->conf.modName, "For high accuracy use lower stepsize  -- set to 6 now");
++    md->conf.stepSize = 6; // maybe 4
+   }
+ 
+   // shift: shakiness 1: height/40; 10: height/4
+   int minDimension = VS_MIN(md->fi.width, md->fi.height);
+-  md->maxShift
+-    = VS_MAX(4,(minDimension*md->shakiness)/40);
++  md->maxShift = VS_MAX(4,(minDimension*md->conf.shakiness)/40);
+   // size: shakiness 1: height/40; 10: height/6 (clipped)
+-  md->fieldSize
+-    = VS_MAX(4,VS_MIN(minDimension/6, (minDimension*md->shakiness)/40));
++  md->fieldSize = VS_MAX(4,VS_MIN(minDimension/6, (minDimension*md->conf.shakiness)/40));
+ 
+ #if defined(USE_SSE2) || defined(USE_SSE2_ASM)
+   md->fieldSize = (md->fieldSize / 16 + 1) * 16;
+ #endif
+ 
+-  vs_log_info(md->modName, "Fieldsize: %i, Maximal translation: %i pixel",
+-	      md->fieldSize, md->maxShift);
+-  if (md->algo == 1) {
++  vs_log_info(md->conf.modName, "Fieldsize: %i, Maximal translation: %i pixel\n",
++              md->fieldSize, md->maxShift);
++  if (md->conf.algo == 1) {
+     // initialize measurement fields. field_num is set here.
+     if (!initFields(md)) {
+       return VS_ERROR;
+     }
+-    md->maxFields = (md->accuracy) * md->fieldNum / 15;
+-    vs_log_info(md->modName, "Number of used measurement fields: %i out of %i",
+-		md->maxFields, md->fieldNum);
++    md->maxFields = (md->conf.accuracy) * md->fieldNum / 15;
++    vs_log_info(md->conf.modName, "Number of used measurement fields: %i out of %i\n",
++    md->maxFields, md->fieldNum);
+   }
+   //  if (md->show)
+-  allocateFrame(&md->curr,&md->fi);
+-  allocateFrame(&md->currtmp, &md->fi);
++  vsFrameAllocate(&md->curr,&md->fi);
++  vsFrameAllocate(&md->currtmp, &md->fi);
+ 
+   md->initialized = 2;
+   return VS_OK;
+ }
+ 
+-void cleanupMotionDetection(MotionDetect* md) {
++void vsMotionDetectionCleanup(VSMotionDetect* md) {
+   if(md->fields) {
+     vs_free(md->fields);
+     md->fields=0;
+   }
+-  freeFrame(&md->prev);
+-  freeFrame(&md->curr);
+-  freeFrame(&md->currtmp);
++  vsFrameFree(&md->prev);
++  vsFrameFree(&md->curr);
++  vsFrameFree(&md->currtmp);
+ 
+   md->initialized = 0;
+ }
+ 
+ 
+-int motionDetection(MotionDetect* md, LocalMotions* motions, VSFrame *frame) {
++int vsMotionDetection(VSMotionDetect* md, LocalMotions* motions, VSFrame *frame) {
+   assert(md->initialized==2);
+ 
+   md->currorig = *frame;
+@@ -154,38 +166,38 @@ int motionDetection(MotionDetect* md, LocalMotions* motions, VSFrame *frame) {
+   if (md->fi.pFormat > PF_PACKED) {
+     // we could calculate a grayscale version and use the PLANAR stuff afterwards
+     // so far smoothing is only implemented for PLANAR
+-    copyFrame(&md->curr, frame, &md->fi);
++    vsFrameCopy(&md->curr, frame, &md->fi);
+   } else {
+     // box-kernel smoothing (plain average of pixels), which is fine for us
+-    boxblurYUV(&md->curr, frame, &md->currtmp, &md->fi, md->stepSize*1/*1.4*/,
++    boxblurPlanar(&md->curr, frame, &md->currtmp, &md->fi, md->conf.stepSize*1/*1.4*/,
+                BoxBlurNoColor);
+     // two times yields tent-kernel smoothing, which may be better, but I don't
+     //  think we need it
+-    //boxblurYUV(md->curr, md->curr, md->currtmp, &md->fi, md->stepSize*1,
++    //boxblurPlanar(md->curr, md->curr, md->currtmp, &md->fi, md->stepSize*1,
+     // BoxBlurNoColor);
+   }
+ 
+   if (md->hasSeenOneFrame) {
+     //    md->curr = frame;
+     if (md->fi.pFormat > PF_PACKED) {
+-      if (md->algo == 0)
+-        *motions = calcShiftRGBSimple(md);
+-      else if (md->algo == 1)
+-        *motions = calcTransFields(md, calcFieldTransRGB, contrastSubImgRGB);
++      if (md->conf.algo == 0)
++        *motions = calcShiftPackedSimple(md);
++      else if (md->conf.algo == 1)
++        *motions = calcTransFields(md, calcFieldTransPacked, contrastSubImgPacked);
+     } else { // PLANAR
+-      if (md->algo == 0)
+-        *motions = calcShiftYUVSimple(md);
+-      else if (md->algo == 1)
+-        *motions = calcTransFields(md, calcFieldTransYUV, contrastSubImgYUV);
++      if (md->conf.algo == 0)
++        *motions = calcShiftPlanarSimple(md);
++      else if (md->conf.algo == 1)
++        *motions = calcTransFields(md, calcFieldTransPlanar, contrastSubImgPlanar);
+     }
+   } else {
+     vs_vector_init(motions,md->maxFields);
+     md->hasSeenOneFrame = 1;
+   }
+ 
+-  if(md->virtualTripod < 1 || md->frameNum < md->virtualTripod)
+-  // copy current frame (smoothed) to prev for next frame comparison
+-  copyFrame(&md->prev, &md->curr, &md->fi);
++  if(md->conf.virtualTripod < 1 || md->frameNum < md->conf.virtualTripod)
++    // copy current frame (smoothed) to prev for next frame comparison
++    vsFrameCopy(&md->prev, &md->curr, &md->fi);
+   md->frameNum++;
+   return VS_OK;
+ }
+@@ -195,7 +207,7 @@ int motionDetection(MotionDetect* md, LocalMotions* motions, VSFrame *frame) {
+     The size of the fields and the maxshift is used to
+     calculate an optimal distribution in the frame.
+ */
+-int initFields(MotionDetect* md) {
++int initFields(VSMotionDetect* md) {
+   int size = md->fieldSize;
+   int rows = VS_MAX(3,(md->fi.height - md->maxShift*2)/size-1);
+   int cols = VS_MAX(3,(md->fi.width - md->maxShift*2)/size-1);
+@@ -206,14 +218,14 @@ int initFields(MotionDetect* md) {
+   //            rows, cols, md->field_num);
+ 
+   if (!(md->fields = (Field*) vs_malloc(sizeof(Field) * md->fieldNum))) {
+-    vs_log_error(md->modName, "malloc failed!\n");
++    vs_log_error(md->conf.modName, "malloc failed!\n");
+     return 0;
+   } else {
+     int i, j;
+     // the border is the amount by which the field centers
+     // have to be away from the image boundary
+     // (stepsize is added in case shift is increased through stepsize)
+-    int border = size / 2 + md->maxShift + md->stepSize;
++    int border = size / 2 + md->maxShift + md->conf.stepSize;
+     int step_x = (md->fi.width - 2 * border) / VS_MAX(cols-1,1);
+     int step_y = (md->fi.height - 2 * border) / VS_MAX(rows-1,1);
+     for (j = 0; j < rows; j++) {
+@@ -289,7 +301,7 @@ unsigned int compareImg(unsigned char* I1, unsigned char* I2, int width, int hei
+ 
+ 
+ /** \see contrastSubImg*/
+-double contrastSubImgYUV(MotionDetect* md, const Field* field) {
++double contrastSubImgPlanar(VSMotionDetect* md, const Field* field) {
+ #ifdef USE_SSE2
+   return contrastSubImg1_SSE(md->curr.data[0], field, md->curr.linesize[0],md->fi.height);
+ #else
+@@ -302,7 +314,7 @@ double contrastSubImgYUV(MotionDetect* md, const Field* field) {
+    \see contrastSubImg_Michelson three times called with bytesPerPixel=3
+    for all channels
+ */
+-double contrastSubImgRGB(MotionDetect* md, const Field* field) {
++double contrastSubImgPacked(VSMotionDetect* md, const Field* field) {
+   unsigned char* const I = md->curr.data[0];
+   int linesize2 = md->curr.linesize[0]/3; // linesize in pixels
+   return (contrastSubImg(I, field, linesize2, md->fi.height, 3)
+@@ -346,7 +358,7 @@ double contrastSubImg(unsigned char* const I, const Field* field, int width,
+     shift images to all possible positions and calc summed error
+     Shift with minimal error is selected.
+ */
+-LocalMotions calcShiftRGBSimple(MotionDetect* md) {
++LocalMotions calcShiftPackedSimple(VSMotionDetect* md) {
+   LocalMotions localmotions;
+   vs_vector_init(&localmotions,1);
+   LocalMotion lm;
+@@ -380,7 +392,7 @@ LocalMotions calcShiftRGBSimple(MotionDetect* md) {
+     shift images to all possible positions and calc summed error
+     Shift with minimal error is selected.
+ */
+-LocalMotions calcShiftYUVSimple(MotionDetect* md) {
++LocalMotions calcShiftPlanarSimple(VSMotionDetect* md) {
+   LocalMotions localmotions;
+   vs_vector_init(&localmotions,1);
+   LocalMotion lm;
+@@ -424,17 +436,17 @@ LocalMotions calcShiftYUVSimple(MotionDetect* md) {
+   return localmotions;
+ }
+ 
+-/* calculates the optimal transformation for one field in YUV frames
++/* calculates the optimal transformation for one field in Planar frames
+  * (only luminance)
+  */
+-LocalMotion calcFieldTransYUV(MotionDetect* md, const Field* field, int fieldnum) {
++LocalMotion calcFieldTransPlanar(VSMotionDetect* md, const Field* field, int fieldnum) {
+   int tx = 0;
+   int ty = 0;
+   uint8_t *Y_c = md->curr.data[0], *Y_p = md->prev.data[0];
+   int linesize_c = md->curr.linesize[0], linesize_p = md->prev.linesize[0];
+   // we only use the luminance part of the image
+   int i, j;
+-  int stepSize = md->stepSize;
++  int stepSize = md->conf.stepSize;
+ 
+ #ifdef STABVERBOSE
+   // printf("%i %i %f\n", md->frameNum, fieldnum, contr);
+@@ -552,13 +564,13 @@ LocalMotion calcFieldTransYUV(MotionDetect* md, const Field* field, int fieldnum
+   vs_log_msg(md->modName, "Minerror: %f\n", minerror);
+ #endif
+ 
+-  if (!md->allowMax && fabs(tx) >= md->maxShift + md->stepSize) {
++  if (!md->allowMax && fabs(tx) >= md->maxShift + md->conf.stepSize) {
+ #ifdef STABVERBOSE
+     vs_log_msg(md->modName, "maximal x shift ");
+ #endif
+     tx = 0;
+   }
+-  if (!md->allowMax && fabs(ty) == md->maxShift + md->stepSize) {
++  if (!md->allowMax && fabs(ty) == md->maxShift + md->conf.stepSize) {
+ #ifdef STABVERBOSE
+     vs_log_msg(md->modName, "maximal y shift ");
+ #endif
+@@ -572,10 +584,10 @@ LocalMotion calcFieldTransYUV(MotionDetect* md, const Field* field, int fieldnum
+   return lm;
+ }
+ 
+-/* calculates the optimal transformation for one field in RGB
+- *   slower than the YUV version because it uses all three color channels
++/* calculates the optimal transformation for one field in Packed
++ *   slower than the Planar version because it uses all three color channels
+  */
+-LocalMotion calcFieldTransRGB(MotionDetect* md, const Field* field,
++LocalMotion calcFieldTransPacked(VSMotionDetect* md, const Field* field,
+                               int fieldnum) {
+   int tx = 0;
+   int ty = 0;
+@@ -583,6 +595,7 @@ LocalMotion calcFieldTransRGB(MotionDetect* md, const Field* field,
+   int width1 = md->curr.linesize[0]/3; // linesize in pixels
+   int width2 = md->prev.linesize[0]/3; // linesize in pixels
+   int i, j;
++  int stepSize = md->conf.stepSize;
+ 
+   /* Here we improve speed by checking first the most probable position
+      then the search paths are most effectively cut. (0,0) is a simple start
+@@ -590,8 +603,8 @@ LocalMotion calcFieldTransRGB(MotionDetect* md, const Field* field,
+   unsigned int minerror = compareSubImg(I_c, I_p, field, width1, width2, md->fi.height,
+                                         3, 0, 0, UINT_MAX);
+   // check all positions...
+-  for (i = -md->maxShift; i <= md->maxShift; i += md->stepSize) {
+-    for (j = -md->maxShift; j <= md->maxShift; j += md->stepSize) {
++  for (i = -md->maxShift; i <= md->maxShift; i += stepSize) {
++    for (j = -md->maxShift; j <= md->maxShift; j += stepSize) {
+       if( i==0 && j==0 )
+         continue; //no need to check this since already done
+       unsigned int error = compareSubImg(I_c, I_p, field, width1, width2,
+@@ -603,10 +616,10 @@ LocalMotion calcFieldTransRGB(MotionDetect* md, const Field* field,
+       }
+     }
+   }
+-  if (md->stepSize > 1) { // make fine grain check around the best match
++  if (stepSize > 1) { // make fine grain check around the best match
+     int txc = tx; // save the shifts
+     int tyc = ty;
+-    int r = md->stepSize - 1;
++    int r = stepSize - 1;
+     for (i = txc - r; i <= txc + r; i += 1) {
+       for (j = tyc - r; j <= tyc + r; j += 1) {
+         if (i == txc && j == tyc)
+@@ -622,13 +635,13 @@ LocalMotion calcFieldTransRGB(MotionDetect* md, const Field* field,
+     }
+   }
+ 
+-  if (!md->allowMax && fabs(tx) >= md->maxShift + md->stepSize) {
++  if (!md->allowMax && fabs(tx) >= md->maxShift + stepSize - 1) {
+ #ifdef STABVERBOSE
+     vs_log_msg(md->modName, "maximal x shift ");
+ #endif
+     tx = 0;
+   }
+-  if (!md->allowMax && fabs(ty) == md->maxShift + md->stepSize) {
++  if (!md->allowMax && fabs(ty) >= md->maxShift + stepSize - 1) {
+ #ifdef STABVERBOSE
+     vs_log_msg(md->modName, "maximal y shift ");
+ #endif
+@@ -655,7 +668,7 @@ int cmp_contrast_idx(const void *ci1, const void* ci2) {
+    first calc contrasts then select from each part of the
+    frame a some fields
+ */
+-VSVector selectfields(MotionDetect* md, contrastSubImgFunc contrastfunc) {
++VSVector selectfields(VSMotionDetect* md, contrastSubImgFunc contrastfunc) {
+   int i, j;
+   VSVector goodflds;
+   contrast_idx *ci =
+@@ -675,7 +688,7 @@ VSVector selectfields(MotionDetect* md, contrastSubImgFunc contrastfunc) {
+   for (i = 0; i < md->fieldNum; i++) {
+     ci[i].contrast = contrastfunc(md, &md->fields[i]);
+     ci[i].index = i;
+-    if (ci[i].contrast < md->contrastThreshold)
++    if (ci[i].contrast < md->conf.contrastThreshold)
+       ci[i].contrast = 0;
+     // else printf("%i %lf\n", ci[i].index, ci[i].contrast);
+   }
+@@ -735,7 +748,7 @@ VSVector selectfields(MotionDetect* md, contrastSubImgFunc contrastfunc) {
+  *   calculate rotation angle as cleaned mean of all angles
+  *   compensate for possibly off-center rotation
+  */
+-LocalMotions calcTransFields(MotionDetect* md,
++LocalMotions calcTransFields(VSMotionDetect* md,
+                              calcFieldTransFunc fieldfunc,
+                              contrastSubImgFunc contrastfunc) {
+   LocalMotions localmotions;
+@@ -758,7 +771,7 @@ LocalMotions calcTransFields(MotionDetect* md,
+   for(index=0; index < vs_vector_size(&goodflds); index++){
+     int i = ((contrast_idx*)vs_vector_get(&goodflds,index))->index;
+     LocalMotion m;
+-    m = fieldfunc(md, &md->fields[i], i); // e.g. calcFieldTransYUV
++    m = fieldfunc(md, &md->fields[i], i); // e.g. calcFieldTransPlanar
+     m.contrast = ((contrast_idx*)vs_vector_get(&goodflds,index))->contrast;
+ #ifdef STABVERBOSE
+     fprintf(file, "%i %i\n%f %f %f %f\n \n\n", m.f.x, m.f.y,
+@@ -772,13 +785,13 @@ LocalMotions calcTransFields(MotionDetect* md,
+   num_motions = vs_vector_size(&localmotions); // amount of transforms we actually have
+   vs_vector_del(&goodflds);
+   if (num_motions < 1) {
+-    vs_log_warn(md->modName, "too low contrast! No field remains.\n \
++    vs_log_warn(md->conf.modName, "too low contrast! No field remains.\n \
+                     (no translations are detected in frame %i)", md->frameNum);
+   }
+ 
+-  if (md->show) { // draw fields and transforms into frame.
++  if (md->conf.show) { // draw fields and transforms into frame.
+     // this has to be done one after another to handle possible overlap
+-    if (md->show > 1) {
++    if (md->conf.show > 1) {
+       for (i = 0; i < num_motions; i++)
+         drawFieldScanArea(md, LMGet(&localmotions,i));
+     }
+@@ -798,7 +811,7 @@ LocalMotions calcTransFields(MotionDetect* md,
+ 
+ 
+ /** draws the field scanning area */
+-void drawFieldScanArea(MotionDetect* md, const LocalMotion* lm) {
++void drawFieldScanArea(VSMotionDetect* md, const LocalMotion* lm) {
+   if (md->fi.pFormat > PF_PACKED)
+     return;
+   drawBox(md->currorig.data[0], md->currorig.linesize[0], md->fi.height, 1, lm->f.x, lm->f.y,
+@@ -806,7 +819,7 @@ void drawFieldScanArea(MotionDetect* md, const LocalMotion* lm) {
+ }
+ 
+ /** draws the field */
+-void drawField(MotionDetect* md, const LocalMotion* lm) {
++void drawField(VSMotionDetect* md, const LocalMotion* lm) {
+   if (md->fi.pFormat > PF_PACKED)
+     return;
+   drawBox(md->currorig.data[0], md->currorig.linesize[0], md->fi.height, 1, lm->f.x, lm->f.y,
+@@ -814,7 +827,7 @@ void drawField(MotionDetect* md, const LocalMotion* lm) {
+ }
+ 
+ /** draws the transform data of this field */
+-void drawFieldTrans(MotionDetect* md, const LocalMotion* lm) {
++void drawFieldTrans(VSMotionDetect* md, const LocalMotion* lm) {
+   if (md->fi.pFormat > PF_PACKED)
+     return;
+   drawBox(md->currorig.data[0], md->currorig.linesize[0], md->fi.height, 1,
+@@ -828,7 +841,7 @@ void drawFieldTrans(MotionDetect* md, const LocalMotion* lm) {
+  (the same for all channels)
+ */
+ void drawBox(unsigned char* I, int width, int height, int bytesPerPixel, int x,
+-	     int y, int sizex, int sizey, unsigned char color) {
++       int y, int sizex, int sizey, unsigned char color) {
+ 
+   unsigned char* p = NULL;
+   int j, k;
+@@ -842,18 +855,18 @@ void drawBox(unsigned char* I, int width, int height, int bytesPerPixel, int x,
+   }
+ }
+ 
+-// void addTrans(MotionDetect* md, Transform sl) {
++// void addTrans(VSMotionDetect* md, VSTransform sl) {
+ //   if (!md->transs) {
+ //     md->transs = vs_list_new(0);
+ //   }
+ //   vs_list_append_dup(md->transs, &sl, sizeof(sl));
+ // }
+ 
+-// Transform getLastTransform(MotionDetect* md){
++// VSTransform getLastVSTransform(VSMotionDetect* md){
+ //   if (!md->transs || !md->transs->head) {
+ //     return null_transform();
+ //   }
+-//   return *((Transform*)md->transs->tail);
++//   return *((VSTransform*)md->transs->tail);
+ // }
+ 
+ 
+@@ -861,8 +874,8 @@ void drawBox(unsigned char* I, int width, int height, int bytesPerPixel, int x,
+ /// plain C implementation of compareSubImg (without ORC)
+ unsigned int compareSubImg_thr(unsigned char* const I1, unsigned char* const I2,
+                                const Field* field, int width1, int width2, int height,
+-			     int bytesPerPixel, int d_x, int d_y,
+-			     unsigned int threshold) {
++           int bytesPerPixel, int d_x, int d_y,
++           unsigned int threshold) {
+   int k, j;
+   unsigned char* p1 = NULL;
+   unsigned char* p2 = NULL;
+diff --git a/src/motiondetect.h b/src/motiondetect.h
+index ac225f8..1fabb34 100644
+--- a/src/motiondetect.h
++++ b/src/motiondetect.h
+@@ -36,58 +36,51 @@
+ #include "vsvector.h"
+ #include "frameinfo.h"
+ 
+-#define USE_SPIRAL_FIELD_CALC
++typedef struct _vsmotiondetectconfig {
++  /* meta parameter for maxshift and fieldsize between 1 and 15 */
++  int         shakiness;
++  int         accuracy;         // meta parameter for number of fields between 1 and 10
++  int         stepSize;         // stepsize of field transformation detection
++  int         algo;             // algorithm to use
++  /* if >0 then all the frames are compared with the given frame (1 for first) */
++  int         virtualTripod;
++  /* if 1 and 2 then the fields and transforms are shown in the frames */
++  int         show;
++  /* measurement fields with lower contrast are discarded */
++  double      contrastThreshold;
++  const char* modName;          // module name (used for logging)
++} VSMotionDetectConfig;
+ 
+ 
+ /** data structure for motion detection part of deshaking*/
+-typedef struct motiondetect {
++typedef struct _vsmotiondetect {
+   VSFrameInfo fi;
+ 
+-  VSFrame curr;     // blurred version of current frame buffer
+-  VSFrame currorig; // current frame buffer (original) (only pointer)
+-  VSFrame currtmp;  // temporary buffer for blurring
+-  VSFrame prev;     // frame buffer for last frame (copied)
+-  short hasSeenOneFrame;   // true if we have a valid previous frame
++  VSMotionDetectConfig conf;
+ 
+-  const char* modName;
+-
+-  Field* fields;
+-
+-  /* Options */
+   /* maximum number of pixels we expect the shift of subsequent frames */
+   int maxShift;
+-  int stepSize; // stepsize of field transformation detection
+-  int allowMax; // 1 if maximal shift is allowed
+-  int algo;     // algorithm to use
+-  int fieldNum;  // number of measurement fields
+-  int maxFields;  // maximum number of fields used (selected by contrast)
+-  int fieldSize; // size    = min(md->width, md->height)/10;
+-  int fieldRows; // number of rows
+-  /* if >0 then all the frames are compared with the given frame (1 for first) */
+-  int virtualTripod;
+-  /* if 1 and 2 then the fields and transforms are shown in the frames */
+-  int show;
+-  /* measurement fields with lower contrast are discarded */
+-  double contrastThreshold;
+-  /* meta parameter for maxshift and fieldsize between 1 and 15 */
+-  int shakiness;
+-  int accuracy;   // meta parameter for number of fields between 1 and 10
+-
+-  int initialized; // 1 if initialized and 2 if configured
++  int allowMax;                 // 1 if maximal shift is allowed
++  int fieldNum;                 // number of measurement fields
++  int maxFields;                // maximum number of fields used (selected by contrast)
++  int fieldSize;                // size = min(md->width, md->height)/10;
++  int fieldRows;                // number of rows
++
++  VSFrame curr;                 // blurred version of current frame buffer
++  VSFrame currorig;             // current frame buffer (original) (only pointer)
++  VSFrame currtmp;              // temporary buffer for blurring
++  VSFrame prev;                 // frame buffer for last frame (copied)
++  short hasSeenOneFrame;        // true if we have a valid previous frame
+ 
+-  int frameNum;
+-} MotionDetect;
++  Field* fields;
+ 
+-/* type for a function that calculates the transformation of a certain field
+- */
+-typedef LocalMotion (*calcFieldTransFunc)(MotionDetect*, const Field*, int);
++  int initialized;              // 1 if initialized and 2 if configured
+ 
+-/* type for a function that calculates the contrast of a certain field
+- */
+-typedef double (*contrastSubImgFunc)(MotionDetect*, const Field*);
++  int frameNum;
++} VSMotionDetect;
+ 
+ 
+-static const char motiondetect_help[] = ""
++static const char vs_motiondetect_help[] = ""
+     "Overview:\n"
+     "    Generates a file with relative transform information\n"
+     "     (translation, rotation) about subsequent frames."
+@@ -96,9 +89,9 @@ static const char motiondetect_help[] = ""
+     "    'result'      path to the file used to write the transforms\n"
+     "                  (def:inputfile.stab)\n"
+     "    'shakiness'   how shaky is the video and how quick is the camera?\n"
+-    "                  1: little (fast) 10: very strong/quick (slow) (def: 4)\n"
++    "                  1: little (fast) 10: very strong/quick (slow) (def: 5)\n"
+     "    'accuracy'    accuracy of detection process (>=shakiness)\n"
+-    "                  1: low (fast) 15: high (slow) (def: 4)\n"
++    "                  1: low (fast) 15: high (slow) (def: 9)\n"
+     "    'stepsize'    stepsize of search process, region around minimum \n"
+     "                  is scanned with 1 pixel resolution (def: 6)\n"
+     "    'algo'        0: brute force (translation only);\n"
+@@ -111,16 +104,16 @@ static const char motiondetect_help[] = ""
+     "    'help'        print this help message\n";
+ 
+ 
+-/** initialized the MotionDetect structure and allocates memory
+- *  for the frames and stuff
+- *  @return VS_OK on success otherwise VS_ERROR
++/** returns the default config
+  */
+-int initMotionDetect(MotionDetect* md, const VSFrameInfo* fi, const char* modName);
++VSMotionDetectConfig vsMotionDetectGetDefaulfConfig(const char* modName);
+ 
+-/** configures MotionDetect structure and checks ranges, initializes fields and so on.
++/** initialized the VSMotionDetect structure and allocates memory
++ *  for the frames and stuff
+  *  @return VS_OK on success otherwise VS_ERROR
+  */
+-int configureMotionDetect(MotionDetect* md);
++int vsMotionDetectInit(VSMotionDetect* md, const VSMotionDetectConfig* conf,
++                       const VSFrameInfo* fi);
+ 
+ /**
+  *  Performs a motion detection step
+@@ -128,49 +121,18 @@ int configureMotionDetect(MotionDetect* md);
+  *  is stored internally
+  *  @param motions: calculated local motions. (must be deleted manually)
+  * */
+-int motionDetection(MotionDetect* md, LocalMotions* motions, VSFrame *frame);
++int vsMotionDetection(VSMotionDetect* md, LocalMotions* motions, VSFrame *frame);
+ 
+ /** Deletes internal data structures.
+- * In order to use the MotionDetect again, you have to call initMotionDetect
++ * In order to use the VSMotionDetect again, you have to call vsMotionDetectInit
+  */
+-void cleanupMotionDetection(MotionDetect* md);
+-
+-
+-int initFields(MotionDetect* md);
+-unsigned int compareImg(unsigned char* I1, unsigned char* I2, int width, int height,
+-                        int bytesPerPixel, int strive1, int strive2, int d_x, int d_y);
+-
+-double contrastSubImgYUV(MotionDetect* md, const Field* field);
+-double contrastSubImgRGB(MotionDetect* md, const Field* field);
+-double contrastSubImg(unsigned char* const I, const Field* field,
+-                      int width, int height, int bytesPerPixel);
+-
+-
+-int cmp_contrast_idx(const void *ci1, const void* ci2);
+-VSVector selectfields(MotionDetect* md, contrastSubImgFunc contrastfunc);
+-
+-LocalMotions calcShiftRGBSimple(MotionDetect* md);
+-LocalMotions calcShiftYUVSimple(MotionDetect* md);
+-
+-LocalMotion calcFieldTransYUV(MotionDetect* md, const Field* field,
+-                            int fieldnum);
+-LocalMotion calcFieldTransRGB(MotionDetect* md, const Field* field,
+-                            int fieldnum);
+-LocalMotions calcTransFields(MotionDetect* md, calcFieldTransFunc fieldfunc,
+-                             contrastSubImgFunc contrastfunc);
+-
+-
+-void drawFieldScanArea(MotionDetect* md, const LocalMotion* motion);
+-void drawField(MotionDetect* md, const LocalMotion* motion);
+-void drawFieldTrans(MotionDetect* md, const LocalMotion* motion);
+-void drawBox(unsigned char* I, int width, int height, int bytesPerPixel,
+-             int x, int y, int sizex, int sizey, unsigned char color);
++void vsMotionDetectionCleanup(VSMotionDetect* md);
+ 
++/// returns the current config
++void vsMotionDetectGetConfig(VSMotionDetectConfig* conf, const VSMotionDetect* md);
+ 
+-unsigned int compareSubImg_thr(unsigned char* const I1, unsigned char* const I2,
+-                               const Field* field, int width1, int width2, int height,
+-                               int bytesPerPixel,
+-                               int d_x, int d_y, unsigned int threshold);
++/// returns the frame info
++const VSFrameInfo* vsMotionDetectGetFrameInfo(const VSMotionDetect* md);
+ 
+ #endif  /* MOTIONDETECT_H */
+ 
+@@ -179,7 +141,8 @@ unsigned int compareSubImg_thr(unsigned char* const I1, unsigned char* const I2,
+  *   c-file-style: "stroustrup"
+  *   c-file-offsets: ((case-label . *) (statement-case-intro . *))
+  *   indent-tabs-mode: nil
++ *   c-basic-offset: 2 t
+  * End:
+  *
+- * vim: expandtab shiftwidth=4:
++ * vim: expandtab shiftwidth=2:
+  */
+diff --git a/src/motiondetect_internal.h b/src/motiondetect_internal.h
+new file mode 100644
+index 0000000..3b71ef4
+--- /dev/null
++++ b/src/motiondetect_internal.h
+@@ -0,0 +1,89 @@
++/*
++ *  motiondetect_internal.h
++ *
++ *  Copyright (C) Georg Martius - February 2011
++ *   georg dot martius at web dot de
++ *  Copyright (C) Alexey Osipov - Jule 2011
++ *   simba at lerlan dot ru
++ *   speed optimizations (threshold, spiral, SSE, asm)
++ *
++ *  This file is part of vid.stab video stabilization library
++ *
++ *  vid.stab 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.
++ *
++ *  vid.stab 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 GNU Make; see the file COPYING.  If not, write to
++ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++#ifndef MOTIONDETECT_INTERNAL_H
++#define MOTIONDETECT_INTERNAL_H
++
++#include "motiondetect.h"
++
++/* type for a function that calculates the transformation of a certain field
++ */
++typedef LocalMotion (*calcFieldTransFunc)(VSMotionDetect*, const Field*, int);
++
++/* type for a function that calculates the contrast of a certain field
++ */
++typedef double (*contrastSubImgFunc)(VSMotionDetect*, const Field*);
++
++
++int initFields(VSMotionDetect* md);
++unsigned int compareImg(unsigned char* I1, unsigned char* I2, int width, int height,
++                        int bytesPerPixel, int strive1, int strive2, int d_x, int d_y);
++
++double contrastSubImgPlanar(VSMotionDetect* md, const Field* field);
++double contrastSubImgPacked(VSMotionDetect* md, const Field* field);
++double contrastSubImg(unsigned char* const I, const Field* field,
++                      int width, int height, int bytesPerPixel);
++
++
++int cmp_contrast_idx(const void *ci1, const void* ci2);
++VSVector selectfields(VSMotionDetect* md, contrastSubImgFunc contrastfunc);
++
++LocalMotions calcShiftPackedSimple(VSMotionDetect* md);
++LocalMotions calcShiftPlanarSimple(VSMotionDetect* md);
++
++LocalMotion calcFieldTransPlanar(VSMotionDetect* md, const Field* field,
++                            int fieldnum);
++LocalMotion calcFieldTransPacked(VSMotionDetect* md, const Field* field,
++                            int fieldnum);
++LocalMotions calcTransFields(VSMotionDetect* md, calcFieldTransFunc fieldfunc,
++                             contrastSubImgFunc contrastfunc);
++
++
++void drawFieldScanArea(VSMotionDetect* md, const LocalMotion* motion);
++void drawField(VSMotionDetect* md, const LocalMotion* motion);
++void drawFieldTrans(VSMotionDetect* md, const LocalMotion* motion);
++void drawBox(unsigned char* I, int width, int height, int bytesPerPixel,
++             int x, int y, int sizex, int sizey, unsigned char color);
++
++
++unsigned int compareSubImg_thr(unsigned char* const I1, unsigned char* const I2,
++                               const Field* field, int width1, int width2, int height,
++                               int bytesPerPixel,
++                               int d_x, int d_y, unsigned int threshold);
++
++#endif  /* MOTIONDETECT_INTERNAL_H */
++
++/*
++ * Local variables:
++ *   c-file-style: "stroustrup"
++ *   c-file-offsets: ((case-label . *) (statement-case-intro . *))
++ *   indent-tabs-mode: nil
++ *   c-basic-offset: 2 t
++ * End:
++ *
++ * vim: expandtab shiftwidth=2:
++ */
+diff --git a/src/motiondetect_opt.c b/src/motiondetect_opt.c
+index 5510c84..de63e3b 100644
+--- a/src/motiondetect_opt.c
++++ b/src/motiondetect_opt.c
+@@ -39,7 +39,7 @@
+ 
+ #ifdef USE_SSE2
+ /**
+-   \see contrastSubImg using SSE2 optimization, YUV (1 byte per channel) only
++   \see contrastSubImg using SSE2 optimization, Planar (1 byte per channel) only
+ */
+ double contrastSubImg1_SSE(unsigned char* const I, const Field* field,
+                            int width, int height)
+@@ -171,9 +171,9 @@ double contrastSubImg_variance_C(unsigned char* const I,
+    \param d_y shift in y direction
+ */
+ unsigned int compareSubImg_thr_orc(unsigned char* const I1, unsigned char* const I2,
+-																	 const Field* field, int width1, int width2, int height,
+-																	 int bytesPerPixel, int d_x, int d_y,
+-																	 unsigned int threshold) {
++                                   const Field* field, int width1, int width2, int height,
++                                   int bytesPerPixel, int d_x, int d_y,
++                                   unsigned int threshold) {
+   unsigned char* p1 = NULL;
+   unsigned char* p2 = NULL;
+   int s2 = field->size / 2;
+@@ -198,9 +198,9 @@ unsigned int compareSubImg_thr_orc(unsigned char* const I1, unsigned char* const
+ 
+ // implementation with 1 orc function, but no threshold
+ unsigned int compareSubImg_orc(unsigned char* const I1, unsigned char* const I2,
+-															 const Field* field, int width1, int width2, int height,
+-															 int bytesPerPixel, int d_x, int d_y,
+-															 unsigned int threshold) {
++                               const Field* field, int width1, int width2, int height,
++                               int bytesPerPixel, int d_x, int d_y,
++                               unsigned int threshold) {
+   unsigned char* p1 = NULL;
+   unsigned char* p2 = NULL;
+   int s2 = field->size / 2;
+@@ -217,12 +217,12 @@ unsigned int compareSubImg_orc(unsigned char* const I1, unsigned char* const I2,
+ 
+ #ifdef USE_SSE2
+ unsigned int compareSubImg_thr_sse2(unsigned char* const I1, unsigned char* const I2,
+-																		const Field* field,
+-																		int width1, int width2, int height,
+-																		int bytesPerPixel, int d_x, int d_y,
+-																		unsigned int treshold) {
+-	int k, j;
+-	unsigned char* p1 = NULL;
++                                    const Field* field,
++                                    int width1, int width2, int height,
++                                    int bytesPerPixel, int d_x, int d_y,
++                                    unsigned int treshold) {
++  int k, j;
++  unsigned char* p1 = NULL;
+   unsigned char* p2 = NULL;
+   int s2 = field->size / 2;
+   unsigned int sum = 0;
+diff --git a/src/serialize.c b/src/serialize.c
+index 603774e..cf167bc 100644
+--- a/src/serialize.c
++++ b/src/serialize.c
+@@ -23,9 +23,11 @@
+  */
+ 
+ #include <assert.h>
++#include <string.h>
+ 
+ #include "serialize.h"
+ #include "transformtype.h"
++#include "transformtype_operations.h"
+ #include "motiondetect.h"
+ 
+ const char* modname = "vid.stab - serialization";
+@@ -53,7 +55,7 @@ LocalMotion restoreLocalmotion(FILE* f){
+   return lm;
+ }
+ 
+-int storeLocalmotions(FILE* f, const LocalMotions* lms){
++int vsStoreLocalmotions(FILE* f, const LocalMotions* lms){
+   int len = vs_vector_size(lms);
+   int i;
+   fprintf(f,"List %i [",len);
+@@ -66,7 +68,7 @@ int storeLocalmotions(FILE* f, const LocalMotions* lms){
+ }
+ 
+ /// restores local motions from file
+-LocalMotions restoreLocalmotions(FILE* f){
++LocalMotions vsRestoreLocalmotions(FILE* f){
+   LocalMotions lms;
+   int i;
+   char c;
+@@ -96,99 +98,98 @@ LocalMotions restoreLocalmotions(FILE* f){
+   return lms;
+ }
+ 
+-int prepareFile(const MotionDetect* md, FILE* f){
++int vsPrepareFile(const VSMotionDetect* md, FILE* f){
+     if(!f) return VS_ERROR;
+     fprintf(f, "VID.STAB 1\n");
+-		//    fprintf(f, "#      accuracy = %d\n", md->accuracy);
+-    fprintf(f, "#      accuracy = %d\n", md->accuracy);
+-    fprintf(f, "#     shakiness = %d\n", md->shakiness);
+-    fprintf(f, "#      stepsize = %d\n", md->stepSize);
+-    fprintf(f, "#          algo = %d\n", md->algo);
+-    fprintf(f, "#   mincontrast = %f\n", md->contrastThreshold);
++    fprintf(f, "#      accuracy = %d\n", md->conf.accuracy);
++    fprintf(f, "#     shakiness = %d\n", md->conf.shakiness);
++    fprintf(f, "#      stepsize = %d\n", md->conf.stepSize);
++    fprintf(f, "#          algo = %d\n", md->conf.algo);
++    fprintf(f, "#   mincontrast = %f\n", md->conf.contrastThreshold);
+     return VS_OK;
+ }
+ 
+-int writeToFile(const MotionDetect* md, FILE* f, const LocalMotions* lms){
+-	if(!f || !lms) return VS_ERROR;
++int vsWriteToFile(const VSMotionDetect* md, FILE* f, const LocalMotions* lms){
++  if(!f || !lms) return VS_ERROR;
+ 
+-	if(fprintf(f, "Frame %i (", md->frameNum)>0
+-		 && storeLocalmotions(f,lms)>0 && fprintf(f, ")\n"))
+-		return VS_OK;
+-	else
+-		return VS_ERROR;
++  if(fprintf(f, "Frame %i (", md->frameNum)>0
++     && vsStoreLocalmotions(f,lms)>0 && fprintf(f, ")\n"))
++    return VS_OK;
++  else
++    return VS_ERROR;
+ }
+ 
+ /// reads the header of the file and return the version number
+-int readFileVersion(FILE* f){
+-	if(!f) return VS_ERROR;
+-	int version;
+-	if(fscanf(f, "VID.STAB %i\n", &version)!=1)
+-		return VS_ERROR;
+-	else return version;
++int vsReadFileVersion(FILE* f){
++  if(!f) return VS_ERROR;
++  int version;
++  if(fscanf(f, "VID.STAB %i\n", &version)!=1)
++    return VS_ERROR;
++  else return version;
+ }
+ 
+-int readFromFile(FILE* f, LocalMotions* lms){
+-	char c = fgetc(f);
+-	if(c=='F') {
+-		int num;
+-		if(fscanf(f,"rame %i (", &num)!=1) {
+-			vs_log_error(modname,"cannot read file, expect 'Frame num (...'");
+-			return VS_ERROR;
+-		}
+-		*lms = restoreLocalmotions(f);
+-		if(fscanf(f,")\n")<0) {
+-			vs_log_error(modname,"cannot read file, expect '...)'");
+-			return VS_ERROR;
+-		}
+-		return num;
+-	} else if(c=='#') {
+-		char l[1024];
++int vsReadFromFile(FILE* f, LocalMotions* lms){
++  char c = fgetc(f);
++  if(c=='F') {
++    int num;
++    if(fscanf(f,"rame %i (", &num)!=1) {
++      vs_log_error(modname,"cannot read file, expect 'Frame num (...'");
++      return VS_ERROR;
++    }
++    *lms = vsRestoreLocalmotions(f);
++    if(fscanf(f,")\n")<0) {
++      vs_log_error(modname,"cannot read file, expect '...)'");
++      return VS_ERROR;
++    }
++    return num;
++  } else if(c=='#') {
++    char l[1024];
+     if(fgets(l, sizeof(l), f)==0) return VS_ERROR;
+-		return readFromFile(f,lms);
+-	} else if(c=='\n' || c==' ') {
+-		return readFromFile(f,lms);
+-	} else if(c==EOF) {
+-		return VS_ERROR;
+-	} else {
+-		vs_log_error(modname,"cannot read frame local motions from file, got %c (%i)",
+-								 c, (int) c);
+-		return VS_ERROR;
+-	}
++    return vsReadFromFile(f,lms);
++  } else if(c=='\n' || c==' ') {
++    return vsReadFromFile(f,lms);
++  } else if(c==EOF) {
++    return VS_ERROR;
++  } else {
++    vs_log_error(modname,"cannot read frame local motions from file, got %c (%i)",
++                 c, (int) c);
++    return VS_ERROR;
++  }
+ }
+ 
+-int readLocalMotionsFile(FILE* f, ManyLocalMotions* mlms){
+-	int version = readFileVersion(f);
+-	if(version<1) // old format or unknown
+-		return VS_ERROR;
+-	if(version>1){
+-		vs_log_error(modname,"Version of VID.STAB file too large: got %i, expect <= 1",
+-								 version);
+-		return VS_ERROR;
+-	}
+-	assert(mlms);
+-	// initial number of frames, but it will automatically be increaseed
+-	vs_vector_init(mlms,1024);
+-	int index;
+-	int oldindex = 0;
+-	LocalMotions lms;
+-	while((index = readFromFile(f,&lms)) != VS_ERROR){
+-		if(index > oldindex+1){
+-			vs_log_info(modname,"VID.STAB file: index of frames is not continuous %i -< %i",
+-									oldindex, index);
+-		}
+-		if(index<1){
+-			vs_log_info(modname,"VID.STAB file: Frame number < 1 (%i)", index);
+-		} else {
+-			vs_vector_set_dup(mlms,index-1,&lms, sizeof(LocalMotions));
+-		}
+-		oldindex=index;
+-	}
+-	return VS_OK;
++int vsReadLocalMotionsFile(FILE* f, VSManyLocalMotions* mlms){
++  int version = vsReadFileVersion(f);
++  if(version<1) // old format or unknown
++    return VS_ERROR;
++  if(version>1){
++    vs_log_error(modname,"Version of VID.STAB file too large: got %i, expect <= 1",
++                 version);
++    return VS_ERROR;
++  }
++  assert(mlms);
++  // initial number of frames, but it will automatically be increaseed
++  vs_vector_init(mlms,1024);
++  int index;
++  int oldindex = 0;
++  LocalMotions lms;
++  while((index = vsReadFromFile(f,&lms)) != VS_ERROR){
++    if(index > oldindex+1){
++      vs_log_info(modname,"VID.STAB file: index of frames is not continuous %i -< %i",
++                  oldindex, index);
++    }
++    if(index<1){
++      vs_log_info(modname,"VID.STAB file: Frame number < 1 (%i)", index);
++    } else {
++      vs_vector_set_dup(mlms,index-1,&lms, sizeof(LocalMotions));
++    }
++    oldindex=index;
++  }
++  return VS_OK;
+ }
+ 
+ 
+ /**
+- * readOldTransforms: read transforms file (Deprecated format)
++ * vsReadOldTransforms: read transforms file (Deprecated format)
+  *  The format is as follows:
+  *   Lines with # at the beginning are comments and will be ignored
+  *   Data lines have 5 columns seperated by space or tab containing
+@@ -203,53 +204,54 @@ int readLocalMotionsFile(FILE* f, ManyLocalMotions* mlms){
+  *         number of transforms read
+  * Preconditions: f is opened
+  */
+-int readOldTransforms(const TransformData* td, FILE* f , Transformations* trans)
++int vsReadOldTransforms(const VSTransformData* td, FILE* f , VSTransformations* trans)
+ {
+-    char l[1024];
+-    int s = 0;
+-    int i = 0;
+-    int ti; // time (ignored)
+-    Transform t;
++  char l[1024];
++  int s = 0;
++  int i = 0;
++  int ti; // time (ignored)
++  VSTransform t;
+ 
+-    while (fgets(l, sizeof(l), f)) {
+-        if (l[0] == '#')
+-            continue;    //  ignore comments
+-        if (strlen(l) == 0)
+-            continue; //  ignore empty lines
+-        // try new format
+-        if (sscanf(l, "%i %lf %lf %lf %lf %i", &ti, &t.x, &t.y, &t.alpha,
+-                   &t.zoom, &t.extra) != 6) {
+-            if (sscanf(l, "%i %lf %lf %lf %i", &ti, &t.x, &t.y, &t.alpha,
+-                       &t.extra) != 5) {
+-                vs_log_error(td->modName, "Cannot parse line: %s", l);
+-                return 0;
+-            }
+-            t.zoom=0;
+-        }
++  while (fgets(l, sizeof(l), f)) {
++    t = null_transform();
++    if (l[0] == '#')
++      continue;    //  ignore comments
++    if (strlen(l) == 0)
++      continue; //  ignore empty lines
++    // try new format
++    if (sscanf(l, "%i %lf %lf %lf %lf %i", &ti, &t.x, &t.y, &t.alpha,
++               &t.zoom, &t.extra) != 6) {
++      if (sscanf(l, "%i %lf %lf %lf %i", &ti, &t.x, &t.y, &t.alpha,
++                 &t.extra) != 5) {
++        vs_log_error(td->conf.modName, "Cannot parse line: %s", l);
++        return 0;
++      }
++      t.zoom=0;
++    }
+ 
+-        if (i>=s) { // resize transform array
+-            if (s == 0)
+-                s = 256;
+-            else
+-                s*=2;
+-            /* vs_log_info(td->modName, "resize: %i\n", s); */
+-            trans->ts = vs_realloc(trans->ts, sizeof(Transform)* s);
+-            if (!trans->ts) {
+-                vs_log_error(td->modName, "Cannot allocate memory"
+-                                       " for transformations: %i\n", s);
+-                return 0;
+-            }
+-        }
+-        trans->ts[i] = t;
+-        i++;
++    if (i>=s) { // resize transform array
++      if (s == 0)
++        s = 256;
++      else
++        s*=2;
++      /* vs_log_info(td->modName, "resize: %i\n", s); */
++      trans->ts = vs_realloc(trans->ts, sizeof(VSTransform)* s);
++      if (!trans->ts) {
++        vs_log_error(td->conf.modName, "Cannot allocate memory"
++                     " for transformations: %i\n", s);
++        return 0;
++      }
+     }
+-    trans->len = i;
++    trans->ts[i] = t;
++    i++;
++  }
++  trans->len = i;
+ 
+-    return i;
++  return i;
+ }
+ 
+ 
+-//     t = simpleMotionsToTransform(md, &localmotions);
++//     t = vsSimpleMotionsToTransform(md, &localmotions);
+ 
+ 
+ /*
+diff --git a/src/serialize.h b/src/serialize.h
+index 9018306..2142a7d 100644
+--- a/src/serialize.h
++++ b/src/serialize.h
+@@ -31,33 +31,33 @@
+ 
+ 
+ /// Vector of LocalMotions
+-typedef VSVector ManyLocalMotions;
++typedef VSVector VSManyLocalMotions;
+ /// helper macro to access a localmotions vector in the VSVector of all Frames
+-#define MLMGet(manylocalmotions,index) \
++#define VSMLMGet(manylocalmotions,index) \
+     ((LocalMotions*)vs_vector_get(manylocalmotions,index))
+ 
+ 
+ /// stores local motions to file
+-int storeLocalmotions(FILE* f, const LocalMotions* lms);
++int vsStoreLocalmotions(FILE* f, const LocalMotions* lms);
+ 
+ /// restores local motions from file
+-LocalMotions restoreLocalmotions(FILE* f);
++LocalMotions vsRestoreLocalmotions(FILE* f);
+ 
+ 
+ /// writes the header to the file that is to be holding the local motions
+-int prepareFile(const MotionDetect* td, FILE* f);
++int vsPrepareFile(const VSMotionDetect* td, FILE* f);
+ 
+ /// appends the given localmotions to the file
+-int writeToFile(const MotionDetect* td, FILE* f, const LocalMotions* lms);
++int vsWriteToFile(const VSMotionDetect* td, FILE* f, const LocalMotions* lms);
+ 
+ /// reads the header of the file and return the version number (used by readLocalmotionsFile)
+-int readFileVersion(FILE* f);
++int vsReadFileVersion(FILE* f);
+ 
+ /*
+  * reads the next set of localmotions from the file, return VS_ERROR on error or
+  * if nothing is read (used by readLocalmotionsFile)
+  */
+-int readFromFile(FILE* f, LocalMotions* lms);
++int vsReadFromFile(FILE* f, LocalMotions* lms);
+ 
+ /*
+  * reads the entire file of localmotions, return VS_ERROR on error or if nothing is read
+@@ -68,10 +68,10 @@ int readFromFile(FILE* f, LocalMotions* lms);
+  *   Data lines have the structure: Frame NUM (<LocalMotions>)
+  *   where LocalMotions ::= List [(LM v.x v.y f.x f.y f.size contrast match),...]
+  */
+-int readLocalMotionsFile(FILE* f, ManyLocalMotions* lms);
++int vsReadLocalMotionsFile(FILE* f, VSManyLocalMotions* lms);
+ 
+ // read the transformations from the given file (Deprecated format)
+-int readOldTransforms(const TransformData* td, FILE* f , Transformations* trans);
++int vsReadOldTransforms(const VSTransformData* td, FILE* f , VSTransformations* trans);
+ 
+ 
+ #endif
+diff --git a/src/transform.c b/src/transform.c
+index 7e7a9e0..bb02f53 100644
+--- a/src/transform.c
++++ b/src/transform.c
+@@ -23,6 +23,8 @@
+  */
+ 
+ #include "transform.h"
++#include "transform_internal.h"
++#include "transformtype_operations.h"
+ 
+ #include "transformfixedpoint.h"
+ #ifdef TESTING
+@@ -31,159 +33,185 @@
+ 
+ #include <math.h>
+ #include <libgen.h>
++#include <string.h>
+ 
+-const char* interpolTypes[5] = {"No (0)", "Linear (1)", "Bi-Linear (2)",
+-                                "Bi-Cubic (3)"};
++const char* interpol_type_names[5] = {"No (0)", "Linear (1)", "Bi-Linear (2)",
++                                      "Bi-Cubic (3)"};
+ 
++const char* getInterpolationTypeName(VSInterpolType type){
++  if (type >= VS_Zero && type < VS_NBInterPolTypes)
++    return interpol_type_names[(int) type];
++  else
++    return "unknown";
++}
+ 
+-int initTransformData(TransformData* td, const VSFrameInfo* fi_src,
+-                      const VSFrameInfo* fi_dest , const char* modName){
+-    td->modName = modName;
++VSTransformConfig vsTransformGetDefaulfConfig(const char* modName){
++  VSTransformConfig conf;
++  /* Options */
++  conf.maxShift           = -1;
++  conf.maxAngle           = -1;
++  conf.crop               = VSKeepBorder;
++  conf.relative           = 1;
++  conf.invert             = 0;
++  conf.smoothing          = 10;
++  conf.zoom               = 0;
++  conf.optZoom            = 1;
++  conf.interpolType       = VS_BiLinear;
++  conf.verbose            = 0;
++  conf.modName            = modName;
++  return conf;
++}
+ 
+-    td->fiSrc = *fi_src;
+-    td->fiDest = *fi_dest;
++void vsTransformGetConfig(VSTransformConfig* conf, const VSTransformData* td){
++  if(td && conf)
++    *conf = td->conf;
++}
+ 
+-    nullFrame(&td->src);
+-    td->srcMalloced = 0;
++const VSFrameInfo* vsTransformGetSrcFrameInfo(const VSTransformData* td){
++  return &td->fiSrc;
++}
+ 
+-    nullFrame(&td->destbuf);
+-    nullFrame(&td->dest);
++const VSFrameInfo* vsTransformGetDestFrameInfo(const VSTransformData* td){
++  return &td->fiDest;
++}
+ 
+-    /* Options */
+-    td->maxShift = -1;
+-    td->maxAngle = -1;
+-    td->maxAngleVariation = 1;
+ 
++int vsTransformDataInit(VSTransformData* td, const VSTransformConfig* conf,
++                        const VSFrameInfo* fi_src, const VSFrameInfo* fi_dest){
++  td->conf = *conf;
+ 
+-    td->crop = KeepBorder;
+-    td->relative = 1;
+-    td->invert = 0;
+-    td->smoothing = 10;
++  td->fiSrc = *fi_src;
++  td->fiDest = *fi_dest;
+ 
+-    td->rotationThreshhold = 0.25/(180/M_PI);
++  vsFrameNull(&td->src);
++  td->srcMalloced = 0;
+ 
+-    td->zoom    = 0;
+-    td->optZoom = 1;
+-    td->interpolType = BiLinear;
+-    td->sharpen = 0.8;
++  vsFrameNull(&td->destbuf);
++  vsFrameNull(&td->dest);
<Skipped 4775 lines>
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/vid.stab.git/commitdiff/ca14007dbc5cc183b5dbeaa0abe448178f6b3234




More information about the pld-cvs-commit mailing list