Internal refactoring of tracking module, should be no functional changes
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 15 Jun 2012 11:03:23 +0000 (11:03 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 15 Jun 2012 11:03:23 +0000 (11:03 +0000)
- Re-arrange functions in headers and implementation file to make them
  more grouped by entity they're operating with. Also order of functions
  in implementation file should match order of functions in header for
  easier navigation.

- Rename some functions to match conventions of naming public functions.
- Some code de-duplication, still some room for improvements tho.
- Split main 2D tracking functions into smaller steps to make it more clear.

Accidentally OpenMP was disabled in some of previous commits, re-enable it.

38 files changed:
source/blender/blenkernel/BKE_tracking.h
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/mask.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/tracking.c
source/blender/blenloader/intern/readfile.c
source/blender/compositor/nodes/COM_MovieClipNode.cpp
source/blender/compositor/operations/COM_KeyingScreenOperation.cpp
source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp
source/blender/compositor/operations/COM_MovieDistortionOperation.h
source/blender/editors/gpencil/gpencil_edit.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/interface/interface_draw.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/mask/mask_relationships.c
source/blender/editors/object/object_constraint.c
source/blender/editors/space_clip/clip_buttons.c
source/blender/editors/space_clip/clip_dopesheet_ops.c
source/blender/editors/space_clip/clip_draw.c
source/blender/editors/space_clip/clip_editor.c
source/blender/editors/space_clip/clip_graph_draw.c
source/blender/editors/space_clip/clip_graph_ops.c
source/blender/editors/space_clip/clip_ops.c
source/blender/editors/space_clip/clip_utils.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_clip/tracking_ops.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/space_view3d/view3d_snap.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/makesrna/intern/rna_tracking.c
source/blender/nodes/composite/node_composite_tree.c
source/blender/nodes/composite/nodes/node_composite_keyingscreen.c
source/blender/nodes/composite/nodes/node_composite_movieclip.c
source/blender/nodes/composite/nodes/node_composite_moviedistortion.c
source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
source/blender/windowmanager/intern/wm_init_exit.c

index e6c98c7..2b30c84 100644 (file)
@@ -47,127 +47,159 @@ struct Camera;
 struct Object;
 struct Scene;
 
-void BKE_tracking_init_settings(struct MovieTracking *tracking);
-void BKE_tracking_clamp_marker(struct MovieTrackingMarker *marker, int event);
-void BKE_tracking_track_flag(struct MovieTrackingTrack *track, int area, int flag, int clear);
+/* **** Common functions **** */
 
-struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, struct ListBase *tracksbase,
+void BKE_tracking_free(struct MovieTracking *tracking);
+
+void BKE_tracking_settings_init(struct MovieTracking *tracking);
+
+struct ListBase *BKE_tracking_get_active_tracks(struct MovieTracking *tracking);
+struct MovieTrackingReconstruction *BKE_tracking_get_active_reconstruction(struct MovieTracking *tracking);
+
+/* matrices for constraints and drawing */
+void BKE_tracking_get_camera_object_matrix(struct Scene *scene, struct Object *ob, float mat[4][4]);
+void BKE_tracking_get_projection_matrix(struct MovieTracking *tracking, struct MovieTrackingObject *object,
+                                        int framenr, int winx, int winy, float mat[4][4]);
+
+/* **** Clipboard **** */
+void BKE_tracking_clipboard_free(void);
+void BKE_tracking_clipboard_copy_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object);
+int BKE_tracking_clipboard_has_tracks(void);
+void BKE_tracking_clipboard_paste_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object);
+
+/* **** Track **** */
+struct MovieTrackingTrack *BKE_tracking_track_add(struct MovieTracking *tracking, struct ListBase *tracksbase,
                                                   float x, float y, int framenr, int width, int height);
-struct MovieTrackingMarker *BKE_tracking_insert_marker(struct MovieTrackingTrack *track,
+void BKE_tracking_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track);
+void BKE_tracking_track_free(struct MovieTrackingTrack *track);
+
+void BKE_tracking_track_flag_set(struct MovieTrackingTrack *track, int area, int flag);
+void BKE_tracking_track_flag_clear(struct MovieTrackingTrack *track, int area, int flag);
+
+int BKE_tracking_track_has_marker_at_frame(struct MovieTrackingTrack *track, int framenr);
+int BKE_tracking_track_has_enabled_marker_at_frame(struct MovieTrackingTrack *track, int framenr);
+
+void BKE_tracking_track_path_clear(struct MovieTrackingTrack *track, int ref_frame, int action);
+void BKE_tracking_tracks_join(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track);
+
+struct MovieTrackingTrack *BKE_tracking_track_get_named(struct MovieTracking *tracking,
+                                                        struct MovieTrackingObject *object,
+                                                        const char *name);
+struct MovieTrackingTrack *BKE_tracking_track_get_indexed(struct MovieTracking *tracking, int tracknr,
+                                                          struct ListBase **tracksbase_r);
+
+struct MovieTrackingTrack *BKE_tracking_track_get_active(struct MovieTracking *tracking);
+
+float *BKE_tracking_track_get_mask(int frame_width, int frame_height, struct MovieTrackingTrack *track,
+                                   struct MovieTrackingMarker *marker);
+
+/* selection */
+void BKE_tracking_track_select(struct ListBase *tracksbase, struct MovieTrackingTrack *track, int area, int extend);
+void BKE_tracking_track_deselect(struct MovieTrackingTrack *track, int area);
+
+/* **** Marker **** */
+struct MovieTrackingMarker *BKE_tracking_marker_insert(struct MovieTrackingTrack *track,
                                                        struct MovieTrackingMarker *marker);
-void BKE_tracking_delete_marker(struct MovieTrackingTrack *track, int framenr);
+void BKE_tracking_marker_delete(struct MovieTrackingTrack *track, int framenr);
+
+void BKE_tracking_marker_clamp(struct MovieTrackingMarker *marker, int event);
+
+struct MovieTrackingMarker *BKE_tracking_marker_get(struct MovieTrackingTrack *track, int framenr);
+struct MovieTrackingMarker *BKE_tracking_marker_get_exact(struct MovieTrackingTrack *track, int framenr);
+struct MovieTrackingMarker *BKE_tracking_marker_ensure(struct MovieTrackingTrack *track, int framenr);
 
 void BKE_tracking_marker_pattern_minmax(const struct MovieTrackingMarker *marker, float min[2], float max[2]);
-struct MovieTrackingMarker *BKE_tracking_get_marker(struct MovieTrackingTrack *track, int framenr);
-struct MovieTrackingMarker *BKE_tracking_ensure_marker(struct MovieTrackingTrack *track, int framenr);
-struct MovieTrackingMarker *BKE_tracking_exact_marker(struct MovieTrackingTrack *track, int framenr);
-int BKE_tracking_has_marker(struct MovieTrackingTrack *track, int framenr);
-int BKE_tracking_has_enabled_marker(struct MovieTrackingTrack *track, int framenr);
 
-void BKE_tracking_free_track(struct MovieTrackingTrack *track);
+/* **** Object **** */
+struct MovieTrackingObject *BKE_tracking_object_add(struct MovieTracking *tracking, const char *name);
+void BKE_tracking_object_delete(struct MovieTracking *tracking, struct MovieTrackingObject *object);
 
-void BKE_tracking_clear_path(struct MovieTrackingTrack *track, int ref_frame, int action);
+void BKE_tracking_object_unique_name(struct MovieTracking *tracking, struct MovieTrackingObject *object);
 
-void BKE_tracking_join_tracks(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track);
-void BKE_tracking_free(struct MovieTracking *tracking);
+struct MovieTrackingObject *BKE_tracking_object_get_named(struct MovieTracking *tracking, const char *name);
 
-struct ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height,
-                                                struct ImBuf *struct_ibuf, struct MovieTrackingTrack *track,
-                                                struct MovieTrackingMarker *marker, int use_mask,
-                                                int num_samples_x, int num_samples_y, float pos[2]);
-struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
-                                             struct MovieTrackingMarker *marker, int anchored, int disable_channels);
-struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
-                                            struct MovieTrackingMarker *marker, int anchored, int disable_channels);
-float *BKE_tracking_track_mask_get(int frame_width, int frame_height, struct MovieTrackingTrack *track,
-                                   struct MovieTrackingMarker *marker);
+struct MovieTrackingObject *BKE_tracking_object_get_active(struct MovieTracking *tracking);
+struct MovieTrackingObject *BKE_tracking_object_get_camera(struct MovieTracking *tracking);
 
-void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track);
+struct ListBase *BKE_tracking_object_get_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object);
+struct MovieTrackingReconstruction *BKE_tracking_object_get_reconstruction(struct MovieTracking *tracking,
+                                                                           struct MovieTrackingObject *object);
 
-struct MovieTrackingTrack *BKE_tracking_named_track(struct MovieTracking *tracking, struct MovieTrackingObject *object, const char *name);
-struct MovieTrackingTrack *BKE_tracking_indexed_track(struct MovieTracking *tracking, int tracknr, struct ListBase **tracksbase_r);
+/* **** Camera **** */
+void BKE_tracking_camera_shift_get(struct MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty);
+void BKE_tracking_camera_to_blender(struct MovieTracking *tracking, struct Scene *scene,
+                                    struct Camera *camera, int width, int height);
 
-void BKE_tracking_camera_shift(struct MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty);
-void BKE_tracking_camera_to_blender(struct MovieTracking *tracking, struct Scene *scene, struct Camera *camera, int width, int height);
+struct MovieReconstructedCamera *BKE_tracking_camera_get_reconstructed(struct MovieTracking *tracking,
+                                                                       struct MovieTrackingObject *object,
+                                                                       int framenr);
+void BKE_tracking_camera_get_reconstructed_interpolate(struct MovieTracking *tracking,
+                                                       struct MovieTrackingObject *object,
+                                                       int framenr, float mat[4][4]);
 
-void BKE_get_tracking_mat(struct Scene *scene, struct Object *ob, float mat[4][4]);
-void BKE_tracking_projection_matrix(struct MovieTracking *tracking, struct MovieTrackingObject *object,
-                                    int framenr, int winx, int winy, float mat[4][4]);
+/* **** Distortion/Undistortion **** */
+struct MovieDistortion *BKE_tracking_distortion_new(void);
+void BKE_tracking_distortion_update(struct MovieDistortion *distortion, struct MovieTracking *tracking,
+                                    int calibration_width, int calibration_height);
+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, int undistort);
+void BKE_tracking_distortion_free(struct MovieDistortion *distortion);
 
-struct ListBase *BKE_tracking_get_tracks(struct MovieTracking *tracking);
-struct MovieTrackingReconstruction *BKE_tracking_get_reconstruction(struct MovieTracking *tracking);
+void BKE_tracking_distort_v2(struct MovieTracking *tracking, float co[2], float nco[2]);
+void BKE_tracking_undistort_v2(struct MovieTracking *tracking, float co[2], float nco[2]);
 
-struct MovieTrackingTrack *BKE_tracking_active_track(struct MovieTracking *tracking);
-struct MovieTrackingObject *BKE_tracking_active_object(struct MovieTracking *tracking);
-struct MovieTrackingObject *BKE_tracking_get_camera_object(struct MovieTracking *tracking);
-struct ListBase *BKE_tracking_object_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object);
-struct MovieTrackingReconstruction *BKE_tracking_object_reconstruction(struct MovieTracking *tracking,
-                                                                       struct MovieTrackingObject *object);
+struct ImBuf *BKE_tracking_undistort_frame(struct MovieTracking *tracking, struct ImBuf *ibuf,
+                                           int calibration_width, int calibration_height, float overscan);
+struct ImBuf *BKE_tracking_distort_frame(struct MovieTracking *tracking, struct ImBuf *ibuf,
+                                         int calibration_width, int calibration_height, float overscan);
 
-void BKE_tracking_disable_imbuf_channels(struct ImBuf *ibuf, int disable_red, int disable_green, int disable_blue, int grayscale);
+/* **** Image sampling **** */
+struct ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height,
+                                          struct ImBuf *struct_ibuf, struct MovieTrackingTrack *track,
+                                          struct MovieTrackingMarker *marker, int use_mask,
+                                          int num_samples_x, int num_samples_y, float pos[2]);
+struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
+                                             struct MovieTrackingMarker *marker, int anchored, int disable_channels);
+struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
+                                            struct MovieTrackingMarker *marker, int anchored, int disable_channels);
 
-/* clipboard */
-void BKE_tracking_free_clipboard(void);
-void BKE_tracking_clipboard_copy_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object);
-int BKE_tracking_clipboard_has_tracks(void);
-void BKE_tracking_clipboard_paste_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object);
+void BKE_tracking_disable_channels(struct ImBuf *ibuf, int disable_red, int disable_green,
+                                   int disable_blue, int grayscale);
 
-/* 2D tracking */
+/* **** 2D tracking **** */
 struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user,
                                                       short backwards, short sequence);
 void BKE_tracking_context_free(struct MovieTrackingContext *context);
-void BKE_tracking_sync(struct MovieTrackingContext *context);
-void BKE_tracking_sync_user(struct MovieClipUser *user, struct MovieTrackingContext *context);
-int BKE_tracking_next(struct MovieTrackingContext *context);
+void BKE_tracking_context_sync(struct MovieTrackingContext *context);
+void BKE_tracking_context_sync_user(const struct MovieTrackingContext *context, struct MovieClipUser *user);
+int BKE_tracking_context_step(struct MovieTrackingContext *context);
 
-/* Camera solving */
-int BKE_tracking_can_reconstruct(struct MovieTracking *tracking, struct MovieTrackingObject *object,
-                                 char *error_msg, int error_size);
+/* **** Camera solving **** */
+int BKE_tracking_reconstruction_check(struct MovieTracking *tracking, struct MovieTrackingObject *object,
+                                      char *error_msg, int error_size);
 
 struct MovieReconstructContext *BKE_tracking_reconstruction_context_new(struct MovieTracking *tracking,
-                                                                        struct MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height);
+                                                                        struct MovieTrackingObject *object,
+                                                                        int keyframe1, int keyframe2,
+                                                                        int width, int height);
 void BKE_tracking_reconstruction_context_free(struct MovieReconstructContext *context);
-void BKE_tracking_solve_reconstruction(struct MovieReconstructContext *context, short *stop, short *do_update,
+void BKE_tracking_reconstruction_solve(struct MovieReconstructContext *context, short *stop, short *do_update,
                                        float *progress, char *stats_message, int message_size);
-int BKE_tracking_finish_reconstruction(struct MovieReconstructContext *context, struct MovieTracking *tracking);
-
-struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking,
-                                                                       struct MovieTrackingObject *object, int framenr);
-void BKE_tracking_get_interpolated_camera(struct MovieTracking *tracking, struct MovieTrackingObject *object,
-                                          int framenr, float mat[4][4]);
+int BKE_tracking_reconstruction_finish(struct MovieReconstructContext *context, struct MovieTracking *tracking);
 
-/* Feature detection */
+/* **** Feature detection **** */
 void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ListBase *tracksbase, struct ImBuf *imbuf,
                               int framenr, int margin, int min_trackness, int min_distance, struct bGPDlayer *layer,
                               int place_outside_layer);
 
-/* 2D stabilization */
-void BKE_tracking_stabilization_data(struct MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale, float *angle);
-struct ImBuf *BKE_tracking_stabilize(struct MovieTracking *tracking, int framenr, struct ImBuf *ibuf, float loc[2], float *scale, float *angle);
-void BKE_tracking_stabdata_to_mat4(int width, int height, float aspect, float loc[2], float scale, float angle, float mat[4][4]);
-
-/* Distortion/Undistortion */
-void BKE_tracking_apply_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]);
-void BKE_tracking_invert_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]);
-
-struct MovieDistortion *BKE_tracking_distortion_create(void);
-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, int undistort);
-void BKE_tracking_distortion_destroy(struct MovieDistortion *distortion);
-
-struct ImBuf *BKE_tracking_undistort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan);
-struct ImBuf *BKE_tracking_distort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan);
-
-/* Object tracking */
-struct MovieTrackingObject *BKE_tracking_new_object(struct MovieTracking *tracking, const char *name);
-void BKE_tracking_remove_object(struct MovieTracking *tracking, struct MovieTrackingObject *object);
-void BKE_tracking_object_unique_name(struct MovieTracking *tracking, struct MovieTrackingObject *object);
-struct MovieTrackingObject *BKE_tracking_named_object(struct MovieTracking *tracking, const char *name);
-
-/* Select */
-void BKE_tracking_select_track(struct ListBase *tracksbase, struct MovieTrackingTrack *track, int area, int extend);
-void BKE_tracking_deselect_track(struct MovieTrackingTrack *track, int area);
+/* **** 2D stabilization **** */
+void BKE_tracking_stabilization_data_get(struct MovieTracking *tracking, int framenr, int width, int height,
+                                         float loc[2], float *scale, float *angle);
+struct ImBuf *BKE_tracking_stabilize_frame(struct MovieTracking *tracking, int framenr, struct ImBuf *ibuf,
+                                           float loc[2], float *scale, float *angle);
+void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, float loc[2],
+                                             float scale, float angle, float mat[4][4]);
 
 /* Dopesheet */
 void BKE_tracking_dopesheet_tag_update(struct MovieTracking *tracking);
index 9bb0980..c12e740 100644 (file)
@@ -3917,14 +3917,14 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
        tracking = &clip->tracking;
 
        if (data->object[0])
-               tracking_object = BKE_tracking_named_object(tracking, data->object);
+               tracking_object = BKE_tracking_object_get_named(tracking, data->object);
        else
-               tracking_object = BKE_tracking_get_camera_object(tracking);
+               tracking_object = BKE_tracking_object_get_camera(tracking);
 
        if (!tracking_object)
                return;
 
-       track = BKE_tracking_named_track(tracking, tracking_object, data->track);
+       track = BKE_tracking_track_get_named(tracking, tracking_object, data->track);
 
        if (!track)
                return;
@@ -3942,14 +3942,14 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
 
                                copy_m4_m4(mat, camob->obmat);
 
-                               BKE_tracking_get_interpolated_camera(tracking, tracking_object, framenr, imat);
+                               BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, imat);
                                invert_m4(imat);
 
                                mul_serie_m4(cob->matrix, obmat, mat, imat, NULL, NULL, NULL, NULL, NULL);
                                translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
                        }
                        else {
-                               BKE_get_tracking_mat(cob->scene, camob, mat);
+                               BKE_tracking_get_camera_object_matrix(cob->scene, camob, mat);
 
                                mult_m4_m4m4(cob->matrix, obmat, mat);
                                translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
@@ -3981,7 +3981,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
                        CameraParams params;
                        float pos[2], rmat[4][4];
 
-                       marker = BKE_tracking_get_marker(track, framenr);
+                       marker = BKE_tracking_marker_get(track, framenr);
 
                        add_v2_v2v2(pos, marker->pos, track->offset);
 
@@ -4103,10 +4103,10 @@ static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
        if (clip) {
                float mat[4][4], obmat[4][4];
                MovieTracking *tracking = &clip->tracking;
-               MovieTrackingObject *object = BKE_tracking_get_camera_object(tracking);
+               MovieTrackingObject *object = BKE_tracking_object_get_camera(tracking);
                int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra);
 
-               BKE_tracking_get_interpolated_camera(tracking, object, framenr, mat);
+               BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat);
 
                copy_m4_m4(obmat, cob->matrix);
 
@@ -4165,7 +4165,7 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
                MovieTracking *tracking = &clip->tracking;
                MovieTrackingObject *object;
 
-               object = BKE_tracking_named_object(tracking, data->object);
+               object = BKE_tracking_object_get_named(tracking, data->object);
 
                if (object) {
                        float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4];
@@ -4173,7 +4173,7 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
 
                        BKE_object_where_is_calc_mat4(scene, camob, cammat);
 
-                       BKE_tracking_get_interpolated_camera(tracking, object, framenr, mat);
+                       BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat);
 
                        invert_m4_m4(camimat, cammat);
                        mult_m4_m4m4(parmat, cammat, data->invmat);
index 7e9f189..48db916 100644 (file)
@@ -1156,16 +1156,16 @@ static int BKE_mask_evaluate_parent(MaskParent *parent, float ctime, float r_co[
                if (parent->id) {
                        MovieClip *clip = (MovieClip *) parent->id;
                        MovieTracking *tracking = (MovieTracking *) &clip->tracking;
-                       MovieTrackingObject *ob = BKE_tracking_named_object(tracking, parent->parent);
+                       MovieTrackingObject *ob = BKE_tracking_object_get_named(tracking, parent->parent);
 
                        if (ob) {
-                               MovieTrackingTrack *track = BKE_tracking_named_track(tracking, ob, parent->sub_parent);
+                               MovieTrackingTrack *track = BKE_tracking_track_get_named(tracking, ob, parent->sub_parent);
 
                                MovieClipUser user = {0};
                                user.framenr = ctime;
 
                                if (track) {
-                                       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, ctime);
+                                       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, ctime);
                                        float marker_pos_ofs[2];
                                        add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset);
                                        BKE_mask_coord_from_movieclip(clip, &user, r_co, marker_pos_ofs);
index adf1a2f..52c9ec4 100644 (file)
@@ -436,7 +436,7 @@ static MovieClip *movieclip_alloc(const char *name)
 
        clip->aspx = clip->aspy = 1.0f;
 
-       BKE_tracking_init_settings(&clip->tracking);
+       BKE_tracking_settings_init(&clip->tracking);
 
        clip->proxy.build_size_flag = IMB_PROXY_25;
        clip->proxy.build_tc_flag = IMB_TC_RECORD_RUN |
@@ -548,7 +548,7 @@ static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *dist
        if (distortion)
                undistibuf = BKE_tracking_distortion_exec(distortion, &clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f, 1);
        else
-               undistibuf = BKE_tracking_undistort(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f);
+               undistibuf = BKE_tracking_undistort_frame(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f);
 
        if (undistibuf->userflags & IB_RECT_INVALID) {
                ibuf->userflags &= ~IB_RECT_INVALID;
@@ -678,7 +678,7 @@ static ImBuf *put_postprocessed_frame_to_cache(MovieClip *clip, MovieClipUser *u
                        postproc_ibuf = IMB_dupImBuf(ibuf);
 
                if (disable_red || disable_green || disable_blue || grayscale)
-                       BKE_tracking_disable_imbuf_channels(postproc_ibuf, disable_red, disable_green, disable_blue, 1);
+                       BKE_tracking_disable_channels(postproc_ibuf, disable_red, disable_green, disable_blue, 1);
        }
 
        IMB_refImBuf(postproc_ibuf);
@@ -799,7 +799,7 @@ static ImBuf *get_stable_cached_frame(MovieClip *clip, MovieClipUser *user, int
 
        stableibuf = cache->stabilized.ibuf;
 
-       BKE_tracking_stabilization_data(&clip->tracking, framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle);
+       BKE_tracking_stabilization_data_get(&clip->tracking, framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle);
 
        /* check for stabilization parameters */
        if (tscale != cache->stabilized.scale ||
@@ -825,7 +825,7 @@ static ImBuf *put_stabilized_frame_to_cache(MovieClip *clip, MovieClipUser *user
        if (cache->stabilized.ibuf)
                IMB_freeImBuf(cache->stabilized.ibuf);
 
-       stableibuf = BKE_tracking_stabilize(&clip->tracking, framenr, ibuf, tloc, &tscale, &tangle);
+       stableibuf = BKE_tracking_stabilize_frame(&clip->tracking, framenr, ibuf, tloc, &tscale, &tangle);
 
        cache->stabilized.ibuf = stableibuf;
 
@@ -1043,12 +1043,12 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
        scopes->track_locked = TRUE;
 
        if (clip) {
-               MovieTrackingTrack *act_track = BKE_tracking_active_track(&clip->tracking);
+               MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
 
                if (act_track) {
                        MovieTrackingTrack *track = act_track;
                        int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
-                       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
+                       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
 
                        if (marker->flag & MARKER_DISABLED) {
                                scopes->track_disabled = TRUE;
@@ -1073,7 +1073,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
                                                undist_marker.pos[0] *= width;
                                                undist_marker.pos[1] *= height * aspy;
 
-                                               BKE_tracking_invert_intrinsics(&clip->tracking, undist_marker.pos, undist_marker.pos);
+                                               BKE_tracking_undistort_v2(&clip->tracking, undist_marker.pos, undist_marker.pos);
 
                                                undist_marker.pos[0] /= width;
                                                undist_marker.pos[1] /= height * aspy;
index 0aa0d36..43fe94d 100644 (file)
@@ -76,7 +76,191 @@ static struct {
        ListBase tracks;
 } tracking_clipboard;
 
-/*********************** space transformation functions  *************************/
+/*********************** Common functions  *************************/
+
+static MovieTrackingTrack *tracking_track_duplicate(MovieTrackingTrack *track)
+{
+       MovieTrackingTrack *new_track;
+
+       new_track = MEM_callocN(sizeof(MovieTrackingTrack), "tracksMapMerge new_track");
+
+       *new_track = *track;
+       new_track->next = new_track->prev = NULL;
+
+       new_track->markers = MEM_dupallocN(new_track->markers);
+
+       return new_track;
+}
+
+static void tracking_tracks_free(ListBase *tracks)
+{
+       MovieTrackingTrack *track;
+
+       for (track = tracks->first; track; track = track->next) {
+               BKE_tracking_track_free(track);
+       }
+
+       BLI_freelistN(tracks);
+}
+
+static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
+{
+       if (reconstruction->cameras)
+               MEM_freeN(reconstruction->cameras);
+}
+
+static void tracking_object_free(MovieTrackingObject *object)
+{
+       tracking_tracks_free(&object->tracks);
+       tracking_reconstruction_free(&object->reconstruction);
+}
+
+static void tracking_objects_free(ListBase *objects)
+{
+       MovieTrackingObject *object;
+
+       for (object = objects->first; object; object = object->next)
+               tracking_object_free(object);
+
+       BLI_freelistN(objects);
+}
+
+static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet)
+{
+       MovieTrackingDopesheetChannel *channel;
+
+       channel = dopesheet->channels.first;
+       while (channel) {
+               if (channel->segments) {
+                       MEM_freeN(channel->segments);
+               }
+
+               channel = channel->next;
+       }
+
+       BLI_freelistN(&dopesheet->channels);
+
+       dopesheet->channels.first = dopesheet->channels.last = NULL;
+       dopesheet->tot_channel = 0;
+}
+
+void BKE_tracking_free(MovieTracking *tracking)
+{
+       tracking_tracks_free(&tracking->tracks);
+       tracking_reconstruction_free(&tracking->reconstruction);
+       tracking_objects_free(&tracking->objects);
+
+       if (tracking->stabilization.scaleibuf)
+               IMB_freeImBuf(tracking->stabilization.scaleibuf);
+
+       if (tracking->camera.intrinsics)
+               BKE_tracking_distortion_free(tracking->camera.intrinsics);
+
+       tracking_dopesheet_free(&tracking->dopesheet);
+}
+
+void BKE_tracking_settings_init(MovieTracking *tracking)
+{
+       tracking->camera.sensor_width = 35.0f;
+       tracking->camera.pixel_aspect = 1.0f;
+       tracking->camera.units = CAMERA_UNITS_MM;
+
+       tracking->settings.default_motion_model = TRACK_MOTION_MODEL_TRANSLATION;
+       tracking->settings.default_minimum_correlation = 0.75;
+       tracking->settings.default_pattern_size = 11;
+       tracking->settings.default_search_size = 61;
+       tracking->settings.keyframe1 = 1;
+       tracking->settings.keyframe2 = 30;
+       tracking->settings.dist = 1;
+       tracking->settings.object_distance = 1;
+
+       tracking->stabilization.scaleinf = 1.0f;
+       tracking->stabilization.locinf = 1.0f;
+       tracking->stabilization.rotinf = 1.0f;
+       tracking->stabilization.maxscale = 2.0f;
+
+       BKE_tracking_object_add(tracking, "Camera");
+}
+
+ListBase *BKE_tracking_get_active_tracks(MovieTracking *tracking)
+{
+       MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
+
+       if (object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
+               return &object->tracks;
+       }
+
+       return &tracking->tracks;
+}
+
+MovieTrackingReconstruction *BKE_tracking_get_active_reconstruction(MovieTracking *tracking)
+{
+       MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
+
+       return BKE_tracking_object_get_reconstruction(tracking, object);
+}
+
+void BKE_tracking_get_camera_object_matrix(Scene *scene, Object *ob, float mat[4][4])
+{
+       if (!ob) {
+               if (scene->camera)
+                       ob = scene->camera;
+               else
+                       ob = BKE_scene_camera_find(scene);
+       }
+
+       if (ob)
+               BKE_object_where_is_calc_mat4(scene, ob, mat);
+       else
+               unit_m4(mat);
+}
+
+void BKE_tracking_get_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object,
+                                    int framenr, int winx, int winy, float mat[4][4])
+{
+       MovieReconstructedCamera *camera;
+       float lens = tracking->camera.focal * tracking->camera.sensor_width / (float)winx;
+       float viewfac, pixsize, left, right, bottom, top, clipsta, clipend;
+       float winmat[4][4];
+       float ycor =  1.0f / tracking->camera.pixel_aspect;
+       float shiftx, shifty, winside = MAX2(winx, winy);
+
+       BKE_tracking_camera_shift_get(tracking, winx, winy, &shiftx, &shifty);
+
+       clipsta = 0.1f;
+       clipend = 1000.0f;
+
+       if (winx >= winy)
+               viewfac = (lens * winx) / tracking->camera.sensor_width;
+       else
+               viewfac = (ycor * lens * winy) / tracking->camera.sensor_width;
+
+       pixsize = clipsta / viewfac;
+
+       left = -0.5f * (float)winx + shiftx * winside;
+       bottom = -0.5f * (ycor) * (float)winy + shifty * winside;
+       right =  0.5f * (float)winx + shiftx * winside;
+       top =  0.5f * (ycor) * (float)winy + shifty * winside;
+
+       left *= pixsize;
+       right *= pixsize;
+       bottom *= pixsize;
+       top *= pixsize;
+
+       perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
+
+       camera = BKE_tracking_camera_get_reconstructed(tracking, object, framenr);
+
+       if (camera) {
+               float imat[4][4];
+
+               invert_m4_m4(imat, camera->mat);
+               mult_m4_m4m4(mat, winmat, imat);
+       }
+       else copy_m4_m4(mat, winmat);
+}
+
+/* **** space transformation functions  **** */
 
 /* Three coordinate frames: Frame, Search, and Marker
  * Two units: Pixels, Unified
@@ -100,7 +284,8 @@ static void marker_to_frame_unified(const MovieTrackingMarker *marker, const flo
 
 static void marker_unified_to_frame_pixel_coordinates(int frame_width, int frame_height,
                                                       const MovieTrackingMarker *marker,
-                                                      const float marker_unified_coords[2], float frame_pixel_coords[2])
+                                                      const float marker_unified_coords[2],
+                                                      float frame_pixel_coords[2])
 {
        marker_to_frame_unified(marker, marker_unified_coords, frame_pixel_coords);
        unified_to_pixel(frame_width, frame_height, frame_pixel_coords, frame_pixel_coords);
@@ -168,6 +353,7 @@ static void get_marker_coords_for_tracking(int frame_width, int frame_height,
                search_pixel_x[i] = pixel_coords[0];
                search_pixel_y[i] = pixel_coords[1];
        }
+
        /* Convert the center position (aka "pos"); this is the origin */
        unified_coords[0] = 0.0;
        unified_coords[1] = 0.0;
@@ -211,121 +397,81 @@ static void set_marker_coords_from_tracking(int frame_width, int frame_height, M
 }
 #endif
 
-/*********************** common functions *************************/
+/*********************** clipboard *************************/
 
-void BKE_tracking_init_settings(MovieTracking *tracking)
+void BKE_tracking_clipboard_free(void)
 {
-       tracking->camera.sensor_width = 35.0f;
-       tracking->camera.pixel_aspect = 1.0f;
-       tracking->camera.units = CAMERA_UNITS_MM;
+       MovieTrackingTrack *track = tracking_clipboard.tracks.first, *next_track;
 
-       tracking->settings.default_motion_model = TRACK_MOTION_MODEL_TRANSLATION;
-       tracking->settings.default_minimum_correlation = 0.75;
-       tracking->settings.default_pattern_size = 11;
-       tracking->settings.default_search_size = 61;
-       tracking->settings.keyframe1 = 1;
-       tracking->settings.keyframe2 = 30;
-       tracking->settings.dist = 1;
-       tracking->settings.object_distance = 1;
+       while (track) {
+               next_track = track->next;
 
-       tracking->stabilization.scaleinf = 1.0f;
-       tracking->stabilization.locinf = 1.0f;
-       tracking->stabilization.rotinf = 1.0f;
-       tracking->stabilization.maxscale = 2.0f;
+               BKE_tracking_track_free(track);
+               MEM_freeN(track);
 
-       BKE_tracking_new_object(tracking, "Camera");
+               track = next_track;
+       }
 }
 
-void BKE_tracking_clamp_marker(MovieTrackingMarker *marker, int event)
+void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object)
 {
-       int a;
-       float pat_min[2], pat_max[2];
-
-       BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
+       ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
+       MovieTrackingTrack *track = tracksbase->first;
 
-       if (event == CLAMP_PAT_DIM) {
-               for (a = 0; a < 2; a++) {
-                       /* search shouldn't be resized smaller than pattern */
-                       marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]);
-                       marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]);
-               }
-       }
-       else if (event == CLAMP_PAT_POS) {
-               float dim[2];
+       BKE_tracking_clipboard_free();
 
-               sub_v2_v2v2(dim, pat_max, pat_min);
+       while (track) {
+               if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) {
+                       MovieTrackingTrack *new_track = tracking_track_duplicate(track);
 
-               for (a = 0; a < 2; a++) {
-                       int b;
-                       /* pattern shouldn't be moved outside of search */
-                       if (pat_min[a] < marker->search_min[a]) {
-                               for (b = 0; b < 4; b++)
-                                       marker->pattern_corners[b][a] += marker->search_min[a] - pat_min[a];
-                       }
-                       if (pat_max[a] > marker->search_max[a]) {
-                               for (b = 0; b < 4; b++)
-                                       marker->pattern_corners[b][a] -= pat_max[a] - marker->search_max[a];
-                       }
-               }
-       }
-       else if (event == CLAMP_SEARCH_DIM) {
-               for (a = 0; a < 2; a++) {
-                       /* search shouldn't be resized smaller than pattern */
-                       marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]);
-                       marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]);
+                       BLI_addtail(&tracking_clipboard.tracks, new_track);
                }
-       }
-       else if (event == CLAMP_SEARCH_POS) {
-               float dim[2];
 
-               sub_v2_v2v2(dim, marker->search_max, marker->search_min);
-
-               for (a = 0; a < 2; a++) {
-                       /* search shouldn't be moved inside pattern */
-                       if (marker->search_min[a] > pat_min[a]) {
-                               marker->search_min[a] = pat_min[a];
-                               marker->search_max[a] = marker->search_min[a] + dim[a];
-                       }
-                       if (marker->search_max[a] < pat_max[a]) {
-                               marker->search_max[a] = pat_max[a];
-                               marker->search_min[a] = marker->search_max[a] - dim[a];
-                       }
-               }
-       }
-       else if (event == CLAMP_SEARCH_DIM) {
-               float dim[2];
-               sub_v2_v2v2(dim, pat_max, pat_min);
-               for (a = 0; a < 2; a++) {
-                       marker->search_min[a] = pat_min[a];
-                       marker->search_max[a] = pat_max[a];
-               }
+               track = track->next;
        }
 }
 
