[Bf-blender-cvs] [53729249832] master: Fix T78579: Proxy produces wrong preview when using Offset or Crop

Richard Antalik noreply at git.blender.org
Fri Jul 10 16:17:00 CEST 2020


Commit: 537292498324808c4621f0a749e9f48ee40da7be
Author: Richard Antalik
Date:   Fri Jul 10 16:14:10 2020 +0200
Branches: master
https://developer.blender.org/rB537292498324808c4621f0a749e9f48ee40da7be

Fix T78579: Proxy produces wrong preview when using Offset or Crop

Make sure that proxy and original images are scaled to same size before
applying offset or crop.

During testing, I discovered, that raw cache will lose information whether
this image was proxy or not. Because of this, proxy images will not create
this cache type. It would be fairly easy to implement this functionality for
cache, but I have decided to not do it now, because I did not want to pass yet
another mostly hard-coded bool flag to cache system. Since image is proxy, it
should be fast to read anyway.

In case of using offset property, code was modified to make sure we scale
image only once. I also tried to make code more readable and streamlined and
cleaned up surrounding functions a bit.

Reviewed By: brecht

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

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

M	source/blender/blenkernel/intern/sequencer.c

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

diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 297d60e5976..3dd8be2e106 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -114,8 +114,7 @@ static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
                                          float cfra,
                                          clock_t begin,
                                          bool use_preprocess,
