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:
-rw-r--r--intern/libmv/intern/frame_accessor.cc53
-rw-r--r--intern/libmv/intern/frame_accessor.h15
-rw-r--r--intern/libmv/intern/stub.cc4
-rw-r--r--intern/libmv/intern/track_region.cc2
-rw-r--r--intern/libmv/libmv/autotrack/autotrack.cc23
-rw-r--r--intern/libmv/libmv/autotrack/frame_accessor.h19
-rw-r--r--source/blender/blenkernel/intern/tracking.c51
-rw-r--r--source/blender/blenkernel/intern/tracking_auto.c17
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c62
-rw-r--r--source/blender/blenkernel/tracking_private.h11
10 files changed, 230 insertions, 27 deletions
diff --git a/intern/libmv/intern/frame_accessor.cc b/intern/libmv/intern/frame_accessor.cc
index 5d274d7ccca..e7fc0ab4883 100644
--- a/intern/libmv/intern/frame_accessor.cc
+++ b/intern/libmv/intern/frame_accessor.cc
@@ -40,10 +40,14 @@ using mv::Region;
struct LibmvFrameAccessor : public FrameAccessor {
LibmvFrameAccessor(libmv_FrameAccessorUserData* user_data,
libmv_GetImageCallback get_image_callback,
- libmv_ReleaseImageCallback release_image_callback)
+ libmv_ReleaseImageCallback release_image_callback,
+ libmv_GetMaskForTrackCallback get_mask_for_track_callback,
+ libmv_ReleaseMaskCallback release_mask_callback)
: user_data_(user_data),
get_image_callback_(get_image_callback),
- release_image_callback_(release_image_callback) { }
+ release_image_callback_(release_image_callback),
+ get_mask_for_track_callback_(get_mask_for_track_callback),
+ release_mask_callback_(release_mask_callback) { }
virtual ~LibmvFrameAccessor() {
}
@@ -109,6 +113,41 @@ struct LibmvFrameAccessor : public FrameAccessor {
release_image_callback_(cache_key);
}
+ Key GetMaskForTrack(int clip,
+ int frame,
+ int track,
+ const Region* region,
+ FloatImage* destination) {
+ float *float_buffer;
+ int width, height;
+ libmv_Region libmv_region;
+ if (region) {
+ get_libmv_region(*region, &libmv_region);
+ }
+ Key cache_key = get_mask_for_track_callback_(
+ user_data_,
+ clip,
+ frame,
+ track,
+ region != NULL ? &libmv_region : NULL,
+ &float_buffer,
+ &width,
+ &height);
+
+ // TODO(sergey): Dumb code for until we can set data directly.
+ FloatImage temp_image(float_buffer,
+ height,
+ width,
+ 1);
+ destination->CopyFrom(temp_image);
+
+ return cache_key;
+ }
+
+ void ReleaseMask(Key key) {
+ release_mask_callback_(key);
+ }
+
bool GetClipDimensions(int /*clip*/, int * /*width*/, int * /*height*/) {
return false;
}
@@ -124,6 +163,8 @@ struct LibmvFrameAccessor : public FrameAccessor {
libmv_FrameAccessorUserData* user_data_;
libmv_GetImageCallback get_image_callback_;
libmv_ReleaseImageCallback release_image_callback_;
+ libmv_GetMaskForTrackCallback get_mask_for_track_callback_;
+ libmv_ReleaseMaskCallback release_mask_callback_;
};
} // namespace
@@ -131,11 +172,15 @@ struct LibmvFrameAccessor : public FrameAccessor {
libmv_FrameAccessor* libmv_FrameAccessorNew(
libmv_FrameAccessorUserData* user_data,
libmv_GetImageCallback get_image_callback,
- libmv_ReleaseImageCallback release_image_callback) {
+ libmv_ReleaseImageCallback release_image_callback,
+ libmv_GetMaskForTrackCallback get_mask_for_track_callback,
+ libmv_ReleaseMaskCallback release_mask_callback) {
return (libmv_FrameAccessor*) LIBMV_OBJECT_NEW(LibmvFrameAccessor,
user_data,
get_image_callback,
- release_image_callback);
+ release_image_callback,
+ get_mask_for_track_callback,
+ release_mask_callback);
}
void libmv_FrameAccessorDestroy(libmv_FrameAccessor* frame_accessor) {
diff --git a/intern/libmv/intern/frame_accessor.h b/intern/libmv/intern/frame_accessor.h
index 3e813fe7581..c041d67f56f 100644
--- a/intern/libmv/intern/frame_accessor.h
+++ b/intern/libmv/intern/frame_accessor.h
@@ -61,10 +61,23 @@ typedef libmv_CacheKey (*libmv_GetImageCallback) (
typedef void (*libmv_ReleaseImageCallback) (libmv_CacheKey cache_key);
+typedef libmv_CacheKey (*libmv_GetMaskForTrackCallback) (
+ libmv_FrameAccessorUserData* user_data,
+ int clip,
+ int frame,
+ int track,
+ const libmv_Region* region,
+ float** destination,
+ int* width,
+ int* height);
+typedef void (*libmv_ReleaseMaskCallback) (libmv_CacheKey cache_key);
+
libmv_FrameAccessor* libmv_FrameAccessorNew(
libmv_FrameAccessorUserData* user_data,
libmv_GetImageCallback get_image_callback,
- libmv_ReleaseImageCallback release_image_callback);
+ libmv_ReleaseImageCallback release_image_callback,
+ libmv_GetMaskForTrackCallback get_mask_for_track_callback,
+ libmv_ReleaseMaskCallback release_mask_callback);
void libmv_FrameAccessorDestroy(libmv_FrameAccessor* frame_accessor);
int64_t libmv_frameAccessorgetTransformKey(const libmv_FrameTransform *transform);
diff --git a/intern/libmv/intern/stub.cc b/intern/libmv/intern/stub.cc
index 47e1915e072..8603cc03153 100644
--- a/intern/libmv/intern/stub.cc
+++ b/intern/libmv/intern/stub.cc
@@ -375,7 +375,9 @@ int libmv_autoTrackGetMarker(libmv_AutoTrack* /*libmv_autotrack*/,
libmv_FrameAccessor* libmv_FrameAccessorNew(
libmv_FrameAccessorUserData* /*user_data**/,
libmv_GetImageCallback /*get_image_callback*/,
- libmv_ReleaseImageCallback /*release_image_callback*/)
+ libmv_ReleaseImageCallback /*release_image_callback*/,
+ libmv_GetMaskForTrackCallback /*get_mask_for_track_callback*/,
+ libmv_ReleaseMaskCallback /*release_mask_callback*/)
{
return NULL;
}
diff --git a/intern/libmv/intern/track_region.cc b/intern/libmv/intern/track_region.cc
index 8989897e09f..d395b6457d7 100644
--- a/intern/libmv/intern/track_region.cc
+++ b/intern/libmv/intern/track_region.cc
@@ -36,7 +36,7 @@
/* define this to generate PNG images with content of search areas
on every itteration of tracking */
-#undef DUMP_ALWAYS
+#define DUMP_ALWAYS
using libmv::FloatImage;
using libmv::TrackRegionOptions;
diff --git a/intern/libmv/libmv/autotrack/autotrack.cc b/intern/libmv/libmv/autotrack/autotrack.cc
index 4c7bdf1fde8..00366e0f661 100644
--- a/intern/libmv/libmv/autotrack/autotrack.cc
+++ b/intern/libmv/libmv/autotrack/autotrack.cc
@@ -111,6 +111,17 @@ FrameAccessor::Key GetImageForMarker(const Marker& marker,
image);
}
+FrameAccessor::Key GetMaskForMarker(const Marker& marker,
+ FrameAccessor* frame_accessor,
+ FloatImage* mask) {
+ Region region = marker.search_region.Rounded();
+ return frame_accessor->GetMaskForTrack(marker.clip,
+ marker.frame,
+ marker.track,
+ &region,
+ mask);
+}
+
} // namespace
bool AutoTrack::TrackMarker(Marker* tracked_marker,
@@ -149,6 +160,11 @@ bool AutoTrack::TrackMarker(Marker* tracked_marker,
return false;
}
+ FloatImage reference_mask;
+ FrameAccessor::Key reference_mask_key = GetMaskForMarker(reference_marker,
+ frame_accessor_,
+ &reference_mask);
+
FloatImage tracked_image;
FrameAccessor::Key tracked_key = GetImageForMarker(*tracked_marker,
frame_accessor_,
@@ -167,6 +183,10 @@ bool AutoTrack::TrackMarker(Marker* tracked_marker,
if (track_options) {
local_track_region_options = *track_options;
}
+ if (reference_mask_key != NULL) {
+ LG << "Using mask for reference marker: " << reference_marker;
+ local_track_region_options.image1_mask = &reference_mask;
+ }
local_track_region_options.num_extra_points = 1; // For center point.
local_track_region_options.attempt_refine_before_brute = predicted_position;
TrackRegion(reference_image,
@@ -191,9 +211,10 @@ bool AutoTrack::TrackMarker(Marker* tracked_marker,
tracked_marker->reference_clip = reference_marker.clip;
tracked_marker->reference_frame = reference_marker.frame;
- // Release the images from the accessor cache.
+ // Release the images and masks from the accessor cache.
frame_accessor_->ReleaseImage(reference_key);
frame_accessor_->ReleaseImage(tracked_key);
+ frame_accessor_->ReleaseMask(reference_mask_key);
// TODO(keir): Possibly the return here should get removed since the results
// are part of TrackResult. However, eventually the autotrack stuff will have
diff --git a/intern/libmv/libmv/autotrack/frame_accessor.h b/intern/libmv/libmv/autotrack/frame_accessor.h
index 8de5d865cd7..32f6349963c 100644
--- a/intern/libmv/libmv/autotrack/frame_accessor.h
+++ b/intern/libmv/libmv/autotrack/frame_accessor.h
@@ -76,6 +76,25 @@ struct FrameAccessor {
// free the image immediately; others may hold onto the image.
virtual void ReleaseImage(Key) = 0;
+ // Get mask image for the given track.
+ //
+ // Implementation of this method should sample mask associated with the track
+ // within given region to the given destination.
+ //
+ // Result is supposed to be a single channel image.
+ //
+ // If region is NULL, it it assumed to be full-frame.
+ virtual Key GetMaskForTrack(int clip,
+ int frame,
+ int track,
+ const Region* region,
+ FloatImage* destination) = 0;
+
+ // Release a specified mask.
+ //
+ // Non-caching implementation may free used memory immediately.
+ virtual void ReleaseMask(Key key) = 0;
+
virtual bool GetClipDimensions(int clip, int* width, int* height) = 0;
virtual int NumClips() = 0;
virtual int NumFrames(int clip) = 0;
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 990d250b854..bfe8dcbb21e 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -974,8 +974,11 @@ static void track_mask_set_pixel_cb(int x, int x_end, int y, void *user_data)
}
static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height,
- MovieTrackingMarker *marker, bGPDlayer *layer,
- float *mask, int mask_width, int mask_height)
+ const float region_min[2],
+ bGPDlayer *layer,
+ float *mask,
+ int mask_width,
+ int mask_height)
{
bGPDframe *frame = layer->frames.first;
TrackMaskSetPixelData data;
@@ -994,8 +997,8 @@ static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height
point = mask_points = MEM_callocN(2 * stroke->totpoints * sizeof(int),
"track mask rasterization points");
for (int i = 0; i < stroke->totpoints; i++, point += 2) {
- point[0] = (stroke_points[i].x - marker->search_min[0]) * frame_width;
- point[1] = (stroke_points[i].y - marker->search_min[1]) * frame_height;
+ point[0] = stroke_points[i].x * frame_width - region_min[0];
+ point[1] = stroke_points[i].y * frame_height - region_min[1];
}
/* TODO: add an option to control whether AA is enabled or not */
BLI_bitmap_draw_2d_poly_v2i_n(
@@ -1010,26 +1013,42 @@ static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height
}
}
-float *BKE_tracking_track_get_mask(int frame_width, int frame_height,
- MovieTrackingTrack *track, MovieTrackingMarker *marker)
+/* Region is in pixel space, relative to marker's center. */
+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)
{
float *mask = NULL;
bGPDlayer *layer = track_mask_gpencil_layer_get(track);
- int mask_width, mask_height;
-
- mask_width = (marker->search_max[0] - marker->search_min[0]) * frame_width;
- mask_height = (marker->search_max[1] - marker->search_min[1]) * frame_height;
-
- if (layer) {
+ if (layer != NULL) {
+ const int mask_width = region_max[0] - region_min[0];
+ const int mask_height = region_max[1] - region_min[1];
mask = MEM_callocN(mask_width * mask_height * sizeof(float), "track mask");
-
- track_mask_gpencil_layer_rasterize(frame_width, frame_height, marker, layer,
- mask, mask_width, mask_height);
+ track_mask_gpencil_layer_rasterize(frame_width, frame_height,
+ region_min,
+ layer,
+ mask,
+ mask_width, mask_height);
}
-
return mask;
}
+float *BKE_tracking_track_get_mask(int frame_width, int frame_height,
+ MovieTrackingTrack *track,
+ MovieTrackingMarker *marker)
+{
+ /* Convert normalized space marker's search area to pixel-space region. */
+ const float region_min[2] = {marker->search_min[0] * frame_width,
+ marker->search_min[1] * frame_height};
+ const float region_max[2] = {marker->search_max[0] * frame_width,
+ marker->search_max[1] * frame_height};
+ return tracking_track_get_mask_for_region(frame_width, frame_height,
+ region_min,
+ region_max,
+ track);
+}
+
float BKE_tracking_track_get_weight_for_marker(MovieClip *clip, MovieTrackingTrack *track, MovieTrackingMarker *marker)
{
FCurve *weight_fcurve;
diff --git a/source/blender/blenkernel/intern/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c
index 3b56ea271d0..9475925cdda 100644
--- a/source/blender/blenkernel/intern/tracking_auto.c
+++ b/source/blender/blenkernel/intern/tracking_auto.c
@@ -36,8 +36,9 @@
#include "DNA_movieclip_types.h"
#include "DNA_object_types.h" /* SELECT */
-#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
+#include "BLI_threads.h"
#include "BLI_math.h"
#include "BKE_movieclip.h"
@@ -76,6 +77,9 @@ typedef struct AutoTrackContext {
int num_tracks; /* Number of tracks being tracked. */
AutoTrackOptions *options; /* Per-tracking track options. */
+ /* Array of all tracks, indexed by track_index. */
+ MovieTrackingTrack **tracks;
+
bool backwards;
bool sequence;
int first_frame;
@@ -306,8 +310,15 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip,
BLI_spin_init(&context->spin_lock);
+ int num_total_tracks = BLI_listbase_count(tracksbase);
+ context->tracks =
+ MEM_callocN(sizeof(MovieTrackingTrack*) * num_total_tracks,
+ "auto track pointers");
+
context->image_accessor =
- tracking_image_accessor_new(context->clips, 1, user->framenr);
+ tracking_image_accessor_new(context->clips, 1,
+ context->tracks, num_total_tracks,
+ user->framenr);
context->autotrack =
libmv_autoTrackNew(context->image_accessor->libmv_accessor);
@@ -361,6 +372,7 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip,
options->use_keyframe_match =
track->pattern_match == TRACK_MATCH_KEYFRAME;
}
+ context->tracks[track_index] = track;
++track_index;
}
@@ -565,6 +577,7 @@ void BKE_autotrack_context_free(AutoTrackContext *context)
libmv_autoTrackDestroy(context->autotrack);
tracking_image_accessor_destroy(context->image_accessor);
MEM_freeN(context->options);
+ MEM_freeN(context->tracks);
BLI_spin_end(&context->spin_lock);
MEM_freeN(context);
}
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index 1c056cda68d..a95399562d5 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -875,8 +875,64 @@ static void accessor_release_image_callback(libmv_CacheKey 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);
+ }
+}
+
TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP],
int num_clips,
+ MovieTrackingTrack **tracks,
+ int num_tracks,
int start_frame)
{
TrackingImageAccessor *accessor =
@@ -891,12 +947,16 @@ TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR
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_release_image_callback,
+ accessor_get_mask_for_track_callback,
+ accessor_release_mask_callback);
return accessor;
}
diff --git a/source/blender/blenkernel/tracking_private.h b/source/blender/blenkernel/tracking_private.h
index 591ee4d0d01..1a68a1cac6a 100644
--- a/source/blender/blenkernel/tracking_private.h
+++ b/source/blender/blenkernel/tracking_private.h
@@ -105,6 +105,13 @@ struct MovieTrackingMarker *tracking_get_keyframed_marker(
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;
@@ -114,12 +121,16 @@ typedef struct TrackingImageAccessor {
struct MovieCache *cache;
struct MovieClip *clips[MAX_ACCESSOR_CLIP];
int num_clips;
+ struct MovieTrackingTrack **tracks;
+ int num_tracks;
int start_frame;
struct libmv_FrameAccessor *libmv_accessor;
} TrackingImageAccessor;
TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP],
int num_clips,
+ MovieTrackingTrack **tracks,
+ int num_tracks,
int start_frame);
void tracking_image_accessor_destroy(TrackingImageAccessor *accessor);