-void BKE_tracking_track_flag(MovieTrackingTrack *track, int area, int flag, int clear)
+int BKE_tracking_clipboard_has_tracks(void)
 {
-       if (area == TRACK_AREA_NONE)
-               return;
+       return tracking_clipboard.tracks.first != NULL;
+}
 
-       if (clear) {
-               if (area & TRACK_AREA_POINT)
-                       track->flag &= ~flag;
-               if (area & TRACK_AREA_PAT)
-                       track->pat_flag &= ~flag;
-               if (area & TRACK_AREA_SEARCH)
-                       track->search_flag &= ~flag;
-       }
-       else {
-               if (area & TRACK_AREA_POINT)
-                       track->flag |= flag;
-               if (area & TRACK_AREA_PAT)
-                       track->pat_flag |= flag;
-               if (area & TRACK_AREA_SEARCH)
-                       track->search_flag |= flag;
+void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingObject *object)
+{
+       ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
+       MovieTrackingTrack *track = tracking_clipboard.tracks.first;
+
+       while (track) {
+               MovieTrackingTrack *new_track = tracking_track_duplicate(track);
+
+               BLI_addtail(tracksbase, new_track);
+               BKE_tracking_track_unique_name(tracksbase, new_track);
+
+               track = track->next;
        }
 }
 
-MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tracksbase, float x, float y,
+/*********************** Tracks  *************************/
+
+static void tracking_marker_insert_disabled(MovieTrackingTrack *track, MovieTrackingMarker *ref_marker,
+                                            int before, int overwrite)
+{
+       MovieTrackingMarker marker_new;
+
+       marker_new = *ref_marker;
+       marker_new.flag &= ~MARKER_TRACKED;
+       marker_new.flag |= MARKER_DISABLED;
+
+       if (before)
+               marker_new.framenr--;
+       else
+               marker_new.framenr++;
+
+       if (overwrite || !BKE_tracking_track_has_marker_at_frame(track, marker_new.framenr))
+               BKE_tracking_marker_insert(track, &marker_new);
+}
+
+MovieTrackingTrack *BKE_tracking_track_add(MovieTracking *tracking, ListBase *tracksbase, float x, float y,
                                            int framenr, int width, int height)
 {
        MovieTrackingTrack *track;
@@ -345,6 +491,7 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tr
        track = MEM_callocN(sizeof(MovieTrackingTrack), "add_marker_exec track");
        strcpy(track->name, "Track");
 
+       /* fill track's settings from default settings */
        track->motion_model = settings->default_motion_model;
        track->minimum_correlation = settings->default_minimum_correlation;
        track->margin = settings->default_margin;
@@ -370,194 +517,64 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tr
        copy_v2_v2(marker.search_max, search);
        negate_v2_v2(marker.search_min, search);
 
-       BKE_tracking_insert_marker(track, &marker);
+       BKE_tracking_marker_insert(track, &marker);
 
        BLI_addtail(tracksbase, track);
-       BKE_track_unique_name(tracksbase, track);
+       BKE_tracking_track_unique_name(tracksbase, track);
 
        return track;
 }
 
-MovieTrackingMarker *BKE_tracking_insert_marker(MovieTrackingTrack *track, MovieTrackingMarker *marker)
-{
-       MovieTrackingMarker *old_marker = NULL;
-
-       if (track->markersnr)
-               old_marker = BKE_tracking_exact_marker(track, marker->framenr);
-
-       if (old_marker) {
-               *old_marker = *marker;
-
-               return old_marker;
-       }
-       else {
-               int a = track->markersnr;
-
-               while (a--) {
-                       if (track->markers[a].framenr < marker->framenr)
-                               break;
-               }
-
-               track->markersnr++;
-
-               if (track->markers)
-                       track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
-               else
-                       track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers");
-
-               memmove(track->markers + a + 2, track->markers + a + 1,
-                       (track->markersnr - a - 2) * sizeof(MovieTrackingMarker));
-               track->markers[a + 1] = *marker;
-
-               track->last_marker = a + 1;
-
-               return &track->markers[a + 1];
-       }
-}
-
-void BKE_tracking_delete_marker(MovieTrackingTrack *track, int framenr)
+void BKE_tracking_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
 {
-       int a = 0;
-
-       while (a < track->markersnr) {
-               if (track->markers[a].framenr == framenr) {
-                       if (track->markersnr > 1) {
-                               memmove(track->markers + a, track->markers + a + 1,
-                                       (track->markersnr - a - 1) * sizeof(MovieTrackingMarker));
-                               track->markersnr--;
-                               track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
-                       }
-                       else {
-                               MEM_freeN(track->markers);
-                               track->markers = NULL;
-                               track->markersnr = 0;
-                       }
-
-                       break;
-               }
-
-               a++;
-       }
-}
-
-void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float min[2], float max[2])
-{
-       INIT_MINMAX2(min, max);
-
-       DO_MINMAX2(marker->pattern_corners[0], min, max);
-       DO_MINMAX2(marker->pattern_corners[1], min, max);
-       DO_MINMAX2(marker->pattern_corners[2], min, max);
-       DO_MINMAX2(marker->pattern_corners[3], min, max);
+       BLI_uniquename(tracksbase, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
 }
 
-MovieTrackingMarker *BKE_tracking_get_marker(MovieTrackingTrack *track, int framenr)
+void BKE_tracking_track_free(MovieTrackingTrack *track)
 {
-       int a = track->markersnr - 1;
-
-       if (!track->markersnr)
-               return NULL;
-
-       /* approximate pre-first framenr marker with first marker */
-       if (framenr < track->markers[0].framenr)
-               return &track->markers[0];
-
-       if (track->last_marker < track->markersnr)
-               a = track->last_marker;
-
-       if (track->markers[a].framenr <= framenr) {
-               while (a < track->markersnr && track->markers[a].framenr <= framenr) {
-                       if (track->markers[a].framenr == framenr) {
-                               track->last_marker = a;
-
-                               return &track->markers[a];
-                       }
-                       a++;
-               }
-
-               /* if there's no marker for exact position, use nearest marker from left side */
-               return &track->markers[a - 1];
-       }
-       else {
-               while (a >= 0 && track->markers[a].framenr >= framenr) {
-                       if (track->markers[a].framenr == framenr) {
-                               track->last_marker = a;
-
-                               return &track->markers[a];
-                       }
-
-                       a--;
-               }
-
-               /* if there's no marker for exact position, use nearest marker from left side */
-               return &track->markers[a];
-       }
-
-       return NULL;
+       if (track->markers)
+               MEM_freeN(track->markers);
 }
 
-MovieTrackingMarker *BKE_tracking_ensure_marker(MovieTrackingTrack *track, int framenr)
+void BKE_tracking_track_flag_set(MovieTrackingTrack *track, int area, int flag)
 {
-       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
-
-       if (marker->framenr != framenr) {
-               MovieTrackingMarker marker_new;
-
-               marker_new = *marker;
-               marker_new.framenr = framenr;
-
-               BKE_tracking_insert_marker(track, &marker_new);
-               marker = BKE_tracking_get_marker(track, framenr);
-       }
+       if (area == TRACK_AREA_NONE)
+               return;
 
-       return marker;
+       if (area & TRACK_AREA_POINT)
+               track->flag |= flag;
+       if (area & TRACK_AREA_PAT)
+               track->pat_flag |= flag;
+       if (area & TRACK_AREA_SEARCH)
+               track->search_flag |= flag;
 }
 
-MovieTrackingMarker *BKE_tracking_exact_marker(MovieTrackingTrack *track, int framenr)
+void BKE_tracking_track_flag_clear(MovieTrackingTrack *track, int area, int flag)
 {
-       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
-
-       if (marker->framenr != framenr)
-               return NULL;
+       if (area == TRACK_AREA_NONE)
+               return;
 
-       return marker;
+       if (area & TRACK_AREA_POINT)
+               track->flag &= ~flag;
+       if (area & TRACK_AREA_PAT)
+               track->pat_flag &= ~flag;
+       if (area & TRACK_AREA_SEARCH)
+               track->search_flag &= ~flag;
 }
 
-int BKE_tracking_has_marker(MovieTrackingTrack *track, int framenr)
+int BKE_tracking_track_has_marker_at_frame(MovieTrackingTrack *track, int framenr)
 {
-       return BKE_tracking_exact_marker(track, framenr) != 0;
+       return BKE_tracking_marker_get_exact(track, framenr) != 0;
 }
 
-int BKE_tracking_has_enabled_marker(MovieTrackingTrack *track, int framenr)
+int BKE_tracking_track_has_enabled_marker_at_frame(MovieTrackingTrack *track, int framenr)
 {
-       MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr);
+       MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr);
 
        return marker && (marker->flag & MARKER_DISABLED) == 0;
 }
 
-void BKE_tracking_free_track(MovieTrackingTrack *track)
-{
-       if (track->markers)
-               MEM_freeN(track->markers);
-}
-
-static void put_disabled_marker(MovieTrackingTrack *track, MovieTrackingMarker *ref_marker, int before, int overwrite)
-{
-       MovieTrackingMarker marker_new;
-
-       marker_new = *ref_marker;
-       marker_new.flag &= ~MARKER_TRACKED;
-       marker_new.flag |= MARKER_DISABLED;
-
-       if (before)
-               marker_new.framenr--;
-       else
-               marker_new.framenr++;
-
-       if (!BKE_tracking_has_marker(track, marker_new.framenr) || overwrite)
-               BKE_tracking_insert_marker(track, &marker_new);
-}
-
-void BKE_tracking_clear_path(MovieTrackingTrack *track, int ref_frame, int action)
+void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int action)
 {
        int a;
 
@@ -576,7 +593,7 @@ void BKE_tracking_clear_path(MovieTrackingTrack *track, int ref_frame, int actio
                }
 
                if (track->markersnr)
-                       put_disabled_marker(track, &track->markers[track->markersnr - 1], 0, 1);
+                       tracking_marker_insert_disabled(track, &track->markers[track->markersnr - 1], FALSE, TRUE);
        }
        else if (action == TRACK_CLEAR_UPTO) {
                a = track->markersnr - 1;
@@ -595,26 +612,26 @@ void BKE_tracking_clear_path(MovieTrackingTrack *track, int ref_frame, int actio
                }
 
                if (track->markersnr)
-                       put_disabled_marker(track, &track->markers[0], 1, 1);
+                       tracking_marker_insert_disabled(track, &track->markers[0], TRUE, TRUE);
        }
        else if (action == TRACK_CLEAR_ALL) {
                MovieTrackingMarker *marker, marker_new;
 
-               marker = BKE_tracking_get_marker(track, ref_frame);
+               marker = BKE_tracking_marker_get(track, ref_frame);
                marker_new = *marker;
 
                MEM_freeN(track->markers);
                track->markers = NULL;
                track->markersnr = 0;
 
-               BKE_tracking_insert_marker(track, &marker_new);
+               BKE_tracking_marker_insert(track, &marker_new);
 
-               put_disabled_marker(track, &marker_new, 1, 1);
-               put_disabled_marker(track, &marker_new, 0, 1);
+               tracking_marker_insert_disabled(track, &marker_new, TRUE, TRUE);
+               tracking_marker_insert_disabled(track, &marker_new, FALSE, TRUE);
        }
 }
 
-void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track)
+void BKE_tracking_tracks_join(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track)
 {
        int i = 0, a = 0, b = 0, tot;
        MovieTrackingMarker *markers;
@@ -694,9 +711,13 @@ void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack
                                        /* this values will be incremented at the end of the loop cycle */
                                        a--; b--; i--;
                                }
-                               else markers[i] = src_track->markers[a];
+                               else {
+                                       markers[i] = src_track->markers[a];
+                               }
+                       }
+                       else {
+                               markers[i] = dst_track->markers[b];
                        }
-                       else markers[i] = dst_track->markers[b];
 
                        a++;
                        b++;
@@ -715,541 +736,853 @@ void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack
        MEM_freeN(markers);
 }
 
-static void tracking_tracks_free(ListBase *tracks)
+MovieTrackingTrack *BKE_tracking_track_get_named(MovieTracking *tracking, MovieTrackingObject *object, const char *name)
 {
-       MovieTrackingTrack *track;
-
-       for (track = tracks->first; track; track = track->next) {
-               BKE_tracking_free_track(track);
-       }
+       ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
+       MovieTrackingTrack *track = tracksbase->first;
 
-       BLI_freelistN(tracks);
-}
+       while (track) {
+               if (!strcmp(track->name, name))
+                       return track;
 
-static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
-{
-       if (reconstruction->cameras)
-               MEM_freeN(reconstruction->cameras);
-}
+               track = track->next;
+       }
 
-static void tracking_object_free(MovieTrackingObject *object)
-{
-       tracking_tracks_free(&object->tracks);
-       tracking_reconstruction_free(&object->reconstruction);
+       return NULL;
 }
 
-static void tracking_objects_free(ListBase *objects)
+MovieTrackingTrack *BKE_tracking_track_get_indexed(MovieTracking *tracking, int tracknr, ListBase **tracksbase_r)
 {
        MovieTrackingObject *object;
+       int cur = 1;
 
-       for (object = objects->first; object; object = object->next)
-               tracking_object_free(object);
+       object = tracking->objects.first;
+       while (object) {
+               ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
+               MovieTrackingTrack *track = tracksbase->first;
 
-       BLI_freelistN(objects);
-}
+               while (track) {
+                       if (track->flag & TRACK_HAS_BUNDLE) {
+                               if (cur == tracknr) {
+                                       *tracksbase_r = tracksbase;
+                                       return track;
+                               }
 
-static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet)
-{
-       MovieTrackingDopesheetChannel *channel;
+                               cur++;
+                       }
 
-       channel = dopesheet->channels.first;
-       while (channel) {
-               if (channel->segments) {
-                       MEM_freeN(channel->segments);
+                       track = track->next;
                }
 
-               channel = channel->next;
+               object = object->next;
        }
 
-       BLI_freelistN(&dopesheet->channels);
+       *tracksbase_r = NULL;
 
-       dopesheet->channels.first = dopesheet->channels.last = NULL;
-       dopesheet->tot_channel = 0;
+       return NULL;
 }
 
-void BKE_tracking_free(MovieTracking *tracking)
+MovieTrackingTrack *BKE_tracking_track_get_active(MovieTracking *tracking)
 {
-       tracking_tracks_free(&tracking->tracks);
-       tracking_reconstruction_free(&tracking->reconstruction);
-       tracking_objects_free(&tracking->objects);
+       ListBase *tracksbase;
 
-       if (tracking->stabilization.scaleibuf)
-               IMB_freeImBuf(tracking->stabilization.scaleibuf);
+       if (!tracking->act_track)
+               return NULL;
 
-       if (tracking->camera.intrinsics)
-               BKE_tracking_distortion_destroy(tracking->camera.intrinsics);
+       tracksbase = BKE_tracking_get_active_tracks(tracking);
 
-       tracking_dopesheet_free(&tracking->dopesheet);
+       /* check that active track is in current tracks list */
+       if (BLI_findindex(tracksbase, tracking->act_track) >= 0)
+               return tracking->act_track;
+
+       return NULL;
 }
 
-static MovieTrackingTrack *duplicate_track(MovieTrackingTrack *track)
+static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track)
 {
-       MovieTrackingTrack *new_track;
+       bGPDlayer *layer;
 
-       new_track = MEM_callocN(sizeof(MovieTrackingTrack), "tracksMapMerge new_track");
+       if (!track->gpd)
+               return NULL;
 
-       *new_track = *track;
-       new_track->next = new_track->prev = NULL;
-
-       new_track->markers = MEM_dupallocN(new_track->markers);
-
-       return new_track;
-}
-
-/*********************** clipboard *************************/
-
-void BKE_tracking_free_clipboard(void)
-{
-       MovieTrackingTrack *track = tracking_clipboard.tracks.first, *next_track;
-
-       while (track) {
-               next_track = track->next;
-
-               BKE_tracking_free_track(track);
-               MEM_freeN(track);
-
-               track = next_track;
-       }
-}
+       layer = track->gpd->layers.first;
 
-void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object)
-{
-       ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
-       MovieTrackingTrack *track = tracksbase->first;
+       while (layer) {
+               if (layer->flag & GP_LAYER_ACTIVE) {
+                       bGPDframe *frame = layer->frames.first;
+                       int ok = FALSE;
 
-       BKE_tracking_free_clipboard();
+                       while (frame) {
+                               if (frame->strokes.first) {
+                                       ok = TRUE;
+                               }
 
-       while (track) {
-               if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) {
-                       MovieTrackingTrack *new_track = duplicate_track(track);
+                               frame = frame->next;
+                       }
 
-                       BLI_addtail(&tracking_clipboard.tracks, new_track);
+                       if (ok)
+                               return layer;
                }
 
-               track = track->next;
+               layer = layer->next;
        }
-}
 
-int BKE_tracking_clipboard_has_tracks(void)
-{
-       return tracking_clipboard.tracks.first != NULL;
+       return NULL;
 }
 
-void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingObject *object)
+static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height,
+                                                                                          MovieTrackingMarker *marker, bGPDlayer *layer,
+                                               float *mask, int mask_width, int mask_height)
 {
-       ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
-       MovieTrackingTrack *track = tracking_clipboard.tracks.first;
-
-       while (track) {
-               MovieTrackingTrack *new_track = duplicate_track(track);
+       bGPDframe *frame = layer->frames.first;
 
-               BLI_addtail(tracksbase, new_track);
-               BKE_track_unique_name(tracksbase, new_track);
+       while (frame) {
+               bGPDstroke *stroke = frame->strokes.first;
 
-               track = track->next;
-       }
-}
+               while (stroke) {
+                       bGPDspoint *stroke_points = stroke->points;
+                       float *mask_points, *fp;
+                       int i;
 
-/*********************** tracks map *************************/
+                       if (stroke->flag & GP_STROKE_2DSPACE) {
+                               fp = mask_points = MEM_callocN(2 * stroke->totpoints * sizeof(float),
+                                                              "track mask rasterization points");
 
-typedef struct TracksMap {
-       char object_name[MAX_NAME];
-       int is_camera;
+                               for (i = 0; i < stroke->totpoints; i++, fp += 2) {
+                                       fp[0] = (stroke_points[i].x - marker->search_min[0]) * frame_width / mask_width;
+                                       fp[1] = (stroke_points[i].y - marker->search_min[1]) * frame_height / mask_height;
+                               }
 
-       int num_tracks;
-       int customdata_size;
+                               PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height, FALSE /* XXX- TODO: make on/off for AA*/);
 
-       char *customdata;
-       MovieTrackingTrack *tracks;
+                               MEM_freeN(mask_points);
+                       }
 
-       GHash *hash;
+                       stroke = stroke->next;
+               }
 
-       int ptr;
-} TracksMap;
+               frame = frame->next;
+       }
+}
 
-static TracksMap *tracks_map_new(const char *object_name, int is_camera, int num_tracks, int customdata_size)
+float *BKE_tracking_track_get_mask(int frame_width, int frame_height,
+                                   MovieTrackingTrack *track, MovieTrackingMarker *marker)
 {
-       TracksMap *map = MEM_callocN(sizeof(TracksMap), "TrackingsMap");
-
-       BLI_strncpy(map->object_name, object_name, sizeof(map->object_name));
-       map->is_camera = is_camera;
-
-       map->num_tracks = num_tracks;
-       map->customdata_size = customdata_size;
+       float *mask = NULL;
+       bGPDlayer *layer = track_mask_gpencil_layer_get(track);
+       int mask_width, mask_height;
 
-       map->tracks = MEM_callocN(sizeof(MovieTrackingTrack) * num_tracks, "TrackingsMap tracks");
+       mask_width = (marker->search_max[0] - marker->search_min[0]) * frame_width;
+       mask_height = (marker->search_max[1] - marker->search_min[1]) * frame_height;
 
-       if (customdata_size)
-               map->customdata = MEM_callocN(customdata_size * num_tracks, "TracksMap customdata");
+       if (layer) {
+               mask = MEM_callocN(mask_width * mask_height * sizeof(float), "track mask");
 
-       map->hash = BLI_ghash_ptr_new("TracksMap hash");
+               track_mask_gpencil_layer_rasterize(frame_width, frame_height, marker, layer,
+                                                  mask, mask_width, mask_height);
+       }
 
-       return map;
+       return mask;
 }
 
-static int tracks_map_size(TracksMap *map)
+/* area - which part of marker should be selected. see TRACK_AREA_* constants */
+void BKE_tracking_track_select(ListBase *tracksbase, MovieTrackingTrack *track, int area, int extend)
 {
-       return map->num_tracks;
-}
+       if (extend) {
+               BKE_tracking_track_flag_set(track, area, SELECT);
+       }
+       else {
+               MovieTrackingTrack *cur = tracksbase->first;
 
-static void tracks_map_get(TracksMap *map, int index, MovieTrackingTrack **track, void **customdata)
-{
-       *track = &map->tracks[index];
+               while (cur) {
+                       if ((cur->flag & TRACK_HIDDEN) == 0) {
+                               if (cur == track) {
+                                       BKE_tracking_track_flag_clear(cur, TRACK_AREA_ALL, SELECT);
+                                       BKE_tracking_track_flag_set(cur, area, SELECT);
+                               }
+                               else {
+                                       BKE_tracking_track_flag_clear(cur, TRACK_AREA_ALL, SELECT);
+                               }
+                       }
 
-       if (map->customdata)
-               *customdata = &map->customdata[index * map->customdata_size];
+                       cur = cur->next;
+               }
+       }
 }
 
-static void tracks_map_insert(TracksMap *map, MovieTrackingTrack *track, void *customdata)
+void BKE_tracking_track_deselect(MovieTrackingTrack *track, int area)
 {
-       MovieTrackingTrack new_track = *track;
-
-       new_track.markers = MEM_dupallocN(new_track.markers);
-
-       map->tracks[map->ptr] = new_track;
+       BKE_tracking_track_flag_clear(track, area, SELECT);
+}
 
