diff --git a/intern/libmv/intern/autotrack.cc b/intern/libmv/intern/autotrack.cc index 3b7c9c5a010..980504ed163 100644 --- a/intern/libmv/intern/autotrack.cc +++ b/intern/libmv/intern/autotrack.cc @@ -82,6 +82,21 @@ void libmv_autoTrackAddMarker(libmv_AutoTrack* libmv_autotrack, ((AutoTrack*) libmv_autotrack)->AddMarker(marker); } +void libmv_autoTrackSetMarkers(libmv_AutoTrack* libmv_autotrack, + const libmv_Marker* libmv_marker, + size_t num_markers) { + if (num_markers == 0) { + // Early output. + return; + } + libmv::vector markers; + markers.resize(num_markers); + for (size_t i = 0; i < num_markers; ++i) { + libmv_apiMarkerToMarker(libmv_marker[i], &markers[i]); + } + ((AutoTrack*) libmv_autotrack)->SetMarkers(&markers); +} + int libmv_autoTrackGetMarker(libmv_AutoTrack* libmv_autotrack, int clip, int frame, diff --git a/intern/libmv/intern/autotrack.h b/intern/libmv/intern/autotrack.h index 2a4a8f3c97f..9a073ff249b 100644 --- a/intern/libmv/intern/autotrack.h +++ b/intern/libmv/intern/autotrack.h @@ -58,6 +58,10 @@ int libmv_autoTrackMarker(libmv_AutoTrack* libmv_autotrack, void libmv_autoTrackAddMarker(libmv_AutoTrack* libmv_autotrack, const libmv_Marker* libmv_marker); +void libmv_autoTrackSetMarkers(libmv_AutoTrack* libmv_autotrack, + const libmv_Marker* libmv_marker, + size_t num_markers); + int libmv_autoTrackGetMarker(libmv_AutoTrack* libmv_autotrack, int clip, int frame, diff --git a/intern/libmv/intern/stub.cc b/intern/libmv/intern/stub.cc index 8603cc03153..fa2509ffcf6 100644 --- a/intern/libmv/intern/stub.cc +++ b/intern/libmv/intern/stub.cc @@ -361,6 +361,12 @@ void libmv_autoTrackAddMarker(libmv_AutoTrack* /*libmv_autotrack*/, { } +void libmv_autoTrackSetMarkers(libmv_AutoTrack* /*libmv_autotrack*/, + const libmv_Marker* /*libmv_marker-*/, + size_t /*num_markers*/) +{ +} + int libmv_autoTrackGetMarker(libmv_AutoTrack* /*libmv_autotrack*/, int /*clip*/, int /*frame*/, diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h index 0bdff3eb795..bd193b82b9e 100644 --- a/source/blender/blenkernel/BKE_movieclip.h +++ b/source/blender/blenkernel/BKE_movieclip.h @@ -74,8 +74,8 @@ void BKE_movieclip_build_proxy_frame(struct MovieClip *clip, int clip_flag, stru void BKE_movieclip_build_proxy_frame_for_ibuf(struct MovieClip *clip, struct ImBuf *ibuf, struct MovieDistortion *distortion, int cfra, int *build_sizes, int build_count, bool undistorted); -float BKE_movieclip_remap_scene_to_clip_frame(struct MovieClip *clip, float framenr); -float BKE_movieclip_remap_clip_to_scene_frame(struct MovieClip *clip, float framenr); +float BKE_movieclip_remap_scene_to_clip_frame(const struct MovieClip *clip, float framenr); +float BKE_movieclip_remap_clip_to_scene_frame(const struct MovieClip *clip, float framenr); void BKE_movieclip_filename_for_frame(struct MovieClip *clip, struct MovieClipUser *user, char *name); struct ImBuf *BKE_movieclip_anim_ibuf_for_frame(struct MovieClip *clip, struct MovieClipUser *user); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index db05939b1cc..08df976941b 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -1524,12 +1524,12 @@ void BKE_movieclip_make_local(Main *bmain, MovieClip *clip, const bool lib_local BKE_id_make_local_generic(bmain, &clip->id, true, lib_local); } -float BKE_movieclip_remap_scene_to_clip_frame(MovieClip *clip, float framenr) +float BKE_movieclip_remap_scene_to_clip_frame(const MovieClip *clip, float framenr) { return framenr - (float) clip->start_frame + 1.0f; } -float BKE_movieclip_remap_clip_to_scene_frame(MovieClip *clip, float framenr) +float BKE_movieclip_remap_clip_to_scene_frame(const MovieClip *clip, float framenr) { return framenr + (float) clip->start_frame - 1.0f; } diff --git a/source/blender/blenkernel/intern/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c index 4ff4a129768..40234bacdfe 100644 --- a/source/blender/blenkernel/intern/tracking_auto.c +++ b/source/blender/blenkernel/intern/tracking_auto.c @@ -236,17 +236,15 @@ static void libmv_marker_to_dna_marker(libmv_Marker *libmv_marker, } } -static bool check_track_trackable(MovieClip *clip, +static bool check_track_trackable(const MovieClip *clip, MovieTrackingTrack *track, - MovieClipUser *user) + const MovieClipUser *user) { if (TRACK_SELECTED(track) && (track->flag & (TRACK_LOCKED | TRACK_HIDDEN)) == 0) { - MovieTrackingMarker *marker; - int frame; - frame = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); - marker = BKE_tracking_marker_get(track, frame); + int frame = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); + const MovieTrackingMarker *marker = BKE_tracking_marker_get(track, frame); return (marker->flag & MARKER_DISABLED) == 0; } return false; @@ -283,6 +281,108 @@ static bool tracking_check_marker_margin(libmv_Marker *libmv_marker, return true; } +/* Provide Libmv side of auto track all information about given tracks. */ +static void fill_autotrack_tracks(const int frame_width, + const int frame_height, + const ListBase *tracksbase, + const bool backwards, + struct libmv_AutoTrack *autotrack) +{ + /* Count number of markers to be put to a context. */ + size_t num_trackable_markers = 0; + for (MovieTrackingTrack *track = tracksbase->first; + track != NULL; + track = track->next) + { + for (int i = 0; i < track->markersnr; ++i) { + const MovieTrackingMarker *marker = track->markers + i; + if ((marker->flag & MARKER_DISABLED) == 0) { + num_trackable_markers++; + } + } + } + /* Early output if we don't have any markers. */ + if (num_trackable_markers == 0) { + return; + } + /* Allocate memory for all the markers. */ + libmv_Marker *libmv_markers = MEM_mallocN( + sizeof(libmv_Marker) * num_trackable_markers, + "libmv markers array"); + /* Fill in markers array. */ + int track_index = 0, num_filled_libmv_markers = 0; + for (MovieTrackingTrack *track = tracksbase->first; + track != NULL; + track = track->next) + { + for (int i = 0; i < track->markersnr; ++i) { + MovieTrackingMarker *marker = track->markers + i; + if ((marker->flag & MARKER_DISABLED) != 0) { + continue; + } + dna_marker_to_libmv_marker( + track, + marker, + 0, + track_index, + frame_width, frame_height, + backwards, + &libmv_markers[num_filled_libmv_markers++]); + } + /* Put all markers to autotrack at once. */ + track_index++; + } + /* Add all markers to autotrack. */ + libmv_autoTrackSetMarkers(autotrack, + libmv_markers, + num_trackable_markers); + /* Free temporary memory. */ + MEM_freeN(libmv_markers); +} + +static void create_per_track_tracking_options(const MovieClip *clip, + const MovieClipUser *user, + const ListBase *tracksbase, + AutoTrackContext *context) +{ + /* Count number of trackable tracks. */ + for (MovieTrackingTrack *track = tracksbase->first; + track != NULL; + track = track->next) + { + if (check_track_trackable(clip, track, user)) { + context->num_tracks++; + } + } + /* Allocate required memory. */ + context->options = + MEM_callocN(sizeof(AutoTrackOptions) * context->num_tracks, + "auto track options"); + /* Fill in all the settings. */ + int i = 0, track_index = 0; + for (MovieTrackingTrack *track = tracksbase->first; + track != NULL; + track = track->next) + { + if (!check_track_trackable(clip, track, user)) { + ++track_index; + continue; + } + AutoTrackOptions *options = &context->options[i++]; + /* TODO(sergey): Single clip only for now. */ + options->clip_index = 0; + options->track_index = track_index; + options->track = track; + tracking_configure_tracker(track, + NULL, + &options->track_region_options); + options->use_keyframe_match = + track->pattern_match == TRACK_MATCH_KEYFRAME; + context->tracks[track_index] = track; + ++track_index; + } +} + AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip, MovieClipUser *user, const bool backwards, @@ -291,16 +391,13 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip, AutoTrackContext *context = MEM_callocN(sizeof(AutoTrackContext), "autotrack context"); MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *track; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - int i, track_index, frame_width, frame_height; - + int frame_width, frame_height; + /* get size of frame to convert normalized coordinates to a picture ones. */ BKE_movieclip_get_size(clip, user, &frame_width, &frame_height); - /* TODO(sergey): Currently using only a single clip. */ context->clips[0] = clip; context->num_clips = 1; - context->user = *user; context->user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL; context->user.render_flag = 0; @@ -311,75 +408,27 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip, context->first_frame = user->framenr; context->sync_frame = user->framenr; context->first_sync = true; - BLI_spin_init(&context->spin_lock); - - int num_total_tracks = BLI_listbase_count(tracksbase); + const int num_total_tracks = BLI_listbase_count(tracksbase); context->tracks = - MEM_callocN(sizeof(MovieTrackingTrack *) * num_total_tracks, - "auto track pointers"); - + MEM_callocN(sizeof(MovieTrackingTrack *) * num_total_tracks, + "auto track pointers"); + /* Initialize image accessor. */ context->image_accessor = tracking_image_accessor_new(context->clips, 1, context->tracks, num_total_tracks, user->framenr); + /* Initialize auto track context and provide all information about currently + * tracked markers. + */ context->autotrack = - libmv_autoTrackNew(context->image_accessor->libmv_accessor); - - /* Fill in Autotrack with all markers we know. */ - track_index = 0; - for (track = tracksbase->first; - track; - track = track->next) - { - if (check_track_trackable(clip, track, user)) { - context->num_tracks++; - } - - for (i = 0; i < track->markersnr; ++i) { - MovieTrackingMarker *marker = track->markers + i; - if ((marker->flag & MARKER_DISABLED) == 0) { - libmv_Marker libmv_marker; - dna_marker_to_libmv_marker(track, - marker, - 0, - track_index, - frame_width, - frame_height, - backwards, - &libmv_marker); - libmv_autoTrackAddMarker(context->autotrack, - &libmv_marker); - } - } - track_index++; - } - + libmv_autoTrackNew(context->image_accessor->libmv_accessor); + fill_autotrack_tracks(frame_width, frame_height, + tracksbase, + backwards, + context->autotrack); /* Create per-track tracking options. */ - context->options = - MEM_callocN(sizeof(AutoTrackOptions) * context->num_tracks, - "auto track options"); - i = track_index = 0; - for (track = tracksbase->first; - track; - track = track->next) - { - if (check_track_trackable(clip, track, user)) { - AutoTrackOptions *options = &context->options[i++]; - /* TODO(sergey): Single clip only for now. */ - options->clip_index = 0; - options->track_index = track_index; - options->track = track; - tracking_configure_tracker(track, - NULL, - &options->track_region_options); - options->use_keyframe_match = - track->pattern_match == TRACK_MATCH_KEYFRAME; - } - context->tracks[track_index] = track; - ++track_index; - } - + create_per_track_tracking_options(clip, user, tracksbase, context); return context; } diff --git a/source/blender/blenlib/BLI_math_bits.h b/source/blender/blenlib/BLI_math_bits.h index 1ac98a682d1..86213dc271f 100644 --- a/source/blender/blenlib/BLI_math_bits.h +++ b/source/blender/blenlib/BLI_math_bits.h @@ -31,7 +31,24 @@ extern "C" { #include "BLI_math_inline.h" -MINLINE unsigned int highest_order_bit_i(unsigned int n); +/* Search the value from LSB to MSB for a set bit. Returns index of this bit. */ +MINLINE int bitscan_forward_i(int a); +MINLINE unsigned int bitscan_forward_uint(unsigned int a); + +/* Similar to above, but also clears the bit. */ +MINLINE int bitscan_forward_clear_i(int *a); +MINLINE unsigned int bitscan_forward_clear_uint(unsigned int *a); + +/* Search the value from MSB to LSB for a set bit. Returns index of this bit. */ +MINLINE int bitscan_reverse_i(int a); +MINLINE unsigned int bitscan_reverse_uint(unsigned int a); + +/* Similar to above, but also clears the bit. */ +MINLINE int bitscan_reverse_clear_i(int *a); +MINLINE unsigned int bitscan_reverse_clear_uint(unsigned int *a); + +/* NOTE: Those functions returns 2 to the power of index of highest order bit. */ +MINLINE unsigned int highest_order_bit_uint(unsigned int n); MINLINE unsigned short highest_order_bit_s(unsigned short n); #ifdef __GNUC__ diff --git a/source/blender/blenlib/intern/math_bits_inline.c b/source/blender/blenlib/intern/math_bits_inline.c index 82d7e2114c2..d96cf969dae 100644 --- a/source/blender/blenlib/intern/math_bits_inline.c +++ b/source/blender/blenlib/intern/math_bits_inline.c @@ -27,14 +27,71 @@ #include "BLI_math_bits.h" -MINLINE unsigned int highest_order_bit_i(unsigned int n) +MINLINE int bitscan_forward_i(int a) { - n |= (n >> 1); - n |= (n >> 2); - n |= (n >> 4); - n |= (n >> 8); - n |= (n >> 16); - return n - (n >> 1); + BLI_assert(a != 0); +# ifdef _MSC_VER + unsigned long ctz; + _BitScanForward(&ctz, a); + return ctz; +#else + return __builtin_ctz((unsigned int)a); +#endif +} + +MINLINE unsigned int bitscan_forward_uint(unsigned int a) +{ + return (unsigned int)bitscan_forward_i((int)a); +} + +MINLINE int bitscan_forward_clear_i(int *a) +{ + int i = bitscan_forward_i(*a); + *a &= (*a) - 1; + return i; +} + +MINLINE unsigned int bitscan_forward_clear_uint(unsigned int *a) +{ + return (unsigned int)bitscan_forward_clear_i((int *)a); +} + +MINLINE int bitscan_reverse_i(int a) +{ + BLI_assert(a != 0); +# ifdef _MSC_VER + unsigned long clz; + _BitScanReverse(&clz, a); + return clz; +#else + return __builtin_clz((unsigned int)a); +#endif +} + +MINLINE unsigned int bitscan_reverse_uint(unsigned int a) +{ + return (unsigned int)bitscan_reverse_i((int)a); +} + +MINLINE int bitscan_reverse_clear_i(int *a) +{ + int i = bitscan_reverse_i(*a); + /* TODO(sergey): This could probably be optimized. */ + *a &= ~(1 << (sizeof(int) * 8 - i - 1)); + return i; +} + +MINLINE unsigned int bitscan_reverse_clear_uint(unsigned int *a) +{ + return (unsigned int)bitscan_reverse_clear_i((int *)a); +} + +MINLINE unsigned int highest_order_bit_uint(unsigned int n) +{ + if (n == 0) { + return 0; + } + return 1 << (sizeof(unsigned int) * 8 - bitscan_reverse_uint(n)); } MINLINE unsigned short highest_order_bit_s(unsigned short n)