-                                         const bool is_proxy_image,
-                                         const bool is_preprocessed);
+                                         const bool is_proxy_image);
 static ImBuf *seq_render_strip(const SeqRenderData *context,
                                SeqRenderState *state,
                                Sequence *seq,
@@ -2657,8 +2656,7 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
                                Sequence *seq,
                                float cfra,
                                ImBuf *ibuf,
-                               const bool is_proxy_image,
-                               const bool is_preprocessed)
+                               const bool is_proxy_image)
 {
   Scene *scene = context->scene;
   float mul;
@@ -2672,15 +2670,6 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
   if (seq->flag & (SEQ_USE_CROP | SEQ_USE_TRANSFORM)) {
     StripCrop c = {0};
     StripTransform t = {0};
-    int sx, sy, dx, dy;
-
-    if (is_proxy_image) {
-      double f = BKE_sequencer_rendersize_to_scale_factor(context->preview_render_size);
-
-      if (f != 1.0) {
-        IMB_scalefastImBuf(ibuf, ibuf->x * f, ibuf->y * f);
-      }
-    }
 
     if (seq->flag & SEQ_USE_CROP && seq->strip->crop) {
       c = *seq->strip->crop;
@@ -2689,33 +2678,41 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
       t = *seq->strip->transform;
     }
 
-    if (is_preprocessed) {
-      double xscale = scene->r.xsch ? ((double)context->rectx / (double)scene->r.xsch) : 1.0;
-      double yscale = scene->r.ysch ? ((double)context->recty / (double)scene->r.ysch) : 1.0;
-      if (seq->flag & SEQ_USE_TRANSFORM) {
-        t.xofs *= xscale;
-        t.yofs *= yscale;
+    /* Calculate scale factor for current image if needed. */
+    double scale_factor, image_scale_factor = 1.0;
+    if (context->preview_render_size == SEQ_PROXY_RENDER_SIZE_SCENE) {
+      scale_factor = image_scale_factor = (double)scene->r.size / 100;
+    }
+    else {
+      scale_factor = BKE_sequencer_rendersize_to_scale_factor(context->preview_render_size);
+      if (!is_proxy_image) {
+        image_scale_factor = scale_factor;
+      }
+    }
+
+    if (image_scale_factor != 1.0) {
+      if (context->for_render) {
+        IMB_scaleImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor);
       }
-      if (seq->flag & SEQ_USE_CROP) {
-        c.left *= xscale;
-        c.right *= xscale;
-        c.top *= yscale;
-        c.bottom *= yscale;
+      else {
+        IMB_scalefastImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor);
       }
     }
 
+    t.xofs *= scale_factor;
+    t.yofs *= scale_factor;
+    c.left *= scale_factor;
+    c.right *= scale_factor;
+    c.top *= scale_factor;
+    c.bottom *= scale_factor;
+
+    int sx, sy, dx, dy;
     sx = ibuf->x - c.left - c.right;
     sy = ibuf->y - c.top - c.bottom;
 
     if (seq->flag & SEQ_USE_TRANSFORM) {
-      if (is_preprocessed) {
-        dx = context->rectx;
-        dy = context->recty;
-      }
-      else {
-        dx = scene->r.xsch;
-        dy = scene->r.ysch;
-      }
+      dx = context->rectx;
+      dy = context->recty;
     }
     else {
       dx = sx;
@@ -2724,19 +2721,15 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
 
     if (c.top + c.bottom >= ibuf->y || c.left + c.right >= ibuf->x || t.xofs >= dx ||
         t.yofs >= dy) {
-      make_black_ibuf(ibuf);
+      return NULL;
     }
-    else {
-      ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
 
-      IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
-      sequencer_imbuf_assign_spaces(scene, i);
-
-      IMB_metadata_copy(i, ibuf);
-      IMB_freeImBuf(ibuf);
-
-      ibuf = i;
-    }
+    ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
+    IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
+    sequencer_imbuf_assign_spaces(scene, i);
+    IMB_metadata_copy(i, ibuf);
+    IMB_freeImBuf(ibuf);
+    ibuf = i;
   }
 
   if (seq->flag & SEQ_FLIPX) {
@@ -3097,7 +3090,7 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context,
 
       if (view_id != context->view_id) {
         ibufs_arr[view_id] = seq_render_preprocess_ibuf(
-            &localcontext, seq, ibufs_arr[view_id], cfra, clock(), true, false, false);
+            &localcontext, seq, ibufs_arr[view_id], cfra, clock(), true, false);
       }
     }
 
@@ -3214,7 +3207,7 @@ static ImBuf *seq_render_movie_strip(
 
       if (view_id != context->view_id) {
         ibuf_arr[view_id] = seq_render_preprocess_ibuf(
-            &localcontext, seq, ibuf_arr[view_id], cfra, clock(), true, false, false);
+            &localcontext, seq, ibuf_arr[view_id], cfra, clock(), true, false);
       }
     }
 
@@ -3804,8 +3797,7 @@ static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
                                          float cfra,
                                          clock_t begin,
                                          bool use_preprocess,
-                                         const bool is_proxy_image,
-                                         const bool is_preprocessed)
+                                         const bool is_proxy_image)
 {
   if (context->is_proxy_render == false &&
       (ibuf->x != context->rectx || ibuf->y != context->recty)) {
@@ -3814,11 +3806,17 @@ static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
 
   if (use_preprocess) {
     float cost = seq_estimate_render_cost_end(context->scene, begin);
-    BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost, false);
+
+    /* TODO (Richard): It should be possible to store in cache if image is proxy,
+     * but it adds quite a bit of complexity. Since proxies are fast to read, I would
+     * rather simplify existing code a bit. */
+    if (!is_proxy_image) {
+      BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost, false);
+    }
 
     /* Reset timer so we can get partial render time. */
     begin = seq_estimate_render_cost_begin();
-    ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image, is_preprocessed);
+    ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image);
   }
 
   float cost = seq_estimate_render_cost_end(context->scene, begin);
@@ -3834,11 +3832,6 @@ static ImBuf *seq_render_strip(const SeqRenderData *context,
   ImBuf *ibuf = NULL;
   bool use_preprocess = false;
   bool is_proxy_image = false;
-  /* all effects are handled similarly with the exception of speed effect */
-  int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT :
-                                                                            seq->type;
-  bool is_preprocessed = !ELEM(
-      type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIECLIP);
 
   clock_t begin = seq_estimate_render_cost_begin();
 
@@ -3855,7 +3848,7 @@ static ImBuf *seq_render_strip(const SeqRenderData *context,
   if (ibuf) {
     use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
     ibuf = seq_render_preprocess_ibuf(
-        context, seq, ibuf, cfra, begin, use_preprocess, is_proxy_image, is_preprocessed);
+        context, seq, ibuf, cfra, begin, use_preprocess, is_proxy_image);
   }
 
   if (ibuf == NULL) {



More information about the Bf-blender-cvs mailing list