diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/library.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/tracking_auto.c | 107 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/tracking_util.c | 144 | ||||
-rw-r--r-- | source/blender/blenkernel/tracking_private.h | 1 |
5 files changed, 147 insertions, 126 deletions
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 15a0f1191f8..71fbb3d726a 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -492,18 +492,20 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local) struct IDCopyLibManagementData { const ID *id_src; + ID *id_dst; int flag; }; /* Increases usercount as required, and remap self ID pointers. */ -static int id_copy_libmanagement_cb(void *user_data, ID *id_self, ID **id_pointer, int cb_flag) +static int id_copy_libmanagement_cb(void *user_data, ID *UNUSED(id_self), ID **id_pointer, int cb_flag) { struct IDCopyLibManagementData *data = user_data; ID *id = *id_pointer; /* Remap self-references to new copied ID. */ if (id == data->id_src) { - id = *id_pointer = id_self; + /* We cannot use id_self here, it is not *always* id_dst (thanks to $£!+@#&/? nodetrees). */ + id = *id_pointer = data->id_dst; } /* Increase used IDs refcount if needed and required. */ @@ -656,7 +658,7 @@ bool BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag, con } /* Update ID refcount, remap pointers to self in new ID. */ - struct IDCopyLibManagementData data = {.id_src = id, .flag = flag}; + struct IDCopyLibManagementData data = {.id_src = id, .id_dst = *r_newid, .flag = flag}; BKE_library_foreach_ID_link(bmain, *r_newid, id_copy_libmanagement_cb, &data, IDWALK_NOP); /* Do not make new copy local in case we are copying outside of main... diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index d33b1ce7d06..346d107792e 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1221,17 +1221,12 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname) */ void BKE_node_tree_copy_data(Main *UNUSED(bmain), bNodeTree *ntree_dst, const bNodeTree *ntree_src, const int flag) { - bNode *node_src; bNodeSocket *sock_dst, *sock_src; bNodeLink *link_dst; /* We never handle usercount here for own data. */ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT; - if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { - id_us_plus((ID *)ntree_dst->gpd); - } - /* in case a running nodetree is copied */ ntree_dst->execdata = NULL; @@ -1240,7 +1235,7 @@ void BKE_node_tree_copy_data(Main *UNUSED(bmain), bNodeTree *ntree_dst, const bN BLI_listbase_clear(&ntree_dst->nodes); BLI_listbase_clear(&ntree_dst->links); - for (node_src = ntree_src->nodes.first; node_src; node_src = node_src->next) { + for (bNode *node_src = ntree_src->nodes.first; node_src; node_src = node_src->next) { BKE_node_copy_ex(ntree_dst, node_src, flag_subdata); } @@ -1291,9 +1286,9 @@ void BKE_node_tree_copy_data(Main *UNUSED(bmain), bNodeTree *ntree_dst, const bN } /* update node->parent pointers */ - for (node_src = ntree_dst->nodes.first; node_src; node_src = node_src->next) { - if (node_src->parent) { - node_src->parent = node_src->parent->new_node; + for (bNode *node_dst = ntree_dst->nodes.first, *node_src = ntree_src->nodes.first; node_dst; node_dst = node_dst->next, node_src = node_src->next) { + if (node_dst->parent) { + node_dst->parent = node_dst->parent->new_node; } } diff --git a/source/blender/blenkernel/intern/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c index 414946f877d..30981ed8f23 100644 --- a/source/blender/blenkernel/intern/tracking_auto.c +++ b/source/blender/blenkernel/intern/tracking_auto.c @@ -381,7 +381,7 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip, bool BKE_autotrack_context_step(AutoTrackContext *context) { - int frame_delta = context->backwards ? -1 : 1; + const int frame_delta = context->backwards ? -1 : 1; bool ok = false; int track; @@ -395,67 +395,64 @@ bool BKE_autotrack_context_step(AutoTrackContext *context) libmv_reference_marker, libmv_tracked_marker; libmv_TrackRegionResult libmv_result; - int frame = BKE_movieclip_remap_scene_to_clip_frame( - context->clips[options->clip_index], - context->user.framenr); - bool has_marker; - + const int frame = BKE_movieclip_remap_scene_to_clip_frame( + context->clips[options->clip_index], + context->user.framenr); BLI_spin_lock(&context->spin_lock); - has_marker = libmv_autoTrackGetMarker(context->autotrack, - options->clip_index, - frame, - options->track_index, - &libmv_current_marker); + const bool has_marker = libmv_autoTrackGetMarker(context->autotrack, + options->clip_index, + frame, + options->track_index, + &libmv_current_marker); BLI_spin_unlock(&context->spin_lock); - - if (has_marker) { - if (!tracking_check_marker_margin(&libmv_current_marker, - options->track->margin, - context->frame_width, - context->frame_height)) - { - continue; - } - - libmv_tracked_marker = libmv_current_marker; - libmv_tracked_marker.frame = frame + frame_delta; - - if (options->use_keyframe_match) { - libmv_tracked_marker.reference_frame = - libmv_current_marker.reference_frame; - libmv_autoTrackGetMarker(context->autotrack, - options->clip_index, - libmv_tracked_marker.reference_frame, - options->track_index, - &libmv_reference_marker); - } - else { - libmv_tracked_marker.reference_frame = frame; - libmv_reference_marker = libmv_current_marker; - } - - if (libmv_autoTrackMarker(context->autotrack, - &options->track_region_options, - &libmv_tracked_marker, - &libmv_result)) - { - BLI_spin_lock(&context->spin_lock); - libmv_autoTrackAddMarker(context->autotrack, - &libmv_tracked_marker); - BLI_spin_unlock(&context->spin_lock); - } - else { - options->is_failed = true; - options->failed_frame = frame + frame_delta; - } - ok = true; + /* Check whether we've got marker to sync with. */ + if (!has_marker) { + continue; + } + /* Check whether marker is going outside of allowed frame margin. */ + if (!tracking_check_marker_margin(&libmv_current_marker, + options->track->margin, + context->frame_width, + context->frame_height)) + { + continue; + } + libmv_tracked_marker = libmv_current_marker; + libmv_tracked_marker.frame = frame + frame_delta; + /* Update reference frame. */ + if (options->use_keyframe_match) { + libmv_tracked_marker.reference_frame = + libmv_current_marker.reference_frame; + libmv_autoTrackGetMarker(context->autotrack, + options->clip_index, + libmv_tracked_marker.reference_frame, + options->track_index, + &libmv_reference_marker); } + else { + libmv_tracked_marker.reference_frame = frame; + libmv_reference_marker = libmv_current_marker; + } + /* Perform actual tracking. */ + if (libmv_autoTrackMarker(context->autotrack, + &options->track_region_options, + &libmv_tracked_marker, + &libmv_result)) + { + BLI_spin_lock(&context->spin_lock); + libmv_autoTrackAddMarker(context->autotrack, &libmv_tracked_marker); + BLI_spin_unlock(&context->spin_lock); + } + else { + options->is_failed = true; + options->failed_frame = frame + frame_delta; + } + ok = true; } - + /* Advance the frame. */ BLI_spin_lock(&context->spin_lock); context->user.framenr += frame_delta; BLI_spin_unlock(&context->spin_lock); - return ok; } diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c index fef0a3bc0ac..b1a092517de 100644 --- a/source/blender/blenkernel/intern/tracking_util.c +++ b/source/blender/blenkernel/intern/tracking_util.c @@ -58,6 +58,15 @@ #include "libmv-capi.h" +/* Uncomment this to have caching-specific debug prints. */ +// #define DEBUG_CACHE + +#ifdef DEBUG_CACHE +# define CACHE_PRINTF(...) printf(__VA_ARGS__) +#else +# define CACHE_PRINTF(...) +#endif + /*********************** Tracks map *************************/ TracksMap *tracks_map_new(const char *object_name, bool is_camera, int num_tracks, int customdata_size) @@ -523,6 +532,8 @@ typedef struct AccessCacheKey { int frame; int downscale; libmv_InputMode input_mode; + bool has_region; + float region_min[2], region_max[2]; int64_t transform_key; } AccessCacheKey; @@ -537,23 +548,44 @@ 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; - -#define COMPARE_FIELD(field) - { \ - if (a->clip_index != b->clip_index) { \ - return false; \ - } \ - } (void) 0 - - COMPARE_FIELD(clip_index); - COMPARE_FIELD(frame); - COMPARE_FIELD(downscale); - COMPARE_FIELD(input_mode); - COMPARE_FIELD(transform_key); - -#undef COMPARE_FIELD - - return true; + 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, + int clip_index, + int frame, + libmv_InputMode input_mode, + int downscale, + 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; } static void accesscache_put(TrackingImageAccessor *accessor, @@ -561,15 +593,13 @@ static void accesscache_put(TrackingImageAccessor *accessor, int frame, libmv_InputMode input_mode, int downscale, + const libmv_Region *region, int64_t transform_key, ImBuf *ibuf) { AccessCacheKey key; - key.clip_index = clip_index; - key.frame = frame; - key.input_mode = input_mode; - key.downscale = downscale; - key.transform_key = transform_key; + accesscache_construct_key(&key, clip_index, frame, input_mode, downscale, + region, transform_key); IMB_moviecache_put(accessor->cache, &key, ibuf); } @@ -578,14 +608,12 @@ static ImBuf *accesscache_get(TrackingImageAccessor *accessor, int frame, libmv_InputMode input_mode, int downscale, + const libmv_Region *region, int64_t transform_key) { AccessCacheKey key; - key.clip_index = clip_index; - key.frame = frame; - key.input_mode = input_mode; - key.downscale = downscale; - key.transform_key = transform_key; + accesscache_construct_key(&key, clip_index, frame, input_mode, downscale, + region, transform_key); return IMB_moviecache_get(accessor->cache, &key); } @@ -674,29 +702,37 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor, { 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]; @@ -756,7 +792,7 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor, BLI_unlock_thread(LOCK_MOVIECLIP); final_ibuf = orig_ibuf; } - + /* Downscale if needed. */ if (downscale > 0) { if (final_ibuf == orig_ibuf) { final_ibuf = IMB_dupImBuf(orig_ibuf); @@ -765,7 +801,7 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor, 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); @@ -778,12 +814,13 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor, 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) { @@ -793,37 +830,24 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor, final_ibuf = grayscale_ibuf; } } - - /* it's possible processing still didn't happen at this point, + /* 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); - - /* We put postprocessed frame to the cache always for now, - * not the smartest thing in the world, but who cares at this point. - */ - - /* TODO(sergey): Disable cache for now, because we don't store region - * in the cache key and can't check whether cached version is usable for - * us or not. - * - * Need to think better about what to cache and when. - */ - if (false) { - accesscache_put(accessor, - clip_index, - frame, - input_mode, - downscale, - transform_key, - final_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); return final_ibuf; } @@ -958,6 +982,8 @@ TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR accessor_get_mask_for_track_callback, accessor_release_mask_callback); + BLI_spin_init(&accessor->cache_lock); + return accessor; } diff --git a/source/blender/blenkernel/tracking_private.h b/source/blender/blenkernel/tracking_private.h index 1a68a1cac6a..07236fb2096 100644 --- a/source/blender/blenkernel/tracking_private.h +++ b/source/blender/blenkernel/tracking_private.h @@ -125,6 +125,7 @@ typedef struct TrackingImageAccessor { int num_tracks; int start_frame; struct libmv_FrameAccessor *libmv_accessor; + SpinLock cache_lock; } TrackingImageAccessor; TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP], |