-       if (customdata)
-               memcpy(&map->customdata[map->ptr * map->customdata_size], customdata, map->customdata_size);
+/*********************** Marker  *************************/
 
-       BLI_ghash_insert(map->hash, &map->tracks[map->ptr], track);
+MovieTrackingMarker *BKE_tracking_marker_insert(MovieTrackingTrack *track, MovieTrackingMarker *marker)
+{
+       MovieTrackingMarker *old_marker = NULL;
 
-       map->ptr++;
-}
+       if (track->markersnr)
+               old_marker = BKE_tracking_marker_get_exact(track, marker->framenr);
 
-static void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
-{
-       MovieTrackingTrack *track;
-       MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
-       MovieTrackingTrack *rot_track = tracking->stabilization.rot_track;
-       ListBase tracks = {NULL, NULL}, new_tracks = {NULL, NULL};
-       ListBase *old_tracks;
-       int a;
+       if (old_marker) {
+               /* simply replace settings for already allocated marker */
+               *old_marker = *marker;
 
-       if (map->is_camera) {
-               old_tracks = &tracking->tracks;
+               return old_marker;
        }
        else {
-               MovieTrackingObject *object = BKE_tracking_named_object(tracking, map->object_name);
+               int a = track->markersnr;
 
-               if (!object) {
-                       /* object was deleted by user, create new one */
-                       object = BKE_tracking_new_object(tracking, map->object_name);
+               /* find position in array where to add new marker */
+               while (a--) {
+                       if (track->markers[a].framenr < marker->framenr)
+                               break;
                }
 
-               old_tracks = &object->tracks;
-       }
-
-       /* duplicate currently operating tracks to temporary list.
-        * this is needed to keep names in unique state and it's faster to change names
-        * of currently operating tracks (if needed)
-        */
-       for (a = 0; a < map->num_tracks; a++) {
-               int replace_sel = 0, replace_rot = 0;
-               MovieTrackingTrack *new_track, *old;
+               track->markersnr++;
 
-               track = &map->tracks[a];
+               if (track->markers)
+                       track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
+               else
+                       track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers");
 
-               /* find original of operating track in list of previously displayed tracks */
-               old = BLI_ghash_lookup(map->hash, track);
-               if (old) {
-                       MovieTrackingTrack *cur = old_tracks->first;
+               /* shift array to "free" space for new marker */
+               memmove(track->markers + a + 2, track->markers + a + 1,
+                       (track->markersnr - a - 2) * sizeof(MovieTrackingMarker));
 
-                       while (cur) {
-                               if (cur == old)
-                                       break;
+               /* put new marker */
+               track->markers[a + 1] = *marker;
 
-                               cur = cur->next;
-                       }
+               track->last_marker = a + 1;
 
-                       /* original track was found, re-use flags and remove this track */
-                       if (cur) {
-                               if (cur == act_track)
-                                       replace_sel = 1;
-                               if (cur == rot_track)
-                                       replace_rot = 1;
+               return &track->markers[a + 1];
+       }
+}
 
-                               track->flag = cur->flag;
-                               track->pat_flag = cur->pat_flag;
-                               track->search_flag = cur->search_flag;
+void BKE_tracking_marker_delete(MovieTrackingTrack *track, int framenr)
+{
+       int a = 0;
 
-                               BKE_tracking_free_track(cur);
-                               BLI_freelinkN(old_tracks, cur);
+       while (a < track->markersnr) {
+               if (track->markers[a].framenr == framenr) {
+                       if (track->markersnr > 1) {
+                               memmove(track->markers + a, track->markers + a + 1,
+                                       (track->markersnr - a - 1) * sizeof(MovieTrackingMarker));
+                               track->markersnr--;
+                               track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
+                       }
+                       else {
+                               MEM_freeN(track->markers);
+                               track->markers = NULL;
+                               track->markersnr = 0;
                        }
-               }
 
-               new_track = duplicate_track(track);
+                       break;
+               }
 
-               BLI_ghash_remove(map->hash, track, NULL, NULL); /* XXX: are we actually need this */
-               BLI_ghash_insert(map->hash, track, new_track);
+               a++;
+       }
+}
 
-               if (replace_sel)  /* update current selection in clip */
-                       tracking->act_track = new_track;
+void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event)
+{
+       int a;
+       float pat_min[2], pat_max[2];
 
-               if (replace_rot)  /* update track used for rotation stabilization */
-                       tracking->stabilization.rot_track = new_track;
+       BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
 
-               BLI_addtail(&tracks, new_track);
+       if (event == CLAMP_PAT_DIM) {
+               for (a = 0; a < 2; a++) {
+                       /* search shouldn't be resized smaller than pattern */
+                       marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]);
+                       marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]);
+               }
        }
+       else if (event == CLAMP_PAT_POS) {
+               float dim[2];
 
-       /* move all tracks, which aren't operating */
-       track = old_tracks->first;
-       while (track) {
-               MovieTrackingTrack *next = track->next;
+               sub_v2_v2v2(dim, pat_max, pat_min);
 
-               track->next = track->prev = NULL;
-               BLI_addtail(&new_tracks, track);
-
-               track = next;
+               for (a = 0; a < 2; a++) {
+                       int b;
+                       /* pattern shouldn't be moved outside of search */
+                       if (pat_min[a] < marker->search_min[a]) {
+                               for (b = 0; b < 4; b++)
+                                       marker->pattern_corners[b][a] += marker->search_min[a] - pat_min[a];
+                       }
+                       if (pat_max[a] > marker->search_max[a]) {
+                               for (b = 0; b < 4; b++)
+                                       marker->pattern_corners[b][a] -= pat_max[a] - marker->search_max[a];
+                       }
+               }
        }
+       else if (event == CLAMP_SEARCH_DIM) {
+               for (a = 0; a < 2; a++) {
+                       /* search shouldn't be resized smaller than pattern */
+                       marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]);
+                       marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]);
+               }
+       }
+       else if (event == CLAMP_SEARCH_POS) {
+               float dim[2];
 
-       /* now move all tracks which are currently operating and keep their names unique */
-       track = tracks.first;
-       while (track) {
-               MovieTrackingTrack *next = track->next;
-
-               BLI_remlink(&tracks, track);
-
-               track->next = track->prev = NULL;
-               BLI_addtail(&new_tracks, track);
-
-               BLI_uniquename(&new_tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
+               sub_v2_v2v2(dim, marker->search_max, marker->search_min);
 
-               track = next;
+               for (a = 0; a < 2; a++) {
+                       /* search shouldn't be moved inside pattern */
+                       if (marker->search_min[a] > pat_min[a]) {
+                               marker->search_min[a] = pat_min[a];
+                               marker->search_max[a] = marker->search_min[a] + dim[a];
+                       }
+                       if (marker->search_max[a] < pat_max[a]) {
+                               marker->search_max[a] = pat_max[a];
+                               marker->search_min[a] = marker->search_max[a] - dim[a];
+                       }
+               }
+       }
+       else if (event == CLAMP_SEARCH_DIM) {
+               float dim[2];
+               sub_v2_v2v2(dim, pat_max, pat_min);
+               for (a = 0; a < 2; a++) {
+                       marker->search_min[a] = pat_min[a];
+                       marker->search_max[a] = pat_max[a];
+               }
        }
-
-       *old_tracks = new_tracks;
 }
 
-static void tracks_map_free(TracksMap *map, void (*customdata_free)(void *customdata))
+MovieTrackingMarker *BKE_tracking_marker_get(MovieTrackingTrack *track, int framenr)
 {
-       int i = 0;
+       int a = track->markersnr - 1;
 
-       BLI_ghash_free(map->hash, NULL, NULL);
+       if (!track->markersnr)
+               return NULL;
 
-       for (i = 0; i < map->num_tracks; i++) {
-               if (map->customdata && customdata_free)
-                       customdata_free(&map->customdata[i * map->customdata_size]);
+       /* approximate pre-first framenr marker with first marker */
+       if (framenr < track->markers[0].framenr)
+               return &track->markers[0];
 
-               BKE_tracking_free_track(&map->tracks[i]);
-       }
+       if (track->last_marker < track->markersnr)
+               a = track->last_marker;
 
-       if (map->customdata)
-               MEM_freeN(map->customdata);
+       if (track->markers[a].framenr <= framenr) {
+               while (a < track->markersnr && track->markers[a].framenr <= framenr) {
+                       if (track->markers[a].framenr == framenr) {
+                               track->last_marker = a;
 
-       MEM_freeN(map->tracks);
-       MEM_freeN(map);
-}
+                               return &track->markers[a];
+                       }
+                       a++;
+               }
 
-/*********************** tracking *************************/
+               /* if there's no marker for exact position, use nearest marker from left side */
+               return &track->markers[a - 1];
+       }
+       else {
+               while (a >= 0 && track->markers[a].framenr >= framenr) {
+                       if (track->markers[a].framenr == framenr) {
+                               track->last_marker = a;
 
-typedef struct TrackContext {
-#ifdef WITH_LIBMV
-       /* the reference marker and cutout search area */
-       MovieTrackingMarker marker;
+                               return &track->markers[a];
+                       }
 
-       /* keyframed patch. This is the search area */
-       float *search_area;
-       int search_area_height;
-       int search_area_width;
-       int framenr;
+                       a--;
+               }
 
-       float *mask;
-#else
-       int pad;
-#endif
-} TrackContext;
+               /* if there's no marker for exact position, use nearest marker from left side */
+               return &track->markers[a];
+       }
 
-typedef struct MovieTrackingContext {
-       MovieClipUser user;
-       MovieClip *clip;
-       int clip_flag;
+       return NULL;
+}
 
-       int first_time, frames;
+MovieTrackingMarker *BKE_tracking_marker_get_exact(MovieTrackingTrack *track, int framenr)
+{
+       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
 
-       MovieTrackingSettings settings;
-       TracksMap *tracks_map;
+       if (marker->framenr != framenr)
+               return NULL;
 
-       short backwards, sequence;
-       int sync_frame;
-} MovieTrackingContext;
+       return marker;
+}
 
-MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short sequence)
+MovieTrackingMarker *BKE_tracking_marker_ensure(MovieTrackingTrack *track, int framenr)
 {
-       MovieTrackingContext *context = MEM_callocN(sizeof(MovieTrackingContext), "trackingContext");
-       MovieTracking *tracking = &clip->tracking;
-       MovieTrackingSettings *settings = &tracking->settings;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
-       MovieTrackingTrack *track;
-       MovieTrackingObject *object = BKE_tracking_active_object(tracking);
-       int num_tracks = 0;
-
-       context->settings = *settings;
-       context->backwards = backwards;
-       context->sync_frame = user->framenr;
-       context->first_time = TRUE;
-       context->sequence = sequence;
+       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
 
-       /* count */
-       track = tracksbase->first;
-       while (track) {
-               if (TRACK_SELECTED(track) && (track->flag & (TRACK_LOCKED | TRACK_HIDDEN)) == 0) {
-                       int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
-                       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
+       if (marker->framenr != framenr) {
+               MovieTrackingMarker marker_new;
 
-                       if ((marker->flag & MARKER_DISABLED) == 0)
-                               num_tracks++;
-               }
+               marker_new = *marker;
+               marker_new.framenr = framenr;
 
-               track = track->next;
+               BKE_tracking_marker_insert(track, &marker_new);
+               marker = BKE_tracking_marker_get(track, framenr);
        }
 
-       if (num_tracks) {
-               int width, height;
+       return marker;
+}
 
-               context->tracks_map = tracks_map_new(object->name, object->flag & TRACKING_OBJECT_CAMERA,
-                                                    num_tracks, sizeof(TrackContext));
+void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float min[2], float max[2])
+{
+       INIT_MINMAX2(min, max);
 
-               BKE_movieclip_get_size(clip, user, &width, &height);
+       DO_MINMAX2(marker->pattern_corners[0], min, max);
+       DO_MINMAX2(marker->pattern_corners[1], min, max);
+       DO_MINMAX2(marker->pattern_corners[2], min, max);
+       DO_MINMAX2(marker->pattern_corners[3], min, max);
+}
 
-               /* create tracking data */
-               track = tracksbase->first;
-               while (track) {
-                       if (TRACK_SELECTED(track) && (track->flag & (TRACK_HIDDEN | TRACK_LOCKED)) == 0) {
-                               int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
-                               MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
+/*********************** Object *************************/
 
-                               if ((marker->flag & MARKER_DISABLED) == 0) {
-                                       TrackContext track_context;
-                                       memset(&track_context, 0, sizeof(TrackContext));
-                                       tracks_map_insert(context->tracks_map, track, &track_context);
-                               }
-                       }
+MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char *name)
+{
+       MovieTrackingObject *object = MEM_callocN(sizeof(MovieTrackingObject), "tracking object");
 
-                       track = track->next;
-               }
+       if (tracking->tot_object == 0) {
+               /* first object is always camera */
+               BLI_strncpy(object->name, "Camera", sizeof(object->name));
+
+               object->flag |= TRACKING_OBJECT_CAMERA;
+       }
+       else {
+               BLI_strncpy(object->name, name, sizeof(object->name));
        }
 
-       context->clip = clip;
+       BLI_addtail(&tracking->objects, object);
 
-       /* store needed clip flags passing to get_buffer functions
-        * - MCLIP_USE_PROXY is needed to because timecode affects on movie clip
-        *   only in case Proxy/Timecode flag is set, so store this flag to use
-        *   timecodes properly but reset render size to SIZE_FULL so correct resolution
-        *   would be used for images
-        * - MCLIP_USE_PROXY_CUSTOM_DIR is needed because proxy/timecode files might
-        *   be stored in a different location
-        * ignore all the rest possible flags for now
-        */
-       context->clip_flag = clip->flag & MCLIP_TIMECODE_FLAGS;
+       tracking->tot_object++;
+       tracking->objectnr = BLI_countlist(&tracking->objects) - 1;
 
-       context->user = *user;
-       context->user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
-       context->user.render_flag = 0;
+       object->scale = 1.0f;
 
-       if (!sequence)
-               BLI_begin_threaded_malloc();
+       BKE_tracking_object_unique_name(tracking, object);
 
-       return context;
+       return object;
 }
 
-static void track_context_free(void *customdata)
+void BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *object)
 {
-       TrackContext *track_context = (TrackContext *)customdata;
+       MovieTrackingTrack *track;
+       int index = BLI_findindex(&tracking->objects, object);
 
-#if WITH_LIBMV
-       if (track_context->search_area)
-               MEM_freeN(track_context->search_area);
+       if (index < 0)
+               return;
 
-       if (track_context->mask)
-               MEM_freeN(track_context->mask);
+       if (object->flag & TRACKING_OBJECT_CAMERA) {
+               /* object used for camera solving can't be deleted */
+               return;
+       }
 
-#else
-       (void)track_context;
-#endif
-}
+       track = object->tracks.first;
+       while (track) {
+               if (track == tracking->act_track)
+                       tracking->act_track = NULL;
 
-void BKE_tracking_context_free(MovieTrackingContext *context)
-{
-       if (!context->sequence)
-               BLI_end_threaded_malloc();
+               track = track->next;
+       }
 
-       tracks_map_free(context->tracks_map, track_context_free);
+       tracking_object_free(object);
+       BLI_freelinkN(&tracking->objects, object);
 
-       MEM_freeN(context);
+       tracking->tot_object--;
+
+       if (index > 0)
+               tracking->objectnr = index - 1;
+       else
+               tracking->objectnr = 0;
 }
 
-/* zap channels from the imbuf that are disabled by the user. this can lead to
- * better tracks sometimes. however, instead of simply zeroing the channels
- * out, do a partial grayscale conversion so the display is better.
- */
-void BKE_tracking_disable_imbuf_channels(ImBuf *ibuf, int disable_red, int disable_green, int disable_blue,
-                                         int grayscale)
+void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object)
 {
-       int x, y;
-       float scale;
+       BLI_uniquename(&tracking->objects, object, "Object", '.',
+                      offsetof(MovieTrackingObject, name), sizeof(object->name));
+}
+
+MovieTrackingObject *BKE_tracking_object_get_named(MovieTracking *tracking, const char *name)
+{
+       MovieTrackingObject *object = tracking->objects.first;
+
+       while (object) {
+               if (!strcmp(object->name, name))
+                       return object;
+
+               object = object->next;
+       }
+
+       return NULL;
+}
+
+MovieTrackingObject *BKE_tracking_object_get_active(MovieTracking *tracking)
+{
+       return BLI_findlink(&tracking->objects, tracking->objectnr);
+}
+
+MovieTrackingObject *BKE_tracking_object_get_camera(MovieTracking *tracking)
+{
+       MovieTrackingObject *object = tracking->objects.first;
+
+       while (object) {
+               if (object->flag & TRACKING_OBJECT_CAMERA)
+                       return object;
+
+               object = object->next;
+       }
+
+       return NULL;
+}
+
+ListBase *BKE_tracking_object_get_tracks(MovieTracking *tracking, MovieTrackingObject *object)
+{
+       if (object->flag & TRACKING_OBJECT_CAMERA) {
+               return &tracking->tracks;
+       }
+
+       return &object->tracks;
+}
+
+MovieTrackingReconstruction *BKE_tracking_object_get_reconstruction(MovieTracking *tracking,
+                                                                    MovieTrackingObject *object)
+{
+       if (object->flag & TRACKING_OBJECT_CAMERA) {
+               return &tracking->reconstruction;
+       }
+
+       return &object->reconstruction;
+}
+
+/*********************** Camera *************************/
+
+static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstruction, int framenr, int nearest)
+{
+       MovieReconstructedCamera *cameras = reconstruction->cameras;
+       int a = 0, d = 1;
+
+       if (!reconstruction->camnr)
+               return -1;
+
+       if (framenr < cameras[0].framenr) {
+               if (nearest)
+                       return 0;
+               else
+                       return -1;
+       }
+
+       if (framenr > cameras[reconstruction->camnr - 1].framenr) {
+               if (nearest)
+                       return reconstruction->camnr - 1;
+               else
+                       return -1;
+       }
+
+       if (reconstruction->last_camera < reconstruction->camnr)
+               a = reconstruction->last_camera;
+
+       if (cameras[a].framenr >= framenr)
+               d = -1;
+
+       while (a >= 0 && a < reconstruction->camnr) {
+               int cfra = cameras[a].framenr;
+
+               /* check if needed framenr was "skipped" -- no data for requested frame */
+
+               if (d > 0 && cfra > framenr) {
+                       /* interpolate with previous position */
+                       if (nearest)
+                               return a - 1;
+                       else
+                               break;
+               }
+
+               if (d < 0 && cfra < framenr) {
+                       /* interpolate with next position */
+                       if (nearest)
+                               return a;
+                       else
+                               break;
+               }
+
+               if (cfra == framenr) {
+                       reconstruction->last_camera = a;
+
+                       return a;
+               }
+
+               a += d;
+       }
+
+       return -1;
+}
+
+static void reconstructed_camera_scale_set(MovieTrackingObject *object, float mat[4][4])
+{
+       if ((object->flag & TRACKING_OBJECT_CAMERA) == 0) {
+               float smat[4][4];
+
+               scale_m4_fl(smat, 1.0f / object->scale);
+               mult_m4_m4m4(mat, mat, smat);
+       }
+}
+
+
+/* converts principal offset from center to offset of blender's camera */
+void BKE_tracking_camera_shift_get(MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty)
+{
+       /* indeed in both of cases it should be winx -- it's just how camera shift works for blender's camera */
+       *shiftx = (0.5f * winx - tracking->camera.principal[0]) / winx;
+       *shifty = (0.5f * winy - tracking->camera.principal[1]) / winx;
+}
+
+void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height)
+{
+       float focal = tracking->camera.focal;
+
+       camera->sensor_x = tracking->camera.sensor_width;
+       camera->sensor_fit = CAMERA_SENSOR_FIT_AUTO;
+       camera->lens = focal * camera->sensor_x / width;
+
+       scene->r.xsch = width * tracking->camera.pixel_aspect;
+       scene->r.ysch = height;
+
+       scene->r.xasp = 1.0f;
+       scene->r.yasp = 1.0f;
+
+       BKE_tracking_camera_shift_get(tracking, width, height, &camera->shiftx, &camera->shifty);
+}
+
+MovieReconstructedCamera *BKE_tracking_camera_get_reconstructed(MovieTracking *tracking,
+                                                                MovieTrackingObject *object, int framenr)
+{
+       MovieTrackingReconstruction *reconstruction;
+       int a;
+
+       reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
+       a = reconstructed_camera_index_get(reconstruction, framenr, FALSE);
+
+       if (a == -1)
+               return NULL;
+
+       return &reconstruction->cameras[a];
+}
+
+void BKE_tracking_camera_get_reconstructed_interpolate(MovieTracking *tracking, MovieTrackingObject *object,
+                                                       int framenr, float mat[4][4])
+{
+       MovieTrackingReconstruction *reconstruction;
+       MovieReconstructedCamera *cameras;
+       int a;
+
+       reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
+       cameras = reconstruction->cameras;
+       a = reconstructed_camera_index_get(reconstruction, framenr, 1);
+
+       if (a == -1) {
+               unit_m4(mat);
 
-       if (!disable_red && !disable_green && !disable_blue && !grayscale)
                return;
+       }
 
-       /* If only some components are selected, it's important to rescale the result
-        * appropriately so that e.g. if only blue is selected, it's not zeroed out.
-        */
-       scale = (disable_red   ? 0.0f : 0.2126f) +
-               (disable_green ? 0.0f : 0.7152f) +
-               (disable_blue  ? 0.0f : 0.0722f);
+       if (cameras[a].framenr != framenr && a > 0 && a < reconstruction->camnr - 1) {
+               float t = ((float)framenr - cameras[a].framenr) / (cameras[a + 1].framenr - cameras[a].framenr);
 
-       for (y = 0; y < ibuf->y; y++) {
-               for (x = 0; x < ibuf->x; x++) {
-                       int pixel = ibuf->x * y + x;
+               blend_m4_m4m4(mat, cameras[a].mat, cameras[a + 1].mat, t);
+       }
+       else {
+               copy_m4_m4(mat, cameras[a].mat);
+       }
 
-                       if (ibuf->rect_float) {
-                               float *rrgbf = ibuf->rect_float + pixel * 4;
-                               float r = disable_red   ? 0.0f : rrgbf[0];
-                               float g = disable_green ? 0.0f : rrgbf[1];
-                               float b = disable_blue  ? 0.0f : rrgbf[2];
+       reconstructed_camera_scale_set(object, mat);
+}
 
-                               if (grayscale) {
-                                       float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
+/*********************** Distortion/Undistortion *************************/
 
-                                       rrgbf[0] = rrgbf[1] = rrgbf[2] = gray;
-                               }
-                               else {
-                                       rrgbf[0] = r;
-                                       rrgbf[1] = g;
-                                       rrgbf[2] = b;
-                               }
-                       }
-                       else {
-                               char *rrgb = (char *)ibuf->rect + pixel * 4;
-                               char r = disable_red   ? 0 : rrgb[0];
-                               char g = disable_green ? 0 : rrgb[1];
-                               char b = disable_blue  ? 0 : rrgb[2];
+MovieDistortion *BKE_tracking_distortion_new(void)
+{
+       MovieDistortion *distortion;
+
+       distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
+
+       return distortion;
+}
+
+void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking,
+                                    int calibration_width, int calibration_height)
+{
+       MovieTrackingCamera *camera = &tracking->camera;
+       float aspy = 1.0f / tracking->camera.pixel_aspect;
+
+#ifdef WITH_LIBMV
+       if (!distortion->intrinsics) {
+               distortion->intrinsics = libmv_CameraIntrinsicsNew(camera->focal,
+                                                                  camera->principal[0], camera->principal[1] * aspy,
+                                                                  camera->k1, camera->k2, camera->k3,
+                                                           calibration_width, calibration_height * aspy);
+       }
+       else {
+               libmv_CameraIntrinsicsUpdate(distortion->intrinsics, camera->focal,
+                                            camera->principal[0], camera->principal[1] * aspy,
+                                            camera->k1, camera->k2, camera->k3,
+                                     calibration_width, calibration_height * aspy);
+       }
+#else
+       (void) distortion;
+       (void) width;
+       (void) height;
+       (void) camera;
+       (void) aspy;
+#endif
+}
+
+MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
+{
+       MovieDistortion *new_distortion;
+
+       new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
+
+#ifdef WITH_LIBMV
+       new_distortion->intrinsics = libmv_CameraIntrinsicsCopy(distortion->intrinsics);
+#else
+       (void) distortion;
+#endif
+
+       return new_distortion;
+}
+
+ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *tracking, ImBuf *ibuf,
+                                    int calibration_width, int calibration_height, float overscan, int undistort)
+{
+       ImBuf *resibuf;
+
+       BKE_tracking_distortion_update(distortion, tracking, calibration_width, calibration_height);
+
+       resibuf = IMB_dupImBuf(ibuf);
+
+#ifdef WITH_LIBMV
+       if (ibuf->rect_float) {
+               if (undistort) {
+                       libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics,
+                                                            ibuf->rect_float, resibuf->rect_float,
+                                                            ibuf->x, ibuf->y, overscan, ibuf->channels);
+               }
+               else {
+                       libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics,
+                                                          ibuf->rect_float, resibuf->rect_float,
+                                                          ibuf->x, ibuf->y, overscan, ibuf->channels);
+               }
+
+               resibuf->userflags |= IB_RECT_INVALID;
+       }
+       else {
+               if (undistort) {
+                       libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics,
+                                                           (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
+                                                           ibuf->x, ibuf->y, overscan, ibuf->channels);
+               }
+               else {
+                       libmv_CameraIntrinsicsDistortByte(distortion->intrinsics,
+                                                         (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
+                                                         ibuf->x, ibuf->y, overscan, ibuf->channels);
+               }
+       }
+#else
+       (void) overscan;
+       (void) undistort;
+
+       if (ibuf->rect_float) {
+               resibuf->userflags |= IB_RECT_INVALID;
+       }
+#endif
+
+       return resibuf;
+}
+
+void BKE_tracking_distortion_free(MovieDistortion *distortion)
+{
+#ifdef WITH_LIBMV
+       libmv_CameraIntrinsicsDestroy(distortion->intrinsics);
+#endif
+
+       MEM_freeN(distortion);
+}
+
+void BKE_tracking_distort_v2(MovieTracking *tracking, float co[2], float nco[2])
+{
+       MovieTrackingCamera *camera = &tracking->camera;
+
+#ifdef WITH_LIBMV
+       double x, y;
+       float aspy = 1.0f / tracking->camera.pixel_aspect;
+
+       /* normalize coords */
+       x = (co[0] - camera->principal[0]) / camera->focal;
+       y = (co[1] - camera->principal[1] * aspy) / camera->focal;
+
+       libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
+                                   camera->k1, camera->k2, camera->k3, x, y, &x, &y);
+
+       /* result is in image coords already */
+       nco[0] = x;
+       nco[1] = y;
+#else
+       (void) camera;
+       (void) co;
+       (void) nco;
+#endif
+}
+
+void BKE_tracking_undistort_v2(MovieTracking *tracking, float co[2], float nco[2])
+{
+       MovieTrackingCamera *camera = &tracking->camera;
+
+#ifdef WITH_LIBMV
+       double x = co[0], y = co[1];
+       float aspy = 1.0f / tracking->camera.pixel_aspect;
+
+       libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
+                              camera->k1, camera->k2, camera->k3, x, y, &x, &y);
+
+       nco[0] = x * camera->focal + camera->principal[0];
+       nco[1] = y * camera->focal + camera->principal[1] * aspy;
+#else
+       (void) camera;
+       (void) co;
+       (void) nco;
+#endif
+}
 
-                               if (grayscale) {
-                                       float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
+ImBuf *BKE_tracking_undistort_frame(MovieTracking *tracking, ImBuf *ibuf, int calibration_width,
+                                    int calibration_height, float overscan)
+{
+       MovieTrackingCamera *camera = &tracking->camera;
 
-                                       rrgb[0] = rrgb[1] = rrgb[2] = gray;
-                               }
-                               else {
-                                       rrgb[0] = r;
-                                       rrgb[1] = g;
-                                       rrgb[2] = b;
-                               }
-                       }
-               }
-       }
+       if (camera->intrinsics == NULL)
+               camera->intrinsics = BKE_tracking_distortion_new();
 
-       if (ibuf->rect_float)
-               ibuf->userflags |= IB_RECT_INVALID;
+       return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, calibration_width,
+                                        calibration_height, overscan, TRUE);
+}
+
+ImBuf *BKE_tracking_distort_frame(MovieTracking *tracking, ImBuf *ibuf, int calibration_width,
+                                  int calibration_height, float overscan)
+{
+       MovieTrackingCamera *camera = &tracking->camera;
+
+       if (camera->intrinsics == NULL)
+               camera->intrinsics = BKE_tracking_distortion_new();
+
+       return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, calibration_width,
+                                        calibration_height, overscan, FALSE);
 }
 
