diff options
author | Richard Antalik <richardantalik@gmail.com> | 2021-03-16 20:47:23 +0300 |
---|---|---|
committer | Richard Antalik <richardantalik@gmail.com> | 2021-03-16 20:56:44 +0300 |
commit | 04e1feb83051f75317309ec3659b9263a99dbd7e (patch) | |
tree | c2e71b1f62233b04bfab8f6f307e6d1838e8daa2 /source/blender/sequencer | |
parent | e4f347783320d83e43bc650020013e19b2f22c7f (diff) |
VSE: Automatic proxy building
Build proxies automatically when added to sequencer timeline and when
switching preview size.
This behavior can be disabled in user preferences.
Reviewed By: sergey, fsiddi
Differential Revision: https://developer.blender.org/D10363
Diffstat (limited to 'source/blender/sequencer')
-rw-r--r-- | source/blender/sequencer/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/sequencer/SEQ_proxy.h | 11 | ||||
-rw-r--r-- | source/blender/sequencer/intern/proxy.c | 47 | ||||
-rw-r--r-- | source/blender/sequencer/intern/proxy_job.c | 121 |
4 files changed, 166 insertions, 14 deletions
diff --git a/source/blender/sequencer/CMakeLists.txt b/source/blender/sequencer/CMakeLists.txt index 82e303806b3..9d9553ed858 100644 --- a/source/blender/sequencer/CMakeLists.txt +++ b/source/blender/sequencer/CMakeLists.txt @@ -72,6 +72,7 @@ set(SRC intern/multiview.h intern/prefetch.c intern/prefetch.h + intern/proxy_job.c intern/proxy.c intern/proxy.h intern/render.c diff --git a/source/blender/sequencer/SEQ_proxy.h b/source/blender/sequencer/SEQ_proxy.h index 859eac90609..b06adef2802 100644 --- a/source/blender/sequencer/SEQ_proxy.h +++ b/source/blender/sequencer/SEQ_proxy.h @@ -53,6 +53,17 @@ bool SEQ_can_use_proxy(const struct SeqRenderData *context, struct Sequence *seq int SEQ_rendersize_to_proxysize(int render_size); double SEQ_rendersize_to_scale_factor(int size); +typedef struct ProxyBuildJob { + struct Main *main; + struct Depsgraph *depsgraph; + struct Scene *scene; + struct ListBase queue; + int stop; +} ProxyJob; + +struct wmJob *ED_seq_proxy_wm_job_get(const struct bContext *C); +ProxyJob *ED_seq_proxy_job_get(const struct bContext *C, struct wmJob *wm_job); + #ifdef __cplusplus } #endif diff --git a/source/blender/sequencer/intern/proxy.c b/source/blender/sequencer/intern/proxy.c index 562cd07ddee..a0e6bc7f4f1 100644 --- a/source/blender/sequencer/intern/proxy.c +++ b/source/blender/sequencer/intern/proxy.c @@ -55,6 +55,7 @@ #include "IMB_metadata.h" #include "SEQ_proxy.h" +#include "SEQ_relations.h" #include "SEQ_render.h" #include "SEQ_sequencer.h" @@ -395,6 +396,17 @@ static int seq_proxy_context_count(Sequence *seq, Scene *scene) return num_views; } +static bool seq_proxy_need_rebuild(Sequence *seq, struct anim *anim) +{ + if ((seq->strip->proxy->build_flags & SEQ_PROXY_SKIP_EXISTING) == 0) { + return true; + } + + IMB_Proxy_Size required_proxies = seq->strip->proxy->build_size_flags; + IMB_Proxy_Size built_proxies = IMB_anim_proxy_get_existing(anim); + return (required_proxies & built_proxies) != required_proxies; +} + bool SEQ_proxy_rebuild_context(Main *bmain, Depsgraph *depsgraph, Scene *scene, @@ -423,6 +435,16 @@ bool SEQ_proxy_rebuild_context(Main *bmain, continue; } + /* Check if proxies are already built here, because actually opening anims takes a lot of + * time. */ + seq_open_anim_file(scene, seq, false); + StripAnim *sanim = BLI_findlink(&seq->anims, i); + if (sanim->anim && !seq_proxy_need_rebuild(seq, sanim->anim)) { + continue; + } + + SEQ_relations_sequence_free_anim(seq); + context = MEM_callocN(sizeof(SeqIndexBuildContext), "seq proxy rebuild context"); nseq = SEQ_sequence_dupli_recursive(scene, scene, NULL, seq, 0); @@ -441,28 +463,25 @@ bool SEQ_proxy_rebuild_context(Main *bmain, context->view_id = i; /* only for images */ if (nseq->type == SEQ_TYPE_MOVIE) { - StripAnim *sanim; - seq_open_anim_file(scene, nseq, true); sanim = BLI_findlink(&nseq->anims, i); - if (sanim->anim) { - context->index_context = IMB_anim_index_rebuild_context(sanim->anim, - context->tc_flags, - context->size_flags, - context->quality, - context->overwrite, - file_list); - } - if (!context->index_context) { - MEM_freeN(context); - return false; - } + context->index_context = IMB_anim_index_rebuild_context(sanim->anim, + context->tc_flags, + context->size_flags, + context->quality, + context->overwrite, + file_list); + } + if (!context->index_context) { + SEQ_proxy_rebuild_finish(context, false); + return false; } link = BLI_genericNodeN(context); BLI_addtail(queue, link); } + return true; } diff --git a/source/blender/sequencer/intern/proxy_job.c b/source/blender/sequencer/intern/proxy_job.c new file mode 100644 index 00000000000..aea66da4cc4 --- /dev/null +++ b/source/blender/sequencer/intern/proxy_job.c @@ -0,0 +1,121 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * - Blender Foundation, 2003-2009 + * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006 + */ + +/** \file + * \ingroup bke + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_ghash.h" +#include "BLI_timecode.h" + +#include "DNA_scene_types.h" +#include "DNA_sequence_types.h" + +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_report.h" + +#include "SEQ_iterator.h" +#include "SEQ_proxy.h" +#include "SEQ_relations.h" +#include "SEQ_sequencer.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "RNA_define.h" + +static void proxy_freejob(void *pjv) +{ + ProxyJob *pj = pjv; + + BLI_freelistN(&pj->queue); + + MEM_freeN(pj); +} + +/* Only this runs inside thread. */ +static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress) +{ + ProxyJob *pj = pjv; + LinkData *link; + + for (link = pj->queue.first; link; link = link->next) { + struct SeqIndexBuildContext *context = link->data; + + SEQ_proxy_rebuild(context, stop, do_update, progress); + + if (*stop) { + pj->stop = 1; + fprintf(stderr, "Canceling proxy rebuild on users request...\n"); + break; + } + } +} + +static void proxy_endjob(void *pjv) +{ + ProxyJob *pj = pjv; + Editing *ed = SEQ_editing_get(pj->scene, false); + LinkData *link; + + for (link = pj->queue.first; link; link = link->next) { + SEQ_proxy_rebuild_finish(link->data, pj->stop); + } + + SEQ_relations_free_imbuf(pj->scene, &ed->seqbase, false); + + WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, pj->scene); +} + +ProxyJob *ED_seq_proxy_job_get(const bContext *C, wmJob *wm_job) +{ + Scene *scene = CTX_data_scene(C); + struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + ProxyJob *pj = WM_jobs_customdata_get(wm_job); + if (!pj) { + pj = MEM_callocN(sizeof(ProxyJob), "proxy rebuild job"); + pj->depsgraph = depsgraph; + pj->scene = scene; + pj->main = CTX_data_main(C); + WM_jobs_customdata_set(wm_job, pj, proxy_freejob); + WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_SEQUENCER, NC_SCENE | ND_SEQUENCER); + WM_jobs_callbacks(wm_job, proxy_startjob, NULL, NULL, proxy_endjob); + } + return pj; +} + +struct wmJob *ED_seq_proxy_wm_job_get(const bContext *C) +{ + Scene *scene = CTX_data_scene(C); + wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), + CTX_wm_window(C), + scene, + "Building Proxies", + WM_JOB_PROGRESS, + WM_JOB_TYPE_SEQ_BUILD_PROXY); + return wm_job; +} |