[Bf-blender-cvs] [c9e4808d363] temp-vse-thumbnail-mod: VSE strip thumbnails

Aditya Y Jeppu noreply at git.blender.org
Wed Sep 8 17:53:04 CEST 2021


Commit: c9e4808d3638bd1fd39341229996247a79455e99
Author: Aditya Y Jeppu
Date:   Wed Sep 8 00:22:45 2021 +0200
Branches: temp-vse-thumbnail-mod
https://developer.blender.org/rBc9e4808d3638bd1fd39341229996247a79455e99

VSE strip thumbnails

The goal is to provide thumbnails in the rectangle coloured strips. Works for
movie clips and image sequences. The thumbnails are loaded from source
using separate thread and stores them in cache. The drawing is called inside the
drawing for each strip, and takes images from cache. Drawing is below the
handles from one end of strip to other, inside view only. The job for caching
is called when images are not available, or there is view change.

All strip operations are valid, and overlap of strip adds transparency to the
image. Images are shown only when strip size is wide enough for clear
visibility of images, and the thumbnails represent source footage clearly.

Cache is limited to 5000 thumbnails and performs cleanup of non visible images
when limit crossed.

Related Task : T89143

Maniphest Tasks: T89143

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

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

M	release/scripts/startup/bl_ui/space_sequencer.py
M	source/blender/blenloader/intern/versioning_300.c
M	source/blender/blenloader/intern/versioning_defaults.c
M	source/blender/editors/interface/interface_templates.c
M	source/blender/editors/space_sequencer/sequencer_draw.c
M	source/blender/editors/space_sequencer/sequencer_edit.c
M	source/blender/editors/space_sequencer/space_sequencer.c
M	source/blender/makesdna/DNA_sequence_types.h
M	source/blender/makesdna/DNA_space_types.h
M	source/blender/makesrna/intern/rna_space.c
M	source/blender/sequencer/SEQ_render.h
M	source/blender/sequencer/intern/image_cache.c
M	source/blender/sequencer/intern/image_cache.h
M	source/blender/sequencer/intern/render.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_jobs.c

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

diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 30115618f3d..1905b990eba 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -250,7 +250,8 @@ class SEQUENCER_PT_sequencer_overlay(Panel):
         layout.prop(st, "show_strip_offset", text="Offsets")
         layout.prop(st, "show_fcurves", text="F-Curves")
         layout.prop(st, "show_grid", text="Grid")
-
+        layout.prop(st, "show_thumbnails", text="Thumbnails")
+        
         layout.separator()
 
         layout.prop_menu_enum(st, "waveform_display_type")
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index f050de6e6e9..bb7f12612ac 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -1084,6 +1084,32 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
     }
   }
 