+/*********************** Image sampling *************************/
+
 static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale)
 {
-       BKE_tracking_disable_imbuf_channels(ibuf, track->flag & TRACK_DISABLE_RED,
-                                           track->flag & TRACK_DISABLE_GREEN, track->flag & TRACK_DISABLE_BLUE, grayscale);
+       BKE_tracking_disable_channels(ibuf, track->flag & TRACK_DISABLE_RED,
+                                           track->flag & TRACK_DISABLE_GREEN,
+                                        track->flag & TRACK_DISABLE_BLUE, grayscale);
 }
 
-ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, ImBuf *search_ibuf,
+ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *search_ibuf,
                                          MovieTrackingTrack *track, MovieTrackingMarker *marker,
                                          int use_mask, int num_samples_x, int num_samples_y,
                                          float pos[2])
@@ -1270,7 +1603,7 @@ ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, ImBu
        get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y);
 
        if (use_mask) {
-               mask = BKE_tracking_track_mask_get(frame_width, frame_height, track, marker);
+               mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
        }
 
        libmv_samplePlanarPatch(search_ibuf->rect_float, search_ibuf->x, search_ibuf->y, 4,
@@ -1327,7 +1660,7 @@ ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mo
 
        search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels);
 
-       pattern_ibuf = BKE_tracking_sample_pattern_imbuf(ibuf->x, ibuf->y, search_ibuf, track, marker,
+       pattern_ibuf = BKE_tracking_sample_pattern(ibuf->x, ibuf->y, search_ibuf, track, marker,
                                                         FALSE, num_samples_x, num_samples_y, NULL);
 
        IMB_freeImBuf(search_ibuf);
@@ -1373,1272 +1706,1256 @@ ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mov
        return searchibuf;
 }
 
-static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track)
+/* zap channels from the imbuf that are disabled by the user. this can lead to
+ * better tracks sometimes. however, instead of simply zeroing the channels
+ * out, do a partial grayscale conversion so the display is better.
+ */
+void BKE_tracking_disable_channels(ImBuf *ibuf, int disable_red, int disable_green, int disable_blue,
+                                         int grayscale)
 {
-       bGPDlayer *layer;
+       int x, y;
+       float scale;
 
-       if (!track->gpd)
-               return NULL;
+       if (!disable_red && !disable_green && !disable_blue && !grayscale)
+               return;
 
-       layer = track->gpd->layers.first;
+       /* if only some components are selected, it's important to rescale the result
+        * appropriately so that e.g. if only blue is selected, it's not zeroed out.
+        */
+       scale = (disable_red   ? 0.0f : 0.2126f) +
+               (disable_green ? 0.0f : 0.7152f) +
+               (disable_blue  ? 0.0f : 0.0722f);
 
-       while (layer) {
-               if (layer->flag & GP_LAYER_ACTIVE) {
-                       bGPDframe *frame = layer->frames.first;
-                       int ok = FALSE;
+       for (y = 0; y < ibuf->y; y++) {
+               for (x = 0; x < ibuf->x; x++) {
+                       int pixel = ibuf->x * y + x;
 
-                       while (frame) {
-                               if (frame->strokes.first) {
-                                       ok = TRUE;
-                               }
+                       if (ibuf->rect_float) {
+                               float *rrgbf = ibuf->rect_float + pixel * 4;
+                               float r = disable_red   ? 0.0f : rrgbf[0];
+                               float g = disable_green ? 0.0f : rrgbf[1];
+                               float b = disable_blue  ? 0.0f : rrgbf[2];
 
-                               frame = frame->next;
+                               if (grayscale) {
+                                       float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
+
+                                       rrgbf[0] = rrgbf[1] = rrgbf[2] = gray;
+                               }
+                               else {
+                                       rrgbf[0] = r;
+                                       rrgbf[1] = g;
+                                       rrgbf[2] = b;
+                               }
                        }
+                       else {
+                               char *rrgb = (char *)ibuf->rect + pixel * 4;
+                               char r = disable_red   ? 0 : rrgb[0];
+                               char g = disable_green ? 0 : rrgb[1];
+                               char b = disable_blue  ? 0 : rrgb[2];
 
-                       if (ok)
-                               return layer;
-               }
+                               if (grayscale) {
+                                       float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
 
-               layer = layer->next;
+                                       rrgb[0] = rrgb[1] = rrgb[2] = gray;
+                               }
+                               else {
+                                       rrgb[0] = r;
+                                       rrgb[1] = g;
+                                       rrgb[2] = b;
+                               }
+                       }
+               }
        }
 
-       return NULL;
+       if (ibuf->rect_float)
+               ibuf->userflags |= IB_RECT_INVALID;
 }
 
-static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height,
-                                                                                          MovieTrackingMarker *marker, bGPDlayer *layer,
-                                               float *mask, int mask_width, int mask_height)
-{
-       bGPDframe *frame = layer->frames.first;
-
-       while (frame) {
-               bGPDstroke *stroke = frame->strokes.first;
+/*********************** Tracks map *************************/
 
-               while (stroke) {
-                       bGPDspoint *stroke_points = stroke->points;
-                       float *mask_points, *fp;
-                       int i;
+typedef struct TracksMap {
+       char object_name[MAX_NAME];
+       int is_camera;
 
-                       if (stroke->flag & GP_STROKE_2DSPACE) {
-                               fp = mask_points = MEM_callocN(2 * stroke->totpoints * sizeof(float),
-                                                              "track mask rasterization points");
+       int num_tracks;
+       int customdata_size;
 
-                               for (i = 0; i < stroke->totpoints; i++, fp += 2) {
-                                       fp[0] = (stroke_points[i].x - marker->search_min[0]) * frame_width / mask_width;
-                                       fp[1] = (stroke_points[i].y - marker->search_min[1]) * frame_height / mask_height;
-                               }
+       char *customdata;
+       MovieTrackingTrack *tracks;
 
-                               PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height, FALSE /* XXX- TODO: make on/off for AA*/);
+       GHash *hash;
 
-                               MEM_freeN(mask_points);
-                       }
+       int ptr;
+} TracksMap;
 
-                       stroke = stroke->next;
-               }
+static TracksMap *tracks_map_new(const char *object_name, int is_camera, int num_tracks, int customdata_size)
+{
+       TracksMap *map = MEM_callocN(sizeof(TracksMap), "TrackingsMap");
 
-               frame = frame->next;
-       }
-}
+       BLI_strncpy(map->object_name, object_name, sizeof(map->object_name));
+       map->is_camera = is_camera;
 
-float *BKE_tracking_track_mask_get(int frame_width, int frame_height,
-                                   MovieTrackingTrack *track, MovieTrackingMarker *marker)
-{
-       float *mask = NULL;
-       bGPDlayer *layer = track_mask_gpencil_layer_get(track);
-       int mask_width, mask_height;
+       map->num_tracks = num_tracks;
+       map->customdata_size = customdata_size;
 
-       mask_width = (marker->search_max[0] - marker->search_min[0]) * frame_width;
-       mask_height = (marker->search_max[1] - marker->search_min[1]) * frame_height;
+       map->tracks = MEM_callocN(sizeof(MovieTrackingTrack) * num_tracks, "TrackingsMap tracks");
 
-       if (layer) {
-               mask = MEM_callocN(mask_width * mask_height * sizeof(float), "track mask");
+       if (customdata_size)
+               map->customdata = MEM_callocN(customdata_size * num_tracks, "TracksMap customdata");
 
-               track_mask_gpencil_layer_rasterize(frame_width, frame_height, marker, layer,
-                                                  mask, mask_width, mask_height);
-       }
+       map->hash = BLI_ghash_ptr_new("TracksMap hash");
 
-       return mask;
+       return map;
 }
 
-#ifdef WITH_LIBMV
-
-/* Convert from float and byte RGBA to grayscale. Supports different coefficients for RGB. */
-static void float_rgba_to_gray(const float *rgba, float *gray, int num_pixels,
-                               float weight_red, float weight_green, float weight_blue)
+static int tracks_map_get_size(TracksMap *map)
 {
-       int i;
-
-       for (i = 0; i < num_pixels; i++) {
-               const float *pixel = rgba + 4 * i;
-
-               gray[i] = weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2];
-       }
+       return map->num_tracks;
 }
 
-static void uint8_rgba_to_float_gray(const unsigned char *rgba, float *gray, int num_pixels,
-                                     float weight_red, float weight_green, float weight_blue)
+static void tracks_map_get_indexed_element(TracksMap *map, int index, MovieTrackingTrack **track, void **customdata)
 {
-       int i;
-
-       for (i = 0; i < num_pixels; i++) {
-               const unsigned char *pixel = rgba + i * 4;
+       *track = &map->tracks[index];
 
-               *gray++ = (weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]) / 255.0f;
-       }
+       if (map->customdata)
+               *customdata = &map->customdata[index * map->customdata_size];
 }
 
-static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
-                                  int *width_r, int *height_r)
+static void tracks_map_insert(TracksMap *map, MovieTrackingTrack *track, void *customdata)
 {
-       ImBuf *searchibuf;
-       float *gray_pixels;
-       int width, height;
+       MovieTrackingTrack new_track = *track;
 
-       searchibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, FALSE, TRUE);
+       new_track.markers = MEM_dupallocN(new_track.markers);
 
-       width = searchibuf->x;
-       height = searchibuf->y;
+       map->tracks[map->ptr] = new_track;
 
-       *width_r = searchibuf->x;
-       *height_r = searchibuf->y;
+       if (customdata)
+               memcpy(&map->customdata[map->ptr * map->customdata_size], customdata, map->customdata_size);
 
-       gray_pixels = MEM_callocN(width * height * sizeof(float), "tracking floatBuf");
+       BLI_ghash_insert(map->hash, &map->tracks[map->ptr], track);
 
-       if (searchibuf->rect_float) {
-               float_rgba_to_gray(searchibuf->rect_float, gray_pixels, width * height,
-                                  0.2126f, 0.7152f, 0.0722f);
+       map->ptr++;
+}
+
+static void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
+{
+       MovieTrackingTrack *track;
+       MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
+       MovieTrackingTrack *rot_track = tracking->stabilization.rot_track;
+       ListBase tracks = {NULL, NULL}, new_tracks = {NULL, NULL};
+       ListBase *old_tracks;
+       int a;
+
+       if (map->is_camera) {
+               old_tracks = &tracking->tracks;
        }
        else {
-               uint8_rgba_to_float_gray((unsigned char *)searchibuf->rect, gray_pixels, width * height,
-                                        0.2126f, 0.7152f, 0.0722f);
-       }
+               MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, map->object_name);
 
-       IMB_freeImBuf(searchibuf);
+               if (!object) {
+                       /* object was deleted by user, create new one */
+                       object = BKE_tracking_object_add(tracking, map->object_name);
+               }
 
-       return gray_pixels;
-}
+               old_tracks = &object->tracks;
+       }
 
-static unsigned char *get_ucharbuf(ImBuf *ibuf)
-{
-       int x, y;
-       unsigned char *pixels, *cp;
+       /* duplicate currently operating tracks to temporary list.
+        * this is needed to keep names in unique state and it's faster to change names
+        * of currently operating tracks (if needed)
+        */
+       for (a = 0; a < map->num_tracks; a++) {
+               int replace_sel = 0, replace_rot = 0;
+               MovieTrackingTrack *new_track, *old;
 
-       cp = pixels = MEM_callocN(ibuf->x * ibuf->y * sizeof(unsigned char), "tracking ucharBuf");
-       for (y = 0; y < ibuf->y; y++) {
-               for (x = 0; x < ibuf->x; x++) {
-                       int pixel = ibuf->x * y + x;
+               track = &map->tracks[a];
 
-                       if (ibuf->rect_float) {
-                               const float *rrgbf = ibuf->rect_float + pixel * 4;
-                               const float grey_f = 0.2126f * rrgbf[0] + 0.7152f * rrgbf[1] + 0.0722f * rrgbf[2];
+               /* find original of operating track in list of previously displayed tracks */
+               old = BLI_ghash_lookup(map->hash, track);
+               if (old) {
+                       MovieTrackingTrack *cur = old_tracks->first;
 
-                               *cp = FTOCHAR(grey_f);
+                       while (cur) {
+                               if (cur == old)
+                                       break;
+
+                               cur = cur->next;
                        }
-                       else {
-                               const unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4;
 
-                               *cp = 0.2126f * rrgb[0] + 0.7152f * rrgb[1] + 0.0722f * rrgb[2];
-                       }
+                       /* original track was found, re-use flags and remove this track */
+                       if (cur) {
+                               if (cur == act_track)
+                                       replace_sel = 1;
+                               if (cur == rot_track)
+                                       replace_rot = 1;
+
+                               track->flag = cur->flag;
+                               track->pat_flag = cur->pat_flag;
+                               track->search_flag = cur->search_flag;
 
-                       cp++;
+                               BKE_tracking_track_free(cur);
+                               BLI_freelinkN(old_tracks, cur);
+                       }
                }
-       }
-
-       return pixels;
-}
 
-static ImBuf *get_frame_ibuf(MovieTrackingContext *context, int framenr)
-{
-       ImBuf *ibuf;
-       MovieClipUser user = context->user;
+               new_track = tracking_track_duplicate(track);
 
-       user.framenr = BKE_movieclip_remap_clip_to_scene_frame(context->clip, framenr);
+               BLI_ghash_remove(map->hash, track, NULL, NULL); /* XXX: are we actually need this */
+               BLI_ghash_insert(map->hash, track, new_track);
 
-       ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &user, context->clip_flag, MOVIECLIP_CACHE_SKIP);
+               if (replace_sel)  /* update current selection in clip */
+                       tracking->act_track = new_track;
 
-       return ibuf;
-}
+               if (replace_rot)  /* update track used for rotation stabilization */
+                       tracking->stabilization.rot_track = new_track;
 
-static ImBuf *get_keyframed_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track,
-                                 MovieTrackingMarker *marker, MovieTrackingMarker **marker_keyed)
-{
-       int framenr = marker->framenr;
-       int a = marker - track->markers;
+               BLI_addtail(&tracks, new_track);
+       }
 
-       *marker_keyed = marker;
+       /* move all tracks, which aren't operating */
+       track = old_tracks->first;
+       while (track) {
+               MovieTrackingTrack *next = track->next;
 
-       while (a >= 0 && a < track->markersnr) {
-               int next = (context->backwards) ? a + 1 : a - 1;
-               int is_keyframed = FALSE;
-               MovieTrackingMarker *cur_marker = &track->markers[a];
-               MovieTrackingMarker *next_marker = NULL;
+               track->next = track->prev = NULL;
+               BLI_addtail(&new_tracks, track);
 
-               if (next >= 0 && next < track->markersnr)
-                       next_marker = &track->markers[next];
+               track = next;
+       }
 
-               /* if next mrker is disabled, stop searching keyframe and use current frame as keyframe */
-               if (next_marker && next_marker->flag & MARKER_DISABLED)
-                       is_keyframed = TRUE;
+       /* now move all tracks which are currently operating and keep their names unique */
+       track = tracks.first;
+       while (track) {
+               MovieTrackingTrack *next = track->next;
 
-               is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0;
+               BLI_remlink(&tracks, track);
 
-               if (is_keyframed) {
-                       framenr = cur_marker->framenr;
-                       *marker_keyed = cur_marker;
+               track->next = track->prev = NULL;
+               BLI_addtail(&new_tracks, track);
 
-                       break;
-               }
+               BLI_uniquename(&new_tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
 
-               a = next;
+               track = next;
        }
 
-       return get_frame_ibuf(context, framenr);
+       *old_tracks = new_tracks;
 }
 
-static ImBuf *get_adjust_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track, MovieTrackingMarker *marker,
-                              int curfra, MovieTrackingMarker **marker_keyed)
+static void tracks_map_free(TracksMap *map, void (*customdata_free)(void *customdata))
 {
-       ImBuf *ibuf = NULL;
+       int i = 0;
 
-       if (track->pattern_match == TRACK_MATCH_KEYFRAME) {
-               ibuf = get_keyframed_ibuf(context, track, marker, marker_keyed);
-       }
-       else {
-               ibuf = get_frame_ibuf(context, curfra);
+       BLI_ghash_free(map->hash, NULL, NULL);
 
-               /* use current marker as keyframed position */
-               *marker_keyed = marker;
-       }
+       for (i = 0; i < map->num_tracks; i++) {
+               if (map->customdata && customdata_free)
+                       customdata_free(&map->customdata[i * map->customdata_size]);
 
-       return ibuf;
-}
+               BKE_tracking_track_free(&map->tracks[i]);
+       }
 
-static void marker_search_scale_after_tracking(const MovieTrackingMarker *old_marker, MovieTrackingMarker *new_marker)
-{
-       float old_pat_min[2], old_pat_max[2];
-       float new_pat_min[2], new_pat_max[2];
-       float scale_x, scale_y;
+       if (map->customdata)
+               MEM_freeN(map->customdata);
 
-       BKE_tracking_marker_pattern_minmax(old_marker, old_pat_min, old_pat_max);
-       BKE_tracking_marker_pattern_minmax(new_marker, new_pat_min, new_pat_max);
+       MEM_freeN(map->tracks);
+       MEM_freeN(map);
+}
 
-       scale_x = (new_pat_max[0] - new_pat_min[0]) / (old_pat_max[0] - old_pat_min[0]);
-       scale_y = (new_pat_max[1] - new_pat_min[1]) / (old_pat_max[1] - old_pat_min[1]);
+/*********************** 2D tracking *************************/
 
-       new_marker->search_min[0] *= scale_x;
-       new_marker->search_min[1] *= scale_y;
+typedef struct TrackContext {
+#ifdef WITH_LIBMV
+       /* the reference marker and cutout search area */
+       MovieTrackingMarker marker;
 
-       new_marker->search_max[0] *= scale_x;
-       new_marker->search_max[1] *= scale_y;
-}
+       /* keyframed patch. This is the search area */
+       float *search_area;
+       int search_area_height;
+       int search_area_width;
+       int framenr;
 
+       float *mask;
+#else
+       int pad;
 #endif
+} TrackContext;
 
-void BKE_tracking_sync(MovieTrackingContext *context)
-{
-       MovieTracking *tracking = &context->clip->tracking;
-       int newframe;
-
-       tracks_map_merge(context->tracks_map, tracking);
-
-       if (context->backwards)
-               newframe = context->user.framenr + 1;
-       else
-               newframe = context->user.framenr - 1;
+typedef struct MovieTrackingContext {
+       MovieClipUser user;
+       MovieClip *clip;
+       int clip_flag;
 
-       context->sync_frame = newframe;
+       int first_time, frames;
 
-       tracking->dopesheet.ok = FALSE;
-}
+       MovieTrackingSettings settings;
+       TracksMap *tracks_map;
 
-void BKE_tracking_sync_user(MovieClipUser *user, MovieTrackingContext *context)
-{
-       user->framenr = context->sync_frame;
-}
+       short backwards, sequence;
+       int sync_frame;
+} MovieTrackingContext;
 
-int BKE_tracking_next(MovieTrackingContext *context)
+static void track_context_free(void *customdata)
 {
-       ImBuf *destination_ibuf;
-       int curfra =  BKE_movieclip_remap_scene_to_clip_frame(context->clip, context->user.framenr);
-       int a, ok = FALSE, map_size;
-
-       int frame_width, frame_height;
-
-       map_size = tracks_map_size(context->tracks_map);
+       TrackContext *track_context = (TrackContext *)customdata;
 
-       /* nothing to track, avoid unneeded frames reading to save time and memory */
-       if (!map_size)
-               return FALSE;
+#if WITH_LIBMV
+       if (track_context->search_area)
+               MEM_freeN(track_context->search_area);
 
-       if (context->backwards)
-               context->user.framenr--;
-       else
-               context->user.framenr++;
+       if (track_context->mask)
+               MEM_freeN(track_context->mask);
 
-       destination_ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &context->user,
-                                                      context->clip_flag, MOVIECLIP_CACHE_SKIP);
-       if (!destination_ibuf)
-               return FALSE;
+#else
+       (void)track_context;
+#endif
+}
 
-       frame_width = destination_ibuf->x;
-       frame_height = destination_ibuf->y;
+MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short sequence)
+{
+       MovieTrackingContext *context = MEM_callocN(sizeof(MovieTrackingContext), "trackingContext");
+       MovieTracking *tracking = &clip->tracking;
+       MovieTrackingSettings *settings = &tracking->settings;
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+       MovieTrackingTrack *track;
+       MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
+       int num_tracks = 0;
 
-       //#pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size>1)
-       for (a = 0; a < map_size; a++) {
-               TrackContext *track_context = NULL;
-               MovieTrackingTrack *track;
-               MovieTrackingMarker *marker;
+       context->clip = clip;
+       context->settings = *settings;
+       context->backwards = backwards;
+       context->sync_frame = user->framenr;
+       context->first_time = TRUE;
+       context->sequence = sequence;
 
-               tracks_map_get(context->tracks_map, a, &track, (void **)&track_context);
+       /* count */
+       track = tracksbase->first;
+       while (track) {
+               if (TRACK_SELECTED(track) && (track->flag & (TRACK_LOCKED | TRACK_HIDDEN)) == 0) {
+                       int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
+                       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
 
-               marker = BKE_tracking_exact_marker(track, curfra);
+                       if ((marker->flag & MARKER_DISABLED) == 0)
+                               num_tracks++;
+               }
 
-               if (marker && (marker->flag & MARKER_DISABLED) == 0) {
-#ifdef WITH_LIBMV
-                       int width, height, tracked = 0, need_readjust = 0;
-                       float margin[2], dim[2], pat_min[2], pat_max[2];
-                       MovieTrackingMarker marker_new, *marker_keyed;
-                       int onbound = FALSE, nextfra;
-                       double dst_pixel_x[5], dst_pixel_y[5];
+               track = track->next;
+       }
 
-                       if (track->pattern_match == TRACK_MATCH_KEYFRAME)
-                               need_readjust = context->first_time;
-                       else
-                               need_readjust = TRUE;
+       /* create tracking contextx for all tracks which would be tracked */
+       if (num_tracks) {
+               int width, height;
 
-                       if (context->backwards)
-                               nextfra = curfra - 1;
-                       else
-                               nextfra = curfra + 1;
+               context->tracks_map = tracks_map_new(object->name, object->flag & TRACKING_OBJECT_CAMERA,
+                                                    num_tracks, sizeof(TrackContext));
 
-                       /* margin from frame boundaries */
-                       BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
-                       sub_v2_v2v2(dim, pat_max, pat_min);
-                       margin[0] = margin[1] = MAX2(dim[0], dim[1]) / 2.0f;
+               BKE_movieclip_get_size(clip, user, &width, &height);
 
-                       margin[0] = MAX2(margin[0], (float)track->margin / destination_ibuf->x);
-                       margin[1] = MAX2(margin[1], (float)track->margin / destination_ibuf->y);
+               /* create tracking data */
+               track = tracksbase->first;
+               while (track) {
+                       if (TRACK_SELECTED(track) && (track->flag & (TRACK_HIDDEN | TRACK_LOCKED)) == 0) {
+                               int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
+                               MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
 
-                       /* do not track markers which are too close to boundary */
-                       if (marker->pos[0] < margin[0] || marker->pos[0] > 1.0f - margin[0] ||
-                           marker->pos[1] < margin[1] || marker->pos[1] > 1.0f - margin[1])
-                       {
-                               onbound = TRUE;
+                               if ((marker->flag & MARKER_DISABLED) == 0) {
+                                       TrackContext track_context;
+                                       memset(&track_context, 0, sizeof(TrackContext));
+                                       tracks_map_insert(context->tracks_map, track, &track_context);
+                               }
                        }
-                       else {
-                               /* to convert to the x/y split array format for libmv. */
-                               double src_pixel_x[5];
-                               double src_pixel_y[5];
 
-                               /* settings for the tracker */
-                               struct libmv_trackRegionOptions options = {0};
-                               struct libmv_trackRegionResult result;
+                       track = track->next;
+               }
+       }
 
-                               float *patch_new;
+       /* store needed clip flags passing to get_buffer functions
+        * - MCLIP_USE_PROXY is needed to because timecode affects on movie clip
+        *   only in case Proxy/Timecode flag is set, so store this flag to use
+        *   timecodes properly but reset render size to SIZE_FULL so correct resolution
+        *   would be used for images
+        * - MCLIP_USE_PROXY_CUSTOM_DIR is needed because proxy/timecode files might
+        *   be stored in a different location
+        * ignore all the rest possible flags for now
+        */
+       context->clip_flag = clip->flag & MCLIP_TIMECODE_FLAGS;
 
-                               if (need_readjust) {
-                                       ImBuf *reference_ibuf = NULL;
-                                       /* calculate patch for keyframed position */
-                                       reference_ibuf = get_adjust_ibuf(context, track, marker, curfra, &marker_keyed);
-                                       track_context->marker = *marker_keyed;
+       context->user = *user;
+       context->user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
+       context->user.render_flag = 0;
 
-                                       if (track_context->search_area)
-                                               MEM_freeN(track_context->search_area);
+       if (!sequence)
+               BLI_begin_threaded_malloc();
 
-                                       track_context->search_area = get_search_floatbuf(reference_ibuf, track,
-                                                                                        marker_keyed, &width, &height);
-                                       track_context->search_area_height = height;
-                                       track_context->search_area_width = width;
+       return context;
+}
 
-                                       IMB_freeImBuf(reference_ibuf);
+void BKE_tracking_context_free(MovieTrackingContext *context)
+{
+       if (!context->sequence)
+               BLI_end_threaded_malloc();
 
-                                       if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) {
-                                               if (track_context->mask)
-                                                       MEM_freeN(track_context->mask);
+       tracks_map_free(context->tracks_map, track_context_free);
 
-                                               track_context->mask = BKE_tracking_track_mask_get(frame_width, frame_height,
-                                                                                                 track, marker);
-                                       }
-                               }
+       MEM_freeN(context);
+}
 
-                               /* for now track to the same search area dimension as marker has got for current frame
-                                * will make all tracked markers in currently tracked segment have the same search area
-                                * size, but it's quite close to what is actually needed
-                                */
-                               patch_new = get_search_floatbuf(destination_ibuf, track, marker, &width, &height);
+void BKE_tracking_context_sync(MovieTrackingContext *context)
+{
+       MovieTracking *tracking = &context->clip->tracking;
+       int newframe;
 
-                               /* Configure the tracker */
-                               options.motion_model = track->motion_model;
+       tracks_map_merge(context->tracks_map, tracking);
 
-                               options.use_brute =
-                                   ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_BRUTE) != 0);
+       if (context->backwards)
+               newframe = context->user.framenr + 1;
+       else
+               newframe = context->user.framenr - 1;
 
-                               options.use_normalization =
-                                   ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_NORMALIZATION) != 0);
+       context->sync_frame = newframe;
 
-                               options.num_iterations = 50;
-                               options.minimum_correlation = track->minimum_correlation;
-                               options.sigma = 0.9;
+       tracking->dopesheet.ok = FALSE;
+}
 
-                               if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0)
-                                       options.image1_mask = track_context->mask;
+void BKE_tracking_context_sync_user(const MovieTrackingContext *context, MovieClipUser *user)
+{
+       user->framenr = context->sync_frame;
+}
 
-                               /* Convert the marker corners and center into pixel coordinates in the search/destination images. */
-                               get_marker_coords_for_tracking(frame_width, frame_height, &track_context->marker, src_pixel_x, src_pixel_y);
-                               get_marker_coords_for_tracking(frame_width, frame_height, marker, dst_pixel_x, dst_pixel_y);
+#ifdef WITH_LIBMV
+/* **** utility functions for tracking **** */
 
-                               /* Run the tracker! */
-                               tracked = libmv_trackRegion(&options,
-                                                           track_context->search_area,
-                                                                                       track_context->search_area_width,
-                                                                                       track_context->search_area_height,
-                                                                                       patch_new, width, height,
-                                                           src_pixel_x, src_pixel_y,
-                                                           &result,
-                                                           dst_pixel_x, dst_pixel_y);
-                               MEM_freeN(patch_new);
-                       }
+/* convert from float and byte RGBA to grayscale. Supports different coefficients for RGB. */
+static void float_rgba_to_gray(const float *rgba, float *gray, int num_pixels,
+                               float weight_red, float weight_green, float weight_blue)
+{
+       int i;
+
+       for (i = 0; i < num_pixels; i++) {
+               const float *pixel = rgba + 4 * i;
 
-                       if (tracked && !onbound) {
-                               memset(&marker_new, 0, sizeof(marker_new));
-                               marker_new = *marker;
-                               set_marker_coords_from_tracking(frame_width, frame_height, &marker_new, dst_pixel_x, dst_pixel_y);
-                               marker_new.flag |= MARKER_TRACKED;
-                               marker_new.framenr = nextfra;
+               gray[i] = weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2];
+       }
+}
 
