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
path: root/source
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2017-08-14 18:07:30 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2017-08-14 18:07:30 +0300
commit3ab46f42046854e1f4c036a9b779177136017772 (patch)
tree9d0b1414feb32b955a4282d9f7117893d2811e99 /source
parent230be97284de444e6b2566f535141ca31647f6ab (diff)
parent3cd51c0379638045cd32c9aa74215032d7bc381b (diff)
Merge branch 'master' into blender2.8
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/library.c8
-rw-r--r--source/blender/blenkernel/intern/node.c13
-rw-r--r--source/blender/blenkernel/intern/tracking_auto.c107
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c144
-rw-r--r--source/blender/blenkernel/tracking_private.h1
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],