This change solves a bottleneck which was caused by attempt to cache postprocessed search areas used for tracking. It was a single cache used by all threads, which required to have some synchronization mechanism. This synchronization turned out to be making all threads to idle while one thread is accessing the cache. The access was not cheap, so the multi-threading did not provide expected speedup. Current solution is to remove the cache of search areas. This avoids any threading synchronization overhead because there is no need for it anymore. The downside is that for certain configurations tracking became slower when comparing to master branch. There is no expected slowdown compared to 2.91 release. The slowdown is mainly experienced when using big search area and keyframe matching strategy. Other cases should still be within a ballpark of performance of single-threaded code prior to this change. The reason why is it so is because while this change makes it so the image accessors needs to process images multiple times the complexity of this process is almost the same as all the overhead for the cache lookup and maintenance. Here are Some numbers gained on different configurations. CPU: Intel Xeom CPU E5-2699 v4 OS: Linux Footage: Old_Factory MVI_4005.mov from the first part of Track Match Blend training which can be found on the Blender Cloud. Tracking 443 markers across 250 frames. The unit is seconds. File: F9433209 2.91: 401.520874 before: 358.650055 after: 14.966302 Tracking single marker across 250 frames. The unit is seconds. File: F9433211 2.91 before after Big keyframe 1.307203 1.005324 1.227300 Big previous frame 1.144055 0.881139 0.944044 Small keyframe 0.434015 0.197760 0.224982 Small previous frame 0.463207 0.218058 0.234172 All at once 2.338268 1.481220 1.518060
161 lines
6.1 KiB
C++
161 lines
6.1 KiB
C++
/*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2011 Blender Foundation.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
/** \file
|
|
* \ingroup bke
|
|
*
|
|
* This file contains declarations of function which are used
|
|
* by multiple tracking files but which should not be public.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "BLI_threads.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
struct GHash;
|
|
struct MovieTracking;
|
|
struct MovieTrackingMarker;
|
|
|
|
struct libmv_CameraIntrinsicsOptions;
|
|
|
|
/*********************** Tracks map *************************/
|
|
|
|
typedef struct TracksMap {
|
|
char object_name[MAX_NAME];
|
|
bool is_camera;
|
|
|
|
int num_tracks;
|
|
int customdata_size;
|
|
|
|
char *customdata;
|
|
MovieTrackingTrack *tracks;
|
|
|
|
struct GHash *hash;
|
|
|
|
int ptr;
|
|
|
|
/* Spin lock is used to sync context during tracking. */
|
|
SpinLock spin_lock;
|
|
} TracksMap;
|
|
|
|
struct TracksMap *tracks_map_new(const char *object_name,
|
|
bool is_camera,
|
|
int num_tracks,
|
|
int customdata_size);
|
|
int tracks_map_get_size(struct TracksMap *map);
|
|
void tracks_map_get_indexed_element(struct TracksMap *map,
|
|
int index,
|
|
struct MovieTrackingTrack **track,
|
|
void **customdata);
|
|
void tracks_map_insert(struct TracksMap *map, struct MovieTrackingTrack *track, void *customdata);
|
|
void tracks_map_free(struct TracksMap *map, void (*customdata_free)(void *customdata));
|
|
void tracks_map_merge(struct TracksMap *map, struct MovieTracking *tracking);
|
|
|
|
/*********************** Space transformation functions *************************/
|
|
|
|
void tracking_get_search_origin_frame_pixel(int frame_width,
|
|
int frame_height,
|
|
const struct MovieTrackingMarker *marker,
|
|
float frame_pixel[2]);
|
|
|
|
void tracking_get_marker_coords_for_tracking(int frame_width,
|
|
int frame_height,
|
|
const struct MovieTrackingMarker *marker,
|
|
double search_pixel_x[5],
|
|
double search_pixel_y[5]);
|
|
|
|
void tracking_set_marker_coords_from_tracking(int frame_width,
|
|
int frame_height,
|
|
struct MovieTrackingMarker *marker,
|
|
const double search_pixel_x[5],
|
|
const double search_pixel_y[5]);
|
|
|
|
/*********************** General purpose utility functions *************************/
|
|
|
|
void tracking_marker_insert_disabled(struct MovieTrackingTrack *track,
|
|
const struct MovieTrackingMarker *ref_marker,
|
|
bool before,
|
|
bool overwrite);
|
|
|
|
void tracking_cameraIntrinscisOptionsFromTracking(
|
|
struct MovieTracking *tracking,
|
|
int calibration_width,
|
|
int calibration_height,
|
|
struct libmv_CameraIntrinsicsOptions *camera_intrinsics_options);
|
|
|
|
void tracking_trackingCameraFromIntrinscisOptions(
|
|
struct MovieTracking *tracking,
|
|
const struct libmv_CameraIntrinsicsOptions *camera_intrinsics_options);
|
|
|
|
struct libmv_TrackRegionOptions;
|
|
|
|
void tracking_configure_tracker(const MovieTrackingTrack *track,
|
|
float *mask,
|
|
struct libmv_TrackRegionOptions *options);
|
|
|
|
struct MovieTrackingMarker *tracking_get_keyframed_marker(struct MovieTrackingTrack *track,
|
|
int current_frame,
|
|
bool backwards);
|
|
|
|
/*********************** Masking *************************/
|
|
|
|
float *tracking_track_get_mask_for_region(int frame_width,
|
|
int frame_height,
|
|
const float region_min[2],
|
|
const float region_max[2],
|
|
MovieTrackingTrack *track);
|
|
|
|
/*********************** Frame accessr *************************/
|
|
|
|
struct libmv_FrameAccessor;
|
|
|
|
#define MAX_ACCESSOR_CLIP 64
|
|
typedef struct TrackingImageAccessor {
|
|
struct MovieClip *clips[MAX_ACCESSOR_CLIP];
|
|
int num_clips;
|
|
|
|
/* Array of tracks which are being tracked.
|
|
* Points to actual track from the `MovieClip` (or multiple of them).
|
|
* This accessor owns the array, but not the tracks themselves. */
|
|
struct MovieTrackingTrack **tracks;
|
|
int num_tracks;
|
|
|
|
struct libmv_FrameAccessor *libmv_accessor;
|
|
SpinLock cache_lock;
|
|
} TrackingImageAccessor;
|
|
|
|
/* Clips are used to access images of an actual footage.
|
|
* Tracks are used to access masks associated with the tracks.
|
|
*
|
|
* NOTE: Both clips and tracks arrays are copied into the image accessor. It means that the caller
|
|
* is allowed to pass temporary arrays which are only valid during initialization. */
|
|
TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP],
|
|
int num_clips,
|
|
MovieTrackingTrack **tracks,
|
|
int num_tracks);
|
|
void tracking_image_accessor_destroy(TrackingImageAccessor *accessor);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|