-                               marker_search_scale_after_tracking(marker, &marker_new);
+static void uint8_rgba_to_float_gray(const unsigned char *rgba, float *gray, int num_pixels,
+                                     float weight_red, float weight_green, float weight_blue)
+{
+       int i;
 
-                               //#pragma omp critical
-                               {
-                                       if (context->first_time) {
-                                               /* check if there's no keyframe/tracked markers before tracking marker.
-                                                * if so -- create disabled marker before currently tracking "segment"
-                                                */
+       for (i = 0; i < num_pixels; i++) {
+               const unsigned char *pixel = rgba + i * 4;
 
-                                               put_disabled_marker(track, &marker_new, !context->backwards, 0);
-                                       }
+               gray[i] = (weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]) / 255.0f;
+       }
+}
 
-                                       /* insert currently tracked marker */
-                                       BKE_tracking_insert_marker(track, &marker_new);
+static float *track_get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
+                                        int *width_r, int *height_r)
+{
+       ImBuf *searchibuf;
+       float *gray_pixels;
+       int width, height;
 
-                                       /* make currently tracked segment be finished with disabled marker */
-                                       put_disabled_marker(track, &marker_new, context->backwards, 0);
-                               }
-                       }
-                       else {
-                               marker_new = *marker;
+       searchibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, FALSE, TRUE);
 
-                               marker_new.framenr = nextfra;
-                               marker_new.flag |= MARKER_DISABLED;
+       width = searchibuf->x;
+       height = searchibuf->y;
 
-                               //#pragma omp critical
-                               {
-                                       BKE_tracking_insert_marker(track, &marker_new);
-                               }
-                       }
+       gray_pixels = MEM_callocN(width * height * sizeof(float), "tracking floatBuf");
 
-                       ok = TRUE;
-#else
-                       (void)frame_height;
-                       (void)frame_width;
-#endif
-               }
+       if (searchibuf->rect_float) {
+               float_rgba_to_gray(searchibuf->rect_float, gray_pixels, width * height,
+                                  0.2126f, 0.7152f, 0.0722f);
+       }
+       else {
+               uint8_rgba_to_float_gray((unsigned char *)searchibuf->rect, gray_pixels, width * height,
+                                        0.2126f, 0.7152f, 0.0722f);
        }
 
-       IMB_freeImBuf(destination_ibuf);
+       IMB_freeImBuf(searchibuf);
 
-       context->first_time = FALSE;
-       context->frames++;
+       *width_r = width;
+       *height_r = height;
 
-       return ok;
+       return gray_pixels;
 }
 
-/*********************** camera solving *************************/
-
-typedef struct MovieReconstructContext {
-#ifdef WITH_LIBMV
-       struct libmv_Tracks *tracks;
-       int keyframe1, keyframe2;
-       short refine_flags;
+static ImBuf *tracking_context_get_frame_ibuf(MovieTrackingContext *context, int framenr)
+{
+       ImBuf *ibuf;
+       MovieClipUser user = context->user;
 
-       struct libmv_Reconstruction *reconstruction;
-#endif
-       char object_name[MAX_NAME];
-       int is_camera;
-       short motion_flag;
+       user.framenr = BKE_movieclip_remap_clip_to_scene_frame(context->clip, framenr);
 
-       float focal_length;
-       float principal_point[2];
-       float k1, k2, k3;
+       ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &user, context->clip_flag, MOVIECLIP_CACHE_SKIP);
 
-       float reprojection_error;
+       return ibuf;
+}
 
-       TracksMap *tracks_map;
+MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingContext *context, MovieTrackingTrack *track,
+                                                           MovieTrackingMarker *marker)
+{
+       int a = marker - track->markers;
+       MovieTrackingMarker *marker_keyed = marker;
 
-       int sfra, efra;
-} MovieReconstructContext;
+       while (a >= 0 && a < track->markersnr) {
+               int next = (context->backwards) ? a + 1 : a - 1;
+               int is_keyframed = FALSE;
+               MovieTrackingMarker *cur_marker = &track->markers[a];
+               MovieTrackingMarker *next_marker = NULL;
 
-typedef struct ReconstructProgressData {
-       short *stop;
-       short *do_update;
-       float *progress;
-       char *stats_message;
-       int message_size;
-} ReconstructProgressData;
+               if (next >= 0 && next < track->markersnr)
+                       next_marker = &track->markers[next];
 
-#if WITH_LIBMV
-static struct libmv_Tracks *create_libmv_tracks(ListBase *tracksbase, int width, int height)
-{
-       int tracknr = 0;
-       MovieTrackingTrack *track;
-       struct libmv_Tracks *tracks = libmv_tracksNew();
+               /* if next mrker is disabled, stop searching keyframe and use current frame as keyframe */
+               if (next_marker && next_marker->flag & MARKER_DISABLED)
+                       is_keyframed = TRUE;
 
-       track = tracksbase->first;
-       while (track) {
-               int a = 0;
+               is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0;
 
-               for (a = 0; a < track->markersnr; a++) {
-                       MovieTrackingMarker *marker = &track->markers[a];
+               if (is_keyframed) {
+                       marker_keyed = cur_marker;
 
-                       if ((marker->flag & MARKER_DISABLED) == 0) {
-                               libmv_tracksInsert(tracks, marker->framenr, tracknr,
-                                                  marker->pos[0] * width, marker->pos[1] * height);
-                       }
+                       break;
                }
 
-               track = track->next;
-               tracknr++;
+               a = next;
        }
 
-       return tracks;
+       return marker_keyed;
 }
 
-static void retrieve_libmv_reconstruct_intrinscis(MovieReconstructContext *context, MovieTracking *tracking)
+static ImBuf *tracking_context_get_keyframed_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track,
+                                                  MovieTrackingMarker *marker, MovieTrackingMarker **marker_keyed_r)
 {
-       struct libmv_Reconstruction *libmv_reconstruction = context->reconstruction;
-       struct libmv_CameraIntrinsics *libmv_intrinsics = libmv_ReconstructionExtractIntrinsics(libmv_reconstruction);
+       MovieTrackingMarker *marker_keyed;
+       int keyed_framenr;
 
-       float aspy = 1.0f / tracking->camera.pixel_aspect;
-
-       double focal_length, principal_x, principal_y, k1, k2, k3;
-       int width, height;
+       marker_keyed = tracking_context_get_keyframed_marker(context, track, marker);
+       keyed_framenr = marker_keyed->framenr;
 
-       libmv_CameraIntrinsicsExtract(libmv_intrinsics, &focal_length, &principal_x, &principal_y,
-                                     &k1, &k2, &k3, &width, &height);
-
-       tracking->camera.focal = focal_length;
-       tracking->camera.principal[0] = principal_x;
+       *marker_keyed_r = marker_keyed;
 
-       tracking->camera.principal[1] = principal_y / aspy;
-       tracking->camera.k1 = k1;
-       tracking->camera.k2 = k2;
+       return tracking_context_get_frame_ibuf(context, keyed_framenr);
 }
 
-static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, MovieTracking *tracking)
+static ImBuf *tracking_context_get_reference_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track,
+                                                  MovieTrackingMarker *marker, int curfra,
+                                                  MovieTrackingMarker **marker_keyed)
 {
-       struct libmv_Reconstruction *libmv_reconstruction = context->reconstruction;
-       MovieTrackingReconstruction *reconstruction = NULL;
-       MovieReconstructedCamera *reconstructed;
-       MovieTrackingTrack *track;
-       ListBase *tracksbase =  NULL;
-       int ok = TRUE, tracknr = 0, a, origin_set = FALSE;
-       int sfra = context->sfra, efra = context->efra;
-       float imat[4][4];
+       ImBuf *ibuf = NULL;
 
-       if (context->is_camera) {
-               tracksbase = &tracking->tracks;
-               reconstruction = &tracking->reconstruction;
+       if (track->pattern_match == TRACK_MATCH_KEYFRAME) {
+               ibuf = tracking_context_get_keyframed_ibuf(context, track, marker, marker_keyed);
        }
        else {
-               MovieTrackingObject *object = BKE_tracking_named_object(tracking, context->object_name);
+               ibuf = tracking_context_get_frame_ibuf(context, curfra);
 
-               tracksbase = &object->tracks;
-               reconstruction = &object->reconstruction;
+               /* use current marker as keyframed position */
+               *marker_keyed = marker;
        }
 
-       unit_m4(imat);
+       return ibuf;
+}
 
-       track = tracksbase->first;
-       while (track) {
-               double pos[3];
+static void track_context_update_reference(MovieTrackingContext *context, TrackContext *track_context,
+                                           MovieTrackingTrack *track, MovieTrackingMarker *marker, int curfra,
+                                           int frame_width, int frame_height)
+{
+       MovieTrackingMarker *marker_keyed = NULL;
+       ImBuf *reference_ibuf = NULL;
+       int width, height;
 
-               if (libmv_reporojectionPointForTrack(libmv_reconstruction, tracknr, pos)) {
-                       track->bundle_pos[0] = pos[0];
-                       track->bundle_pos[1] = pos[1];
-                       track->bundle_pos[2] = pos[2];
+       /* calculate patch for keyframed position */
+       reference_ibuf = tracking_context_get_reference_ibuf(context, track, marker, curfra, &marker_keyed);
+       track_context->marker = *marker_keyed;
 
-                       track->flag |= TRACK_HAS_BUNDLE;
-                       track->error = libmv_reporojectionErrorForTrack(libmv_reconstruction, tracknr);
-               }
-               else {
-                       track->flag &= ~TRACK_HAS_BUNDLE;
-                       ok = FALSE;
+       if (track_context->search_area) {
+               MEM_freeN(track_context->search_area);
+       }
 
-                       printf("No bundle for track #%d '%s'\n", tracknr, track->name);
-               }
+       track_context->search_area = track_get_search_floatbuf(reference_ibuf, track, marker_keyed, &width, &height);
+       track_context->search_area_height = height;
+       track_context->search_area_width = width;
 
-               track = track->next;
-               tracknr++;
+       if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) {
+               if (track_context->mask)
+                       MEM_freeN(track_context->mask);
+
+               track_context->mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
        }
 
-       if (reconstruction->cameras)
-               MEM_freeN(reconstruction->cameras);
+       IMB_freeImBuf(reference_ibuf);
+}
 
-       reconstruction->camnr = 0;
-       reconstruction->cameras = NULL;
-       reconstructed = MEM_callocN((efra - sfra + 1) * sizeof(MovieReconstructedCamera),
-                                   "temp reconstructed camera");
+static void tracking_configure_tracker(TrackContext *track_context, MovieTrackingTrack *track,
+                                       struct libmv_trackRegionOptions *options)
+{
+       options->motion_model = track->motion_model;
 
-       for (a = sfra; a <= efra; a++) {
-               double matd[4][4];
+       options->use_brute = ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_BRUTE) != 0);
 
-               if (libmv_reporojectionCameraForImage(libmv_reconstruction, a, matd)) {
-                       int i, j;
-                       float mat[4][4];
-                       float error = libmv_reporojectionErrorForImage(libmv_reconstruction, a);
+       options->use_normalization = ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_NORMALIZATION) != 0);
 
-                       for (i = 0; i < 4; i++)
-                               for (j = 0; j < 4; j++)
-                                       mat[i][j] = matd[i][j];
+       options->num_iterations = 50;
+       options->minimum_correlation = track->minimum_correlation;
+       options->sigma = 0.9;
 
-                       if (!origin_set) {
-                               copy_m4_m4(imat, mat);
-                               invert_m4(imat);
-                               origin_set = TRUE;
-                       }
+       if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0)
+               options->image1_mask = track_context->mask;
+}
 
-                       if (origin_set)
-                               mult_m4_m4m4(mat, imat, mat);
+/* returns FALSE if marker crossed margin area from frame bounds */
+static int tracking_check_marker_margin(MovieTrackingTrack *track, MovieTrackingMarker *marker,
+                                        int frame_width, int frame_height)
+{
+       float pat_min[2], pat_max[2], dim[2], margin[2];
 
-                       copy_m4_m4(reconstructed[reconstruction->camnr].mat, mat);
-                       reconstructed[reconstruction->camnr].framenr = a;
-                       reconstructed[reconstruction->camnr].error = error;
-                       reconstruction->camnr++;
-               }
-               else {
-                       ok = FALSE;
-                       printf("No camera for frame %d\n", a);
-               }
-       }
+       /* margin from frame boundaries */
+       BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
+       sub_v2_v2v2(dim, pat_max, pat_min);
+       margin[0] = margin[1] = MAX2(dim[0], dim[1]) / 2.0f;
 
-       if (reconstruction->camnr) {
-               int size = reconstruction->camnr * sizeof(MovieReconstructedCamera);
-               reconstruction->cameras = MEM_callocN(size, "reconstructed camera");
-               memcpy(reconstruction->cameras, reconstructed, size);
+       margin[0] = MAX2(margin[0], (float)track->margin / frame_width);
+       margin[1] = MAX2(margin[1], (float)track->margin / frame_height);
+
+       /* do not track markers which are too close to boundary */
+       if (marker->pos[0] < margin[0] || marker->pos[0] > 1.0f - margin[0] ||
+           marker->pos[1] < margin[1] || marker->pos[1] > 1.0f - margin[1])
+       {
+               return FALSE;
        }
 
-       if (origin_set) {
-               track = tracksbase->first;
-               while (track) {
-                       if (track->flag & TRACK_HAS_BUNDLE)
-                               mul_v3_m4v3(track->bundle_pos, imat, track->bundle_pos);
+       return TRUE;
+}
 
-                       track = track->next;
-               }
-       }
+static void tracking_scale_marker_search(const MovieTrackingMarker *old_marker, MovieTrackingMarker *new_marker)
+{
+       float old_pat_min[2], old_pat_max[2];
+       float new_pat_min[2], new_pat_max[2];
+       float scale_x, scale_y;
 
-       MEM_freeN(reconstructed);
+       BKE_tracking_marker_pattern_minmax(old_marker, old_pat_min, old_pat_max);
+       BKE_tracking_marker_pattern_minmax(new_marker, new_pat_min, new_pat_max);
 
-       return ok;
-}
+       scale_x = (new_pat_max[0] - new_pat_min[0]) / (old_pat_max[0] - old_pat_min[0]);
+       scale_y = (new_pat_max[1] - new_pat_min[1]) / (old_pat_max[1] - old_pat_min[1]);
 
-static int retrieve_libmv_reconstruct(MovieReconstructContext *context, MovieTracking *tracking)
-{
-       /* take the intrinscis back from libmv */
-       retrieve_libmv_reconstruct_intrinscis(context, tracking);
+       new_marker->search_min[0] *= scale_x;
+       new_marker->search_min[1] *= scale_y;
 
-       return retrieve_libmv_reconstruct_tracks(context, tracking);
+       new_marker->search_max[0] *= scale_x;
+       new_marker->search_max[1] *= scale_y;
 }
 
-static int get_refine_intrinsics_flags(MovieTracking *tracking, MovieTrackingObject *object)
+static void tracking_insert_new_marker(MovieTrackingContext *context, MovieTrackingTrack *track,
+                                       const MovieTrackingMarker *old_marker, int curfra, int tracked,
+                                       int frame_width, int frame_height,
+                                       double dst_pixel_x[5], double dst_pixel_y[5])
 {
-       int refine = tracking->settings.refine_camera_intrinsics;
-       int flags = 0;
-
-       if ((object->flag & TRACKING_OBJECT_CAMERA) == 0)
-               return 0;
-
-       if (refine & REFINE_FOCAL_LENGTH)
-               flags |= LIBMV_REFINE_FOCAL_LENGTH;
+       MovieTrackingMarker new_marker;
+       int frame_delta = context->backwards ? -1 : 1;
+       int nextfra = curfra + frame_delta;
 
-       if (refine & REFINE_PRINCIPAL_POINT)
-               flags |= LIBMV_REFINE_PRINCIPAL_POINT;
+       new_marker = *old_marker;
 
-       if (refine & REFINE_RADIAL_DISTORTION_K1)
-               flags |= REFINE_RADIAL_DISTORTION_K1;
+       if (tracked) {
+               set_marker_coords_from_tracking(frame_width, frame_height, &new_marker, dst_pixel_x, dst_pixel_y);
+               new_marker.flag |= MARKER_TRACKED;
+               new_marker.framenr = nextfra;
 
-       if (refine & REFINE_RADIAL_DISTORTION_K2)
-               flags |= REFINE_RADIAL_DISTORTION_K2;
+               tracking_scale_marker_search(old_marker, &new_marker);
 
-       return flags;
-}
+               if (context->first_time) {
+                       /* check if there's no keyframe/tracked markers before tracking marker.
+                        * if so -- create disabled marker before currently tracking "segment"
+                        */
 
-static int count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase)
-{
-       int tot = 0;
-       int frame1 = tracking->settings.keyframe1, frame2 = tracking->settings.keyframe2;
-       MovieTrackingTrack *track;
+                       tracking_marker_insert_disabled(track, &new_marker, !context->backwards, FALSE);
+               }
 
-       track = tracksbase->first;
-       while (track) {
-               if (BKE_tracking_has_enabled_marker(track, frame1))
-                       if (BKE_tracking_has_enabled_marker(track, frame2))
-                               tot++;
+               /* insert currently tracked marker */
+               BKE_tracking_marker_insert(track, &new_marker);
 
-               track = track->next;
+               /* make currently tracked segment be finished with disabled marker */
+               tracking_marker_insert_disabled(track, &new_marker, context->backwards, FALSE);
        }
+       else {
+               new_marker.framenr = nextfra;
+               new_marker.flag |= MARKER_DISABLED;
 
-       return tot;
+               BKE_tracking_marker_insert(track, &new_marker);
+       }
 }
+
 #endif
 
-int BKE_tracking_can_reconstruct(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size)
+int BKE_tracking_context_step(MovieTrackingContext *context)
 {
-#if WITH_LIBMV
-       ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
+       ImBuf *destination_ibuf;
+       int frame_delta = context->backwards ? -1 : 1;
+       int curfra =  BKE_movieclip_remap_scene_to_clip_frame(context->clip, context->user.framenr);
+       int nextfra;
+       int a, ok = FALSE, map_size;
 
-       if (tracking->settings.motion_flag & TRACKING_MOTION_MODAL) {
-               /* TODO: check for number of tracks? */
-               return TRUE;
-       }
-       else if (count_tracks_on_both_keyframes(tracking, tracksbase) < 8) {
-               BLI_strncpy(error_msg, "At least 8 common tracks on both of keyframes are needed for reconstruction",
-                           error_size);
+       int frame_width, frame_height;
 
-               return FALSE;
-       }
+       map_size = tracks_map_get_size(context->tracks_map);
 
-       return TRUE;
-#else
-       BLI_strncpy(error_msg, "Blender is compiled without motion tracking library", error_size);
+       /* nothing to track, avoid unneeded frames reading to save time and memory */
+       if (!map_size)
+               return FALSE;
 
-       (void) tracking;
-       (void) object;
+       context->user.framenr += frame_delta;
 
-       return 0;
-#endif
-}
+       destination_ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &context->user,
+                                                      context->clip_flag, MOVIECLIP_CACHE_SKIP);
+       if (!destination_ibuf)
+               return FALSE;
 
-MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking *tracking, MovieTrackingObject *object,
-                                                                 int keyframe1, int keyframe2, int width, int height)
-{
-       MovieReconstructContext *context = MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data");
-       MovieTrackingCamera *camera = &tracking->camera;
-       ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
-       float aspy = 1.0f / tracking->camera.pixel_aspect;
-       int num_tracks = BLI_countlist(tracksbase);
-       int sfra = INT_MAX, efra = INT_MIN;
-       MovieTrackingTrack *track;
+       nextfra = curfra + frame_delta;
 
-       BLI_strncpy(context->object_name, object->name, sizeof(context->object_name));
-       context->is_camera = object->flag & TRACKING_OBJECT_CAMERA;
-       context->motion_flag = tracking->settings.motion_flag;
+       frame_width = destination_ibuf->x;
+       frame_height = destination_ibuf->y;
 
-       context->tracks_map = tracks_map_new(context->object_name, context->is_camera, num_tracks, 0);
+       #pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size>1)
+       for (a = 0; a < map_size; a++) {
+               TrackContext *track_context = NULL;
+               MovieTrackingTrack *track;
+               MovieTrackingMarker *marker;
 
-       track = tracksbase->first;
-       while (track) {
-               int first = 0, last = track->markersnr - 1;
-               MovieTrackingMarker *first_marker = &track->markers[0];
-               MovieTrackingMarker *last_marker = &track->markers[track->markersnr - 1];
+               tracks_map_get_indexed_element(context->tracks_map, a, &track, (void **)&track_context);
 
-               /* find first not-disabled marker */
-               while (first <= track->markersnr - 1 && first_marker->flag & MARKER_DISABLED) {
-                       first++;
-                       first_marker++;
-               }
+               marker = BKE_tracking_marker_get_exact(track, curfra);
 
-               /* find last not-disabled marker */
-               while (last >= 0 && last_marker->flag & MARKER_DISABLED) {
-                       last--;
-                       last_marker--;
-               }
+               if (marker && (marker->flag & MARKER_DISABLED) == 0) {
+#ifdef WITH_LIBMV
+                       int width, height, tracked = FALSE, need_readjust;
+                       double dst_pixel_x[5], dst_pixel_y[5];
 
-               if (first < track->markersnr - 1)
-                       sfra = MIN2(sfra, first_marker->framenr);
+                       if (track->pattern_match == TRACK_MATCH_KEYFRAME)
+                               need_readjust = context->first_time;
+                       else
+                               need_readjust = TRUE;
 
-               if (last >= 0)
-                       efra = MAX2(efra, last_marker->framenr);
+                       /* do not track markers which are too close to boundary */
+                       if (tracking_check_marker_margin(track, marker, frame_width, frame_height)) {
+                               /* to convert to the x/y split array format for libmv. */
+                               double src_pixel_x[5], src_pixel_y[5];
 
-               tracks_map_insert(context->tracks_map, track, NULL);
+                               /* settings for the tracker */
+                               struct libmv_trackRegionOptions options = {0};
+                               struct libmv_trackRegionResult result;
 
-               track = track->next;
-       }
+                               float *patch_new;
 
-       context->sfra = sfra;
-       context->efra = efra;
+                               if (need_readjust) {
+                                       track_context_update_reference(context, track_context, track, marker,
+                                                                      curfra, frame_width, frame_height);
+                               }
 
-#ifdef WITH_LIBMV
-       context->tracks = create_libmv_tracks(tracksbase, width, height * aspy);
-       context->keyframe1 = keyframe1;
-       context->keyframe2 = keyframe2;
-       context->refine_flags = get_refine_intrinsics_flags(tracking, object);
-#else
-       (void) width;
-       (void) height;
-       (void) keyframe1;
-       (void) keyframe2;
-#endif
+                               /* for now track to the same search area dimension as marker has got for current frame
+                                * will make all tracked markers in currently tracked segment have the same search area
+                                * size, but it's quite close to what is actually needed
+                                */
+                               patch_new = track_get_search_floatbuf(destination_ibuf, track, marker, &width, &height);
 
-       context->focal_length = camera->focal;
-       context->principal_point[0] = camera->principal[0];
-       context->principal_point[1] = camera->principal[1] * aspy;
+                               /* configure the tracker */
+                               tracking_configure_tracker(track_context, track, &options);
 
-       context->k1 = camera->k1;
-       context->k2 = camera->k2;
-       context->k3 = camera->k3;
+                               /* convert the marker corners and center into pixel coordinates in the search/destination images. */
+                               get_marker_coords_for_tracking(frame_width, frame_height, &track_context->marker, src_pixel_x, src_pixel_y);
+                               get_marker_coords_for_tracking(frame_width, frame_height, marker, dst_pixel_x, dst_pixel_y);
 
-       return context;
-}
+                               /* run the tracker! */
+                               tracked = libmv_trackRegion(&options,
+                                                           track_context->search_area,
+                                                                                       track_context->search_area_width,
+                                                                                       track_context->search_area_height,
+                                                                                       patch_new, width, height,
+                                                           src_pixel_x, src_pixel_y,
+                                                           &result,
+                                                           dst_pixel_x, dst_pixel_y);
+                               MEM_freeN(patch_new);
+                       }
 
-void BKE_tracking_reconstruction_context_free(MovieReconstructContext *context)
-{
-#ifdef WITH_LIBMV
-       if (context->reconstruction)
-               libmv_destroyReconstruction(context->reconstruction);
+                       #pragma omp critical
+                       {
+                               tracking_insert_new_marker(context, track, marker, curfra, tracked,
+                                                                frame_width, frame_height, dst_pixel_x, dst_pixel_y);
+                       }
 
-       libmv_tracksDestroy(context->tracks);
+                       ok = TRUE;
+#else
+                       (void)frame_height;
+                       (void)frame_width;
 #endif
+               }
+       }
 
-       tracks_map_free(context->tracks_map, NULL);
+       IMB_freeImBuf(destination_ibuf);
 
-       MEM_freeN(context);
+       context->first_time = FALSE;
+       context->frames++;
+
+       return ok;
 }
 
-#ifdef WITH_LIBMV
-static void solve_reconstruction_update_cb(void *customdata, double progress, const char *message)
-{
-       ReconstructProgressData *progressdata = customdata;
+/*********************** Camera solving *************************/
 
-       if (progressdata->progress) {
-               *progressdata->progress = progress;
-               *progressdata->do_update = TRUE;
-       }
+typedef struct MovieReconstructContext {
+#ifdef WITH_LIBMV
+       struct libmv_Tracks *tracks;
+       int keyframe1, keyframe2;
+       short refine_flags;
 
-       BLI_snprintf(progressdata->stats_message, progressdata->message_size, "Solving camera | %s", message);
-}
+       struct libmv_Reconstruction *reconstruction;
 #endif
+       char object_name[MAX_NAME];
+       int is_camera;
+       short motion_flag;
 
-#if 0
-static int solve_reconstruction_testbreak_cb(void *customdata)
-{
-       ReconstructProgressData *progressdata = customdata;
+       float focal_length;
+       float principal_point[2];
+       float k1, k2, k3;
 
-       if (progressdata->stop && *progressdata->stop)
-               return TRUE;
+       float reprojection_error;
 
-       return G.afbreek;
-}
-#endif
+       TracksMap *tracks_map;
+
+       int sfra, efra;
+} MovieReconstructContext;
+
+typedef struct ReconstructProgressData {
+       short *stop;
+       short *do_update;
+       float *progress;
+       char *stats_message;
+       int message_size;
+} ReconstructProgressData;
 
