[Bf-blender-cvs] [28617bb1679] master: Sequencer: Transform ImBuf Processor.

Jeroen Bakker noreply at git.blender.org
Fri Jun 11 09:35:56 CEST 2021


Commit: 28617bb167981ac1e02655c0fc262fe1571d8e1e
Author: Jeroen Bakker
Date:   Fri Jun 11 09:34:31 2021 +0200
Branches: master
https://developer.blender.org/rB28617bb167981ac1e02655c0fc262fe1571d8e1e

Sequencer: Transform ImBuf Processor.

Inside the sequencer the cropping and transform of images/buffers were
implemented locally. This reduced the optimizations that a compiler
could do and added confusing code styles. This patch adds
`IMB_transform` to reduce the confusion and increases compiler
optimizations as more code can be inlined and we can keep track of
indices inside the inner loop.

This increases end-user performance by 30% when playing back aa video
in VSE.

Reviewed By: ISS, zeddb

Differential Revision: https://developer.blender.org/D11549

===================================================================

M	release/datafiles/locale
M	release/scripts/addons
M	source/blender/imbuf/IMB_imbuf.h
M	source/blender/imbuf/intern/imageprocess.c
M	source/blender/sequencer/intern/render.c
M	source/tools

===================================================================

diff --git a/release/datafiles/locale b/release/datafiles/locale
index 5ab29b1331d..4833954c0ac 160000
--- a/release/datafiles/locale
+++ b/release/datafiles/locale
@@ -1 +1 @@
-Subproject commit 5ab29b1331d2103dae634b987f121c4599459d7f
+Subproject commit 4833954c0ac85cc407e1d5a153aa11b1d1823ec0
diff --git a/release/scripts/addons b/release/scripts/addons
index cdabac54c4f..f86f25e6221 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit cdabac54c4fe7c6f8df125814442762aa539172b
+Subproject commit f86f25e62217264495d05f116ccb09d575fe9841
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 9c84127105a..651c69726ff 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -70,6 +70,7 @@ extern "C" {
  */
 struct ImBuf;
 struct rcti;
+struct rctf;
 
 /**
  *
@@ -323,6 +324,11 @@ typedef enum IMB_Proxy_Size {
   IMB_PROXY_MAX_SLOT = 4,
 } IMB_Proxy_Size;
 
+typedef enum eIMBInterpolationFilterMode {
+  IMB_FILTER_NEAREST,
+  IMB_FILTER_BILINEAR,
+} eIMBInterpolationFilterMode;
+
 /* Defaults to BL_proxy within the directory of the animation. */
 void IMB_anim_set_index_dir(struct anim *anim, const char *dir);
 void IMB_anim_get_fname(struct anim *anim, char *file, int size);
@@ -732,6 +738,12 @@ void IMB_processor_apply_threaded_scanlines(int total_scanlines,
                                             ScanlineThreadFunc do_thread,
                                             void *custom_data);
 
+void IMB_transform(struct ImBuf *src,
+                   struct ImBuf *dst,
+                   float transform_matrix[3][3],
+                   struct rctf *src_crop,
+                   const eIMBInterpolationFilterMode filter);
+
 /* ffmpeg */
 void IMB_ffmpeg_init(void);
 const char *IMB_ffmpeg_last_error(void);
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index 1fe3a7717fb..c88a9b81ff2 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -349,6 +349,137 @@ void nearest_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, in
   nearest_interpolation_color(in, outI, outF, u, v);
 }
 
