Speedup track preview widget for byte images
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 10 Apr 2014 15:14:36 +0000 (21:14 +0600)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 10 Apr 2014 15:14:36 +0000 (21:14 +0600)
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
extern/libmv/libmv-capi.h
extern/libmv/libmv-capi_stub.cc
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/tracking.c
source/blender/editors/interface/interface_draw.c

index 74e9e52094d024ed695337d11bf63ff455f09198..2d3afcd16e7dd768dc93b0146be6f26d4ac716ec 100644 (file)
@@ -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)
index d183bc4cd41e4f375ae8537e4ca5cd075b53edfb..53bf40064fb33bd24c5e54dd05d6808b139fc1fe 100644 (file)
@@ -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);
index bd5d16c9077532d60c176f8efc3f2e6408092adf..6db07974c4759c252ed6617319f877e73515e623 100644 (file)
@@ -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 */
 }
index f9cd1b2a6c5709f80ab9d9fdcd737260beec7c53..de4846e177220d739e0b89e6b8ca5f69efa1b579 100644 (file)
@@ -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;
 
index a96960c0345fcb530b918680ed2c9092a2c96013..8434fde30058eccf5b47a560b535bd5b75c98dd0 100644 (file)
@@ -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;
index 42ee3681297b43e09355d2cb4fd9ce7c12e60996..85c82efc34701b4b8646b5145d016adf68ba285d 100644 (file)
@@ -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)