-void BKE_tracking_solve_reconstruction(MovieReconstructContext *context, short *stop, short *do_update,
-                                       float *progress, char *stats_message, int message_size)
-{
 #ifdef WITH_LIBMV
-       float error;
+static struct libmv_Tracks *libmv_tracks_new(ListBase *tracksbase, int width, int height)
+{
+       int tracknr = 0;
+       MovieTrackingTrack *track;
+       struct libmv_Tracks *tracks = libmv_tracksNew();
 
-       ReconstructProgressData progressdata;
+       track = tracksbase->first;
+       while (track) {
+               int a = 0;
 
-       progressdata.stop = stop;
-       progressdata.do_update = do_update;
-       progressdata.progress = progress;
-       progressdata.stats_message = stats_message;
-       progressdata.message_size = message_size;
+               for (a = 0; a < track->markersnr; a++) {
+                       MovieTrackingMarker *marker = &track->markers[a];
 
-       if (context->motion_flag & TRACKING_MOTION_MODAL) {
-               context->reconstruction = libmv_solveModal(context->tracks,
-                                                          context->focal_length,
-                                                          context->principal_point[0], context->principal_point[1],
-                                                          context->k1, context->k2, context->k3,
-                                                          solve_reconstruction_update_cb, &progressdata);
-       }
-       else {
-               context->reconstruction = libmv_solveReconstruction(context->tracks,
-                                                                   context->keyframe1, context->keyframe2,
-                                                                   context->refine_flags,
-                                                                   context->focal_length,
-                                                                   context->principal_point[0], context->principal_point[1],
-                                                                   context->k1, context->k2, context->k3,
-                                                                   solve_reconstruction_update_cb, &progressdata);
-       }
+                       if ((marker->flag & MARKER_DISABLED) == 0) {
+                               libmv_tracksInsert(tracks, marker->framenr, tracknr,
+                                                  marker->pos[0] * width, marker->pos[1] * height);
+                       }
+               }
 
-       error = libmv_reprojectionError(context->reconstruction);
+               track = track->next;
+               tracknr++;
+       }
 
-       context->reprojection_error = error;
-#else
-       (void) context;
-       (void) stop;
-       (void) do_update;
-       (void) progress;
-       (void) stats_message;
-       (void) message_size;
-#endif
+       return tracks;
 }
 
-int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTracking *tracking)
+static void reconstruct_retrieve_libmv_intrinscis(MovieReconstructContext *context, MovieTracking *tracking)
 {
-       MovieTrackingReconstruction *reconstruction;
+       struct libmv_Reconstruction *libmv_reconstruction = context->reconstruction;
+       struct libmv_CameraIntrinsics *libmv_intrinsics = libmv_ReconstructionExtractIntrinsics(libmv_reconstruction);
 
-       tracks_map_merge(context->tracks_map, tracking);
+       float aspy = 1.0f / tracking->camera.pixel_aspect;
+
+       double focal_length, principal_x, principal_y, k1, k2, k3;
+       int width, height;
+
+       libmv_CameraIntrinsicsExtract(libmv_intrinsics, &focal_length, &principal_x, &principal_y,
+                                     &k1, &k2, &k3, &width, &height);
+
+       tracking->camera.focal = focal_length;
+       tracking->camera.principal[0] = principal_x;
+
+       tracking->camera.principal[1] = principal_y / aspy;
+       tracking->camera.k1 = k1;
+       tracking->camera.k2 = k2;
+}
+
+static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, MovieTracking *tracking)
+{
+       struct libmv_Reconstruction *libmv_reconstruction = context->reconstruction;
+       MovieTrackingReconstruction *reconstruction = NULL;
+       MovieReconstructedCamera *reconstructed;
+       MovieTrackingTrack *track;
+       ListBase *tracksbase =  NULL;
+       int ok = TRUE, tracknr = 0, a, origin_set = FALSE;
+       int sfra = context->sfra, efra = context->efra;
+       float imat[4][4];
 
        if (context->is_camera) {
+               tracksbase = &tracking->tracks;
                reconstruction = &tracking->reconstruction;
        }
        else {
-               MovieTrackingObject *object;
+               MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, context->object_name);
 
-               object = BKE_tracking_named_object(tracking, context->object_name);
+               tracksbase = &object->tracks;
                reconstruction = &object->reconstruction;
        }
 
-       reconstruction->error = context->reprojection_error;
-       reconstruction->flag |= TRACKING_RECONSTRUCTED;
-
-#ifdef WITH_LIBMV
-       if (!retrieve_libmv_reconstruct(context, tracking))
-               return FALSE;
-#endif
+       unit_m4(imat);
 
-       return TRUE;
-}
+       track = tracksbase->first;
+       while (track) {
+               double pos[3];
 
-void BKE_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
-{
-       BLI_uniquename(tracksbase, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
-}
+               if (libmv_reporojectionPointForTrack(libmv_reconstruction, tracknr, pos)) {
+                       track->bundle_pos[0] = pos[0];
+                       track->bundle_pos[1] = pos[1];
+                       track->bundle_pos[2] = pos[2];
 
-MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, MovieTrackingObject *object, const char *name)
-{
-       ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
-       MovieTrackingTrack *track = tracksbase->first;
+                       track->flag |= TRACK_HAS_BUNDLE;
+                       track->error = libmv_reporojectionErrorForTrack(libmv_reconstruction, tracknr);
+               }
+               else {
+                       track->flag &= ~TRACK_HAS_BUNDLE;
+                       ok = FALSE;
 
-       while (track) {
-               if (!strcmp(track->name, name))
-                       return track;
+                       printf("No bundle for track #%d '%s'\n", tracknr, track->name);
+               }
 
                track = track->next;
+               tracknr++;
        }
 
-       return NULL;
-}
-
-static int reconstruction_camera_index(MovieTrackingReconstruction *reconstruction, int framenr, int nearest)
-{
-       MovieReconstructedCamera *cameras = reconstruction->cameras;
-       int a = 0, d = 1;
-
-       if (!reconstruction->camnr)
-               return -1;
+       if (reconstruction->cameras)
+               MEM_freeN(reconstruction->cameras);
 
-       if (framenr < cameras[0].framenr) {
-               if (nearest)
-                       return 0;
-               else
-                       return -1;
-       }
+       reconstruction->camnr = 0;
+       reconstruction->cameras = NULL;
+       reconstructed = MEM_callocN((efra - sfra + 1) * sizeof(MovieReconstructedCamera),
+                                   "temp reconstructed camera");
 
-       if (framenr > cameras[reconstruction->camnr - 1].framenr) {
-               if (nearest)
-                       return reconstruction->camnr - 1;
-               else
-                       return -1;
-       }
+       for (a = sfra; a <= efra; a++) {
+               double matd[4][4];
 
-       if (reconstruction->last_camera < reconstruction->camnr)
-               a = reconstruction->last_camera;
+               if (libmv_reporojectionCameraForImage(libmv_reconstruction, a, matd)) {
+                       int i, j;
+                       float mat[4][4];
+                       float error = libmv_reporojectionErrorForImage(libmv_reconstruction, a);
 
-       if (cameras[a].framenr >= framenr)
-               d = -1;
+                       for (i = 0; i < 4; i++)
+                               for (j = 0; j < 4; j++)
+                                       mat[i][j] = matd[i][j];
 
-       while (a >= 0 && a < reconstruction->camnr) {
-               int cfra = cameras[a].framenr;
+                       if (!origin_set) {
+                               copy_m4_m4(imat, mat);
+                               invert_m4(imat);
+                               origin_set = TRUE;
+                       }
 
-               /* check if needed framenr was "skipped" -- no data for requested frame */
+                       if (origin_set)
+                               mult_m4_m4m4(mat, imat, mat);
 
-               if (d > 0 && cfra > framenr) {
-                       /* interpolate with previous position */
-                       if (nearest)
-                               return a - 1;
-                       else
-                               break;
+                       copy_m4_m4(reconstructed[reconstruction->camnr].mat, mat);
+                       reconstructed[reconstruction->camnr].framenr = a;
+                       reconstructed[reconstruction->camnr].error = error;
+                       reconstruction->camnr++;
                }
-
-               if (d < 0 && cfra < framenr) {
-                       /* interpolate with next position */
-                       if (nearest)
-                               return a;
-                       else
-                               break;
+               else {
+                       ok = FALSE;
+                       printf("No camera for frame %d\n", a);
                }
+       }
 
-               if (cfra == framenr) {
-                       reconstruction->last_camera = a;
+       if (reconstruction->camnr) {
+               int size = reconstruction->camnr * sizeof(MovieReconstructedCamera);
+               reconstruction->cameras = MEM_callocN(size, "reconstructed camera");
+               memcpy(reconstruction->cameras, reconstructed, size);
+       }
 
-                       return a;
-               }
+       if (origin_set) {
+               track = tracksbase->first;
+               while (track) {
+                       if (track->flag & TRACK_HAS_BUNDLE)
+                               mul_v3_m4v3(track->bundle_pos, imat, track->bundle_pos);
 
-               a += d;
+                       track = track->next;
+               }
        }
 
-       return -1;
-}
-
-static void scale_reconstructed_camera(MovieTrackingObject *object, float mat[4][4])
-{
-       if ((object->flag & TRACKING_OBJECT_CAMERA) == 0) {
-               float smat[4][4];
+       MEM_freeN(reconstructed);
 
-               scale_m4_fl(smat, 1.0f / object->scale);
-               mult_m4_m4m4(mat, mat, smat);
-       }
+       return ok;
 }
 
-MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking,
-                                                                MovieTrackingObject *object, int framenr)
+static int reconstruct_retrieve_libmv(MovieReconstructContext *context, MovieTracking *tracking)
 {
-       MovieTrackingReconstruction *reconstruction;
-       int a;
-
-       reconstruction = BKE_tracking_object_reconstruction(tracking, object);
-       a = reconstruction_camera_index(reconstruction, framenr, FALSE);
-
-       if (a == -1)
-               return NULL;
+       /* take the intrinscis back from libmv */
+       reconstruct_retrieve_libmv_intrinscis(context, tracking);
 
-       return &reconstruction->cameras[a];
+       return reconstruct_retrieve_libmv_tracks(context, tracking);
 }
 
-void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, MovieTrackingObject *object,
-                                          int framenr, float mat[4][4])
+static int reconstruct_refine_intrinsics_get_flags(MovieTracking *tracking, MovieTrackingObject *object)
 {
-       MovieTrackingReconstruction *reconstruction;
-       MovieReconstructedCamera *cameras;
-       int a;
+       int refine = tracking->settings.refine_camera_intrinsics;
+       int flags = 0;
 
-       reconstruction = BKE_tracking_object_reconstruction(tracking, object);
-       cameras = reconstruction->cameras;
-       a = reconstruction_camera_index(reconstruction, framenr, 1);
+       if ((object->flag & TRACKING_OBJECT_CAMERA) == 0)
+               return 0;
 
-       if (a == -1) {
-               unit_m4(mat);
+       if (refine & REFINE_FOCAL_LENGTH)
+               flags |= LIBMV_REFINE_FOCAL_LENGTH;
 
-               return;
-       }
+       if (refine & REFINE_PRINCIPAL_POINT)
+               flags |= LIBMV_REFINE_PRINCIPAL_POINT;
 
-       if (cameras[a].framenr != framenr && a > 0 && a < reconstruction->camnr - 1) {
-               float t = ((float)framenr - cameras[a].framenr) / (cameras[a + 1].framenr - cameras[a].framenr);
+       if (refine & REFINE_RADIAL_DISTORTION_K1)
+               flags |= REFINE_RADIAL_DISTORTION_K1;
 
-               blend_m4_m4m4(mat, cameras[a].mat, cameras[a + 1].mat, t);
-       }
-       else {
-               copy_m4_m4(mat, cameras[a].mat);
-       }
+       if (refine & REFINE_RADIAL_DISTORTION_K2)
+               flags |= REFINE_RADIAL_DISTORTION_K2;
 
-       scale_reconstructed_camera(object, mat);
+       return flags;
 }
 
-void BKE_get_tracking_mat(Scene *scene, Object *ob, float mat[4][4])
+static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase)
 {
-       if (!ob) {
-               if (scene->camera)
-                       ob = scene->camera;
-               else
-                       ob = BKE_scene_camera_find(scene);
+       int tot = 0;
+       int frame1 = tracking->settings.keyframe1, frame2 = tracking->settings.keyframe2;
+       MovieTrackingTrack *track;
+
+       track = tracksbase->first;
+       while (track) {
+               if (BKE_tracking_track_has_enabled_marker_at_frame(track, frame1)) {
+                       if (BKE_tracking_track_has_enabled_marker_at_frame(track, frame2)) {
+                               tot++;
+                       }
+               }
+
+               track = track->next;
        }
 
-       if (ob)
-               BKE_object_where_is_calc_mat4(scene, ob, mat);
-       else
-               unit_m4(mat);
+       return tot;
 }
+#endif
 
-void BKE_tracking_camera_shift(MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty)
+int BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size)
 {
-       /* indeed in both of cases it should be winx -- it's just how camera shift works for blender's camera */
-       *shiftx = (0.5f * winx - tracking->camera.principal[0]) / winx;
-       *shifty = (0.5f * winy - tracking->camera.principal[1]) / winx;
-}
+#if WITH_LIBMV
+       ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
 
-void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height)
-{
-       float focal = tracking->camera.focal;
+       if (tracking->settings.motion_flag & TRACKING_MOTION_MODAL) {
+               /* TODO: check for number of tracks? */
+               return TRUE;
+       }
+       else if (reconstruct_count_tracks_on_both_keyframes(tracking, tracksbase) < 8) {
+               BLI_strncpy(error_msg, "At least 8 common tracks on both of keyframes are needed for reconstruction",
+                           error_size);
 
-       camera->sensor_x = tracking->camera.sensor_width;
-       camera->sensor_fit = CAMERA_SENSOR_FIT_AUTO;
-       camera->lens = focal * camera->sensor_x / width;
+               return FALSE;
+       }
 
-       scene->r.xsch = width * tracking->camera.pixel_aspect;
-       scene->r.ysch = height;
+       return TRUE;
+#else
+       BLI_strncpy(error_msg, "Blender is compiled without motion tracking library", error_size);
 
-       scene->r.xasp = 1.0f;
-       scene->r.yasp = 1.0f;
+       (void) tracking;
+       (void) object;
 
-       BKE_tracking_camera_shift(tracking, width, height, &camera->shiftx, &camera->shifty);
+       return 0;
+#endif
 }
 
-void BKE_tracking_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object,
-                                    int framenr, int winx, int winy, float mat[4][4])
+MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking *tracking, MovieTrackingObject *object,
+                                                                 int keyframe1, int keyframe2, int width, int height)
 {
-       MovieReconstructedCamera *camera;
-       float lens = tracking->camera.focal * tracking->camera.sensor_width / (float)winx;
-       float viewfac, pixsize, left, right, bottom, top, clipsta, clipend;
-       float winmat[4][4];
-       float ycor =  1.0f / tracking->camera.pixel_aspect;
-       float shiftx, shifty, winside = MAX2(winx, winy);
+       MovieReconstructContext *context = MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data");
+       MovieTrackingCamera *camera = &tracking->camera;
+       ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
+       float aspy = 1.0f / tracking->camera.pixel_aspect;
+       int num_tracks = BLI_countlist(tracksbase);
+       int sfra = INT_MAX, efra = INT_MIN;
+       MovieTrackingTrack *track;
 
-       BKE_tracking_camera_shift(tracking, winx, winy, &shiftx, &shifty);
+       BLI_strncpy(context->object_name, object->name, sizeof(context->object_name));
+       context->is_camera = object->flag & TRACKING_OBJECT_CAMERA;
+       context->motion_flag = tracking->settings.motion_flag;
 
-       clipsta = 0.1f;
-       clipend = 1000.0f;
+       context->focal_length = camera->focal;
+       context->principal_point[0] = camera->principal[0];
+       context->principal_point[1] = camera->principal[1] * aspy;
 
-       if (winx >= winy)
-               viewfac = (lens * winx) / tracking->camera.sensor_width;
-       else
-               viewfac = (ycor * lens * winy) / tracking->camera.sensor_width;
+       context->k1 = camera->k1;
+       context->k2 = camera->k2;
+       context->k3 = camera->k3;
 
-       pixsize = clipsta / viewfac;
+       context->tracks_map = tracks_map_new(context->object_name, context->is_camera, num_tracks, 0);
 
-       left = -0.5f * (float)winx + shiftx * winside;
-       bottom = -0.5f * (ycor) * (float)winy + shifty * winside;
-       right =  0.5f * (float)winx + shiftx * winside;
-       top =  0.5f * (ycor) * (float)winy + shifty * winside;
+       track = tracksbase->first;
+       while (track) {
+               int first = 0, last = track->markersnr - 1;
+               MovieTrackingMarker *first_marker = &track->markers[0];
+               MovieTrackingMarker *last_marker = &track->markers[track->markersnr - 1];
 
-       left *= pixsize;
-       right *= pixsize;
-       bottom *= pixsize;
-       top *= pixsize;
+               /* find first not-disabled marker */
+               while (first <= track->markersnr - 1 && first_marker->flag & MARKER_DISABLED) {
+                       first++;
+                       first_marker++;
+               }
 
-       perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
+               /* find last not-disabled marker */
+               while (last >= 0 && last_marker->flag & MARKER_DISABLED) {
+                       last--;
+                       last_marker--;
+               }
 
-       camera = BKE_tracking_get_reconstructed_camera(tracking, object, framenr);
+               if (first < track->markersnr - 1)
+                       sfra = MIN2(sfra, first_marker->framenr);
 
-       if (camera) {
-               float imat[4][4];
+               if (last >= 0)
+                       efra = MAX2(efra, last_marker->framenr);
 
-               invert_m4_m4(imat, camera->mat);
-               mult_m4_m4m4(mat, winmat, imat);
+               tracks_map_insert(context->tracks_map, track, NULL);
+
+               track = track->next;
        }
-       else copy_m4_m4(mat, winmat);
-}
 
-ListBase *BKE_tracking_get_tracks(MovieTracking *tracking)
-{
-       MovieTrackingObject *object = BKE_tracking_active_object(tracking);
+       context->sfra = sfra;
+       context->efra = efra;
 
-       if (object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
-               return &object->tracks;
-       }
+#ifdef WITH_LIBMV
+       context->tracks = libmv_tracks_new(tracksbase, width, height * aspy);
+       context->keyframe1 = keyframe1;
+       context->keyframe2 = keyframe2;
+       context->refine_flags = reconstruct_refine_intrinsics_get_flags(tracking, object);
+#else
+       (void) width;
+       (void) height;
+       (void) keyframe1;
+       (void) keyframe2;
+#endif
 
-       return &tracking->tracks;
+       return context;
 }
 
-MovieTrackingTrack *BKE_tracking_active_track(MovieTracking *tracking)
+void BKE_tracking_reconstruction_context_free(MovieReconstructContext *context)
 {
-       ListBase *tracksbase;
-
-       if (!tracking->act_track)
-               return NULL;
-
-       tracksbase = BKE_tracking_get_tracks(tracking);
+#ifdef WITH_LIBMV
+       if (context->reconstruction)
+               libmv_destroyReconstruction(context->reconstruction);
 
-       /* check that active track is in current tracks list */
-       if (BLI_findindex(tracksbase, tracking->act_track) >= 0)
-               return tracking->act_track;
+       libmv_tracksDestroy(context->tracks);
+#endif
 
-       return NULL;
-}
+       tracks_map_free(context->tracks_map, NULL);
 
-MovieTrackingObject *BKE_tracking_active_object(MovieTracking *tracking)
-{
-       return BLI_findlink(&tracking->objects, tracking->objectnr);
+       MEM_freeN(context);
 }
 
-MovieTrackingObject *BKE_tracking_get_camera_object(MovieTracking *tracking)
+#ifdef WITH_LIBMV
+static void reconstruct_update_solve_cb(void *customdata, double progress, const char *message)
 {
-       MovieTrackingObject *object = tracking->objects.first;
-
-       while (object) {
-               if (object->flag & TRACKING_OBJECT_CAMERA)
-                       return object;
+       ReconstructProgressData *progressdata = customdata;
 
-               object = object->next;
+       if (progressdata->progress) {
+               *progressdata->progress = progress;
+               *progressdata->do_update = TRUE;
        }
 
-       return NULL;
+       BLI_snprintf(progressdata->stats_message, progressdata->message_size, "Solving camera | %s", message);
 }
+#endif
 
-ListBase *BKE_tracking_object_tracks(MovieTracking *tracking, MovieTrackingObject *object)
+#if 0
+static int solve_reconstruction_testbreak_cb(void *customdata)
 {
-       if (object->flag & TRACKING_OBJECT_CAMERA) {
-               return &tracking->tracks;
-       }
-
-       return &object->tracks;
-}
+       ReconstructProgressData *progressdata = customdata;
 
-MovieTrackingReconstruction *BKE_tracking_object_reconstruction(MovieTracking *tracking, MovieTrackingObject *object)
-{
-       if (object->flag & TRACKING_OBJECT_CAMERA) {
-               return &tracking->reconstruction;
-       }
+       if (progressdata->stop && *progressdata->stop)
+               return TRUE;
 
-       return &object->reconstruction;
+       return G.afbreek;
 }
+#endif
 
-MovieTrackingReconstruction *BKE_tracking_get_reconstruction(MovieTracking *tracking)
+void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short *stop, short *do_update,
+                                       float *progress, char *stats_message, int message_size)
 {
-       MovieTrackingObject *object = BKE_tracking_active_object(tracking);
-
-       return BKE_tracking_object_reconstruction(tracking, object);
-}
+#ifdef WITH_LIBMV
+       float error;
 
-void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float nco[2])
-{
-       MovieTrackingCamera *camera = &tracking->camera;
+       ReconstructProgressData progressdata;
 
-#ifdef WITH_LIBMV
-       double x, y;
-       float aspy = 1.0f / tracking->camera.pixel_aspect;
+       progressdata.stop = stop;
+       progressdata.do_update = do_update;
+       progressdata.progress = progress;
+       progressdata.stats_message = stats_message;
+       progressdata.message_size = message_size;
 
-       /* normalize coords */
-       x = (co[0] - camera->principal[0]) / camera->focal;
-       y = (co[1] - camera->principal[1] * aspy) / camera->focal;
+       if (context->motion_flag & TRACKING_MOTION_MODAL) {
+               context->reconstruction = libmv_solveModal(context->tracks,
+                                                          context->focal_length,
+                                                          context->principal_point[0], context->principal_point[1],
+                                                          context->k1, context->k2, context->k3,
+                                                          reconstruct_update_solve_cb, &progressdata);
+       }
+       else {
+               context->reconstruction = libmv_solveReconstruction(context->tracks,
+                                                                   context->keyframe1, context->keyframe2,
+                                                                   context->refine_flags,
+                                                                   context->focal_length,
+                                                                   context->principal_point[0], context->principal_point[1],
+                                                                   context->k1, context->k2, context->k3,
+                                                                   reconstruct_update_solve_cb, &progressdata);
+       }
 
-       libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
-                                   camera->k1, camera->k2, camera->k3, x, y, &x, &y);
+       error = libmv_reprojectionError(context->reconstruction);
 
-       /* result is in image coords already */
-       nco[0] = x;
-       nco[1] = y;
+       context->reprojection_error = error;
 #else
-       (void) camera;
-       (void) co;
-       (void) nco;
+       (void) context;
+       (void) stop;
+       (void) do_update;
+       (void) progress;
+       (void) stats_message;
+       (void) message_size;
 #endif
 }
 
-void BKE_tracking_invert_intrinsics(MovieTracking *tracking, float co[2], float nco[2])
+int BKE_tracking_reconstruction_finish(MovieReconstructContext *context, MovieTracking *tracking)
 {
-       MovieTrackingCamera *camera = &tracking->camera;
+       MovieTrackingReconstruction *reconstruction;
 
-#ifdef WITH_LIBMV
-       double x = co[0], y = co[1];
-       float aspy = 1.0f / tracking->camera.pixel_aspect;
+       tracks_map_merge(context->tracks_map, tracking);
 
-       libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
-                              camera->k1, camera->k2, camera->k3, x, y, &x, &y);
+       if (context->is_camera) {
+               reconstruction = &tracking->reconstruction;
+       }
+       else {
+               MovieTrackingObject *object;
 
-       nco[0] = x * camera->focal + camera->principal[0];
-       nco[1] = y * camera->focal + camera->principal[1] * aspy;
-#else
-       (void) camera;
-       (void) co;
-       (void) nco;
+               object = BKE_tracking_object_get_named(tracking, context->object_name);
+               reconstruction = &object->reconstruction;
+       }
+
+       reconstruction->error = context->reprojection_error;
+       reconstruction->flag |= TRACKING_RECONSTRUCTED;
+
+#ifdef WITH_LIBMV
+       if (!reconstruct_retrieve_libmv(context, tracking))
+               return FALSE;
 #endif
+
+       return TRUE;
 }
 
+/*********************** Feature detection *************************/
+
 #ifdef WITH_LIBMV
-static int point_in_stroke(bGPDstroke *stroke, float x, float y)
+static int check_point_in_stroke(bGPDstroke *stroke, float x, float y)
 {
        int i, prev;
        int count = 0;
@@ -2660,7 +2977,7 @@ static int point_in_stroke(bGPDstroke *stroke, float x, float y)
        return count % 2;
 }
 
