Compositor: Speedup movie (un)distortion operation
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 26 Jan 2016 10:42:55 +0000 (11:42 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 26 Jan 2016 10:44:43 +0000 (11:44 +0100)
Avoid per-pixel camera intrincs object construction and synchronization.

Here on a bit synthetic file it gives about 40% speedup with a single node.

intern/libmv/intern/camera_intrinsics.cc
intern/libmv/intern/camera_intrinsics.h
intern/libmv/intern/stub.cc
source/blender/blenkernel/BKE_tracking.h
source/blender/blenkernel/intern/tracking.c
source/blender/compositor/intern/COM_compositor.cpp
source/blender/compositor/operations/COM_MovieDistortionOperation.cpp
source/blender/compositor/operations/COM_MovieDistortionOperation.h

index 0ce757cc93b3644db0028b8c79711823b4c85e27..24a34ae40bbfa6b357a7f679e41542179c8ebf0c 100644 (file)
@@ -264,33 +264,23 @@ void libmv_cameraIntrinsicsDistortFloat(
 }
 
 void libmv_cameraIntrinsicsApply(
-    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+    const struct libmv_CameraIntrinsics* libmv_intrinsics,
     double x,
     double y,
     double* x1,
     double* y1) {
-  /* Do a lens distortion if focal length is non-zero only. */
-  if (libmv_camera_intrinsics_options->focal_length) {
-    CameraIntrinsics* camera_intrinsics =
-      libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
-    camera_intrinsics->ApplyIntrinsics(x, y, x1, y1);
-    LIBMV_OBJECT_DELETE(camera_intrinsics, CameraIntrinsics);
-  }
+  CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+  intrinsics->ApplyIntrinsics(x, y, x1, y1);
 }
 
 void libmv_cameraIntrinsicsInvert(
-    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+    const struct libmv_CameraIntrinsics* libmv_intrinsics,
     double x,
     double y,
     double* x1,
     double* y1) {
-  /* Do a lens un-distortion if focal length is non-zero only/ */
-  if (libmv_camera_intrinsics_options->focal_length) {
-    CameraIntrinsics *camera_intrinsics =
-      libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
-    camera_intrinsics->InvertIntrinsics(x, y, x1, y1);
-    LIBMV_OBJECT_DELETE(camera_intrinsics, CameraIntrinsics);
-  }
+  CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+  intrinsics->InvertIntrinsics(x, y, x1, y1);
 }
 
 static void libmv_cameraIntrinsicsFillFromOptions(
index 9910d16a108b17b68532e8dc95be78ef6faad01d..50a0073437bd821372ed43a9656e2971d8ae49f2 100644 (file)
@@ -108,14 +108,14 @@ void libmv_cameraIntrinsicsDistortFloat(
     float* destination_image);
 
 void libmv_cameraIntrinsicsApply(
-    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+    const struct libmv_CameraIntrinsics* libmv_intrinsics,
     double x,
     double y,
     double* x1,
     double* y1);
 
 void libmv_cameraIntrinsicsInvert(
-    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+    const struct libmv_CameraIntrinsics* libmv_intrinsics,
     double x,
     double y,
     double* x1,
index ad6482037649f5c00cbe05efb28aa61cf81324c1..47e1915e0725bf1e086a091d7a0829fd8cd91725 100644 (file)
@@ -303,29 +303,23 @@ void libmv_cameraIntrinsicsDistortFloat(
 /* ************ utils ************ */
 
 void libmv_cameraIntrinsicsApply(
-    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
-    double x,
-    double y,
+    const struct libmv_CameraIntrinsics* /*libmv_intrinsics*/,
+    double /*x*/,
+    double /*y*/,
     double* x1,
     double* y1) {
-  double focal_length = libmv_camera_intrinsics_options->focal_length;
-  double principal_x = libmv_camera_intrinsics_options->principal_point_x;
-  double principal_y = libmv_camera_intrinsics_options->principal_point_y;
-  *x1 = x * focal_length + principal_x;
-  *y1 = y * focal_length + principal_y;
+  *x1 = 0.0;
+  *y1 = 0.0;
 }
 
 void libmv_cameraIntrinsicsInvert(
-    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
-    double x,
-    double y,
+    const struct libmv_CameraIntrinsics* /*libmv_intrinsics*/,
+    double /*x*/,
+    double /*y*/,
     double* x1,
     double* y1) {
-  double focal_length = libmv_camera_intrinsics_options->focal_length;
-  double principal_x = libmv_camera_intrinsics_options->principal_point_x;
-  double principal_y = libmv_camera_intrinsics_options->principal_point_y;
-  *x1 = (x - principal_x) / focal_length;
-  *y1 = (y - principal_y) / focal_length;
+  *x1 = 0.0;
+  *y1 = 0.0;
 }
 
 void libmv_homography2DFromCorrespondencesEuc(/* const */ double (* /*x1*/)[2],
index 264bf2bd8faf596575af87aec0d02778e171891f..2ca88425c2941af3da612aed4b448282cddac51e 100644 (file)
@@ -200,6 +200,12 @@ void BKE_tracking_distortion_set_threads(struct MovieDistortion *distortion, int
 struct MovieDistortion *BKE_tracking_distortion_copy(struct MovieDistortion *distortion);
 struct ImBuf *BKE_tracking_distortion_exec(struct MovieDistortion *distortion, struct MovieTracking *tracking,
                                            struct ImBuf *ibuf, int width, int height, float overscan, bool undistort);
+void BKE_tracking_distortion_distort_v2(struct MovieDistortion *distortion,
+                                        const float co[2],
+                                        float r_co[2]);
+void BKE_tracking_distortion_undistort_v2(struct MovieDistortion *distortion,
+                                          const float co[2],
+                                          float r_co[2]);
 void BKE_tracking_distortion_free(struct MovieDistortion *distortion);
 
 void BKE_tracking_distort_v2(struct MovieTracking *tracking, const float co[2], float r_co[2]);
index e5719bdca62bf91559761814196d179e129713e0..3b76e456ff7d353ce4ebf65f20f997212b546b4e 100644 (file)
 
 typedef struct MovieDistortion {
        struct libmv_CameraIntrinsics *intrinsics;
+       /* Parameters needed for coordinates normalization. */
+       float principal[2];
+       float pixel_aspect;
+       float focal;
 } MovieDistortion;
 
 static struct {
@@ -1878,6 +1882,11 @@ MovieDistortion *BKE_tracking_distortion_new(MovieTracking *tracking,
        distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
        distortion->intrinsics = libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
 
+       const MovieTrackingCamera *camera = &tracking->camera;
+       copy_v2_v2(distortion->principal, camera->principal);
+       distortion->pixel_aspect = camera->pixel_aspect;
+       distortion->focal = camera->focal;
+
        return distortion;
 }
 
@@ -1891,6 +1900,11 @@ void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *
                                                     calibration_height,
                                                     &camera_intrinsics_options);
 
+       const MovieTrackingCamera *camera = &tracking->camera;
+       copy_v2_v2(distortion->principal, camera->principal);
+       distortion->pixel_aspect = camera->pixel_aspect;
+       distortion->focal = camera->focal;
+
        libmv_cameraIntrinsicsUpdate(&camera_intrinsics_options, distortion->intrinsics);
 }
 
@@ -1904,7 +1918,7 @@ MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
        MovieDistortion *new_distortion;
 
        new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
-
+       *new_distortion = *distortion;
        new_distortion->intrinsics = libmv_cameraIntrinsicsCopy(distortion->intrinsics);
 
        return new_distortion;
@@ -1962,6 +1976,36 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *
        return resibuf;
 }
 
+void BKE_tracking_distortion_distort_v2(MovieDistortion *distortion,
+                                        const float co[2],
+                                        float r_co[2])
+{
+       const float aspy = 1.0f / distortion->pixel_aspect;
+
+       /* Normalize coords. */
+       float inv_focal = 1.0f / distortion->focal;
+       double x = (co[0] - distortion->principal[0]) * inv_focal,
+              y = (co[1] - distortion->principal[1] * aspy) * inv_focal;
+
+       libmv_cameraIntrinsicsApply(distortion->intrinsics, x, y, &x, &y);
+
+       /* Result is in image coords already. */
+       r_co[0] = x;
+       r_co[1] = y;
+}
+
+void BKE_tracking_distortion_undistort_v2(MovieDistortion *distortion,
+                                          const float co[2],
+                                          float r_co[2])
+{
+       double x = co[0], y = co[1];
+       libmv_cameraIntrinsicsInvert(distortion->intrinsics, x, y, &x, &y);
+
+       const float aspy = 1.0f / distortion->pixel_aspect;
+       r_co[0] = (float)x * distortion->focal + distortion->principal[0];
+       r_co[1] = (float)y * distortion->focal + distortion->principal[1] * aspy;
+}
+
 void BKE_tracking_distortion_free(MovieDistortion *distortion)
 {
        libmv_cameraIntrinsicsDestroy(distortion->intrinsics);
@@ -1971,40 +2015,43 @@ void BKE_tracking_distortion_free(MovieDistortion *distortion)
 
 void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r_co[2])
 {
-       MovieTrackingCamera *camera = &tracking->camera;
+       const MovieTrackingCamera *camera = &tracking->camera;
+       const float aspy = 1.0f / tracking->camera.pixel_aspect;
 
        libmv_CameraIntrinsicsOptions camera_intrinsics_options;
-       double x, y;
-       float aspy = 1.0f / tracking->camera.pixel_aspect;
-
        tracking_cameraIntrinscisOptionsFromTracking(tracking,
                                                     0, 0,
                                                     &camera_intrinsics_options);
+       libmv_CameraIntrinsics *intrinsics =
+               libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
 
-       /* normalize coords */
-       x = (co[0] - camera->principal[0]) / camera->focal;
-       y = (co[1] - camera->principal[1] * aspy) / camera->focal;
+       /* Normalize coordinates. */
+       double x = (co[0] - camera->principal[0]) / camera->focal,
+              y = (co[1] - camera->principal[1] * aspy) / camera->focal;
 
-       libmv_cameraIntrinsicsApply(&camera_intrinsics_options, x, y, &x, &y);
+       libmv_cameraIntrinsicsApply(intrinsics, x, y, &x, &y);
+       libmv_cameraIntrinsicsDestroy(intrinsics);
 
-       /* result is in image coords already */
+       /* Result is in image coords already. */
        r_co[0] = x;
        r_co[1] = y;
 }
 
 void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float r_co[2])
 {
-       MovieTrackingCamera *camera = &tracking->camera;
+       const MovieTrackingCamera *camera = &tracking->camera;
+       const float aspy = 1.0f / tracking->camera.pixel_aspect;
 
        libmv_CameraIntrinsicsOptions camera_intrinsics_options;
-       double x = co[0], y = co[1];
-       float aspy = 1.0f / tracking->camera.pixel_aspect;
-
        tracking_cameraIntrinscisOptionsFromTracking(tracking,
                                                     0, 0,
                                                     &camera_intrinsics_options);
+       libmv_CameraIntrinsics *intrinsics =
+               libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
 
-       libmv_cameraIntrinsicsInvert(&camera_intrinsics_options, x, y, &x, &y);
+       double x = co[0], y = co[1];
+       libmv_cameraIntrinsicsInvert(intrinsics, x, y, &x, &y);
+       libmv_cameraIntrinsicsDestroy(intrinsics);
 
        r_co[0] = (float)x * camera->focal + camera->principal[0];
        r_co[1] = (float)y * camera->focal + camera->principal[1] * aspy;
index d41bc9648f5e1c1abb4cc3e8d97f34e5d8c03ecc..e3dfd69d8ecca89d3ff22a72a2c9e97546a34f89 100644 (file)
@@ -39,11 +39,6 @@ extern "C" {
 static ThreadMutex s_compositorMutex;
 static bool is_compositorMutex_init = false;
 
-static void intern_freeCompositorCaches()
-{
-       deintializeDistortionCache();
-}
-
 void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rendering,
                  const ColorManagedViewSettings *viewSettings,
                  const ColorManagedDisplaySettings *displaySettings,
@@ -104,20 +99,10 @@ void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rende
        BLI_mutex_unlock(&s_compositorMutex);
 }
 
-static void UNUSED_FUNCTION(COM_freeCaches)()
-{
-       if (is_compositorMutex_init) {
-               BLI_mutex_lock(&s_compositorMutex);
-               intern_freeCompositorCaches();
-               BLI_mutex_unlock(&s_compositorMutex);
-       }
-}
-
 void COM_deinitialize()
 {
        if (is_compositorMutex_init) {
                BLI_mutex_lock(&s_compositorMutex);
-               intern_freeCompositorCaches();
                WorkScheduler::deinitialize();
                is_compositorMutex_init = false;
                BLI_mutex_unlock(&s_compositorMutex);
index 4f34d7fb150415714bd9e3492644f096bcbedfe9..3b8f09fffb2083e643c71724a7ddc8f0d2d043d0 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
- * Contributor: 
- *             Jeroen Bakker 
+ * Contributor:
+ *             Jeroen Bakker
  *             Monique Dewanchand
+ *             Sergey Sharybin
  */
 
 #include "COM_MovieDistortionOperation.h"
@@ -29,17 +30,6 @@ extern "C" {
 }
 
 
-static vector<DistortionCache *> s_cache;
-
-void deintializeDistortionCache(void) 
-{
-       while (s_cache.size() > 0) {
-               DistortionCache * cache = s_cache.back();
-               s_cache.pop_back();
-               delete cache;
-       }
-}
-
 MovieDistortionOperation::MovieDistortionOperation(bool distortion) : NodeOperation()
 {
        this->addInputSocket(COM_DT_COLOR);
@@ -47,40 +37,32 @@ MovieDistortionOperation::MovieDistortionOperation(bool distortion) : NodeOperat
        this->setResolutionInputSocketIndex(0);
        this->m_inputOperation = NULL;
        this->m_movieClip = NULL;
-       this->m_cache = NULL;
-       this->m_distortion = distortion;
+       this->m_apply = distortion;
 }
 
 void MovieDistortionOperation::initExecution()
 {
        this->m_inputOperation = this->getInputSocketReader(0);
        if (this->m_movieClip) {
+               MovieTracking *tracking = &this->m_movieClip->tracking;
                MovieClipUser clipUser = {0};
                int calibration_width, calibration_height;
 
                BKE_movieclip_user_set_frame(&clipUser, this->m_framenumber);
-               BKE_movieclip_get_size(this->m_movieClip, &clipUser, &calibration_width, &calibration_height);
-
-               for (unsigned int i = 0; i < s_cache.size(); i++) {
-                       DistortionCache *c = (DistortionCache *)s_cache[i];
-                       if (c->isCacheFor(this->m_movieClip, this->m_width, this->m_height,
-                                         calibration_width, calibration_height, this->m_distortion))
-                       {
-                               this->m_cache = c;
-                               this->m_cache->updateLastUsage();
-                               this->m_cache->getMargin(this->m_margin);
-                               return;
-                       }
-               }
+               BKE_movieclip_get_size(this->m_movieClip,
+                                      &clipUser,
+                                      &calibration_width,
+                                      &calibration_height);
 
                float delta[2];
                rcti full_frame;
                full_frame.xmin = full_frame.ymin = 0;
                full_frame.xmax = this->m_width;
                full_frame.ymax = this->m_height;
-               BKE_tracking_max_distortion_delta_across_bound(
-                       &this->m_movieClip->tracking, &full_frame,
-                       !this->m_distortion, delta);
+               BKE_tracking_max_distortion_delta_across_bound(tracking,
+                                                              &full_frame,
+                                                              !this->m_apply,
+                                                              delta);
 
                /* 5 is just in case we didn't hit real max of distortion in
                 * BKE_tracking_max_undistortion_delta_across_bound
@@ -88,17 +70,16 @@ void MovieDistortionOperation::initExecution()
                m_margin[0] = delta[0] + 5;
                m_margin[1] = delta[1] + 5;
 
-               DistortionCache *newC = new DistortionCache(this->m_movieClip,
-                                                           this->m_width, this->m_height,
-                                                           calibration_width, calibration_height,
-                                                           this->m_distortion,
-                                                           this->m_margin);
-               s_cache.push_back(newC);
-               this->m_cache = newC;
+               this->m_distortion = BKE_tracking_distortion_new(tracking,
+                                                                calibration_width,
+                                                                calibration_height);
+               this->m_calibration_width = calibration_width;
+               this->m_calibration_height = calibration_height;
+               this->m_pixel_aspect = tracking->camera.pixel_aspect;
        }
        else {
-               this->m_cache = NULL;
                m_margin[0] = m_margin[1] = 0;
+               this->m_distortion = NULL;
        }
 }
 
@@ -106,27 +87,39 @@ void MovieDistortionOperation::deinitExecution()
 {
        this->m_inputOperation = NULL;
        this->m_movieClip = NULL;
-       while (s_cache.size() > COM_DISTORTIONCACHE_MAXSIZE) {
-               double minTime = PIL_check_seconds_timer();
-               vector<DistortionCache*>::iterator minTimeIterator = s_cache.begin();
-               for (vector<DistortionCache*>::iterator it = s_cache.begin(); it < s_cache.end(); it ++) {
-                       DistortionCache * cache = *it;
-                       if (cache->getTimeLastUsage() < minTime) {
-                               minTime = cache->getTimeLastUsage();
-                               minTimeIterator = it;
-                       }
-               }
-               s_cache.erase(minTimeIterator);
+       if (this->m_distortion != NULL) {
+               BKE_tracking_distortion_free(this->m_distortion);
        }
 }
 
-
-void MovieDistortionOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/)
+void MovieDistortionOperation::executePixelSampled(float output[4],
+                                                   float x,
+                                                   float y,
+                                                   PixelSampler /*sampler*/)
 {
-       
-       if (this->m_cache != NULL) {
-               float u, v;
-               this->m_cache->getUV(&this->m_movieClip->tracking, x, y, &u, &v);
+       if (this->m_distortion != NULL) {
+               /* float overscan = 0.0f; */
+               const float pixel_aspect = this->m_pixel_aspect;
+               const float w = (float)this->m_width /* / (1 + overscan) */;
+               const float h = (float)this->m_height /* / (1 + overscan) */;
+               const float aspx = w / (float)this->m_calibration_width;
+               const float aspy = h / (float)this->m_calibration_height;
+               float in[2];
+               float out[2];
+
+               in[0] = (x /* - 0.5 * overscan * w */) / aspx;
+               in[1] = (y /* - 0.5 * overscan * h */) / aspy / pixel_aspect;
+
+               if (this->m_apply) {
+                       BKE_tracking_distortion_undistort_v2(this->m_distortion, in, out);
+               }
+               else {
+                       BKE_tracking_distortion_distort_v2(this->m_distortion, in, out);
+               }
+
+               float u = out[0] * aspx /* + 0.5 * overscan * w */,
+                     v = (out[1] * aspy /* + 0.5 * overscan * h */) * pixel_aspect;
+
                this->m_inputOperation->readSampled(output, u, v, COM_PS_BILINEAR);
        }
        else {
@@ -134,12 +127,17 @@ void MovieDistortionOperation::executePixelSampled(float output[4], float x, flo
        }
 }
 
-bool MovieDistortionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+bool MovieDistortionOperation::determineDependingAreaOfInterest(
+        rcti *input,
+        ReadBufferOperation *readOperation,
+        rcti *output)
 {
        rcti newInput;
        newInput.xmin = input->xmin - m_margin[0];
        newInput.ymin = input->ymin - m_margin[1];
        newInput.xmax = input->xmax + m_margin[0];
        newInput.ymax = input->ymax + m_margin[1];
-       return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+       return NodeOperation::determineDependingAreaOfInterest(&newInput,
+                                                              readOperation,
+                                                              output);
 }
index 38b1dbfa8569bad29c820d3af9640e0a35fd9574..689fcfe11ad3a908c08aeec58647a6cd38e75de3 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
- * Contributor: 
- *             Jeroen Bakker 
+ * Contributor:
+ *             Jeroen Bakker
  *             Monique Dewanchand
+ *             Sergey Sharybin
  */
 
 #ifndef _COM_MovieDistortionOperation_h_
 
 extern "C" {
 #  include "BKE_tracking.h"
-#  include "PIL_time.h"
 }
 
-#define COM_DISTORTIONCACHE_MAXSIZE 10
-
-class DistortionCache {
-private:
-       short m_distortion_model;
-       float m_k1, m_k2, m_k3;
-       float m_division_k1, m_division_k2;
-       float m_principal_x;
-       float m_principal_y;
-       float m_pixel_aspect;
-       int m_width;
-       int m_height;
-       int m_calibration_width;
-       int m_calibration_height;
-       bool m_inverted;
-       double timeLastUsage;
-       int m_margin[2];
-
-public:
-       DistortionCache(MovieClip *movieclip,
-                       int width, int height,
-                       int calibration_width, int calibration_height,
-                       bool inverted,
-                       const int margin[2])
-       {
-               this->m_distortion_model = movieclip->tracking.camera.distortion_model;
-               this->m_k1 = movieclip->tracking.camera.k1;
-               this->m_k2 = movieclip->tracking.camera.k2;
-               this->m_k3 = movieclip->tracking.camera.k3;
-               this->m_division_k1 = movieclip->tracking.camera.division_k1;
-               this->m_division_k2 = movieclip->tracking.camera.division_k2;
-               this->m_principal_x = movieclip->tracking.camera.principal[0];
-               this->m_principal_y = movieclip->tracking.camera.principal[1];
-               this->m_pixel_aspect = movieclip->tracking.camera.pixel_aspect;
-               this->m_width = width;
-               this->m_height = height;
-               this->m_calibration_width = calibration_width;
-               this->m_calibration_height = calibration_height;
-               this->m_inverted = inverted;
-               copy_v2_v2_int(this->m_margin, margin);
-               this->updateLastUsage();
-       }
-
-       void updateLastUsage() {
-               this->timeLastUsage = PIL_check_seconds_timer();
-       }
-
-       inline double getTimeLastUsage() {
-               return this->timeLastUsage;
-       }
-
-       bool isCacheFor(MovieClip *movieclip,
-                       int width, int height,
-                       int calibration_width, int claibration_height,
-                       bool inverted)
-       {
-               return this->m_distortion_model == movieclip->tracking.camera.distortion_model &&
-                      this->m_k1 == movieclip->tracking.camera.k1 &&
-                      this->m_k2 == movieclip->tracking.camera.k2 &&
-                      this->m_k3 == movieclip->tracking.camera.k3 &&
-                      this->m_division_k1 == movieclip->tracking.camera.division_k1 &&
-                      this->m_division_k2 == movieclip->tracking.camera.division_k2 &&
-                      this->m_principal_x == movieclip->tracking.camera.principal[0] &&
-                      this->m_principal_y == movieclip->tracking.camera.principal[1] &&
-                      this->m_pixel_aspect == movieclip->tracking.camera.pixel_aspect &&
-                      this->m_inverted == inverted &&
-                      this->m_width == width &&
-                      this->m_height == height &&
-                      this->m_calibration_width == calibration_width &&
-                      this->m_calibration_height == claibration_height;
-       }
-
-       void getUV(MovieTracking *trackingData,
-                  float x,
-                  float y,
-                  float *r_u,
-                  float *r_v)
-       {
-               if (x < 0 || x >= this->m_width || y < 0 || y >= this->m_height) {
-                       *r_u = x;
-                       *r_v = y;
-               }
-               else {
-                       /* float overscan = 0.0f; */
-                       const float w = (float)this->m_width /* / (1 + overscan) */;
-                       const float h = (float)this->m_height /* / (1 + overscan) */;
-                       const float aspx = w / (float)this->m_calibration_width;
-                       const float aspy = h / (float)this->m_calibration_height;
-                       float in[2];
-                       float out[2];
-
-                       in[0] = (x /* - 0.5 * overscan * w */) / aspx;
-                       in[1] = (y /* - 0.5 * overscan * h */) / aspy / this->m_pixel_aspect;
-
-                       if (this->m_inverted) {
-                               BKE_tracking_undistort_v2(trackingData, in, out);
-                       }
-                       else {
-                               BKE_tracking_distort_v2(trackingData, in, out);
-                       }
-
-                       *r_u = out[0] * aspx /* + 0.5 * overscan * w */;
-                       *r_v = (out[1] * aspy /* + 0.5 * overscan * h */) * this->m_pixel_aspect;
-               }
-       }
-
-       void getMargin(int margin[2])
-       {
-               copy_v2_v2_int(margin, m_margin);
-       }
-};
-
 class MovieDistortionOperation : public NodeOperation {
 private:
-       DistortionCache *m_cache;
        SocketReader *m_inputOperation;
        MovieClip *m_movieClip;
        int m_margin[2];
 
 protected:
-       bool m_distortion;
+       bool m_apply;
        int m_framenumber;
 
+       struct MovieDistortion *m_distortion;
+       int m_calibration_width, m_calibration_height;
+       float m_pixel_aspect;
+
 public:
        MovieDistortionOperation(bool distortion);
-       void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
+       void executePixelSampled(float output[4],
+                                float x, float y,
+                                PixelSampler sampler);
 
        void initExecution();
        void deinitExecution();
-       
+
        void setMovieClip(MovieClip *clip) { this->m_movieClip = clip; }
        void setFramenumber(int framenumber) { this->m_framenumber = framenumber; }
-       bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+       bool determineDependingAreaOfInterest(rcti *input,
+                                             ReadBufferOperation *readOperation,
+                                             rcti *output);
 
 };
 
-void deintializeDistortionCache(void);
-
 #endif