+/* -------------------------------------------------------------------- */
+/** \name Image transform
+ * \{ */
+typedef struct TransformUserData {
+  ImBuf *src;
+  ImBuf *dst;
+  float start_uv[2];
+  float add_x[2];
+  float add_y[2];
+  rctf src_crop;
+} TransformUserData;
+
+static void imb_transform_calc_start_uv(const float transform_matrix[3][3], float r_start_uv[2])
+{
+  float orig[2];
+  orig[0] = 0.0f;
+  orig[1] = 0.0f;
+  mul_v2_m3v2(r_start_uv, transform_matrix, orig);
+}
+
+static void imb_transform_calc_add_x(const float transform_matrix[3][3],
+                                     const float start_uv[2],
+                                     const int width,
+                                     float r_add_x[2])
+{
+  float uv_max_x[2];
+  uv_max_x[0] = width;
+  uv_max_x[1] = 0.0f;
+  mul_v2_m3v2(r_add_x, transform_matrix, uv_max_x);
+  sub_v2_v2(r_add_x, start_uv);
+  mul_v2_fl(r_add_x, 1.0f / width);
+}
+
+static void imb_transform_calc_add_y(const float transform_matrix[3][3],
+                                     const float start_uv[2],
+                                     const int height,
+                                     float r_add_y[2])
+{
+  float uv_max_y[2];
+  uv_max_y[0] = 0.0f;
+  uv_max_y[1] = height;
+  mul_v2_m3v2(r_add_y, transform_matrix, uv_max_y);
+  sub_v2_v2(r_add_y, start_uv);
+  mul_v2_fl(r_add_y, 1.0f / height);
+}
+
+typedef void (*InterpolationColorFunction)(
+    struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v);
+BLI_INLINE void imb_transform_scanlines(const TransformUserData *user_data,
+                                        int start_scanline,
+                                        int num_scanlines,
+                                        InterpolationColorFunction interpolation)
+{
+  const int width = user_data->dst->x;
+
+  float next_line_start_uv[2];
+  madd_v2_v2v2fl(next_line_start_uv, user_data->start_uv, user_data->add_y, start_scanline);
+
+  unsigned char *outI = NULL;
+  float *outF = NULL;
+  pixel_from_buffer(user_data->dst, &outI, &outF, 0, start_scanline);
+
+  for (int yi = start_scanline; yi < start_scanline + num_scanlines; yi++) {
+    float uv[2];
+    copy_v2_v2(uv, next_line_start_uv);
+    add_v2_v2(next_line_start_uv, user_data->add_y);
+    for (int xi = 0; xi < width; xi++) {
+      if (uv[0] >= user_data->src_crop.xmin && uv[0] < user_data->src_crop.xmax &&
+          uv[1] >= user_data->src_crop.ymin && uv[1] < user_data->src_crop.ymax) {
+        interpolation(user_data->src, outI, outF, uv[0], uv[1]);
+      }
+      add_v2_v2(uv, user_data->add_x);
+      if (outI) {
+        outI += 4;
+      }
+      if (outF) {
+        outF += 4;
+      }
+    }
+  }
+}
+
+static void imb_transform_nearest_scanlines(void *custom_data,
+                                            int start_scanline,
+                                            int num_scanlines)
+{
+  const TransformUserData *user_data = custom_data;
+  imb_transform_scanlines(user_data, start_scanline, num_scanlines, nearest_interpolation_color);
+}
+
+static void imb_transform_bilinear_scanlines(void *custom_data,
+                                             int start_scanline,
+                                             int num_scanlines)
+{
+  const TransformUserData *user_data = custom_data;
+  imb_transform_scanlines(user_data, start_scanline, num_scanlines, bilinear_interpolation_color);
+}
+
+static ScanlineThreadFunc imb_transform_scanline_func(const eIMBInterpolationFilterMode filter)
+{
+  ScanlineThreadFunc scanline_func = NULL;
+  switch (filter) {
+    case IMB_FILTER_NEAREST:
+      scanline_func = imb_transform_nearest_scanlines;
+      break;
+    case IMB_FILTER_BILINEAR:
+      scanline_func = imb_transform_bilinear_scanlines;
+      break;
+  }
+  return scanline_func;
+}
+
+void IMB_transform(struct ImBuf *src,
+                   struct ImBuf *dst,
+                   float transform_matrix[3][3],
+                   struct rctf *src_crop,
+                   const eIMBInterpolationFilterMode filter)
+{
+  TransformUserData user_data;
+  user_data.src = src;
+  user_data.dst = dst;
+  user_data.src_crop = *src_crop;
+  imb_transform_calc_start_uv(transform_matrix, user_data.start_uv);
+  imb_transform_calc_add_x(transform_matrix, user_data.start_uv, src->x, user_data.add_x);
+  imb_transform_calc_add_y(transform_matrix, user_data.start_uv, src->y, user_data.add_y);
+  ScanlineThreadFunc scanline_func = imb_transform_scanline_func(filter);
+  IMB_processor_apply_threaded_scanlines(dst->y, scanline_func, &user_data);
+}
+
+/** \} */
+
 /* -------------------------------------------------------------------- */
 /** \name Threaded Image Processing
  * \{ */
diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c
index 73a9569fcd5..b0a8605e922 100644
--- a/source/blender/sequencer/intern/render.c
+++ b/source/blender/sequencer/intern/render.c
@@ -37,6 +37,7 @@
 #include "BLI_linklist.h"
 #include "BLI_listbase.h"
 #include "BLI_path_util.h"
+#include "BLI_rect.h"
 
 #include "BKE_anim_data.h"
 #include "BKE_animsys.h"
@@ -470,29 +471,6 @@ static bool seq_input_have_to_preprocess(const SeqRenderData *context,
   return false;
 }
 
-typedef struct ImageTransformThreadInitData {
-  ImBuf *ibuf_source;
-  ImBuf *ibuf_out;
-  Sequence *seq;
-  float preview_scale_factor;
-  bool is_proxy_image;
-  bool for_render;
-} ImageTransformThreadInitData;
-
-typedef struct ImageTransformThreadData {
-  ImBuf *ibuf_source;
-  ImBuf *ibuf_out;
-  Sequence *seq;
-  /* image_scale_factor is used to scale proxies to correct preview size. */
-  float image_scale_factor;
-  /* Preview scale factor is needed to correct translation to match preview size. */
-  float preview_scale_factor;
-  float crop_scale_factor;
-  bool for_render;
-  int start_line;
-  int tot_line;
-} ImageTransformThreadData;
-
 /**
  * Effect, mask and scene in strip input strips are rendered in preview resolution.
  * They are already down-scaled. #input_preprocess() does not expect this to happen.
@@ -512,49 +490,21 @@ static bool seq_need_scale_to_render_size(const Sequence *seq, bool is_proxy_ima
   return false;
 }
 
-static void sequencer_image_crop_transform_init(void *handle_v,
-                                                int start_line,
-                                                int tot_line,
-                                                void *init_data_v)
-{
-  ImageTransformThreadData *handle = (ImageTransformThreadData *)handle_v;
-  const ImageTransformThreadInitData *init_data = (ImageTransformThreadInitData *)init_data_v;
-
-  handle->ibuf_source = init_data->ibuf_source;
-  handle->ibuf_out = init_data->ibuf_out;
-  handle->seq = init_data->seq;
-
-  handle->preview_scale_factor = init_data->preview_scale_factor;
-  if (seq_need_scale_to_render_size(init_data->seq, init_data->is_proxy_image)) {
-    handle->image_scale_factor = 1.0f;
-  }
-  else {
-    handle->image_scale_factor = handle->preview_scale_factor;
-  }
-
-  /* Proxy image is smaller, so crop values must be corrected by proxy scale factor.
-   * Proxy scale factor always matches preview_scale_factor. */
-  handle->crop_scale_factor = seq_need_scale_to_render_size(init_data->seq,
-                                                            init_data->is_proxy_image) ?
-                                  init_data->preview_scale_factor :
-                                  1.0f;
-
-  handle->for_render = init_data->for_render;
-  handle->start_line = start_line;
-  handle->tot_line = tot_line;
-}
-
-static void sequencer_image_crop_transform_matrix(const ImageTransformThreadData *data,
+static void sequencer_image_crop_transform_matrix(const Sequence *seq,
+                                                  const ImBuf *in,
+                                                  const ImBuf *out,
+                                                  const float image_scale_factor,

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list