-static int point_in_layer(bGPDlayer *layer, float x, float y)
+static int check_point_in_layer(bGPDlayer *layer, float x, float y)
 {
        bGPDframe *frame = layer->frames.first;
 
@@ -2668,7 +2985,7 @@ static int point_in_layer(bGPDlayer *layer, float x, float y)
                bGPDstroke *stroke = frame->strokes.first;
 
                while (stroke) {
-                       if (point_in_stroke(stroke, x, y))
+                       if (check_point_in_stroke(stroke, x, y))
                                return TRUE;
 
                        stroke = stroke->next;
@@ -2679,9 +2996,9 @@ static int point_in_layer(bGPDlayer *layer, float x, float y)
        return FALSE;
 }
 
-static void retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase,
-                                    struct libmv_Features *features, int framenr, int width, int height,
-                                    bGPDlayer *layer, int place_outside_layer)
+static void detect_retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase,
+                                           struct libmv_Features *features, int framenr, int width, int height,
+                                           bGPDlayer *layer, int place_outside_layer)
 {
        int a;
 
@@ -2694,19 +3011,48 @@ static void retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbas
 
                libmv_getFeature(features, a, &x, &y, &score, &size);
 
-               xu = x / width;
-               yu = y / height;
+               xu = x / width;
+               yu = y / height;
+
+               if (layer)
+                       ok = check_point_in_layer(layer, xu, yu) != place_outside_layer;
+
+               if (ok) {
+                       track = BKE_tracking_track_add(tracking, tracksbase, xu, yu, framenr, width, height);
+                       track->flag |= SELECT;
+                       track->pat_flag |= SELECT;
+                       track->search_flag |= SELECT;
+               }
+       }
+}
+
+static unsigned char *detect_get_frame_ucharbuf(ImBuf *ibuf)
+{
+       int x, y;
+       unsigned char *pixels, *cp;
+
+       cp = pixels = MEM_callocN(ibuf->x * ibuf->y * sizeof(unsigned char), "tracking ucharBuf");
+       for (y = 0; y < ibuf->y; y++) {
+               for (x = 0; x < ibuf->x; x++) {
+                       int pixel = ibuf->x * y + x;
+
+                       if (ibuf->rect_float) {
+                               const float *rrgbf = ibuf->rect_float + pixel * 4;
+                               const float grey_f = 0.2126f * rrgbf[0] + 0.7152f * rrgbf[1] + 0.0722f * rrgbf[2];
+
+                               *cp = FTOCHAR(grey_f);
+                       }
+                       else {
+                               const unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4;
 
-               if (layer)
-                       ok = point_in_layer(layer, xu, yu) != place_outside_layer;
+                               *cp = 0.2126f * rrgb[0] + 0.7152f * rrgb[1] + 0.0722f * rrgb[2];
+                       }
 
-               if (ok) {
-                       track = BKE_tracking_add_track(tracking, tracksbase, xu, yu, framenr, width, height);
-                       track->flag |= SELECT;
-                       track->pat_flag |= SELECT;
-                       track->search_flag |= SELECT;
+                       cp++;
                }
        }
+
+       return pixels;
 }
 #endif
 
@@ -2716,14 +3062,14 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImB
 {
 #ifdef WITH_LIBMV
        struct libmv_Features *features;
-       unsigned char *pixels = get_ucharbuf(ibuf);
+       unsigned char *pixels = detect_get_frame_ucharbuf(ibuf);
 
        features = libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x,
                                            margin, min_trackness, min_distance);
 
        MEM_freeN(pixels);
 
-       retrieve_libmv_features(tracking, tracksbase, features, framenr,
+       detect_retrieve_libmv_features(tracking, tracksbase, features, framenr,
                                ibuf->x, ibuf->y, layer, place_outside_layer);
 
        libmv_destroyFeatures(features);
@@ -2740,38 +3086,9 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImB
 #endif
 }
 
-MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr, ListBase **tracksbase_r)
-{
-       MovieTrackingObject *object;
-       int cur = 1;
-
-       object = tracking->objects.first;
-       while (object) {
-               ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
-               MovieTrackingTrack *track = tracksbase->first;
-
-               while (track) {
-                       if (track->flag & TRACK_HAS_BUNDLE) {
-                               if (cur == tracknr) {
-                                       *tracksbase_r = tracksbase;
-                                       return track;
-                               }
-
-                               cur++;
-                       }
-
-                       track = track->next;
-               }
-
-               object = object->next;
-       }
-
-       *tracksbase_r = NULL;
+/*********************** 2D stabilization *************************/
 
-       return NULL;
-}
-
-static int stabilization_median_point(MovieTracking *tracking, int framenr, float median[2])
+static int stabilization_median_point_get(MovieTracking *tracking, int framenr, float median[2])
 {
        int ok = FALSE;
        float min[2], max[2];
@@ -2782,7 +3099,7 @@ static int stabilization_median_point(MovieTracking *tracking, int framenr, floa
        track = tracking->tracks.first;
        while (track) {
                if (track->flag & TRACK_USE_2D_STAB) {
-                       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
+                       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
 
                        DO_MINMAX2(marker->pos, min, max);
 
@@ -2798,8 +3115,9 @@ static int stabilization_median_point(MovieTracking *tracking, int framenr, floa
        return ok;
 }
 
-static void calculate_stabdata(MovieTracking *tracking, int framenr, float width, float height,
-                               float firstmedian[2], float median[2], float loc[2], float *scale, float *angle)
+static void stabilization_calculate_data(MovieTracking *tracking, int framenr, float width, float height,
+                                         float firstmedian[2], float median[2], float loc[2],
+                                         float *scale, float *angle)
 {
        MovieTrackingStabilization *stab = &tracking->stabilization;
 
@@ -2817,12 +3135,12 @@ static void calculate_stabdata(MovieTracking *tracking, int framenr, float width
                float x0 = (float)width / 2.0f, y0 = (float)height / 2.0f;
                float x = median[0] * width, y = median[1] * height;
 
-               marker = BKE_tracking_get_marker(stab->rot_track, 1);
+               marker = BKE_tracking_marker_get(stab->rot_track, 1);
                sub_v2_v2v2(a, marker->pos, firstmedian);
                a[0] *= width;
                a[1] *= height;
 
-               marker = BKE_tracking_get_marker(stab->rot_track, framenr);
+               marker = BKE_tracking_marker_get(stab->rot_track, framenr);
                sub_v2_v2v2(b, marker->pos, median);
                b[0] *= width;
                b[1] *= height;
@@ -2836,7 +3154,7 @@ static void calculate_stabdata(MovieTracking *tracking, int framenr, float width
        }
 }
 
-static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, int height)
+static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, int width, int height)
 {
        float firstmedian[2];
        MovieTrackingStabilization *stab = &tracking->stabilization;
@@ -2845,7 +3163,7 @@ static float stabilization_auto_scale_factor(MovieTracking *tracking, int width,
        if (stab->ok)
                return stab->scale;
 
-       if (stabilization_median_point(tracking, 1, firstmedian)) {
+       if (stabilization_median_point_get(tracking, 1, firstmedian)) {
                int sfra = INT_MAX, efra = INT_MIN, cfra;
                float scale = 1.0f;
                MovieTrackingTrack *track;
@@ -2872,11 +3190,11 @@ static float stabilization_auto_scale_factor(MovieTracking *tracking, int width,
                        float points[4][2] = {{0.0f, 0.0f}, {0.0f, height}, {width, height}, {width, 0.0f}};
                        float si, co;
 
-                       stabilization_median_point(tracking, cfra, median);
+                       stabilization_median_point_get(tracking, cfra, median);
 
-                       calculate_stabdata(tracking, cfra, width, height, firstmedian, median, loc, &tmp_scale, &angle);
+                       stabilization_calculate_data(tracking, cfra, width, height, firstmedian, median, loc, &tmp_scale, &angle);
 
-                       BKE_tracking_stabdata_to_mat4(width, height, aspect, loc, 1.0f, angle, mat);
+                       BKE_tracking_stabilization_data_to_mat4(width, height, aspect, loc, 1.0f, angle, mat);
 
                        si = sin(angle);
                        co = cos(angle);
@@ -2954,7 +3272,7 @@ static float stabilization_auto_scale_factor(MovieTracking *tracking, int width,
        return stab->scale;
 }
 
-static ImBuf *stabilize_alloc_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill)
+static ImBuf *stabilization_allocate_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill)
 {
        int flags;
 
@@ -2983,8 +3301,8 @@ static ImBuf *stabilize_alloc_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill)
        return cacheibuf;
 }
 
-void BKE_tracking_stabilization_data(MovieTracking *tracking, int framenr, int width, int height,
-                                     float loc[2], float *scale, float *angle)
+void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, int width, int height,
+                                         float loc[2], float *scale, float *angle)
 {
        float firstmedian[2], median[2];
        MovieTrackingStabilization *stab = &tracking->stabilization;
@@ -2997,22 +3315,22 @@ void BKE_tracking_stabilization_data(MovieTracking *tracking, int framenr, int w
                return;
        }
 
-       if (stabilization_median_point(tracking, 1, firstmedian)) {
-               stabilization_median_point(tracking, framenr, median);
+       if (stabilization_median_point_get(tracking, 1, firstmedian)) {
+               stabilization_median_point_get(tracking, framenr, median);
 
                if ((stab->flag & TRACKING_AUTOSCALE) == 0)
                        stab->scale = 1.0f;
 
                if (!stab->ok) {
                        if (stab->flag & TRACKING_AUTOSCALE)
-                               stabilization_auto_scale_factor(tracking, width, height);
+                               stabilization_calculate_autoscale_factor(tracking, width, height);
 
-                       calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
+                       stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
 
                        stab->ok = TRUE;
                }
                else {
-                       calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
+                       stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
                }
        }
        else {
@@ -3022,8 +3340,8 @@ void BKE_tracking_stabilization_data(MovieTracking *tracking, int framenr, int w
        }
 }
 
-ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf,
-                              float loc[2], float *scale, float *angle)
+ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf *ibuf,
+                                    float loc[2], float *scale, float *angle)
 {
        float tloc[2], tscale, tangle;
        MovieTrackingStabilization *stab = &tracking->stabilization;
@@ -3047,17 +3365,17 @@ ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf,
                return ibuf;
        }
 
-       BKE_tracking_stabilization_data(tracking, framenr, width, height, tloc, &tscale, &tangle);
+       BKE_tracking_stabilization_data_get(tracking, framenr, width, height, tloc, &tscale, &tangle);
 
-       tmpibuf = stabilize_alloc_ibuf(NULL, ibuf, TRUE);
+       tmpibuf = stabilization_allocate_ibuf(NULL, ibuf, TRUE);
 
        /* scale would be handled by matrix transformation when angle is non-zero */
        if (tscale != 1.0f && tangle == 0.0f) {
                ImBuf *scaleibuf;
 
-               stabilization_auto_scale_factor(tracking, width, height);
+               stabilization_calculate_autoscale_factor(tracking, width, height);
 
-               scaleibuf = stabilize_alloc_ibuf(stab->scaleibuf, ibuf, 0);
+               scaleibuf = stabilization_allocate_ibuf(stab->scaleibuf, ibuf, 0);
                stab->scaleibuf = scaleibuf;
 
                IMB_rectcpy(scaleibuf, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
@@ -3080,7 +3398,7 @@ ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf,
                int i, j, filter = tracking->stabilization.filter;
                void (*interpolation)(struct ImBuf *, struct ImBuf *, float, float, int, int) = NULL;
 
-               BKE_tracking_stabdata_to_mat4(ibuf->x, ibuf->y, aspect, tloc, tscale, tangle, mat);
+               BKE_tracking_stabilization_data_to_mat4(ibuf->x, ibuf->y, aspect, tloc, tscale, tangle, mat);
                invert_m4(mat);
 
                if (filter == TRACKING_FILTER_NEAREAST)
@@ -3121,8 +3439,8 @@ ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf,
        return tmpibuf;
 }
 
-void BKE_tracking_stabdata_to_mat4(int width, int height, float aspect,
-                                   float loc[2], float scale, float angle, float mat[4][4])
+void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, float loc[2],
+                                             float scale, float angle, float mat[4][4])
 {
        float lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4], amat[4][4], iamat[4][4];
        float svec[3] = {scale, scale, scale};
@@ -3150,241 +3468,7 @@ void BKE_tracking_stabdata_to_mat4(int width, int height, float aspect,
        mul_serie_m4(mat, lmat, cmat, amat, rmat, iamat, smat, icmat, NULL);
 }
 
-MovieDistortion *BKE_tracking_distortion_create(void)
-{
-       MovieDistortion *distortion;
-
-       distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
-
-       return distortion;
-}
-
-MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
-{
-       MovieDistortion *new_distortion;
-
-       new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
-
-#ifdef WITH_LIBMV
-       new_distortion->intrinsics = libmv_CameraIntrinsicsCopy(distortion->intrinsics);
-#else
-       (void) distortion;
-#endif
-
-       return new_distortion;
-}
-
-void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking, int width, int height)
-{
-       MovieTrackingCamera *camera = &tracking->camera;
-       float aspy = 1.0f / tracking->camera.pixel_aspect;
-
-#ifdef WITH_LIBMV
-       if (!distortion->intrinsics) {
-               distortion->intrinsics = libmv_CameraIntrinsicsNew(camera->focal,
-                                                                  camera->principal[0], camera->principal[1] * aspy,
-                                                                  camera->k1, camera->k2, camera->k3, width, height * aspy);
-       }
-       else {
-               libmv_CameraIntrinsicsUpdate(distortion->intrinsics, camera->focal,
-                                            camera->principal[0], camera->principal[1] * aspy,
-                                            camera->k1, camera->k2, camera->k3, width, height * aspy);
-       }
-#else
-       (void) distortion;
-       (void) width;
-       (void) height;
-       (void) camera;
-       (void) aspy;
-#endif
-}
-
-ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *tracking,
-                                    ImBuf *ibuf, int width, int height, float overscan, int undistort)
-{
-       ImBuf *resibuf;
-
-       BKE_tracking_distortion_update(distortion, tracking, width, height);
-
-       resibuf = IMB_dupImBuf(ibuf);
-
-       if (ibuf->rect_float) {
-#ifdef WITH_LIBMV
-               if (undistort) {
-                       libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics,
-                                                            ibuf->rect_float, resibuf->rect_float,
-                                                            ibuf->x, ibuf->y, overscan, ibuf->channels);
-               }
-               else {
-                       libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics,
-                                                          ibuf->rect_float, resibuf->rect_float,
-                                                          ibuf->x, ibuf->y, overscan, ibuf->channels);
-               }
-#endif
-
-               resibuf->userflags |= IB_RECT_INVALID;
-       }
-       else {
-#ifdef WITH_LIBMV
-               if (undistort) {
-                       libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics,
-                                                           (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
-                                                           ibuf->x, ibuf->y, overscan, ibuf->channels);
-               }
-               else {
-                       libmv_CameraIntrinsicsDistortByte(distortion->intrinsics,
-                                                         (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
-                                                         ibuf->x, ibuf->y, overscan, ibuf->channels);
-               }
-#endif
-       }
-
-#ifndef WITH_LIBMV
-       (void) overscan;
-       (void) undistort;
-#endif
-
-       return resibuf;
-}
-
-void BKE_tracking_distortion_destroy(MovieDistortion *distortion)
-{
-#ifdef WITH_LIBMV
-       libmv_CameraIntrinsicsDestroy(distortion->intrinsics);
-#endif
-
-       MEM_freeN(distortion);
-}
-
-ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan)
-{
-       MovieTrackingCamera *camera = &tracking->camera;
-
-       if (camera->intrinsics == NULL)
-               camera->intrinsics = BKE_tracking_distortion_create();
-
-       return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 1);
-}
-
-ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan)
-{
-       MovieTrackingCamera *camera = &tracking->camera;
-
-       if (camera->intrinsics == NULL)
-               camera->intrinsics = BKE_tracking_distortion_create();
-
-       return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 0);
-}
-
-/* area - which part of marker should be selected. see TRACK_AREA_* constants */
-void BKE_tracking_select_track(ListBase *tracksbase, MovieTrackingTrack *track, int area, int extend)
-{
-       if (extend) {
-               BKE_tracking_track_flag(track, area, SELECT, 0);
-       }
-       else {
-               MovieTrackingTrack *cur = tracksbase->first;
-
-               while (cur) {
-                       if ((cur->flag & TRACK_HIDDEN) == 0) {
-                               if (cur == track) {
-                                       BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1);
-                                       BKE_tracking_track_flag(cur, area, SELECT, 0);
-                               }
-                               else {
-                                       BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1);
-                               }
-                       }
-
-                       cur = cur->next;
-               }
-       }
-}
-
-void BKE_tracking_deselect_track(MovieTrackingTrack *track, int area)
-{
-       BKE_tracking_track_flag(track, area, SELECT, 1);
-}
-
-MovieTrackingObject *BKE_tracking_new_object(MovieTracking *tracking, const char *name)
-{
-       MovieTrackingObject *object = MEM_callocN(sizeof(MovieTrackingObject), "tracking object");
-
-       if (tracking->tot_object == 0) {
-               /* first object is always camera */
-               BLI_strncpy(object->name, "Camera", sizeof(object->name));
-
-               object->flag |= TRACKING_OBJECT_CAMERA;
-       }
-       else {
-               BLI_strncpy(object->name, name, sizeof(object->name));
-       }
-
-       BLI_addtail(&tracking->objects, object);
-
-       tracking->tot_object++;
-       tracking->objectnr = BLI_countlist(&tracking->objects) - 1;
-
-       object->scale = 1.0f;
-
-       BKE_tracking_object_unique_name(tracking, object);
-
-       return object;
-}
-
-void BKE_tracking_remove_object(MovieTracking *tracking, MovieTrackingObject *object)
-{
-       MovieTrackingTrack *track;
-       int index = BLI_findindex(&tracking->objects, object);
-
-       if (index < 0)
-               return;
-
-       if (object->flag & TRACKING_OBJECT_CAMERA) {
-               /* object used for camera solving can't be deleted */
-               return;
-       }
-
-       track = object->tracks.first;
-       while (track) {
-               if (track == tracking->act_track)
-                       tracking->act_track = NULL;
-
-               track = track->next;
-       }
-
-       tracking_object_free(object);
-       BLI_freelinkN(&tracking->objects, object);
-
-       tracking->tot_object--;
-
-       if (index > 0)
-               tracking->objectnr = index - 1;
-       else
-               tracking->objectnr = 0;
-}
-
-void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object)
-{
-       BLI_uniquename(&tracking->objects, object, "Object", '.',
-                      offsetof(MovieTrackingObject, name), sizeof(object->name));
-}
-
-MovieTrackingObject *BKE_tracking_named_object(MovieTracking *tracking, const char *name)
-{
-       MovieTrackingObject *object = tracking->objects.first;
-
-       while (object) {
-               if (!strcmp(object->name, name))
-                       return object;
-
-               object = object->next;
-       }
-
-       return NULL;
-}
-
-/*********************** dopesheet functions *************************/
+/*********************** Dopesheet functions *************************/
 
 static int channels_alpha_sort(void *a, void *b)
 {
@@ -3586,11 +3670,11 @@ void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking)
 
 void BKE_tracking_dopesheet_update(MovieTracking *tracking)
 {
-       MovieTrackingObject *object = BKE_tracking_active_object(tracking);
+       MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
        MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
        MovieTrackingTrack *track;
        MovieTrackingReconstruction *reconstruction;
-       ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
+       ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
 
        short sort_method = dopesheet->sort_method;
        short inverse = dopesheet->flag & TRACKING_DOPE_SORT_INVERSE;
@@ -3602,7 +3686,7 @@ void BKE_tracking_dopesheet_update(MovieTracking *tracking)
 
        tracking_dopesheet_free(dopesheet);
 
-       reconstruction = BKE_tracking_object_reconstruction(tracking, object);
+       reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
 
        for (track = tracksbase->first; track; track = track->next) {
                MovieTrackingDopesheetChannel *channel;
index db4d40d..48f9d1d 100644 (file)
@@ -7260,7 +7260,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        tracking->settings.object_distance = 1.0f;
                                
                                if (tracking->objects.first == NULL)
-                                       BKE_tracking_new_object(tracking, "Camera");
+                                       BKE_tracking_object_add(tracking, "Camera");
                                
                                while (tracking_object) {
                                        if (!tracking_object->scale)
index eac581d..6a325d7 100644 (file)
@@ -91,7 +91,7 @@ void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContex
 
        if (ibuf) {
                if (stab->flag&TRACKING_2D_STABILIZATION) {
-                       BKE_tracking_stabilization_data(&movieClip->tracking, context->getFramenumber(), ibuf->x, ibuf->y, loc, &scale, &angle);
+                       BKE_tracking_stabilization_data_get(&movieClip->tracking, context->getFramenumber(), ibuf->x, ibuf->y, loc, &scale, &angle);
                }
        }
        
index 757afe7..f630155 100644 (file)
@@ -87,15 +87,15 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri
        int height = this->getHeight();
 
        if (this->trackingObject[0]) {
-               MovieTrackingObject *object = BKE_tracking_named_object(tracking, this->trackingObject);
+               MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, this->trackingObject);
 
                if (!object)
                        return NULL;
 
-               tracksbase = BKE_tracking_object_tracks(tracking, object);
+               tracksbase = BKE_tracking_object_get_tracks(tracking, object);
        }
        else
-               tracksbase = BKE_tracking_get_tracks(tracking);
+               tracksbase = BKE_tracking_get_active_tracks(tracking);
 
        sites_total = BLI_countlist(tracksbase);
 
@@ -115,7 +115,7 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri
        i = 0;
        while (track) {
                VoronoiSite *site = &sites[i];
-               MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenumber);
+               MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenumber);
                ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE);
                int j;
 
index a81288b..5a2e58d 100644 (file)
@@ -41,7 +41,7 @@ void MovieClipAttributeOperation::executePixel(float *outputValue, float x, floa
                scale = 1.0f;
                angle = 0.0f;
                if (clip) {
-                       BKE_tracking_stabilization_data(&clip->tracking, framenumber, getWidth(), getHeight(), loc, &scale, &angle);
+                       BKE_tracking_stabilization_data_get(&clip->tracking, framenumber, getWidth(), getHeight(), loc, &scale, &angle);
                }
                switch (this->attribute) {
                case MCA_SCALE:
index 9c7050e..c2ce04a 100644 (file)
@@ -99,10 +99,10 @@ public:
                                in[1] = (y /* - 0.5 * overscan * h */) / aspy / this->pixel_aspect;
 
                                if (inverted) {
-                                       BKE_tracking_invert_intrinsics(trackingData, in, out);
+                                       BKE_tracking_undistort_v2(trackingData, in, out);
                                }
                                else {
-                                       BKE_tracking_apply_intrinsics(trackingData, in, out);
+                                       BKE_tracking_distort_v2(trackingData, in, out);
                                }
 
                                buffer[offset2] = out[0] * aspx /* + 0.5 * overscan * w */;
index 7708d99..ed530be 100644 (file)
@@ -150,7 +150,7 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
                                
                                if (clip) {
                                        if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
-                                               MovieTrackingTrack *track = BKE_tracking_active_track(&clip->tracking);
+                                               MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking);
 
                                                if (!track)
                                                        return NULL;
index 4004efa..6d90824 100644 (file)
@@ -1033,8 +1033,8 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
                        
                        if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
                                int framenr = sc->user.framenr;
-                               MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking);
-                               MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr);
+                               MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking);
+                               MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr);
                                
                                p->imat[3][0] -= marker->pos[0];
                                p->imat[3][1] -= marker->pos[1];
index 22aa103..3c80202 100644 (file)
@@ -1549,7 +1549,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
                if (scopes->track_preview)
                        IMB_freeImBuf(scopes->track_preview);
 
-               tmpibuf = BKE_tracking_sample_pattern_imbuf(scopes->frame_width, scopes->frame_height,
+               tmpibuf = BKE_tracking_sample_pattern(scopes->frame_width, scopes->frame_height,
                                                            scopes->track_search, scopes->track,
                                                            &scopes->undist_marker, scopes->use_track_mask,
                                                            width, height, scopes->track_pos);
index 4615906..a8a7a55 100644 (file)
@@ -4203,7 +4203,7 @@ static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDa
        else {
                if (!scopes->track_locked) {
                        if (scopes->marker->framenr != scopes->framenr)
-                               scopes->marker = BKE_tracking_ensure_marker(scopes->track, scopes->framenr);
+                               scopes->marker = BKE_tracking_marker_ensure(scopes->track, scopes->framenr);
 
                        scopes->marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
                        scopes->marker->pos[0] += -dx * scopes->slide_scale[0] / (but->block->maxx - but->block->minx);
index 77fe2a7..7ba3c27 100644 (file)
@@ -113,8 +113,8 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
        if ((NULL == (sc = CTX_wm_space_clip(C))) ||
            (NULL == (clip = sc->clip)) ||
            (NULL == (track = clip->tracking.act_track)) ||
-           (NULL == (marker = BKE_tracking_get_marker(track, sc->user.framenr))) ||
-           (NULL == (tracking = BKE_tracking_active_object(&clip->tracking))))
+           (NULL == (marker = BKE_tracking_marker_get(track, sc->user.framenr))) ||
+           (NULL == (tracking = BKE_tracking_object_get_active(&clip->tracking))))
        {
                return OPERATOR_CANCELLED;
        }
index 7cc11fa..a38c69f 100644 (file)
@@ -418,15 +418,15 @@ static void test_constraints(Object *owner, bPoseChannel *pchan)
                                                MovieTrackingObject *tracking_object;
                                                
                                                if (data->object[0])
-                                                       tracking_object = BKE_tracking_named_object(tracking, data->object);
+                                                       tracking_object = BKE_tracking_object_get_named(tracking, data->object);
                                                else
-                                                       tracking_object = BKE_tracking_get_camera_object(tracking);
+                                                       tracking_object = BKE_tracking_object_get_camera(tracking);
                                                
                                                if (!tracking_object) {
                                                        curcon->flag |= CONSTRAINT_DISABLE;
                                                }
                                                else {
-                                                       if (!BKE_tracking_named_track(tracking, tracking_object, data->track))
+                                                       if (!BKE_tracking_track_get_named(tracking, tracking_object, data->track))
                                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                }
                                        }
index 66fa2ae..3a12156 100644 (file)
@@ -211,7 +211,7 @@ static void marker_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
        if (!cb->compact)
                return;
 
-       marker = BKE_tracking_ensure_marker(cb->track, cb->framenr);
+       marker = BKE_tracking_marker_ensure(cb->track, cb->framenr);
 
        marker->flag = cb->marker_flag;
 
@@ -226,7 +226,7 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event)
 
        BKE_movieclip_get_size(cb->clip, cb->user, &width, &height);
 
-       marker = BKE_tracking_ensure_marker(cb->track, cb->framenr);
+       marker = BKE_tracking_marker_ensure(cb->track, cb->framenr);
 
        if (event == B_MARKER_POS) {
                marker->pos[0] = cb->marker_pos[0] / width;
@@ -258,7 +258,7 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event)
                        cb->marker->pattern_corners[a][1] *= scale_y;
                }
 
-               BKE_tracking_clamp_marker(cb->marker, CLAMP_PAT_DIM);
+               BKE_tracking_marker_clamp(cb->marker, CLAMP_PAT_DIM);
 
                ok = TRUE;
        }
@@ -274,7 +274,7 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event)
                sub_v2_v2v2(cb->marker->search_min, delta, side);
                add_v2_v2v2(cb->marker->search_max, delta, side);
 
-               BKE_tracking_clamp_marker(cb->marker, CLAMP_SEARCH_POS);
+               BKE_tracking_marker_clamp(cb->marker, CLAMP_SEARCH_POS);
 
                ok = TRUE;
        }
@@ -295,7 +295,7 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event)
                cb->marker->search_max[0] += dim[0];
                cb->marker->search_max[1] += dim[1];
 
-               BKE_tracking_clamp_marker(cb->marker, CLAMP_SEARCH_DIM);
+               BKE_tracking_marker_clamp(cb->marker, CLAMP_SEARCH_DIM);
 
                ok = TRUE;
        }
@@ -364,7 +364,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P
        user = userptr->data;
        track = trackptr->data;
 
-       marker = BKE_tracking_get_marker(track, user->framenr);
+       marker = BKE_tracking_marker_get(track, user->framenr);
 
        cb = MEM_callocN(sizeof(MarkerUpdateCb), "uiTemplateMarker update_cb");
        cb->compact = compact;
index 6576d2a..716994f 100644 (file)
@@ -93,10 +93,10 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op)
        SpaceClip *sc = CTX_wm_space_clip(C);
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       MovieTrackingObject *object = BKE_tracking_active_object(tracking);
+       MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
        MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
        MovieTrackingDopesheetChannel *channel;
-       ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
+       ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
        float location[2];
        int extend = RNA_boolean_get(op->ptr, "extend");
        int current_channel_index = 0, channel_index;
@@ -115,7 +115,7 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op)
 
                        if (track->flag & TRACK_DOPE_SEL) {
                                tracking->act_track = track;
-                               BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, TRUE);
+                               BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, TRUE);
                        }
                }
                else if (!extend)
index 655a09e..ec70944 100644 (file)
@@ -98,8 +98,8 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
        float x;
        int *points, totseg, i, a;
        float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1);
-       MovieTrackingTrack *act_track = BKE_tracking_active_track(&clip->tracking);
-       MovieTrackingReconstruction *reconstruction = BKE_tracking_get_reconstruction(&clip->tracking);
+       MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
+       MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(&clip->tracking);
 
        glEnable(GL_BLEND);
 
@@ -346,14 +346,14 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin
 
        start_frame = framenr = ED_space_clip_clip_framenr(sc);
 
