diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index d14023f6f88..6b9c4faa3d2 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -34,6 +34,7 @@ struct bContext; struct EvaluationContext; struct StripColorBalance; struct Editing; +struct GSet; struct ImBuf; struct Main; struct Mask; @@ -236,7 +237,7 @@ struct StripElem *BKE_sequencer_give_stripelem(struct Sequence *seq, int cfra); void BKE_sequencer_update_changed_seq_and_deps(struct Scene *scene, struct Sequence *changed_seq, int len_change, int ibuf_change); bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context, struct Sequence *seq, float cfra); -struct SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(struct Main *bmain, struct Scene *scene, struct Sequence *seq); +struct SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(struct Main *bmain, struct Scene *scene, struct Sequence *seq, struct GSet *file_list); void BKE_sequencer_proxy_rebuild(struct SeqIndexBuildContext *context, short *stop, short *do_update, float *progress); void BKE_sequencer_proxy_rebuild_finish(struct SeqIndexBuildContext *context, bool stop); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index e27116f07f8..45036369269 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1532,7 +1532,7 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i IMB_freeImBuf(ibuf); } -SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(Main *bmain, Scene *scene, Sequence *seq) +SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(Main *bmain, Scene *scene, Sequence *seq, struct GSet *file_list) { SeqIndexBuildContext *context; Sequence *nseq; @@ -1565,7 +1565,7 @@ SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(Main *bmain, Scene *sc if (nseq->anim) { context->index_context = IMB_anim_index_rebuild_context(nseq->anim, context->tc_flags, context->size_flags, context->quality, - context->overwrite); + context->overwrite, file_list); } } diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 231677688ad..b99b23c60d3 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -1343,7 +1343,7 @@ static int clip_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) if (clip->anim) { pj->index_context = IMB_anim_index_rebuild_context(clip->anim, clip->proxy.build_tc_flag, clip->proxy.build_size_flag, clip->proxy.quality, - true); + true, NULL); } WM_jobs_customdata_set(wm_job, pj, proxy_freejob); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index a05cbfffb9f..9246667a427 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -37,6 +37,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_ghash.h" #include "BLF_translation.h" @@ -181,7 +182,8 @@ static void seq_proxy_build_job(const bContext *C) struct SeqIndexBuildContext *context; LinkData *link; Sequence *seq; - + GSet *file_list; + if (ed == NULL) { return; } @@ -202,16 +204,19 @@ static void seq_proxy_build_job(const bContext *C) WM_jobs_callbacks(wm_job, proxy_startjob, NULL, NULL, proxy_endjob); } + file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list"); SEQP_BEGIN (ed, seq) { if ((seq->flag & SELECT)) { - context = BKE_sequencer_proxy_rebuild_context(pj->main, pj->scene, seq); + context = BKE_sequencer_proxy_rebuild_context(pj->main, pj->scene, seq, file_list); link = BLI_genericNodeN(context); BLI_addtail(&pj->queue, link); } } SEQ_END + BLI_gset_free(file_list, MEM_freeN); + if (!WM_jobs_is_running(wm_job)) { G.is_break = false; WM_jobs_start(CTX_wm_manager(C), wm_job); @@ -3362,18 +3367,21 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); Editing *ed = BKE_sequencer_editing_get(scene, false); Sequence *seq; - + GSet *file_list; + if (ed == NULL) { return OPERATOR_CANCELLED; } + file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list"); + SEQP_BEGIN(ed, seq) { if ((seq->flag & SELECT)) { struct SeqIndexBuildContext *context; short stop = 0, do_update; float progress; - context = BKE_sequencer_proxy_rebuild_context(bmain, scene, seq); + context = BKE_sequencer_proxy_rebuild_context(bmain, scene, seq, file_list); BKE_sequencer_proxy_rebuild(context, &stop, &do_update, &progress); BKE_sequencer_proxy_rebuild_finish(context, 0); BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); @@ -3381,6 +3389,8 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) } SEQ_END + BLI_gset_free(file_list, MEM_freeN); + return OPERATOR_FINISHED; } diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index b0250a142ff..17bb873cd98 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -86,6 +86,7 @@ struct anim; struct ColorManagedDisplay; +struct GSet; /** * * \attention Defined in allocimbuf.c @@ -243,7 +244,7 @@ struct IndexBuildContext; /* prepare context for proxies/imecodes builder */ struct IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim, IMB_Timecode_Type tcs_in_use, IMB_Proxy_Size proxy_sizes_in_use, int quality, - const bool overwite); + const bool overwite, struct GSet *file_list); /* will rebuild all used indices and proxies at once */ void IMB_anim_index_rebuild(struct IndexBuildContext *context, diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index 8b62555a05c..d0281744830 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -35,6 +35,7 @@ #include "BLI_path_util.h" #include "BLI_string.h" #include "BLI_fileops.h" +#include "BLI_ghash.h" #include "IMB_indexer.h" #include "IMB_anim.h" @@ -1149,11 +1150,30 @@ static void index_rebuild_fallback(FallbackIndexBuilderContext *context, IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim, IMB_Timecode_Type tcs_in_use, IMB_Proxy_Size proxy_sizes_in_use, int quality, - const bool overwrite) + const bool overwrite, GSet *file_list) { IndexBuildContext *context = NULL; IMB_Proxy_Size proxy_sizes_to_build = proxy_sizes_in_use; int i; + + /* Don't generate the same file twice! */ + if (file_list) { + for (i = 0; i < IMB_PROXY_MAX_SLOT; ++i) { + IMB_Proxy_Size proxy_size = proxy_sizes[i]; + if (proxy_size & proxy_sizes_to_build) { + char filename[FILE_MAX]; + get_proxy_filename(anim, proxy_size, filename, false); + + if (BLI_gset_haskey(file_list, filename)) { + proxy_sizes_to_build &= ~proxy_size; + printf("Proxy: %s already registered for generation, skipping\n", filename); + } + else { + BLI_gset_insert(file_list, BLI_strdup(filename)); + } + } + } + } if (!overwrite) { IMB_Proxy_Size built_proxies = IMB_anim_proxy_get_existing(anim); @@ -1166,26 +1186,12 @@ IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim, IMB_Timecod get_proxy_filename(anim, proxy_size, filename, false); printf("Skipping proxy: %s\n", filename); } - /* if file doesn't exist, create it here so subsequent runs won't re-add it for generation */ - else if (proxy_size & proxy_sizes_to_build) { - char filename[FILE_MAX]; - get_proxy_filename(anim, proxy_size, filename, false); - BLI_file_touch(filename); - } - } - } - else { - for (i = 0; i < IMB_PROXY_MAX_SLOT; ++i) { - IMB_Proxy_Size proxy_size = proxy_sizes[i]; - if (proxy_size & proxy_sizes_to_build) { - char filename[FILE_MAX]; - get_proxy_filename(anim, proxy_size, filename, false); - BLI_file_touch(filename); - } } } proxy_sizes_to_build &= ~built_proxies; } + + fflush(stdout); if (proxy_sizes_to_build == 0) { return NULL;