From df63e8fd9331594eaef0a7897b9322533188da79 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 10 Apr 2014 21:14:36 +0600 Subject: Speedup track preview widget for byte images This gives a huge speedup gain for cases when you've got rather huge markers on a byte images. Done by skipping IMB_float_from_rect()/IMB_rect_from_float() for such cases. We can sample the buffers without color space conversion. --- extern/libmv/libmv-capi.cc | 59 ++++++++++++++++++++--- extern/libmv/libmv-capi.h | 17 +++++-- extern/libmv/libmv-capi_stub.cc | 23 +++++++-- source/blender/blenkernel/intern/movieclip.c | 12 +---- source/blender/blenkernel/intern/tracking.c | 32 ++++++++---- source/blender/editors/interface/interface_draw.c | 6 +-- 6 files changed, 112 insertions(+), 37 deletions(-) diff --git a/extern/libmv/libmv-capi.cc b/extern/libmv/libmv-capi.cc index 74e9e52094d..2d3afcd16e7 100644 --- a/extern/libmv/libmv-capi.cc +++ b/extern/libmv/libmv-capi.cc @@ -158,6 +158,19 @@ static void imageToFloatBuf(const libmv::FloatImage *image, int channels, float } } +static void imageToByteBuf(const libmv::FloatImage *image, int channels, unsigned char *buf) +{ + int x, y, k, a = 0; + + for (y = 0; y < image->Height(); y++) { + for (x = 0; x < image->Width(); x++) { + for (k = 0; k < channels; k++) { + buf[a++] = (*image)(y, x, k) * 255.0f; + } + } + } +} + #if defined(DUMP_FAILURE) || defined (DUMP_ALWAYS) static void savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int color_type, const char *file_name) @@ -385,10 +398,12 @@ int libmv_trackRegion(const libmv_TrackRegionOptions *options, return tracking_result; } -void libmv_samplePlanarPatch(const float *image, int width, int height, - int channels, const double *xs, const double *ys, +void libmv_samplePlanarPatch(const float *image, + int width, int height, int channels, + const double *xs, const double *ys, int num_samples_x, int num_samples_y, - const float *mask, float *patch, + const float *mask, + float *patch, double *warped_position_x, double *warped_position_y) { libmv::FloatImage libmv_image, libmv_patch, libmv_mask; @@ -402,13 +417,45 @@ void libmv_samplePlanarPatch(const float *image, int width, int height, libmv_mask_for_sample = &libmv_mask; } - libmv::SamplePlanarPatch(libmv_image, xs, ys, num_samples_x, num_samples_y, - libmv_mask_for_sample, &libmv_patch, - warped_position_x, warped_position_y); + libmv::SamplePlanarPatch(libmv_image, xs, ys, + num_samples_x, num_samples_y, + libmv_mask_for_sample, + &libmv_patch, + warped_position_x, + warped_position_y); imageToFloatBuf(&libmv_patch, channels, patch); } + void libmv_samplePlanarPatchByte(const unsigned char *image, + int width, int height, int channels, + const double *xs, const double *ys, + int num_samples_x, int num_samples_y, + const float *mask, + unsigned char *patch, + double *warped_position_x, double *warped_position_y) +{ + libmv::FloatImage libmv_image, libmv_patch, libmv_mask; + libmv::FloatImage *libmv_mask_for_sample = NULL; + + byteBufToImage(image, width, height, channels, &libmv_image); + + if (mask) { + floatBufToImage(mask, width, height, 1, &libmv_mask); + + libmv_mask_for_sample = &libmv_mask; + } + + libmv::SamplePlanarPatch(libmv_image, xs, ys, + num_samples_x, num_samples_y, + libmv_mask_for_sample, + &libmv_patch, + warped_position_x, + warped_position_y); + + imageToByteBuf(&libmv_patch, channels, patch); +} + /* ************ Tracks ************ */ struct libmv_Tracks *libmv_tracksNew(void) diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h index d183bc4cd41..53bf40064fb 100644 --- a/extern/libmv/libmv-capi.h +++ b/extern/libmv/libmv-capi.h @@ -64,11 +64,22 @@ int libmv_trackRegion(const libmv_TrackRegionOptions *options, const double *x1, const double *y1, libmv_TrackRegionResult *result, double *x2, double *y2); -void libmv_samplePlanarPatch(const float *image, int width, int height, - int channels, const double *xs, const double *ys, +void libmv_samplePlanarPatch(const float *image, + int width, int height, + int channels, + const double *xs, const double *ys, int num_samples_x, int num_samples_y, - const float *mask, float *patch, + const float *mask, + float *patch, double *warped_position_x, double *warped_position_y); +void libmv_samplePlanarPatchByte(const unsigned char *image, + int width, int height, + int channels, + const double *xs, const double *ys, + int num_samples_x, int num_samples_y, + const float *mask, + unsigned char *patch, + double *warped_position_x, double *warped_position_y); /* Tracks */ struct libmv_Tracks *libmv_tracksNew(void); diff --git a/extern/libmv/libmv-capi_stub.cc b/extern/libmv/libmv-capi_stub.cc index bd5d16c9077..6db07974c47 100644 --- a/extern/libmv/libmv-capi_stub.cc +++ b/extern/libmv/libmv-capi_stub.cc @@ -68,11 +68,24 @@ int libmv_trackRegion(const libmv_TrackRegionOptions * /*options*/, return false; } -void libmv_samplePlanarPatch(const float *image, int width, int height, - int channels, const double *xs, const double *ys, - int num_samples_x, int num_samples_y, - const float *mask, float *patch, - double *warped_position_x, double *warped_position_y) +void libmv_samplePlanarPatch(const float * /*image*/, + int /*width*/, int /*height*/, int /*channels*/, + const double * /*xs*/, const double * /*ys*/, + int /*num_samples_x*/, int /*num_samples_y*/, + const float * /*mask*/, + float * /*patch*/, + double * /*warped_position_x*/, double * /*warped_position_y*/ +{ + /* TODO(sergey): implement */ +} + +void libmv_samplePlanarPatch(const unsigned char * /*image*/, + int /*width*/, int /*height*/, int /*channels*/, + const double * /*xs*/, const double * /*ys*/, + int /*num_samples_x*/, int /*num_samples_y*/, + const float * /*mask*/, + unsigned char * /*patch*/, + double * /*warped_position_x*/, double * /*warped_position_y*/ { /* TODO(sergey): implement */ } diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index f9cd1b2a6c5..de4846e1772 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -1243,7 +1243,6 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip scopes->track_disabled = false; if (ibuf && (ibuf->rect || ibuf->rect_float)) { - ImBuf *search_ibuf; MovieTrackingMarker undist_marker = *marker; if (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { @@ -1261,16 +1260,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip undist_marker.pos[1] /= height * aspy; } - search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, &undist_marker, true, true); - - if (search_ibuf) { - if (!search_ibuf->rect_float) { - /* sampling happens in float buffer */ - IMB_float_from_rect(search_ibuf); - } - - scopes->track_search = search_ibuf; - } + scopes->track_search = BKE_tracking_get_search_imbuf(ibuf, track, &undist_marker, true, true); scopes->undist_marker = undist_marker; diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index a96960c0345..8434fde3005 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1981,11 +1981,9 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea if (num_samples_x <= 0 || num_samples_y <= 0) return NULL; - pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat); - - if (!search_ibuf->rect_float) { - IMB_float_from_rect(search_ibuf); - } + pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, + 32, + search_ibuf->rect_float ? IB_rectfloat : IB_rect); tracking_get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y); @@ -2015,10 +2013,26 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker); } - libmv_samplePlanarPatch(search_ibuf->rect_float, search_ibuf->x, search_ibuf->y, 4, - src_pixel_x, src_pixel_y, num_samples_x, - num_samples_y, mask, pattern_ibuf->rect_float, - &warped_position_x, &warped_position_y); + if (search_ibuf->rect_float) { + libmv_samplePlanarPatch(search_ibuf->rect_float, + search_ibuf->x, search_ibuf->y, 4, + src_pixel_x, src_pixel_y, + num_samples_x, num_samples_y, + mask, + pattern_ibuf->rect_float, + &warped_position_x, + &warped_position_y); + } + else { + libmv_samplePlanarPatchByte((unsigned char *) search_ibuf->rect, + search_ibuf->x, search_ibuf->y, 4, + src_pixel_x, src_pixel_y, + num_samples_x, num_samples_y, + mask, + (unsigned char *) pattern_ibuf->rect, + &warped_position_x, + &warped_position_y); + } if (pos) { pos[0] = warped_position_x; diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 42ee3681297..85c82efc347 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1522,9 +1522,9 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc IMB_freeImBuf(scopes->track_preview); tmpibuf = BKE_tracking_sample_pattern(scopes->frame_width, scopes->frame_height, - scopes->track_search, scopes->track, - &scopes->undist_marker, true, scopes->use_track_mask, - width, height, scopes->track_pos); + scopes->track_search, scopes->track, + &scopes->undist_marker, true, scopes->use_track_mask, + width, height, scopes->track_pos); if (tmpibuf) { if (tmpibuf->rect_float) -- cgit v1.2.3