-       marker = BKE_tracking_get_marker(track, framenr);
+       marker = BKE_tracking_marker_get(track, framenr);
        if (marker->framenr != framenr || marker->flag & MARKER_DISABLED)
                return;
 
        a = count;
        i = framenr - 1;
        while (i >= framenr - count) {
-               marker = BKE_tracking_get_marker(track, i);
+               marker = BKE_tracking_marker_get(track, i);
 
                if (!marker || marker->flag & MARKER_DISABLED)
                        break;
@@ -375,7 +375,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin
        b = count;
        i = framenr;
        while (i <= framenr + count) {
-               marker = BKE_tracking_get_marker(track, i);
+               marker = BKE_tracking_marker_get(track, i);
 
                if (!marker || marker->flag & MARKER_DISABLED)
                        break;
@@ -943,7 +943,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
 {
        float x, y;
        MovieTracking *tracking = &clip->tracking;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
        MovieTrackingTrack *track, *act_track;
        MovieTrackingMarker *marker;
        int framenr = ED_space_clip_clip_framenr(sc);
@@ -967,7 +967,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
        glMultMatrixf(sc->stabmat);
        glScalef(width, height, 0);
 
-       act_track = BKE_tracking_active_track(tracking);
+       act_track = BKE_tracking_track_get_active(tracking);
 
        if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
                int count = 0;
@@ -976,7 +976,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
                track = tracksbase->first;
                while (track) {
                        if ((track->flag & TRACK_HIDDEN) == 0) {
-                               marker = BKE_tracking_get_marker(track, framenr);
+                               marker = BKE_tracking_marker_get(track, framenr);
 
                                if (MARKER_VISIBLE(sc, track, marker))
                                        count++;
@@ -993,7 +993,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
                        fp = marker_pos;
                        while (track) {
                                if ((track->flag & TRACK_HIDDEN) == 0) {
-                                       marker = BKE_tracking_get_marker(track, framenr);
+                                       marker = BKE_tracking_marker_get(track, framenr);
 
                                        if (MARKER_VISIBLE(sc, track, marker)) {
                                                ED_clip_point_undistorted_pos(sc, marker->pos, fp);
@@ -1025,7 +1025,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
        fp = marker_pos;
        while (track) {
                if ((track->flag & TRACK_HIDDEN) == 0) {
-                       marker = BKE_tracking_get_marker(track, framenr);
+                       marker = BKE_tracking_marker_get(track, framenr);
 
                        if (MARKER_VISIBLE(sc, track, marker)) {
                                copy_v2_v2(cur_pos, fp ? fp : marker->pos);
@@ -1050,7 +1050,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
        while (track) {
                if ((track->flag & TRACK_HIDDEN) == 0) {
                        int act = track == act_track;
-                       marker = BKE_tracking_get_marker(track, framenr);
+                       marker = BKE_tracking_marker_get(track, framenr);
 
                        if (MARKER_VISIBLE(sc, track, marker)) {
                                if (!act) {
@@ -1071,7 +1071,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
        /* active marker would be displayed on top of everything else */
        if (act_track) {
                if ((act_track->flag & TRACK_HIDDEN) == 0) {
-                       marker = BKE_tracking_get_marker(act_track, framenr);
+                       marker = BKE_tracking_marker_get(act_track, framenr);
 
                        if (MARKER_VISIBLE(sc, act_track, marker)) {
                                copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos);
@@ -1083,19 +1083,19 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
        }
 
        if (sc->flag & SC_SHOW_BUNDLES) {
-               MovieTrackingObject *object = BKE_tracking_active_object(tracking);
+               MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
                float pos[4], vec[4], mat[4][4], aspy;
 
                glEnable(GL_POINT_SMOOTH);
                glPointSize(3.0f);
 
                aspy = 1.0f / clip->tracking.camera.pixel_aspect;
-               BKE_tracking_projection_matrix(tracking, object, framenr, width, height, mat);
+               BKE_tracking_get_projection_matrix(tracking, object, framenr, width, height, mat);
 
                track = tracksbase->first;
                while (track) {
                        if ((track->flag & TRACK_HIDDEN) == 0 && track->flag & TRACK_HAS_BUNDLE) {
-                               marker = BKE_tracking_get_marker(track, framenr);
+                               marker = BKE_tracking_marker_get(track, framenr);
 
                                if (MARKER_VISIBLE(sc, track, marker)) {
                                        float npos[2];
@@ -1107,7 +1107,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
                                        pos[0] = (pos[0] / (pos[3] * 2.0f) + 0.5f) * width;
                                        pos[1] = (pos[1] / (pos[3] * 2.0f) + 0.5f) * height * aspy;
 
-                                       BKE_tracking_apply_intrinsics(tracking, pos, npos);
+                                       BKE_tracking_distort_v2(tracking, pos, npos);
 
                                        if (npos[0] >= 0.0f && npos[1] >= 0.0f && npos[0] <= width && npos[1] <= height * aspy) {
                                                vec[0] = (marker->pos[0] + track->offset[0]) * width;
@@ -1145,7 +1145,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
                fp = marker_pos;
                while (track) {
                        if ((track->flag & TRACK_HIDDEN) == 0) {
-                               marker = BKE_tracking_get_marker(track, framenr);
+                               marker = BKE_tracking_marker_get(track, framenr);
 
                                if (MARKER_VISIBLE(sc, track, marker)) {
                                        int act = track == act_track;
@@ -1215,7 +1215,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
                for (i = 0; i <= n; i++) {
                        for (j = 0; j <= n; j++) {
                                if (i == 0 || j == 0 || i == n || j == n) {
-                                       BKE_tracking_apply_intrinsics(tracking, pos, tpos);
+                                       BKE_tracking_distort_v2(tracking, pos, tpos);
 
                                        for (a = 0; a < 4; a++) {
                                                int ok;
@@ -1246,7 +1246,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
                        pos[0] = idx[a][0] * dx;
                        pos[1] = idx[a][1] * dy;
 
-                       BKE_tracking_invert_intrinsics(tracking, pos, tpos);
+                       BKE_tracking_undistort_v2(tracking, pos, tpos);
 
                        DO_MINMAX2(tpos, min, max);
                }
@@ -1257,7 +1257,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
 
                for (i = 0; i <= n; i++) {
                        for (j = 0; j <= n; j++) {
-                               BKE_tracking_apply_intrinsics(tracking, pos, grid[i][j]);
+                               BKE_tracking_distort_v2(tracking, pos, grid[i][j]);
 
                                grid[i][j][0] /= width;
                                grid[i][j][1] /= height * aspy;
@@ -1289,11 +1289,11 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
        }
 
        if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
-               MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking);
+               MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking);
 
                if (track) {
                        int framenr = sc->user.framenr;
-                       MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr);
+                       MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr);
 
                        offsx = marker->pos[0];
                        offsy = marker->pos[1];
@@ -1343,15 +1343,15 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
 
                                                                /* we want to distort only long straight lines */
                                                                if (stroke->totpoints == 2) {
-                                                                       BKE_tracking_invert_intrinsics(tracking, pos, pos);
-                                                                       BKE_tracking_invert_intrinsics(tracking, npos, npos);
+                                                                       BKE_tracking_undistort_v2(tracking, pos, pos);
+                                                                       BKE_tracking_undistort_v2(tracking, npos, npos);
                                                                }
 
                                                                sub_v2_v2v2(dpos, npos, pos);
                                                                mul_v2_fl(dpos, 1.0f / steps);
 
                                                                for (j = 0; j <= steps; j++) {
-                                                                       BKE_tracking_apply_intrinsics(tracking, pos, tpos);
+                                                                       BKE_tracking_distort_v2(tracking, pos, tpos);
                                                                        glVertex2f(tpos[0] / width, tpos[1] / (height * aspy));
 
                                                                        add_v2_v2(pos, dpos);
@@ -1410,7 +1410,7 @@ void clip_draw_main(SpaceClip *sc, ARegion *ar, Scene *scene)
                        else
                                copy_v2_v2(loc, sc->loc);
 
-                       BKE_tracking_stabdata_to_mat4(width, height, aspect, loc, sc->scale, sc->angle, sc->stabmat);
+                       BKE_tracking_stabilization_data_to_mat4(width, height, aspect, loc, sc->scale, sc->angle, sc->stabmat);
 
                        unit_m4(smat);
                        smat[0][0] = 1.0f / width;
@@ -1463,12 +1463,12 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d)
                        glMultMatrixf(sc->unistabmat);
 
                        if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
-                               MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking);
+                               MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking);
 
                                if (track) {
                                        int framenr = sc->user.framenr;
                                        /* don't get the exact marker since it may not exist for the frame */
-                                       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
+                                       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
                                        if (marker) {
                                                glTranslatef(marker->pos[0], marker->pos[1], 0.0f);
                                        }
index 3096536..275cb78 100644 (file)
@@ -342,7 +342,7 @@ static int selected_boundbox(SpaceClip *sc, float min[2], float max[2])
        MovieClip *clip = ED_space_clip(sc);
        MovieTrackingTrack *track;
        int width, height, ok = FALSE;
-       ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
 
        INIT_MINMAX2(min, max);
 
@@ -351,7 +351,7 @@ static int selected_boundbox(SpaceClip *sc, float min[2], float max[2])
        track = tracksbase->first;
        while (track) {
                if (TRACK_VIEW_SELECTED(sc, track)) {
-                       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr);
+                       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, sc->user.framenr);
 
                        if (marker) {
                                float pos[3];
@@ -439,7 +439,7 @@ void ED_clip_point_undistorted_pos(SpaceClip *sc, const float co[2], float r_co[
                r_co[0] *= width;
                r_co[1] *= height * aspy;
 
-               BKE_tracking_invert_intrinsics(&clip->tracking, r_co, r_co);
+               BKE_tracking_undistort_v2(&clip->tracking, r_co, r_co);
 
                r_co[0] /= width;
                r_co[1] /= height * aspy;
@@ -474,7 +474,7 @@ void ED_clip_point_stable_pos(bContext *C, float x, float y, float *xr, float *y
                float aspy = 1.0f / tracking->camera.pixel_aspect;
                float tmp[2] = {*xr * width, *yr * height * aspy};
 
-               BKE_tracking_apply_intrinsics(tracking, tmp, tmp);
+               BKE_tracking_distort_v2(tracking, tmp, tmp);
 
                *xr = tmp[0] / width;
                *yr = tmp[1] / (height * aspy);
index d3d01f9..6290adf 100644 (file)
@@ -148,7 +148,7 @@ static void draw_tracks_curves(View2D *v2d, SpaceClip *sc)
 {
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
+       MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
        int width, height;
        struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } userdata;
 
@@ -182,7 +182,7 @@ static void draw_frame_curves(SpaceClip *sc)
 {
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       MovieTrackingReconstruction *reconstruction = BKE_tracking_get_reconstruction(tracking);
+       MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
        int i, lines = 0, prevfra = 0;
 
        glColor3f(0.0f, 0.0f, 1.0f);
index 64547d3..b7687eb 100644 (file)
@@ -170,7 +170,7 @@ static int mouse_select_knot(bContext *C, float co[2], int extend)
        ARegion *ar = CTX_wm_region(C);
        View2D *v2d = &ar->v2d;
        MovieTracking *tracking = &clip->tracking;
-       MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
+       MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
        static const int delta = 6;
 
        if (act_track) {
@@ -213,7 +213,7 @@ static int mouse_select_curve(bContext *C, float co[2], int extend)
        SpaceClip *sc = CTX_wm_space_clip(C);
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
+       MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
        MouseSelectUserData userdata;
 
        mouse_select_init_data(&userdata, co);
@@ -230,11 +230,11 @@ static int mouse_select_curve(bContext *C, float co[2], int extend)
                }
                else if (act_track != userdata.track) {
                        SelectUserData selectdata = {SEL_DESELECT};
-                       MovieTrackingObject *object = BKE_tracking_active_object(tracking);
-                       ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
+                       MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
+                       ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
 
                        tracking->act_track = userdata.track;
-                       BKE_tracking_select_track(tracksbase, userdata.track, TRACK_AREA_ALL, TRUE);
+                       BKE_tracking_track_select(tracksbase, userdata.track, TRACK_AREA_ALL, TRUE);
 
                        /* deselect all knots on newly selected curve */
                        clip_graph_tracking_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY,
@@ -347,7 +347,7 @@ static int border_select_graph_exec(bContext *C, wmOperator *op)
        ARegion *ar = CTX_wm_region(C);
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
+       MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
        BorderSelectuserData userdata;
        rcti rect;
 
@@ -402,7 +402,7 @@ static int graph_select_all_markers_exec(bContext *C, wmOperator *op)
        SpaceClip *sc = CTX_wm_space_clip(C);
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
+       MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
        MovieTrackingMarker *marker;
        int action = RNA_enum_get(op->ptr, "action");
        int a;
@@ -468,8 +468,8 @@ static int delete_curve_exec(bContext *C, wmOperator *UNUSED(op))
        SpaceClip *sc = CTX_wm_space_clip(C);
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
-       MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+       MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
 
        if (act_track)
                clip_delete_track(C, clip, tracksbase, act_track);
@@ -500,8 +500,8 @@ static int delete_knot_exec(bContext *C, wmOperator *UNUSED(op))
        SpaceClip *sc = CTX_wm_space_clip(C);
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
-       MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+       MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
 
        if (act_track) {
                int a = 0;
@@ -650,7 +650,7 @@ static int graph_disable_markers_exec(bContext *C, wmOperator *op)
        SpaceClip *sc = CTX_wm_space_clip(C);
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
+       MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
        MovieTrackingMarker *marker;
        int action = RNA_enum_get(op->ptr, "action");
        int a;
index 73eb8ee..d5ec65e 100644 (file)
@@ -986,7 +986,7 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog
        }
 
        if (build_undistort_count)
-               distortion = BKE_tracking_distortion_create();
+               distortion = BKE_tracking_distortion_new();
 
        for (cfra = sfra; cfra <= efra; cfra++) {
                if (clip->source != MCLIP_SRC_MOVIE)
@@ -1003,7 +1003,7 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog
        }
 
        if (distortion)
-               BKE_tracking_distortion_destroy(distortion);
+               BKE_tracking_distortion_free(distortion);
 
        if (*stop)
                pj->stop = 1;
index 51870c6..8dda125 100644 (file)
@@ -128,7 +128,7 @@ void clip_graph_tracking_values_iterate(SpaceClip *sc, int selected_only, int in
 {
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
        MovieTrackingTrack *track;
 
        for (track = tracksbase->first; track; track = track->next) {
@@ -147,7 +147,7 @@ void clip_graph_tracking_iterate(SpaceClip *sc, int selected_only, int include_h
 {
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
        MovieTrackingTrack *track;
 
        for (track = tracksbase->first; track; track = track->next) {
@@ -175,7 +175,7 @@ void clip_delete_track(bContext *C, MovieClip *clip, ListBase *tracksbase, Movie
 {
        MovieTracking *tracking = &clip->tracking;
        MovieTrackingStabilization *stab = &tracking->stabilization;
-       MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
+       MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
 
        int has_bundle = FALSE, update_stab = FALSE;
 
@@ -192,7 +192,7 @@ void clip_delete_track(bContext *C, MovieClip *clip, ListBase *tracksbase, Movie
        if (track->flag & TRACK_HAS_BUNDLE)
                has_bundle = TRUE;
 
-       BKE_tracking_free_track(track);
+       BKE_tracking_track_free(track);
        BLI_freelinkN(tracksbase, track);
 
        WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
@@ -215,7 +215,7 @@ void clip_delete_marker(bContext *C, MovieClip *clip, ListBase *tracksbase,
                clip_delete_track(C, clip, tracksbase, track);
        }
        else {
-               BKE_tracking_delete_marker(track, marker->framenr);
+               BKE_tracking_marker_delete(track, marker->framenr);
 
                WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
        }
index 2f684f9..174b7fc 100644 (file)
@@ -1084,7 +1084,7 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
        /* if tracking is in progress, we should synchronize framenr from clipuser
         * so latest tracked frame would be shown */
        if (clip && clip->tracking_context)
-               BKE_tracking_sync_user(&sc->user, clip->tracking_context);
+               BKE_tracking_context_sync_user(clip->tracking_context, &sc->user);
 
        if (sc->flag & SC_LOCK_SELECTION) {
                ImBuf *tmpibuf = NULL;
index 3a19580..f3a7d4e 100644 (file)
@@ -87,16 +87,16 @@ static void add_marker(SpaceClip *sc, float x, float y)
 {
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
        MovieTrackingTrack *track;
        int width, height;
        int framenr = ED_space_clip_clip_framenr(sc);
 
        ED_space_clip_size(sc, &width, &height);
 
-       track = BKE_tracking_add_track(tracking, tracksbase, x, y, framenr, width, height);
+       track = BKE_tracking_track_add(tracking, tracksbase, x, y, framenr, width, height);
 
-       BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, 0);
+       BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, 0);
 
        clip->tracking.act_track = track;
 }
@@ -164,7 +164,7 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op))
        SpaceClip *sc = CTX_wm_space_clip(C);
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
        MovieTrackingTrack *track = tracksbase->first, *next;
 
        while (track) {
@@ -204,7 +204,7 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op))
 {
        SpaceClip *sc = CTX_wm_space_clip(C);
        MovieClip *clip = ED_space_clip(sc);
-       ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
        MovieTrackingTrack *track = tracksbase->first, *next;
        int framenr = ED_space_clip_clip_framenr(sc);
        int has_selection = 0;
@@ -213,7 +213,7 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op))
                next = track->next;
 
                if (TRACK_VIEW_SELECTED(sc, track)) {
-                       MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr);
+                       MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr);
 
                        if (marker) {
                                has_selection |= track->markersnr > 1;
@@ -276,7 +276,7 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra
        SlideMarkerData *data = MEM_callocN(sizeof(SlideMarkerData), "slide marker data");
        int framenr = ED_space_clip_clip_framenr(sc);
 
-       marker = BKE_tracking_ensure_marker(track, framenr);
+       marker = BKE_tracking_marker_ensure(track, framenr);
 
        data->area = area;
        data->action = action;
@@ -493,7 +493,7 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event)
        int width, height;
        float co[2];
        void *customdata = NULL;
-       ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
        int framenr = ED_space_clip_clip_framenr(sc);
 
        ED_space_clip_size(sc, &width, &height);
@@ -506,7 +506,7 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event)
        track = tracksbase->first;
        while (track) {
                if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
-                       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
+                       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
 
                        if ((marker->flag & MARKER_DISABLED) == 0) {
                                if (!customdata) {
@@ -702,9 +702,9 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event)
                                        }
 
                                        if (data->area == TRACK_AREA_SEARCH)
-                                               BKE_tracking_clamp_marker(data->marker, CLAMP_SEARCH_DIM);
+                                               BKE_tracking_marker_clamp(data->marker, CLAMP_SEARCH_DIM);
                                        else
-                                               BKE_tracking_clamp_marker(data->marker, CLAMP_PAT_DIM);
+                                               BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM);
                                }
                                else if (data->action == SLIDE_ACTION_OFFSET) {
                                        float d[2] = {dx, dy};
@@ -723,7 +723,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event)
                                        }
 
                                        if (data->area == TRACK_AREA_SEARCH)
-                                               BKE_tracking_clamp_marker(data->marker, CLAMP_SEARCH_POS);
+                                               BKE_tracking_marker_clamp(data->marker, CLAMP_SEARCH_POS);
                                }
                                else if (data->action == SLIDE_ACTION_POS) {
                                        if (data->scale) {
@@ -754,7 +754,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event)
                                        }
 
                                        /* currently only patterns are allowed to have such combination of event and data */
-                                       BKE_tracking_clamp_marker(data->marker, CLAMP_PAT_DIM);
+                                       BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM);
                                }
                        }
 
@@ -842,7 +842,7 @@ static int mouse_on_crns(float co[2], float pos[2], float crns[4][2], float epsx
 static int track_mouse_area(SpaceClip *sc, float co[2], MovieTrackingTrack *track)
 {
        int framenr = ED_space_clip_clip_framenr(sc);
-       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
+       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
        float pat_min[2], pat_max[2];
        float epsx, epsy;
        int width, height;
@@ -920,7 +920,7 @@ static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbas
 
        cur = tracksbase->first;
        while (cur) {
-               MovieTrackingMarker *marker = BKE_tracking_get_marker(cur, framenr);
+               MovieTrackingMarker *marker = BKE_tracking_marker_get(cur, framenr);
 
                if (((cur->flag & TRACK_HIDDEN) == 0) && MARKER_VISIBLE(sc, cur, marker)) {
                        float dist, d1, d2 = FLT_MAX, d3 = FLT_MAX;
@@ -957,8 +957,8 @@ static int mouse_select(bContext *C, float co[2], int extend)
        SpaceClip *sc = CTX_wm_space_clip(C);
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
-       MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+       MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
        MovieTrackingTrack *track = NULL;   /* selected marker */
 
        track = find_nearest_track(sc, tracksbase, co);
@@ -971,7 +971,7 @@ static int mouse_select(bContext *C, float co[2], int extend)
 
                if (extend && TRACK_AREA_SELECTED(track, area)) {
                        if (track == act_track)
-                               BKE_tracking_deselect_track(track, area);
+                               BKE_tracking_track_deselect(track, area);
                        else
                                clip->tracking.act_track = track;
                }
@@ -979,7 +979,7 @@ static int mouse_select(bContext *C, float co[2], int extend)
                        if (area == TRACK_AREA_POINT)
                                area = TRACK_AREA_ALL;
 
-                       BKE_tracking_select_track(tracksbase, track, area, extend);
+                       BKE_tracking_track_select(tracksbase, track, area, extend);
                        clip->tracking.act_track = track;
                }
        }
@@ -1066,7 +1066,7 @@ static int border_select_exec(bContext *C, wmOperator *op)
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
        MovieTrackingTrack *track;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
        rcti rect;
        rctf rectf;
        int change = FALSE, mode, extend;
@@ -1088,14 +1088,17 @@ static int border_select_exec(bContext *C, wmOperator *op)
        track = tracksbase->first;
        while (track) {
                if ((track->flag & TRACK_HIDDEN) == 0) {
-                       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
+                       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
 
                        if (MARKER_VISIBLE(sc, track, marker)) {
                                if (BLI_in_rctf(&rectf, marker->pos[0], marker->pos[1])) {
-                                       BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode != GESTURE_MODAL_SELECT);
+                                       if (mode == GESTURE_MODAL_SELECT)
+                                               BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT);
+                                       else
+                                               BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT);
                                }
                                else if (!extend) {
-                                       BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, 1);
+                                       BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT);
                                }
 
                                change = TRUE;
@@ -1144,7 +1147,7 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
        MovieTrackingTrack *track;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
        rcti rect;
        int change = FALSE;
        int framenr = ED_space_clip_clip_framenr(sc);
@@ -1156,7 +1159,7 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho
        track = tracksbase->first;
        while (track) {
                if ((track->flag & TRACK_HIDDEN) == 0) {
-                       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
+                       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
 
                        if (MARKER_VISIBLE(sc, track, marker)) {
                                float screen_co[2];
@@ -1167,7 +1170,10 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho
                                if (BLI_in_rcti(&rect, screen_co[0], screen_co[1]) &&
                                    BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], V2D_IS_CLIPPED))
                                {
-                                       BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, !select);
+                                       if (select)
+                                               BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT);
+                                       else
+                                               BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT);
                                }
 
                                change = TRUE;
@@ -1247,7 +1253,7 @@ static int circle_select_exec(bContext *C, wmOperator *op)
        ARegion *ar = CTX_wm_region(C);
        MovieTracking *tracking = &clip->tracking;
        MovieTrackingTrack *track;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
        int x, y, radius, width, height, mode, change = FALSE;
        float zoomx, zoomy, offset[2], ellipse[2];
        int framenr = ED_space_clip_clip_framenr(sc);
@@ -1272,10 +1278,13 @@ static int circle_select_exec(bContext *C, wmOperator *op)
        track = tracksbase->first;
        while (track) {
                if ((track->flag & TRACK_HIDDEN) == 0) {
-                       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
+                       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
 
                        if (MARKER_VISIBLE(sc, track, marker) && marker_inside_ellipse(marker, offset, ellipse)) {
-                               BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode != GESTURE_MODAL_SELECT);
+                               if (mode == GESTURE_MODAL_SELECT)
+                                       BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT);
+                               else
+                                       BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT);
 
                                change = TRUE;
                        }
@@ -1327,7 +1336,7 @@ static int select_all_exec(bContext *C, wmOperator *op)
        MovieTracking *tracking = &clip->tracking;
        MovieTrackingTrack *track = NULL;   /* selected track */
        MovieTrackingMarker *marker;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
        int action = RNA_enum_get(op->ptr, "action");
        int framenr = ED_space_clip_clip_framenr(sc);
        int has_selection = FALSE;
@@ -1337,7 +1346,7 @@ static int select_all_exec(bContext *C, wmOperator *op)
                track = tracksbase->first;
                while (track) {
                        if (TRACK_VIEW_SELECTED(sc, track)) {
-                               marker = BKE_tracking_get_marker(track, framenr);
+                               marker = BKE_tracking_marker_get(track, framenr);
 
                                if (MARKER_VISIBLE(sc, track, marker)) {
                                        action = SEL_DESELECT;
@@ -1352,7 +1361,7 @@ static int select_all_exec(bContext *C, wmOperator *op)
        track = tracksbase->first;
        while (track) {
                if ((track->flag & TRACK_HIDDEN) == 0) {
-                       marker = BKE_tracking_get_marker(track, framenr);
+                       marker = BKE_tracking_marker_get(track, framenr);
 
                        if (MARKER_VISIBLE(sc, track, marker)) {
                                switch (action) {
@@ -1417,7 +1426,7 @@ static int select_groped_exec(bContext *C, wmOperator *op)
        MovieTrackingTrack *track;
        MovieTrackingMarker *marker;
        MovieTracking *tracking = &clip->tracking;
-       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
        int group = RNA_enum_get(op->ptr, "group");
        int framenr = ED_space_clip_clip_framenr(sc);
 
@@ -1425,7 +1434,7 @@ static int select_groped_exec(bContext *C, wmOperator *op)
        while (track) {
                int ok = FALSE;
 
-               marker = BKE_tracking_get_marker(track, framenr);
+               marker = BKE_tracking_marker_get(track, framenr);
 
                if (group == 0) { /* Keyframed */
                        ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED) == 0;
@@ -1443,7 +1452,7 @@ static int select_groped_exec(bContext *C, wmOperator *op)
                        ok = marker->flag & MARKER_DISABLED;
                }
                else if (group == 5) { /* color */
-                       MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
+                       MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
 
                        if (act_track) {
                                ok = (track->flag & TRACK_CUSTOMCOLOR) == (act_track->flag & TRACK_CUSTOMCOLOR);
@@ -1525,14 +1534,14 @@ static int track_markers_testbreak(void)
 static int track_count_markers(SpaceClip *sc, MovieClip *clip)
 {
        int tot = 0;
-       ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
        MovieTrackingTrack *track;
        int framenr = ED_space_clip_clip_framenr(sc);
 
        track = tracksbase->first;
        while (track) {
                if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
-                       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
+                       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
 
                        if (!marker || (marker->flag & MARKER_DISABLED) == 0)
                                tot++;
@@ -1546,7 +1555,7 @@ static int track_count_markers(SpaceClip *sc, MovieClip *clip)
 
 static void clear_invisible_track_selection(SpaceClip *sc, MovieClip *clip)
 {
-       ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
        int hidden = 0;
 
        if ((sc->flag & SC_SHOW_MARKER_PATTERN) == 0)
@@ -1560,7 +1569,7 @@ static void clear_invisible_track_selection(SpaceClip *sc, MovieClip *clip)
 
                while (track) {
                        if ((track->flag & TRACK_HIDDEN) == 0)
-                               BKE_tracking_track_flag(track, hidden, SELECT, 1);
+                               BKE_tracking_track_flag_clear(track, hidden, SELECT);
 
                        track = track->next;
                }
@@ -1569,7 +1578,7 @@ static void clear_invisible_track_selection(SpaceClip *sc, MovieClip *clip)
 
 static void track_init_markers(SpaceClip *sc, MovieClip *clip, int *frames_limit_r)
 {
-       ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
        MovieTrackingTrack *track;
        int framenr = ED_space_clip_clip_framenr(sc);
        int frames_limit = 0;
@@ -1580,7 +1589,7 @@ static void track_init_markers(SpaceClip *sc, MovieClip *clip, int *frames_limit
        while (track) {
                if (TRACK_VIEW_SELECTED(sc, track)) {
                        if ((track->flag & TRACK_HIDDEN) == 0 && (track->flag & TRACK_LOCKED) == 0) {
-                               BKE_tracking_ensure_marker(track, framenr);
+                               BKE_tracking_marker_ensure(track, framenr);
 
                                if (track->frames_limit) {
                                        if (frames_limit == 0)
@@ -1685,14 +1694,14 @@ static void track_markers_startjob(void *tmv, short *stop, short *do_update, flo
 
                        double start_time = PIL_check_seconds_timer(), exec_time;
 
-                       if (!BKE_tracking_next(tmj->context))
+                       if (!BKE_tracking_context_step(tmj->context))
                                break;
 
                        exec_time = PIL_check_seconds_timer() - start_time;
                        if (tmj->delay > (float)exec_time)
                                PIL_sleep_ms(tmj->delay - (float)exec_time);
                }
-               else if (!BKE_tracking_next(tmj->context))
+               else if (!BKE_tracking_context_step(tmj->context))
                        break;
 
                *do_update = TRUE;
@@ -1716,7 +1725,7 @@ static void track_markers_updatejob(void *tmv)
 {
        TrackMarkersJob *tmj = (TrackMarkersJob *)tmv;
 
-       BKE_tracking_sync(tmj->context);
+       BKE_tracking_context_sync(tmj->context);
 }
 
 static void track_markers_freejob(void *tmv)
@@ -1727,7 +1736,7 @@ static void track_markers_freejob(void *tmv)
        tmj->scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(tmj->clip, tmj->lastfra);
        ED_update_for_newframe(tmj->main, tmj->scene, 0);
 
-       BKE_tracking_sync(tmj->context);
+       BKE_tracking_context_sync(tmj->context);
        BKE_tracking_context_free(tmj->context);
 
        MEM_freeN(tmj);
@@ -1774,7 +1783,7 @@ static int track_markers_exec(bContext *C, wmOperator *op)
        context = BKE_tracking_context_new(clip, &sc->user, backwards, sequence);
 
        while (framenr != efra) {
-               if (!BKE_tracking_next(context))
+               if (!BKE_tracking_context_step(context))
                        break;
 
                if (backwards) framenr--;
@@ -1784,7 +1793,7 @@ static int track_markers_exec(bContext *C, wmOperator *op)
                        break;
        }
 
-       BKE_tracking_sync(context);
+       BKE_tracking_context_sync(context);
        BKE_tracking_context_free(context);
 
        /* update scene current frame to the lastes tracked frame */
@@ -1911,10 +1920,10 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op
        Scene *scene = CTX_data_scene(C);
        MovieTracking *tracking = &clip->tracking;
        MovieTrackingSettings *settings = &clip->tracking.settings;
-       MovieTrackingObject *object = BKE_tracking_active_object(tracking);
+       MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
        int width, height;
 
-       if (!BKE_tracking_can_reconstruct(tracking, object, error_msg, max_error))
+       if (!BKE_tracking_reconstruction_check(tracking, object, error_msg, max_error))
                return 0;
 
        /* could fail if footage uses images with different sizes */
@@ -1945,7 +1954,7 @@ static void solve_camera_startjob(void *scv, short *stop, short *do_update, floa
 {
        SolveCameraJob *scj = (SolveCameraJob *)scv;
 
-       BKE_tracking_solve_reconstruction(scj->context, stop, do_update, progress,
+       BKE_tracking_reconstruction_solve(scj->context, stop, do_update, progress,
                                          scj->stats_message, sizeof(scj->stats_message));
 }
 
@@ -1963,7 +1972,7 @@ static void solve_camera_freejob(void *scv)
                return;
        }
 
-       solved = BKE_tracking_finish_reconstruction(scj->context, tracking);
+       solved = BKE_tracking_reconstruction_finish(scj->context, tracking);
 
        if (!solved)
                BKE_report(scj->reports, RPT_WARNING, "Some data failed to reconstruct, see console for details");
@@ -2033,7 +2042,7 @@ static int solve_camera_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(even
        SpaceClip *sc = CTX_wm_space_clip(C);
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       MovieTrackingReconstruction *reconstruction = BKE_tracking_get_reconstruction(tracking);
+       MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
        wmJob *steve;
        char error_msg[256] = "\0";
 
@@ -2115,8 +2124,8 @@ static int clear_solution_exec(bContext *C, wmOperator *UNUSED(op))
        SpaceClip *sc = CTX_wm_space_clip(C);
        MovieClip *clip = ED_space_clip(sc);
        MovieTracking *tracking = &clip->tracking;
-       ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking);
-       MovieTrackingReconstruction *reconstruction = BKE_tracking_get_reconstruction(tracking);
+       ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
+       MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
        MovieTrackingTrack *track = tracksbase->first;
 
        while (track) {