+  if (!MAIN_VERSION_ATLEAST(bmain, 300, 20)) {
+    LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+      LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+        LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+          if (sl->spacetype == SPACE_SEQ) {
+            SpaceSeq *sseq = (SpaceSeq *)sl;
+            sseq->flag |= SEQ_SHOW_THUMBNAILS;
+          }
+        }
+      }
+    }
+  }
+
+  if (!MAIN_VERSION_ATLEAST(bmain, 300, 21)) {
+    LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+      LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+        LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+          if (sl->spacetype == SPACE_SEQ) {
+            SpaceSeq *sseq = (SpaceSeq *)sl;
+            sseq->flag |= SEQ_SHOW_THUMBNAILS;
+          }
+        }
+      }
+    }
+  }
+
   /**
    * Versioning code until next subversion bump goes here.
    *
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index 82c577d11a0..ac5696b7ef0 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -157,7 +157,7 @@ static void blo_update_defaults_screen(bScreen *screen,
       SpaceSeq *seq = area->spacedata.first;
       seq->flag |= SEQ_SHOW_MARKERS | SEQ_SHOW_FCURVES | SEQ_ZOOM_TO_FIT | SEQ_SHOW_STRIP_OVERLAY |
                    SEQ_SHOW_STRIP_SOURCE | SEQ_SHOW_STRIP_NAME | SEQ_SHOW_STRIP_DURATION |
-                   SEQ_SHOW_GRID;
+                   SEQ_SHOW_GRID | SEQ_SHOW_THUMBNAILS;
 
       seq->render_size = SEQ_RENDER_SIZE_PROXY_100;
       seq->flag |= SEQ_USE_PROXIES;
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 08d78552710..11983c75253 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -5823,6 +5823,11 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
       icon = ICON_SEQUENCE;
       break;
     }
+    if (WM_jobs_test(wm, scene, WM_JOB_TYPE_SEQ_DRAW_THUMBNAIL)) {
+      handle_event = B_STOPSEQ;
+      icon = ICON_SEQUENCE;
+      break;
+    }
     if (WM_jobs_test(wm, scene, WM_JOB_TYPE_CLIP_BUILD_PROXY)) {
       handle_event = B_STOPCLIP;
       icon = ICON_TRACKER;
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index b56ad48cec2..1ec6d9dc4a7 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -25,6 +25,7 @@
 #include <string.h>
 
 #include "BLI_blenlib.h"
+#include "BLI_ghash.h"
 #include "BLI_math.h"
 #include "BLI_string_utils.h"
 #include "BLI_threads.h"
@@ -1277,6 +1278,363 @@ static void draw_seq_fcurve_overlay(
   }
 }
 
+typedef struct ThumbnailDrawJob {
+  SeqRenderData context;
+  GHash *sequences_ghash;
+  Scene *scene;
+  rctf *view_area;
+  float pixelx;
+  float pixely;
+} ThumbnailDrawJob;
+
+typedef struct ThumbDataItem {
+  Sequence *seq_dupli;
+  Scene *scene;
+} ThumbDataItem;
+
+static void thumbnail_hash_data_free(void *val)
+{
+  ThumbDataItem *item = val;
+  SEQ_sequence_free(item->scene, item->seq_dupli, 0);
+  MEM_freeN(val);
+}
+
+static void thumbnail_freejob(void *data)
+{
+  ThumbnailDrawJob *tj = data;
+  BLI_ghash_free(tj->sequences_ghash, NULL, thumbnail_hash_data_free);
+  MEM_freeN(tj->view_area);
+  MEM_freeN(tj);
+}
+
+static void thumbnail_endjob(void *data)
+{
+  ThumbnailDrawJob *tj = data;
+  WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, tj->scene);
+}
+
+static bool check_seq_need_thumbnails(Sequence *seq, rctf *view_area)
+{
+  if (seq->type != SEQ_TYPE_MOVIE && seq->type != SEQ_TYPE_IMAGE) {
+    return false;
+  }
+  if (min_ii(seq->startdisp, seq->start) > view_area->xmax) {
+    return false;
+  }
+  else if (max_ii(seq->enddisp, seq->start + seq->len) < view_area->xmin) {
+    return false;
+  }
+  else if (seq->machine + 1.0f < view_area->ymin) {
+    return false;
+  }
+  else if (seq->machine > view_area->ymax) {
+    return false;
+  }
+
+  return true;
+}
+
+static void seq_get_thumb_image_dimensions(Sequence *seq,
+                                           float pixelx,
+                                           float pixely,
+                                           float *r_thumb_width,
+                                           float *r_thumb_height,
+                                           float *r_image_width,
+                                           float *r_image_height)
+{
+  float image_width = seq->strip->stripdata->orig_width;
+  float image_height = seq->strip->stripdata->orig_height;
+
+  /* Fix the dimensions to be max SEQ_RENDER_THUMB_SIZE (256) for x or y. */
+  float aspect_ratio = (float)image_width / image_height;
+  if (image_width > image_height) {
+    image_width = SEQ_RENDER_THUMB_SIZE;
+    image_height = round_fl_to_int(image_width / aspect_ratio);
+  }
+  else {
+    image_height = SEQ_RENDER_THUMB_SIZE;
+    image_width = round_fl_to_int(image_height * aspect_ratio);
+  }
+
+  /* Calculate thumb dimensions. */
+  float thumb_height = (SEQ_STRIP_OFSTOP - SEQ_STRIP_OFSBOTTOM) - (20 * U.dpi_fac * pixely);
+  aspect_ratio = ((float)image_width) / image_height;
+  float thumb_h_px = thumb_height / pixely;
+  float thumb_width = aspect_ratio * thumb_h_px * pixelx;
+
+  if (r_thumb_height == NULL) {
+    *r_thumb_width = thumb_width;
+    return;
+  }
+
+  *r_thumb_height = thumb_height;
+  *r_image_width = image_width;
+  *r_image_height = image_height;
+  *r_thumb_width = thumb_width;
+}
+
+static float seq_thumbnail_get_start_frame(Sequence *seq, float frame_step, rctf *view_area)
+{
+  if (seq->start > view_area->xmin && seq->start < view_area->xmax) {
+    return seq->start;
+  }
+
+  /* Drawing and caching both check to see if strip is in view area or not before calling this
+   * function so assuming strip/part of strip in view. */
+
+  int no_invisible_thumbs = (view_area->xmin - seq->start) / frame_step;
+  return ((no_invisible_thumbs - 1) * frame_step) + seq->start;
+}
+
+static void thumbnail_start_job(void *data, short *stop, short *do_update, float *progress)
+{
+  ThumbnailDrawJob *tj = data;
+  float start_frame, frame_step;
+
+  GHashIterator gh_iter;
+  BLI_ghashIterator_init(&gh_iter, tj->sequences_ghash);
+  while (!BLI_ghashIterator_done(&gh_iter) & !*stop) {
+    Sequence *seq_orig = BLI_ghashIterator_getKey(&gh_iter);
+    ThumbDataItem *val = BLI_ghash_lookup(tj->sequences_ghash, seq_orig);
+
+    if (check_seq_need_thumbnails(seq_orig, tj->view_area)) {
+      seq_get_thumb_image_dimensions(
+          val->seq_dupli, tj->pixelx, tj->pixely, &frame_step, NULL, NULL, NULL);
+      start_frame = seq_thumbnail_get_start_frame(seq_orig, frame_step, tj->view_area);
+      SEQ_render_thumbnails(
+          &tj->context, val->seq_dupli, seq_orig, start_frame, frame_step, tj->view_area, stop);
+    }
+    BLI_ghashIterator_step(&gh_iter);
+  }
+  UNUSED_VARS(do_update, progress);
+}
+
+static SeqRenderData sequencer_thumbnail_context_init(const bContext *C)
+{
+  struct Main *bmain = CTX_data_main(C);
+  struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+  Scene *scene = CTX_data_scene(C);
+  SpaceSeq *sseq = CTX_wm_space_seq(C);
+  SeqRenderData context = {0};
+
+  /* Taking rectx and recty as 0 as dimensions not known here, and context is used to calculate
+   * hash key but not necessary as other variables of SeqRenderData are unique enough. */
+  SEQ_render_new_render_data(bmain, depsgraph, scene, 0, 0, sseq->render_size, false, &context);
+  context.view_id = BKE_scene_multiview_view_id_get(&scene->r, STEREO_LEFT_NAME);
+  context.use_proxies = false;
+
+  return context;
+}
+
+static GHash *sequencer_thumbnail_ghash_init(const bContext *C, View2D *v2d, Editing *ed)
+{
+  Scene *scene = CTX_data_scene(C);
+
+  /* Set the data for thumbnail caching job. */
+  GHash *thumb_data_hash = BLI_ghash_ptr_new("seq_duplicates_and_origs");
+
+  LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) {
+    ThumbDataItem *val_need_update = BLI_ghash_lookup(thumb_data_hash, seq);
+    if (val_need_update == NULL && check_seq_need_thumbnails(seq, &v2d->cur)) {
+      ThumbDataItem *val = MEM_callocN(sizeof(ThumbDataItem), "Thumbnail Hash Values");
+      val->seq_dupli = SEQ_sequence_dupli_recursive(scene, scene, NULL, seq, 0);
+      val->scene = scene;
+      BLI_ghash_insert(thumb_data_hash, seq, val);
+    }
+    else {
+      if (val_need_update != NULL) {
+        val_need_update->seq_dupli->start = seq->start;
+        val_need_update->seq_dupli->startdisp = seq->startdisp;
+      }
+    }
+  }
+
+  return thumb_data_hash;
+}
+
+static void sequencer_thumbnail_init_job(const bContext *C, View2D *v2d, Editing *ed)
+{
+  wmJob *wm_job;
+  ThumbnailDrawJob *tj = NULL;
+  ScrArea *area = CTX_wm_area(C);
+  wm_job = WM_jobs_get(CTX_wm_manager(C),
+                       CTX_wm_window(C),
+                       CTX_data_scene(C),
+                       "Draw Thumbnails",
+          

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list