Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/blenkernel/intern/tracking_util.c
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/blenkernel/intern/tracking_util.c')
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c1345
1 files changed, 671 insertions, 674 deletions
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index f2f3e1d56b5..4de10aca0ec 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -61,172 +61,182 @@
/*********************** Tracks map *************************/
-TracksMap *tracks_map_new(const char *object_name, bool is_camera, int num_tracks, int customdata_size)
+TracksMap *tracks_map_new(const char *object_name,
+ bool is_camera,
+ int num_tracks,
+ int customdata_size)
{
- TracksMap *map = MEM_callocN(sizeof(TracksMap), "TrackingsMap");
+ TracksMap *map = MEM_callocN(sizeof(TracksMap), "TrackingsMap");
- BLI_strncpy(map->object_name, object_name, sizeof(map->object_name));
- map->is_camera = is_camera;
+ 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;
+ map->num_tracks = num_tracks;
+ map->customdata_size = customdata_size;
- map->tracks = MEM_callocN(sizeof(MovieTrackingTrack) * num_tracks, "TrackingsMap tracks");
+ map->tracks = MEM_callocN(sizeof(MovieTrackingTrack) * num_tracks, "TrackingsMap tracks");
- if (customdata_size)
- map->customdata = MEM_callocN(customdata_size * num_tracks, "TracksMap customdata");
+ if (customdata_size)
+ map->customdata = MEM_callocN(customdata_size * num_tracks, "TracksMap customdata");
- map->hash = BLI_ghash_ptr_new("TracksMap hash");
+ map->hash = BLI_ghash_ptr_new("TracksMap hash");
- BLI_spin_init(&map->spin_lock);
+ BLI_spin_init(&map->spin_lock);
- return map;
+ return map;
}
int tracks_map_get_size(TracksMap *map)
{
- return map->num_tracks;
+ return map->num_tracks;
}
-void tracks_map_get_indexed_element(TracksMap *map, int index, MovieTrackingTrack **track, void **customdata)
+void tracks_map_get_indexed_element(TracksMap *map,
+ int index,
+ MovieTrackingTrack **track,
+ void **customdata)
{
- *track = &map->tracks[index];
+ *track = &map->tracks[index];
- if (map->customdata)
- *customdata = &map->customdata[index * map->customdata_size];
+ if (map->customdata)
+ *customdata = &map->customdata[index * map->customdata_size];
}
void tracks_map_insert(TracksMap *map, MovieTrackingTrack *track, void *customdata)
{
- MovieTrackingTrack new_track = *track;
+ MovieTrackingTrack new_track = *track;
- new_track.markers = MEM_dupallocN(new_track.markers);
+ new_track.markers = MEM_dupallocN(new_track.markers);
- map->tracks[map->ptr] = new_track;
+ map->tracks[map->ptr] = new_track;
- if (customdata)
- memcpy(&map->customdata[map->ptr * map->customdata_size], customdata, map->customdata_size);
+ if (customdata)
+ memcpy(&map->customdata[map->ptr * map->customdata_size], customdata, map->customdata_size);
- BLI_ghash_insert(map->hash, &map->tracks[map->ptr], track);
+ BLI_ghash_insert(map->hash, &map->tracks[map->ptr], track);
- map->ptr++;
+ map->ptr++;
}
void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
{
- MovieTrackingTrack *track;
- ListBase tracks = {NULL, NULL}, new_tracks = {NULL, NULL};
- ListBase *old_tracks;
- int a;
+ MovieTrackingTrack *track;
+ ListBase tracks = {NULL, NULL}, new_tracks = {NULL, NULL};
+ ListBase *old_tracks;
+ int a;
- if (map->is_camera) {
- old_tracks = &tracking->tracks;
- }
- else {
- MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, map->object_name);
+ if (map->is_camera) {
+ old_tracks = &tracking->tracks;
+ }
+ else {
+ MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, map->object_name);
- if (!object) {
- /* object was deleted by user, create new one */
- object = BKE_tracking_object_add(tracking, map->object_name);
- }
+ if (!object) {
+ /* object was deleted by user, create new one */
+ object = BKE_tracking_object_add(tracking, map->object_name);
+ }
- old_tracks = &object->tracks;
- }
+ 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++) {
- MovieTrackingTrack *old_track;
- bool mapped_to_old = false;
+ /* 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++) {
+ MovieTrackingTrack *old_track;
+ bool mapped_to_old = false;
- track = &map->tracks[a];
+ track = &map->tracks[a];
- /* find original of operating track in list of previously displayed tracks */
- old_track = BLI_ghash_lookup(map->hash, track);
- if (old_track) {
- if (BLI_findindex(old_tracks, old_track) != -1) {
- BLI_remlink(old_tracks, old_track);
+ /* find original of operating track in list of previously displayed tracks */
+ old_track = BLI_ghash_lookup(map->hash, track);
+ if (old_track) {
+ if (BLI_findindex(old_tracks, old_track) != -1) {
+ BLI_remlink(old_tracks, old_track);
- BLI_spin_lock(&map->spin_lock);
+ BLI_spin_lock(&map->spin_lock);
- /* Copy flags like selection back to the track map. */
- track->flag = old_track->flag;
- track->pat_flag = old_track->pat_flag;
- track->search_flag = old_track->search_flag;
+ /* Copy flags like selection back to the track map. */
+ track->flag = old_track->flag;
+ track->pat_flag = old_track->pat_flag;
+ track->search_flag = old_track->search_flag;
- /* Copy all the rest settings back from the map to the actual tracks. */
- MEM_freeN(old_track->markers);
- *old_track = *track;
- old_track->markers = MEM_dupallocN(old_track->markers);
+ /* Copy all the rest settings back from the map to the actual tracks. */
+ MEM_freeN(old_track->markers);
+ *old_track = *track;
+ old_track->markers = MEM_dupallocN(old_track->markers);
- BLI_spin_unlock(&map->spin_lock);
+ BLI_spin_unlock(&map->spin_lock);
- BLI_addtail(&tracks, old_track);
+ BLI_addtail(&tracks, old_track);
- mapped_to_old = true;
- }
- }
+ mapped_to_old = true;
+ }
+ }
- if (mapped_to_old == false) {
- MovieTrackingTrack *new_track = BKE_tracking_track_duplicate(track);
+ if (mapped_to_old == false) {
+ MovieTrackingTrack *new_track = BKE_tracking_track_duplicate(track);
- /* Update old-new track mapping */
- BLI_ghash_reinsert(map->hash, track, new_track, NULL, NULL);
+ /* Update old-new track mapping */
+ BLI_ghash_reinsert(map->hash, track, new_track, NULL, NULL);
- BLI_addtail(&tracks, new_track);
- }
- }
+ BLI_addtail(&tracks, new_track);
+ }
+ }
- /* move all tracks, which aren't operating */
- track = old_tracks->first;
- while (track) {
- MovieTrackingTrack *next = track->next;
- BLI_addtail(&new_tracks, track);
- track = next;
- }
+ /* move all tracks, which aren't operating */
+ track = old_tracks->first;
+ while (track) {
+ MovieTrackingTrack *next = track->next;
+ BLI_addtail(&new_tracks, track);
+ track = next;
+ }
- /* now move all tracks which are currently operating and keep their names unique */
- track = tracks.first;
- while (track) {
- MovieTrackingTrack *next = track->next;
+ /* 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);
+ BLI_remlink(&tracks, track);
- track->next = track->prev = NULL;
- BLI_addtail(&new_tracks, track);
+ track->next = track->prev = NULL;
+ BLI_addtail(&new_tracks, track);
- BLI_uniquename(&new_tracks, track, CTX_DATA_(BLT_I18NCONTEXT_ID_MOVIECLIP, "Track"), '.',
- offsetof(MovieTrackingTrack, name), sizeof(track->name));
+ BLI_uniquename(&new_tracks,
+ track,
+ CTX_DATA_(BLT_I18NCONTEXT_ID_MOVIECLIP, "Track"),
+ '.',
+ offsetof(MovieTrackingTrack, name),
+ sizeof(track->name));
- track = next;
- }
+ track = next;
+ }
- *old_tracks = new_tracks;
+ *old_tracks = new_tracks;
}
void tracks_map_free(TracksMap *map, void (*customdata_free)(void *customdata))
{
- int i = 0;
+ int i = 0;
- BLI_ghash_free(map->hash, NULL, NULL);
+ BLI_ghash_free(map->hash, NULL, NULL);
- for (i = 0; i < map->num_tracks; i++) {
- if (map->customdata && customdata_free)
- customdata_free(&map->customdata[i * map->customdata_size]);
+ for (i = 0; i < map->num_tracks; i++) {
+ if (map->customdata && customdata_free)
+ customdata_free(&map->customdata[i * map->customdata_size]);
- BKE_tracking_track_free(&map->tracks[i]);
- }
+ BKE_tracking_track_free(&map->tracks[i]);
+ }
- if (map->customdata)
- MEM_freeN(map->customdata);
+ if (map->customdata)
+ MEM_freeN(map->customdata);
- MEM_freeN(map->tracks);
+ MEM_freeN(map->tracks);
- BLI_spin_end(&map->spin_lock);
+ BLI_spin_end(&map->spin_lock);
- MEM_freeN(map);
+ MEM_freeN(map);
}
/*********************** Space transformation functions *************************/
@@ -237,70 +247,86 @@ void tracks_map_free(TracksMap *map, void (*customdata_free)(void *customdata))
* window relative coordinates in pixels, and "frame_unified" are unified 0..1
* coordinates relative to the entire frame.
*/
-static void unified_to_pixel(int frame_width, int frame_height,
- const float unified_coords[2], float pixel_coords[2])
+static void unified_to_pixel(int frame_width,
+ int frame_height,
+ const float unified_coords[2],
+ float pixel_coords[2])
{
- pixel_coords[0] = unified_coords[0] * frame_width;
- pixel_coords[1] = unified_coords[1] * frame_height;
+ pixel_coords[0] = unified_coords[0] * frame_width;
+ pixel_coords[1] = unified_coords[1] * frame_height;
}
-static void marker_to_frame_unified(const MovieTrackingMarker *marker, const float marker_unified_coords[2],
+static void marker_to_frame_unified(const MovieTrackingMarker *marker,
+ const float marker_unified_coords[2],
float frame_unified_coords[2])
{
- frame_unified_coords[0] = marker_unified_coords[0] + marker->pos[0];
- frame_unified_coords[1] = marker_unified_coords[1] + marker->pos[1];
+ frame_unified_coords[0] = marker_unified_coords[0] + marker->pos[0];
+ frame_unified_coords[1] = marker_unified_coords[1] + marker->pos[1];
}
-static void marker_unified_to_frame_pixel_coordinates(int frame_width, int frame_height,
+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])
{
- marker_to_frame_unified(marker, marker_unified_coords, frame_pixel_coords);
- unified_to_pixel(frame_width, frame_height, frame_pixel_coords, frame_pixel_coords);
+ marker_to_frame_unified(marker, marker_unified_coords, frame_pixel_coords);
+ unified_to_pixel(frame_width, frame_height, frame_pixel_coords, frame_pixel_coords);
}
-void tracking_get_search_origin_frame_pixel(int frame_width, int frame_height,
+void tracking_get_search_origin_frame_pixel(int frame_width,
+ int frame_height,
const MovieTrackingMarker *marker,
float frame_pixel[2])
{
- /* Get the lower left coordinate of the search window and snap to pixel coordinates */
- marker_unified_to_frame_pixel_coordinates(frame_width, frame_height, marker, marker->search_min, frame_pixel);
- frame_pixel[0] = (int)frame_pixel[0];
- frame_pixel[1] = (int)frame_pixel[1];
+ /* Get the lower left coordinate of the search window and snap to pixel coordinates */
+ marker_unified_to_frame_pixel_coordinates(
+ frame_width, frame_height, marker, marker->search_min, frame_pixel);
+ frame_pixel[0] = (int)frame_pixel[0];
+ frame_pixel[1] = (int)frame_pixel[1];
}
-static void pixel_to_unified(int frame_width, int frame_height, const float pixel_coords[2], float unified_coords[2])
+static void pixel_to_unified(int frame_width,
+ int frame_height,
+ const float pixel_coords[2],
+ float unified_coords[2])
{
- unified_coords[0] = pixel_coords[0] / frame_width;
- unified_coords[1] = pixel_coords[1] / frame_height;
+ unified_coords[0] = pixel_coords[0] / frame_width;
+ unified_coords[1] = pixel_coords[1] / frame_height;
}
-static void marker_unified_to_search_pixel(int frame_width, int frame_height,
+static void marker_unified_to_search_pixel(int frame_width,
+ int frame_height,
const MovieTrackingMarker *marker,
- const float marker_unified[2], float search_pixel[2])
+ const float marker_unified[2],
+ float search_pixel[2])
{
- float frame_pixel[2];
- float search_origin_frame_pixel[2];
+ float frame_pixel[2];
+ float search_origin_frame_pixel[2];
- marker_unified_to_frame_pixel_coordinates(frame_width, frame_height, marker, marker_unified, frame_pixel);
- tracking_get_search_origin_frame_pixel(frame_width, frame_height, marker, search_origin_frame_pixel);
- sub_v2_v2v2(search_pixel, frame_pixel, search_origin_frame_pixel);
+ marker_unified_to_frame_pixel_coordinates(
+ frame_width, frame_height, marker, marker_unified, frame_pixel);
+ tracking_get_search_origin_frame_pixel(
+ frame_width, frame_height, marker, search_origin_frame_pixel);
+ sub_v2_v2v2(search_pixel, frame_pixel, search_origin_frame_pixel);
}
-static void search_pixel_to_marker_unified(int frame_width, int frame_height,
+static void search_pixel_to_marker_unified(int frame_width,
+ int frame_height,
const MovieTrackingMarker *marker,
- const float search_pixel[2], float marker_unified[2])
+ const float search_pixel[2],
+ float marker_unified[2])
{
- float frame_unified[2];
- float search_origin_frame_pixel[2];
+ float frame_unified[2];
+ float search_origin_frame_pixel[2];
- tracking_get_search_origin_frame_pixel(frame_width, frame_height, marker, search_origin_frame_pixel);
- add_v2_v2v2(frame_unified, search_pixel, search_origin_frame_pixel);
- pixel_to_unified(frame_width, frame_height, frame_unified, frame_unified);
+ tracking_get_search_origin_frame_pixel(
+ frame_width, frame_height, marker, search_origin_frame_pixel);
+ add_v2_v2v2(frame_unified, search_pixel, search_origin_frame_pixel);
+ pixel_to_unified(frame_width, frame_height, frame_unified, frame_unified);
- /* marker pos is in frame unified */
- sub_v2_v2v2(marker_unified, frame_unified, marker->pos);
+ /* marker pos is in frame unified */
+ sub_v2_v2v2(marker_unified, frame_unified, marker->pos);
}
/* Each marker has 5 coordinates associated with it that get warped with
@@ -308,61 +334,68 @@ static void search_pixel_to_marker_unified(int frame_width, int frame_height,
* This function puts those 5 points into the appropriate frame for tracking
* (the "search" coordinate frame).
*/
-void tracking_get_marker_coords_for_tracking(int frame_width, int frame_height,
+void tracking_get_marker_coords_for_tracking(int frame_width,
+ int frame_height,
const MovieTrackingMarker *marker,
- double search_pixel_x[5], double search_pixel_y[5])
+ double search_pixel_x[5],
+ double search_pixel_y[5])
{
- int i;
- float unified_coords[2];
- float pixel_coords[2];
+ int i;
+ float unified_coords[2];
+ float pixel_coords[2];
- /* Convert the corners into search space coordinates. */
- for (i = 0; i < 4; i++) {
- marker_unified_to_search_pixel(frame_width, frame_height, marker, marker->pattern_corners[i], pixel_coords);
- search_pixel_x[i] = pixel_coords[0] - 0.5f;
- search_pixel_y[i] = pixel_coords[1] - 0.5f;
- }
+ /* Convert the corners into search space coordinates. */
+ for (i = 0; i < 4; i++) {
+ marker_unified_to_search_pixel(
+ frame_width, frame_height, marker, marker->pattern_corners[i], pixel_coords);
+ search_pixel_x[i] = pixel_coords[0] - 0.5f;
+ search_pixel_y[i] = pixel_coords[1] - 0.5f;
+ }
- /* Convert the center position (aka "pos"); this is the origin */
- unified_coords[0] = 0.0f;
- unified_coords[1] = 0.0f;
- marker_unified_to_search_pixel(frame_width, frame_height, marker, unified_coords, pixel_coords);
+ /* Convert the center position (aka "pos"); this is the origin */
+ unified_coords[0] = 0.0f;
+ unified_coords[1] = 0.0f;
+ marker_unified_to_search_pixel(frame_width, frame_height, marker, unified_coords, pixel_coords);
- search_pixel_x[4] = pixel_coords[0] - 0.5f;
- search_pixel_y[4] = pixel_coords[1] - 0.5f;
+ search_pixel_x[4] = pixel_coords[0] - 0.5f;
+ search_pixel_y[4] = pixel_coords[1] - 0.5f;
}
/* Inverse of above. */
-void tracking_set_marker_coords_from_tracking(int frame_width, int frame_height, MovieTrackingMarker *marker,
- const double search_pixel_x[5], const double search_pixel_y[5])
-{
- int i;
- float marker_unified[2];
- float search_pixel[2];
-
- /* Convert the corners into search space coordinates. */
- for (i = 0; i < 4; i++) {
- search_pixel[0] = search_pixel_x[i] + 0.5;
- search_pixel[1] = search_pixel_y[i] + 0.5;
- search_pixel_to_marker_unified(frame_width, frame_height, marker, search_pixel, marker->pattern_corners[i]);
- }
-
- /* Convert the center position (aka "pos"); this is the origin */
- search_pixel[0] = search_pixel_x[4] + 0.5;
- search_pixel[1] = search_pixel_y[4] + 0.5;
- search_pixel_to_marker_unified(frame_width, frame_height, marker, search_pixel, marker_unified);
-
- /* If the tracker tracked nothing, then "marker_unified" would be zero.
- * Otherwise, the entire patch shifted, and that delta should be applied to
- * all the coordinates.
- */
- for (i = 0; i < 4; i++) {
- marker->pattern_corners[i][0] -= marker_unified[0];
- marker->pattern_corners[i][1] -= marker_unified[1];
- }
-
- marker->pos[0] += marker_unified[0];
- marker->pos[1] += marker_unified[1];
+void tracking_set_marker_coords_from_tracking(int frame_width,
+ int frame_height,
+ MovieTrackingMarker *marker,
+ const double search_pixel_x[5],
+ const double search_pixel_y[5])
+{
+ int i;
+ float marker_unified[2];
+ float search_pixel[2];
+
+ /* Convert the corners into search space coordinates. */
+ for (i = 0; i < 4; i++) {
+ search_pixel[0] = search_pixel_x[i] + 0.5;
+ search_pixel[1] = search_pixel_y[i] + 0.5;
+ search_pixel_to_marker_unified(
+ frame_width, frame_height, marker, search_pixel, marker->pattern_corners[i]);
+ }
+
+ /* Convert the center position (aka "pos"); this is the origin */
+ search_pixel[0] = search_pixel_x[4] + 0.5;
+ search_pixel[1] = search_pixel_y[4] + 0.5;
+ search_pixel_to_marker_unified(frame_width, frame_height, marker, search_pixel, marker_unified);
+
+ /* If the tracker tracked nothing, then "marker_unified" would be zero.
+ * Otherwise, the entire patch shifted, and that delta should be applied to
+ * all the coordinates.
+ */
+ for (i = 0; i < 4; i++) {
+ marker->pattern_corners[i][0] -= marker_unified[0];
+ marker->pattern_corners[i][1] -= marker_unified[1];
+ }
+
+ marker->pos[0] += marker_unified[0];
+ marker->pos[1] += marker_unified[1];
}
/*********************** General purpose utility functions *************************/
@@ -376,88 +409,91 @@ void tracking_set_marker_coords_from_tracking(int frame_width, int frame_height,
* is expected to be placed, nothing will happen if overwrite
* is false.
*/
-void tracking_marker_insert_disabled(MovieTrackingTrack *track, const MovieTrackingMarker *ref_marker,
- bool before, bool overwrite)
+void tracking_marker_insert_disabled(MovieTrackingTrack *track,
+ const MovieTrackingMarker *ref_marker,
+ bool before,
+ bool overwrite)
{
- MovieTrackingMarker marker_new;
+ MovieTrackingMarker marker_new;
- marker_new = *ref_marker;
- marker_new.flag &= ~MARKER_TRACKED;
- marker_new.flag |= MARKER_DISABLED;
+ marker_new = *ref_marker;
+ marker_new.flag &= ~MARKER_TRACKED;
+ marker_new.flag |= MARKER_DISABLED;
- if (before)
- marker_new.framenr--;
- else
- marker_new.framenr++;
+ 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);
+ if (overwrite || !BKE_tracking_track_has_marker_at_frame(track, marker_new.framenr))
+ BKE_tracking_marker_insert(track, &marker_new);
}
-
/* Fill in Libmv C-API camera intrinsics options from tracking structure. */
-void tracking_cameraIntrinscisOptionsFromTracking(MovieTracking *tracking,
- int calibration_width, int calibration_height,
- libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
-{
- MovieTrackingCamera *camera = &tracking->camera;
- float aspy = 1.0f / tracking->camera.pixel_aspect;
-
- camera_intrinsics_options->focal_length = camera->focal;
-
- camera_intrinsics_options->principal_point_x = camera->principal[0];
- camera_intrinsics_options->principal_point_y = camera->principal[1] * aspy;
-
- switch (camera->distortion_model) {
- case TRACKING_DISTORTION_MODEL_POLYNOMIAL:
- camera_intrinsics_options->distortion_model = LIBMV_DISTORTION_MODEL_POLYNOMIAL;
- camera_intrinsics_options->polynomial_k1 = camera->k1;
- camera_intrinsics_options->polynomial_k2 = camera->k2;
- camera_intrinsics_options->polynomial_k3 = camera->k3;
- camera_intrinsics_options->polynomial_p1 = 0.0;
- camera_intrinsics_options->polynomial_p2 = 0.0;
- break;
- case TRACKING_DISTORTION_MODEL_DIVISION:
- camera_intrinsics_options->distortion_model = LIBMV_DISTORTION_MODEL_DIVISION;
- camera_intrinsics_options->division_k1 = camera->division_k1;
- camera_intrinsics_options->division_k2 = camera->division_k2;
- break;
- default:
- BLI_assert(!"Unknown distortion model");
- break;
- }
-
- camera_intrinsics_options->image_width = calibration_width;
- camera_intrinsics_options->image_height = (int) (calibration_height * aspy);
-}
-
-void tracking_trackingCameraFromIntrinscisOptions(MovieTracking *tracking,
- const libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
-{
- float aspy = 1.0f / tracking->camera.pixel_aspect;
- MovieTrackingCamera *camera = &tracking->camera;
-
- camera->focal = camera_intrinsics_options->focal_length;
-
- camera->principal[0] = camera_intrinsics_options->principal_point_x;
- camera->principal[1] = camera_intrinsics_options->principal_point_y / (double) aspy;
-
- switch (camera_intrinsics_options->distortion_model) {
- case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
- camera->distortion_model = TRACKING_DISTORTION_MODEL_POLYNOMIAL;
- camera->k1 = camera_intrinsics_options->polynomial_k1;
- camera->k2 = camera_intrinsics_options->polynomial_k2;
- camera->k3 = camera_intrinsics_options->polynomial_k3;
- break;
- case LIBMV_DISTORTION_MODEL_DIVISION:
- camera->distortion_model = TRACKING_DISTORTION_MODEL_DIVISION;
- camera->division_k1 = camera_intrinsics_options->division_k1;
- camera->division_k2 = camera_intrinsics_options->division_k2;
- break;
- default:
- BLI_assert(!"Unknown distortion model");
- break;
- }
+void tracking_cameraIntrinscisOptionsFromTracking(
+ MovieTracking *tracking,
+ int calibration_width,
+ int calibration_height,
+ libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
+{
+ MovieTrackingCamera *camera = &tracking->camera;
+ float aspy = 1.0f / tracking->camera.pixel_aspect;
+
+ camera_intrinsics_options->focal_length = camera->focal;
+
+ camera_intrinsics_options->principal_point_x = camera->principal[0];
+ camera_intrinsics_options->principal_point_y = camera->principal[1] * aspy;
+
+ switch (camera->distortion_model) {
+ case TRACKING_DISTORTION_MODEL_POLYNOMIAL:
+ camera_intrinsics_options->distortion_model = LIBMV_DISTORTION_MODEL_POLYNOMIAL;
+ camera_intrinsics_options->polynomial_k1 = camera->k1;
+ camera_intrinsics_options->polynomial_k2 = camera->k2;
+ camera_intrinsics_options->polynomial_k3 = camera->k3;
+ camera_intrinsics_options->polynomial_p1 = 0.0;
+ camera_intrinsics_options->polynomial_p2 = 0.0;
+ break;
+ case TRACKING_DISTORTION_MODEL_DIVISION:
+ camera_intrinsics_options->distortion_model = LIBMV_DISTORTION_MODEL_DIVISION;
+ camera_intrinsics_options->division_k1 = camera->division_k1;
+ camera_intrinsics_options->division_k2 = camera->division_k2;
+ break;
+ default:
+ BLI_assert(!"Unknown distortion model");
+ break;
+ }
+
+ camera_intrinsics_options->image_width = calibration_width;
+ camera_intrinsics_options->image_height = (int)(calibration_height * aspy);
+}
+
+void tracking_trackingCameraFromIntrinscisOptions(
+ MovieTracking *tracking, const libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
+{
+ float aspy = 1.0f / tracking->camera.pixel_aspect;
+ MovieTrackingCamera *camera = &tracking->camera;
+
+ camera->focal = camera_intrinsics_options->focal_length;
+
+ camera->principal[0] = camera_intrinsics_options->principal_point_x;
+ camera->principal[1] = camera_intrinsics_options->principal_point_y / (double)aspy;
+
+ switch (camera_intrinsics_options->distortion_model) {
+ case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
+ camera->distortion_model = TRACKING_DISTORTION_MODEL_POLYNOMIAL;
+ camera->k1 = camera_intrinsics_options->polynomial_k1;
+ camera->k2 = camera_intrinsics_options->polynomial_k2;
+ camera->k3 = camera_intrinsics_options->polynomial_k3;
+ break;
+ case LIBMV_DISTORTION_MODEL_DIVISION:
+ camera->distortion_model = TRACKING_DISTORTION_MODEL_DIVISION;
+ camera->division_k1 = camera_intrinsics_options->division_k1;
+ camera->division_k2 = camera_intrinsics_options->division_k2;
+ break;
+ default:
+ BLI_assert(!"Unknown distortion model");
+ break;
+ }
}
/* Get previous keyframed marker. */
@@ -465,99 +501,93 @@ MovieTrackingMarker *tracking_get_keyframed_marker(MovieTrackingTrack *track,
int current_frame,
bool backwards)
{
- MovieTrackingMarker *marker_keyed = NULL;
- MovieTrackingMarker *marker_keyed_fallback = NULL;
- int a = BKE_tracking_marker_get(track, current_frame) - track->markers;
-
- while (a >= 0 && a < track->markersnr) {
- int next = backwards ? a + 1 : a - 1;
- bool is_keyframed = false;
- MovieTrackingMarker *cur_marker = &track->markers[a];
- MovieTrackingMarker *next_marker = NULL;
-
- if (next >= 0 && next < track->markersnr)
- next_marker = &track->markers[next];
-
- if ((cur_marker->flag & MARKER_DISABLED) == 0) {
- /* If it'll happen so we didn't find a real keyframe marker,
- * fallback to the first marker in current tracked segment
- * as a keyframe.
- */
- if (next_marker == NULL) {
- /* Could happen when trying to get reference marker for the fist
- * one on the segment which isn't surrounded by disabled markers.
- *
- * There's no really good choice here, just use the reference
- * marker which looks correct..
- */
- if (marker_keyed_fallback == NULL) {
- marker_keyed_fallback = cur_marker;
- }
- }
- else if (next_marker->flag & MARKER_DISABLED) {
- if (marker_keyed_fallback == NULL)
- marker_keyed_fallback = cur_marker;
- }
-
- is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0;
- }
-
- if (is_keyframed) {
- marker_keyed = cur_marker;
-
- break;
- }
-
- a = next;
- }
-
- if (marker_keyed == NULL)
- marker_keyed = marker_keyed_fallback;
-
- return marker_keyed;
+ MovieTrackingMarker *marker_keyed = NULL;
+ MovieTrackingMarker *marker_keyed_fallback = NULL;
+ int a = BKE_tracking_marker_get(track, current_frame) - track->markers;
+
+ while (a >= 0 && a < track->markersnr) {
+ int next = backwards ? a + 1 : a - 1;
+ bool is_keyframed = false;
+ MovieTrackingMarker *cur_marker = &track->markers[a];
+ MovieTrackingMarker *next_marker = NULL;
+
+ if (next >= 0 && next < track->markersnr)
+ next_marker = &track->markers[next];
+
+ if ((cur_marker->flag & MARKER_DISABLED) == 0) {
+ /* If it'll happen so we didn't find a real keyframe marker,
+ * fallback to the first marker in current tracked segment
+ * as a keyframe.
+ */
+ if (next_marker == NULL) {
+ /* Could happen when trying to get reference marker for the fist
+ * one on the segment which isn't surrounded by disabled markers.
+ *
+ * There's no really good choice here, just use the reference
+ * marker which looks correct..
+ */
+ if (marker_keyed_fallback == NULL) {
+ marker_keyed_fallback = cur_marker;
+ }
+ }
+ else if (next_marker->flag & MARKER_DISABLED) {
+ if (marker_keyed_fallback == NULL)
+ marker_keyed_fallback = cur_marker;
+ }
+
+ is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0;
+ }
+
+ if (is_keyframed) {
+ marker_keyed = cur_marker;
+
+ break;
+ }
+
+ a = next;
+ }
+
+ if (marker_keyed == NULL)
+ marker_keyed = marker_keyed_fallback;
+
+ return marker_keyed;
}
/*********************** Frame accessr *************************/
typedef struct AccessCacheKey {
- int clip_index;
- int frame;
- int downscale;
- libmv_InputMode input_mode;
- bool has_region;
- float region_min[2], region_max[2];
- int64_t transform_key;
+ int clip_index;
+ int frame;
+ int downscale;
+ libmv_InputMode input_mode;
+ bool has_region;
+ float region_min[2], region_max[2];
+ int64_t transform_key;
} AccessCacheKey;
static unsigned int accesscache_hashhash(const void *key_v)
{
- const AccessCacheKey *key = (const AccessCacheKey *) key_v;
- /* TODP(sergey): Need better hashing here for faster frame access. */
- return key->clip_index << 16 | key->frame;
+ const AccessCacheKey *key = (const AccessCacheKey *)key_v;
+ /* TODP(sergey): Need better hashing here for faster frame access. */
+ return key->clip_index << 16 | key->frame;
}
static bool accesscache_hashcmp(const void *a_v, const void *b_v)
{
- const AccessCacheKey *a = (const AccessCacheKey *) a_v;
- const AccessCacheKey *b = (const AccessCacheKey *) b_v;
- if (a->clip_index != b->clip_index ||
- a->frame != b->frame ||
- a->downscale != b->downscale ||
- a->input_mode != b->input_mode ||
- a->has_region != b->has_region ||
- a->transform_key != b->transform_key)
- {
- return true;
- }
- /* If there is region applied, compare it. */
- if (a->has_region) {
- if (!equals_v2v2(a->region_min, b->region_min) ||
- !equals_v2v2(a->region_max, b->region_max))
- {
- return true;
- }
- }
- return false;
+ const AccessCacheKey *a = (const AccessCacheKey *)a_v;
+ const AccessCacheKey *b = (const AccessCacheKey *)b_v;
+ if (a->clip_index != b->clip_index || a->frame != b->frame || a->downscale != b->downscale ||
+ a->input_mode != b->input_mode || a->has_region != b->has_region ||
+ a->transform_key != b->transform_key) {
+ return true;
+ }
+ /* If there is region applied, compare it. */
+ if (a->has_region) {
+ if (!equals_v2v2(a->region_min, b->region_min) || !equals_v2v2(a->region_max, b->region_max)) {
+ return true;
+ }
+ }
+ return false;
}
static void accesscache_construct_key(AccessCacheKey *key,
@@ -568,16 +598,16 @@ static void accesscache_construct_key(AccessCacheKey *key,
const libmv_Region *region,
int64_t transform_key)
{
- key->clip_index = clip_index;
- key->frame = frame;
- key->input_mode = input_mode;
- key->downscale = downscale;
- key->has_region = (region != NULL);
- if (key->has_region) {
- copy_v2_v2(key->region_min, region->min);
- copy_v2_v2(key->region_max, region->max);
- }
- key->transform_key = transform_key;
+ key->clip_index = clip_index;
+ key->frame = frame;
+ key->input_mode = input_mode;
+ key->downscale = downscale;
+ key->has_region = (region != NULL);
+ if (key->has_region) {
+ copy_v2_v2(key->region_min, region->min);
+ copy_v2_v2(key->region_max, region->max);
+ }
+ key->transform_key = transform_key;
}
static void accesscache_put(TrackingImageAccessor *accessor,
@@ -589,10 +619,9 @@ static void accesscache_put(TrackingImageAccessor *accessor,
int64_t transform_key,
ImBuf *ibuf)
{
- AccessCacheKey key;
- accesscache_construct_key(&key, clip_index, frame, input_mode, downscale,
- region, transform_key);
- IMB_moviecache_put(accessor->cache, &key, ibuf);
+ AccessCacheKey key;
+ accesscache_construct_key(&key, clip_index, frame, input_mode, downscale, region, transform_key);
+ IMB_moviecache_put(accessor->cache, &key, ibuf);
}
static ImBuf *accesscache_get(TrackingImageAccessor *accessor,
@@ -603,85 +632,82 @@ static ImBuf *accesscache_get(TrackingImageAccessor *accessor,
const libmv_Region *region,
int64_t transform_key)
{
- AccessCacheKey key;
- accesscache_construct_key(&key, clip_index, frame, input_mode, downscale,
- region, transform_key);
- return IMB_moviecache_get(accessor->cache, &key);
+ AccessCacheKey key;
+ accesscache_construct_key(&key, clip_index, frame, input_mode, downscale, region, transform_key);
+ return IMB_moviecache_get(accessor->cache, &key);
}
static ImBuf *accessor_get_preprocessed_ibuf(TrackingImageAccessor *accessor,
int clip_index,
int frame)
{
- MovieClip *clip;
- MovieClipUser user;
- ImBuf *ibuf;
- int scene_frame;
+ MovieClip *clip;
+ MovieClipUser user;
+ ImBuf *ibuf;
+ int scene_frame;
- BLI_assert(clip_index < accessor->num_clips);
+ BLI_assert(clip_index < accessor->num_clips);
- clip = accessor->clips[clip_index];
- scene_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, frame);
- BKE_movieclip_user_set_frame(&user, scene_frame);
- user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
- user.render_flag = 0;
- ibuf = BKE_movieclip_get_ibuf(clip, &user);
+ clip = accessor->clips[clip_index];
+ scene_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, frame);
+ BKE_movieclip_user_set_frame(&user, scene_frame);
+ user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
+ user.render_flag = 0;
+ ibuf = BKE_movieclip_get_ibuf(clip, &user);
- return ibuf;
+ return ibuf;
}
static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf)
{
- ImBuf *grayscale = IMB_allocImBuf(ibuf->x, ibuf->y, 32, 0);
- size_t size;
- int i;
+ ImBuf *grayscale = IMB_allocImBuf(ibuf->x, ibuf->y, 32, 0);
+ size_t size;
+ int i;
- BLI_assert(ibuf->channels == 3 || ibuf->channels == 4);
+ BLI_assert(ibuf->channels == 3 || ibuf->channels == 4);
- /* TODO(sergey): Bummer, currently IMB API only allows to create 4 channels
- * float buffer, so we do it manually here.
- *
- * Will generalize it later.
- */
- size = (size_t)grayscale->x * (size_t)grayscale->y * sizeof(float);
- grayscale->channels = 1;
- if ((grayscale->rect_float = MEM_mapallocN(size, "tracking grayscale image")) != NULL) {
- grayscale->mall |= IB_rectfloat;
- grayscale->flags |= IB_rectfloat;
+ /* TODO(sergey): Bummer, currently IMB API only allows to create 4 channels
+ * float buffer, so we do it manually here.
+ *
+ * Will generalize it later.
+ */
+ size = (size_t)grayscale->x * (size_t)grayscale->y * sizeof(float);
+ grayscale->channels = 1;
+ if ((grayscale->rect_float = MEM_mapallocN(size, "tracking grayscale image")) != NULL) {
+ grayscale->mall |= IB_rectfloat;
+ grayscale->flags |= IB_rectfloat;
- for (i = 0; i < grayscale->x * grayscale->y; ++i) {
- const float *pixel = ibuf->rect_float + ibuf->channels * i;
+ for (i = 0; i < grayscale->x * grayscale->y; ++i) {
+ const float *pixel = ibuf->rect_float + ibuf->channels * i;
- grayscale->rect_float[i] = 0.2126f * pixel[0] +
- 0.7152f * pixel[1] +
- 0.0722f * pixel[2];
- }
- }
+ grayscale->rect_float[i] = 0.2126f * pixel[0] + 0.7152f * pixel[1] + 0.0722f * pixel[2];
+ }
+ }
- return grayscale;
+ return grayscale;
}
static void ibuf_to_float_image(const ImBuf *ibuf, libmv_FloatImage *float_image)
{
- BLI_assert(ibuf->rect_float != NULL);
- float_image->buffer = ibuf->rect_float;
- float_image->width = ibuf->x;
- float_image->height = ibuf->y;
- float_image->channels = ibuf->channels;
+ BLI_assert(ibuf->rect_float != NULL);
+ float_image->buffer = ibuf->rect_float;
+ float_image->width = ibuf->x;
+ float_image->height = ibuf->y;
+ float_image->channels = ibuf->channels;
}
static ImBuf *float_image_to_ibuf(libmv_FloatImage *float_image)
{
- ImBuf *ibuf = IMB_allocImBuf(float_image->width, float_image->height, 32, 0);
- size_t size = (size_t)ibuf->x * (size_t)ibuf->y * float_image->channels * sizeof(float);
- ibuf->channels = float_image->channels;
- if ((ibuf->rect_float = MEM_mapallocN(size, "tracking grayscale image")) != NULL) {
- ibuf->mall |= IB_rectfloat;
- ibuf->flags |= IB_rectfloat;
+ ImBuf *ibuf = IMB_allocImBuf(float_image->width, float_image->height, 32, 0);
+ size_t size = (size_t)ibuf->x * (size_t)ibuf->y * float_image->channels * sizeof(float);
+ ibuf->channels = float_image->channels;
+ if ((ibuf->rect_float = MEM_mapallocN(size, "tracking grayscale image")) != NULL) {
+ ibuf->mall |= IB_rectfloat;
+ ibuf->flags |= IB_rectfloat;
- memcpy(ibuf->rect_float, float_image->buffer, size);
- }
- return ibuf;
+ memcpy(ibuf->rect_float, float_image->buffer, size);
+ }
+ return ibuf;
}
static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
@@ -692,258 +718,232 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
const libmv_Region *region,
const libmv_FrameTransform *transform)
{
- ImBuf *ibuf, *orig_ibuf, *final_ibuf;
- int64_t transform_key = 0;
- if (transform != NULL) {
- transform_key = libmv_frameAccessorgetTransformKey(transform);
- }
- /* First try to get fully processed image from the cache. */
- BLI_spin_lock(&accessor->cache_lock);
- ibuf = accesscache_get(accessor,
- clip_index,
- frame,
- input_mode,
- downscale,
- region,
- transform_key);
- BLI_spin_unlock(&accessor->cache_lock);
- if (ibuf != NULL) {
- CACHE_PRINTF("Used cached buffer for frame %d\n", frame);
- /* This is a little heuristic here: if we re-used image once, this is
- * a high probability of the image to be related to a keyframe matched
- * reference image. Those images we don't want to be thrown away because
- * if we toss them out we'll be re-calculating them at the next
- * iteration.
- */
- ibuf->userflags |= IB_PERSISTENT;
- return ibuf;
- }
- CACHE_PRINTF("Calculate new buffer for frame %d\n", frame);
- /* And now we do postprocessing of the original frame. */
- orig_ibuf = accessor_get_preprocessed_ibuf(accessor, clip_index, frame);
- if (orig_ibuf == NULL) {
- return NULL;
- }
- /* Cut a region if requested. */
- if (region != NULL) {
- int width = region->max[0] - region->min[0],
- height = region->max[1] - region->min[1];
-
- /* If the requested region goes outside of the actual frame we still
- * return the requested region size, but only fill it's partially with
- * the data we can.
- */
- int clamped_origin_x = max_ii((int)region->min[0], 0),
- clamped_origin_y = max_ii((int)region->min[1], 0);
- int dst_offset_x = clamped_origin_x - (int)region->min[0],
- dst_offset_y = clamped_origin_y - (int)region->min[1];
- int clamped_width = width - dst_offset_x,
- clamped_height = height - dst_offset_y;
- clamped_width = min_ii(clamped_width, orig_ibuf->x - clamped_origin_x);
- clamped_height = min_ii(clamped_height, orig_ibuf->y - clamped_origin_y);
-
- final_ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat);
-
- if (orig_ibuf->rect_float != NULL) {
- IMB_rectcpy(final_ibuf, orig_ibuf,
- dst_offset_x, dst_offset_y,
- clamped_origin_x, clamped_origin_y,
- clamped_width, clamped_height);
- }
- else {
- int y;
- /* TODO(sergey): We don't do any color space or alpha conversion
- * here. Probably Libmv is better to work in the linear space,
- * but keep sRGB space here for compatibility for now.
- */
- for (y = 0; y < clamped_height; ++y) {
- int x;
- for (x = 0; x < clamped_width; ++x) {
- int src_x = x + clamped_origin_x,
- src_y = y + clamped_origin_y;
- int dst_x = x + dst_offset_x,
- dst_y = y + dst_offset_y;
- int dst_index = (dst_y * width + dst_x) * 4,
- src_index = (src_y * orig_ibuf->x + src_x) * 4;
- rgba_uchar_to_float(final_ibuf->rect_float + dst_index,
- (unsigned char *)orig_ibuf->rect +
- src_index);
- }
- }
- }
- }
- else {
- /* Libmv only works with float images,
- *
- * This would likely make it so loads of float buffers are being stored
- * in the cache which is nice on the one hand (faster re-use of the
- * frames) but on the other hand it bumps the memory usage up.
- */
- BLI_thread_lock(LOCK_MOVIECLIP);
- IMB_float_from_rect(orig_ibuf);
- BLI_thread_unlock(LOCK_MOVIECLIP);
- final_ibuf = orig_ibuf;
- }
- /* Downscale if needed. */
- if (downscale > 0) {
- if (final_ibuf == orig_ibuf) {
- final_ibuf = IMB_dupImBuf(orig_ibuf);
- }
- IMB_scaleImBuf(final_ibuf,
- orig_ibuf->x / (1 << downscale),
- orig_ibuf->y / (1 << downscale));
- }
- /* Apply possible transformation. */
- if (transform != NULL) {
- libmv_FloatImage input_image, output_image;
- ibuf_to_float_image(final_ibuf, &input_image);
- libmv_frameAccessorgetTransformRun(transform,
- &input_image,
- &output_image);
- if (final_ibuf != orig_ibuf) {
- IMB_freeImBuf(final_ibuf);
- }
- final_ibuf = float_image_to_ibuf(&output_image);
- libmv_floatImageDestroy(&output_image);
- }
- /* Transform number of channels. */
- if (input_mode == LIBMV_IMAGE_MODE_RGBA) {
- BLI_assert(orig_ibuf->channels == 3 || orig_ibuf->channels == 4);
- /* pass */
- }
- else /* if (input_mode == LIBMV_IMAGE_MODE_MONO) */ {
- BLI_assert(input_mode == LIBMV_IMAGE_MODE_MONO);
- if (final_ibuf->channels != 1) {
- ImBuf *grayscale_ibuf = make_grayscale_ibuf_copy(final_ibuf);
- if (final_ibuf != orig_ibuf) {
- /* We dereference original frame later. */
- IMB_freeImBuf(final_ibuf);
- }
- final_ibuf = grayscale_ibuf;
- }
- }
- /* It's possible processing still didn't happen at this point,
- * but we really need a copy of the buffer to be transformed
- * and to be put to the cache.
- */
- if (final_ibuf == orig_ibuf) {
- final_ibuf = IMB_dupImBuf(orig_ibuf);
- }
- IMB_freeImBuf(orig_ibuf);
- BLI_spin_lock(&accessor->cache_lock);
- /* Put final buffer to cache. */
- accesscache_put(accessor,
- clip_index,
- frame,
- input_mode,
- downscale,
- region,
- transform_key,
- final_ibuf);
- BLI_spin_unlock(&accessor->cache_lock);
- return final_ibuf;
-}
-
-static libmv_CacheKey accessor_get_image_callback(
- struct libmv_FrameAccessorUserData *user_data,
- int clip_index,
- int frame,
- libmv_InputMode input_mode,
- int downscale,
- const libmv_Region *region,
- const libmv_FrameTransform *transform,
- float **destination,
- int *width,
- int *height,
- int *channels)
-{
- TrackingImageAccessor *accessor = (TrackingImageAccessor *) user_data;
- ImBuf *ibuf;
-
- BLI_assert(clip_index >= 0 && clip_index < accessor->num_clips);
-
- ibuf = accessor_get_ibuf(accessor,
- clip_index,
- frame,
- input_mode,
- downscale,
- region,
- transform);
-
- if (ibuf) {
- *destination = ibuf->rect_float;
- *width = ibuf->x;
- *height = ibuf->y;
- *channels = ibuf->channels;
- }
- else {
- *destination = NULL;
- *width = 0;
- *height = 0;
- *channels = 0;
- }
-
- return ibuf;
+ ImBuf *ibuf, *orig_ibuf, *final_ibuf;
+ int64_t transform_key = 0;
+ if (transform != NULL) {
+ transform_key = libmv_frameAccessorgetTransformKey(transform);
+ }
+ /* First try to get fully processed image from the cache. */
+ BLI_spin_lock(&accessor->cache_lock);
+ ibuf = accesscache_get(
+ accessor, clip_index, frame, input_mode, downscale, region, transform_key);
+ BLI_spin_unlock(&accessor->cache_lock);
+ if (ibuf != NULL) {
+ CACHE_PRINTF("Used cached buffer for frame %d\n", frame);
+ /* This is a little heuristic here: if we re-used image once, this is
+ * a high probability of the image to be related to a keyframe matched
+ * reference image. Those images we don't want to be thrown away because
+ * if we toss them out we'll be re-calculating them at the next
+ * iteration.
+ */
+ ibuf->userflags |= IB_PERSISTENT;
+ return ibuf;
+ }
+ CACHE_PRINTF("Calculate new buffer for frame %d\n", frame);
+ /* And now we do postprocessing of the original frame. */
+ orig_ibuf = accessor_get_preprocessed_ibuf(accessor, clip_index, frame);
+ if (orig_ibuf == NULL) {
+ return NULL;
+ }
+ /* Cut a region if requested. */
+ if (region != NULL) {
+ int width = region->max[0] - region->min[0], height = region->max[1] - region->min[1];
+
+ /* If the requested region goes outside of the actual frame we still
+ * return the requested region size, but only fill it's partially with
+ * the data we can.
+ */
+ int clamped_origin_x = max_ii((int)region->min[0], 0),
+ clamped_origin_y = max_ii((int)region->min[1], 0);
+ int dst_offset_x = clamped_origin_x - (int)region->min[0],
+ dst_offset_y = clamped_origin_y - (int)region->min[1];
+ int clamped_width = width - dst_offset_x, clamped_height = height - dst_offset_y;
+ clamped_width = min_ii(clamped_width, orig_ibuf->x - clamped_origin_x);
+ clamped_height = min_ii(clamped_height, orig_ibuf->y - clamped_origin_y);
+
+ final_ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat);
+
+ if (orig_ibuf->rect_float != NULL) {
+ IMB_rectcpy(final_ibuf,
+ orig_ibuf,
+ dst_offset_x,
+ dst_offset_y,
+ clamped_origin_x,
+ clamped_origin_y,
+ clamped_width,
+ clamped_height);
+ }
+ else {
+ int y;
+ /* TODO(sergey): We don't do any color space or alpha conversion
+ * here. Probably Libmv is better to work in the linear space,
+ * but keep sRGB space here for compatibility for now.
+ */
+ for (y = 0; y < clamped_height; ++y) {
+ int x;
+ for (x = 0; x < clamped_width; ++x) {
+ int src_x = x + clamped_origin_x, src_y = y + clamped_origin_y;
+ int dst_x = x + dst_offset_x, dst_y = y + dst_offset_y;
+ int dst_index = (dst_y * width + dst_x) * 4,
+ src_index = (src_y * orig_ibuf->x + src_x) * 4;
+ rgba_uchar_to_float(final_ibuf->rect_float + dst_index,
+ (unsigned char *)orig_ibuf->rect + src_index);
+ }
+ }
+ }
+ }
+ else {
+ /* Libmv only works with float images,
+ *
+ * This would likely make it so loads of float buffers are being stored
+ * in the cache which is nice on the one hand (faster re-use of the
+ * frames) but on the other hand it bumps the memory usage up.
+ */
+ BLI_thread_lock(LOCK_MOVIECLIP);
+ IMB_float_from_rect(orig_ibuf);
+ BLI_thread_unlock(LOCK_MOVIECLIP);
+ final_ibuf = orig_ibuf;
+ }
+ /* Downscale if needed. */
+ if (downscale > 0) {
+ if (final_ibuf == orig_ibuf) {
+ final_ibuf = IMB_dupImBuf(orig_ibuf);
+ }
+ IMB_scaleImBuf(final_ibuf, orig_ibuf->x / (1 << downscale), orig_ibuf->y / (1 << downscale));
+ }
+ /* Apply possible transformation. */
+ if (transform != NULL) {
+ libmv_FloatImage input_image, output_image;
+ ibuf_to_float_image(final_ibuf, &input_image);
+ libmv_frameAccessorgetTransformRun(transform, &input_image, &output_image);
+ if (final_ibuf != orig_ibuf) {
+ IMB_freeImBuf(final_ibuf);
+ }
+ final_ibuf = float_image_to_ibuf(&output_image);
+ libmv_floatImageDestroy(&output_image);
+ }
+ /* Transform number of channels. */
+ if (input_mode == LIBMV_IMAGE_MODE_RGBA) {
+ BLI_assert(orig_ibuf->channels == 3 || orig_ibuf->channels == 4);
+ /* pass */
+ }
+ else /* if (input_mode == LIBMV_IMAGE_MODE_MONO) */ {
+ BLI_assert(input_mode == LIBMV_IMAGE_MODE_MONO);
+ if (final_ibuf->channels != 1) {
+ ImBuf *grayscale_ibuf = make_grayscale_ibuf_copy(final_ibuf);
+ if (final_ibuf != orig_ibuf) {
+ /* We dereference original frame later. */
+ IMB_freeImBuf(final_ibuf);
+ }
+ final_ibuf = grayscale_ibuf;
+ }
+ }
+ /* It's possible processing still didn't happen at this point,
+ * but we really need a copy of the buffer to be transformed
+ * and to be put to the cache.
+ */
+ if (final_ibuf == orig_ibuf) {
+ final_ibuf = IMB_dupImBuf(orig_ibuf);
+ }
+ IMB_freeImBuf(orig_ibuf);
+ BLI_spin_lock(&accessor->cache_lock);
+ /* Put final buffer to cache. */
+ accesscache_put(
+ accessor, clip_index, frame, input_mode, downscale, region, transform_key, final_ibuf);
+ BLI_spin_unlock(&accessor->cache_lock);
+ return final_ibuf;
+}
+
+static libmv_CacheKey accessor_get_image_callback(struct libmv_FrameAccessorUserData *user_data,
+ int clip_index,
+ int frame,
+ libmv_InputMode input_mode,
+ int downscale,
+ const libmv_Region *region,
+ const libmv_FrameTransform *transform,
+ float **destination,
+ int *width,
+ int *height,
+ int *channels)
+{
+ TrackingImageAccessor *accessor = (TrackingImageAccessor *)user_data;
+ ImBuf *ibuf;
+
+ BLI_assert(clip_index >= 0 && clip_index < accessor->num_clips);
+
+ ibuf = accessor_get_ibuf(accessor, clip_index, frame, input_mode, downscale, region, transform);
+
+ if (ibuf) {
+ *destination = ibuf->rect_float;
+ *width = ibuf->x;
+ *height = ibuf->y;
+ *channels = ibuf->channels;
+ }
+ else {
+ *destination = NULL;
+ *width = 0;
+ *height = 0;
+ *channels = 0;
+ }
+
+ return ibuf;
}
static void accessor_release_image_callback(libmv_CacheKey cache_key)
{
- ImBuf *ibuf = (ImBuf *) cache_key;
- IMB_freeImBuf(ibuf);
-}
-
-static libmv_CacheKey accessor_get_mask_for_track_callback(
- libmv_FrameAccessorUserData *user_data,
- int clip_index,
- int frame,
- int track_index,
- const libmv_Region *region,
- float **r_destination,
- int *r_width,
- int *r_height)
-{
- /* Perform sanity checks first. */
- TrackingImageAccessor *accessor = (TrackingImageAccessor *) user_data;
- BLI_assert(clip_index < accessor->num_clips);
- BLI_assert(track_index < accessor->num_tracks);
- MovieTrackingTrack *track = accessor->tracks[track_index];
- /* Early output, track does not use mask. */
- if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) == 0) {
- return NULL;
- }
- MovieClip *clip = accessor->clips[clip_index];
- /* Construct fake user so we can access movie clip. */
- MovieClipUser user;
- int scene_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, frame);
- BKE_movieclip_user_set_frame(&user, scene_frame);
- user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
- user.render_flag = 0;
- /* Get frame width and height so we can convert stroke coordinates
- * and other things from normalized to pixel space.
- */
- int frame_width, frame_height;
- BKE_movieclip_get_size(clip, &user, &frame_width, &frame_height);
- /* Actual mask sampling. */
- MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, frame);
- const float region_min[2] = {region->min[0] - marker->pos[0] * frame_width,
- region->min[1] - marker->pos[1] * frame_height};
- const float region_max[2] = {region->max[0] - marker->pos[0] * frame_width,
- region->max[1] - marker->pos[1] * frame_height};
- *r_destination = tracking_track_get_mask_for_region(frame_width, frame_height,
- region_min,
- region_max,
- track);
- *r_width = region->max[0] - region->min[0];
- *r_height = region->max[1] - region->min[1];
- return *r_destination;
+ ImBuf *ibuf = (ImBuf *)cache_key;
+ IMB_freeImBuf(ibuf);
+}
+
+static libmv_CacheKey accessor_get_mask_for_track_callback(libmv_FrameAccessorUserData *user_data,
+ int clip_index,
+ int frame,
+ int track_index,
+ const libmv_Region *region,
+ float **r_destination,
+ int *r_width,
+ int *r_height)
+{
+ /* Perform sanity checks first. */
+ TrackingImageAccessor *accessor = (TrackingImageAccessor *)user_data;
+ BLI_assert(clip_index < accessor->num_clips);
+ BLI_assert(track_index < accessor->num_tracks);
+ MovieTrackingTrack *track = accessor->tracks[track_index];
+ /* Early output, track does not use mask. */
+ if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) == 0) {
+ return NULL;
+ }
+ MovieClip *clip = accessor->clips[clip_index];
+ /* Construct fake user so we can access movie clip. */
+ MovieClipUser user;
+ int scene_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, frame);
+ BKE_movieclip_user_set_frame(&user, scene_frame);
+ user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
+ user.render_flag = 0;
+ /* Get frame width and height so we can convert stroke coordinates
+ * and other things from normalized to pixel space.
+ */
+ int frame_width, frame_height;
+ BKE_movieclip_get_size(clip, &user, &frame_width, &frame_height);
+ /* Actual mask sampling. */
+ MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, frame);
+ const float region_min[2] = {region->min[0] - marker->pos[0] * frame_width,
+ region->min[1] - marker->pos[1] * frame_height};
+ const float region_max[2] = {region->max[0] - marker->pos[0] * frame_width,
+ region->max[1] - marker->pos[1] * frame_height};
+ *r_destination = tracking_track_get_mask_for_region(
+ frame_width, frame_height, region_min, region_max, track);
+ *r_width = region->max[0] - region->min[0];
+ *r_height = region->max[1] - region->min[1];
+ return *r_destination;
}
static void accessor_release_mask_callback(libmv_CacheKey cache_key)
{
- if (cache_key != NULL) {
- float *mask = (float *)cache_key;
- MEM_freeN(mask);
- }
+ if (cache_key != NULL) {
+ float *mask = (float *)cache_key;
+ MEM_freeN(mask);
+ }
}
TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP],
@@ -952,38 +952,35 @@ TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR
int num_tracks,
int start_frame)
{
- TrackingImageAccessor *accessor =
- MEM_callocN(sizeof(TrackingImageAccessor), "tracking image accessor");
+ TrackingImageAccessor *accessor = MEM_callocN(sizeof(TrackingImageAccessor),
+ "tracking image accessor");
- BLI_assert(num_clips <= MAX_ACCESSOR_CLIP);
+ BLI_assert(num_clips <= MAX_ACCESSOR_CLIP);
- accessor->cache = IMB_moviecache_create("frame access cache",
- sizeof(AccessCacheKey),
- accesscache_hashhash,
- accesscache_hashcmp);
+ accessor->cache = IMB_moviecache_create(
+ "frame access cache", sizeof(AccessCacheKey), accesscache_hashhash, accesscache_hashcmp);
- memcpy(accessor->clips, clips, num_clips * sizeof(MovieClip *));
- accessor->num_clips = num_clips;
- accessor->tracks = tracks;
- accessor->num_tracks = num_tracks;
- accessor->start_frame = start_frame;
+ memcpy(accessor->clips, clips, num_clips * sizeof(MovieClip *));
+ accessor->num_clips = num_clips;
+ accessor->tracks = tracks;
+ accessor->num_tracks = num_tracks;
+ accessor->start_frame = start_frame;
- accessor->libmv_accessor =
- libmv_FrameAccessorNew((libmv_FrameAccessorUserData *) accessor,
- accessor_get_image_callback,
- accessor_release_image_callback,
- accessor_get_mask_for_track_callback,
- accessor_release_mask_callback);
+ accessor->libmv_accessor = libmv_FrameAccessorNew((libmv_FrameAccessorUserData *)accessor,
+ accessor_get_image_callback,
+ accessor_release_image_callback,
+ accessor_get_mask_for_track_callback,
+ accessor_release_mask_callback);
- BLI_spin_init(&accessor->cache_lock);
+ BLI_spin_init(&accessor->cache_lock);
- return accessor;
+ return accessor;
}
void tracking_image_accessor_destroy(TrackingImageAccessor *accessor)
{
- IMB_moviecache_free(accessor->cache);
- libmv_FrameAccessorDestroy(accessor->libmv_accessor);
- BLI_spin_end(&accessor->cache_lock);
- MEM_freeN(accessor);
+ IMB_moviecache_free(accessor->cache);
+ libmv_FrameAccessorDestroy(accessor->libmv_accessor);
+ BLI_spin_end(&accessor->cache_lock);
+ MEM_freeN(accessor);
}