diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 76c579f221f..8852ff84fe0 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -929,6 +929,7 @@ class SEQUENCER_PT_proxy(SequencerButtonsPanel, Panel): row.prop(strip.proxy, "build_50") row.prop(strip.proxy, "build_75") row.prop(strip.proxy, "build_100") + layout.prop(strip.proxy, "use_overwrite"); col = layout.column() col.label(text="Build JPEG quality") diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 903c660dc97..f63f4cf86ae 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1290,6 +1290,7 @@ typedef struct SeqIndexBuildContext { int tc_flags; int size_flags; int quality; + bool overwrite; Main *bmain; Scene *scene; @@ -1481,7 +1482,8 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c } } -static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, int cfra, int proxy_render_size) +static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, int cfra, + int proxy_render_size, const bool overwrite) { char name[PROXY_MAXFILE]; int quality; @@ -1493,6 +1495,10 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i return; } + if (!overwrite && BLI_exists(name)) { + return; + } + ibuf_tmp = seq_render_strip(context, seq, cfra); rectx = (proxy_render_size * ibuf_tmp->x) / 100; @@ -1546,6 +1552,7 @@ SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(Main *bmain, Scene *sc context->tc_flags = nseq->strip->proxy->build_tc_flags; context->size_flags = nseq->strip->proxy->build_size_flags; context->quality = nseq->strip->proxy->quality; + context->overwrite = (nseq->strip->proxy->build_flags & SEQ_PROXY_SKIP_EXISTING) == 0; context->bmain = bmain; context->scene = scene; @@ -1557,7 +1564,8 @@ 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->tc_flags, context->size_flags, context->quality, + context->overwrite); } } @@ -1566,6 +1574,7 @@ SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(Main *bmain, Scene *sc void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, short *do_update, float *progress) { + const bool overwrite = context->overwrite; SeqRenderData render_context; Sequence *seq = context->seq; Scene *scene = context->scene; @@ -1602,16 +1611,16 @@ void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, sho for (cfra = seq->startdisp + seq->startstill; cfra < seq->enddisp - seq->endstill; cfra++) { if (context->size_flags & IMB_PROXY_25) { - seq_proxy_build_frame(&render_context, seq, cfra, 25); + seq_proxy_build_frame(&render_context, seq, cfra, 25, overwrite); } if (context->size_flags & IMB_PROXY_50) { - seq_proxy_build_frame(&render_context, seq, cfra, 50); + seq_proxy_build_frame(&render_context, seq, cfra, 50, overwrite); } if (context->size_flags & IMB_PROXY_75) { - seq_proxy_build_frame(&render_context, seq, cfra, 75); + seq_proxy_build_frame(&render_context, seq, cfra, 75, overwrite); } if (context->size_flags & IMB_PROXY_100) { - seq_proxy_build_frame(&render_context, seq, cfra, 100); + seq_proxy_build_frame(&render_context, seq, cfra, 100, overwrite); } *progress = (float) (cfra - seq->startdisp - seq->startstill) / (seq->enddisp - seq->endstill - seq->startdisp - seq->startstill); diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index e3d45a297a7..231677688ad 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -1342,7 +1342,8 @@ 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); + clip->proxy.build_size_flag, clip->proxy.quality, + true); } WM_jobs_customdata_set(wm_job, pj, proxy_freejob); diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index ce6a7eb1c47..b0250a142ff 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -236,11 +236,14 @@ void IMB_anim_set_index_dir(struct anim *anim, const char *dir); int IMB_anim_index_get_frame_index(struct anim *anim, IMB_Timecode_Type tc, int position); +IMB_Proxy_Size IMB_anim_proxy_get_existing(struct anim *anim); + 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); + IMB_Proxy_Size proxy_sizes_in_use, int quality, + const bool overwite); /* 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 e067cd64022..856f870fb38 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -1148,19 +1148,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) + IMB_Proxy_Size proxy_sizes_in_use, int quality, + const bool overwrite) { IndexBuildContext *context = NULL; + IMB_Proxy_Size proxy_sizes_to_build = proxy_sizes_in_use; + + if (!overwrite) { + IMB_Proxy_Size built_proxies = IMB_anim_proxy_get_existing(anim); + proxy_sizes_to_build &= ~built_proxies; + } + + if (proxy_sizes_to_build == 0) { + return NULL; + } switch (anim->curtype) { #ifdef WITH_FFMPEG case ANIM_FFMPEG: - context = index_ffmpeg_create_context(anim, tcs_in_use, proxy_sizes_in_use, quality); + context = index_ffmpeg_create_context(anim, tcs_in_use, proxy_sizes_to_build, quality); break; #endif #ifdef WITH_AVI default: - context = index_fallback_create_context(anim, tcs_in_use, proxy_sizes_in_use, quality); + context = index_fallback_create_context(anim, tcs_in_use, proxy_sizes_to_build, quality); break; #endif } @@ -1304,3 +1315,18 @@ int IMB_anim_index_get_frame_index(struct anim *anim, IMB_Timecode_Type tc, return IMB_indexer_get_frame_index(idx, position); } +IMB_Proxy_Size IMB_anim_proxy_get_existing(struct anim *anim) +{ + const int num_proxy_sizes = IMB_PROXY_MAX_SLOT; + IMB_Proxy_Size existing = 0; + int i; + for (i = 0; i < num_proxy_sizes; ++i) { + IMB_Proxy_Size proxy_size = proxy_sizes[i]; + char filename[FILE_MAX]; + get_proxy_filename(anim, proxy_size, filename, false); + if (BLI_exists(filename)) { + existing |= proxy_size; + } + } + return existing; +} diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 20678bdae49..c6748cca8e1 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -94,6 +94,8 @@ typedef struct StripProxy { // to build short build_tc_flags; // time code flags (see below) of all tc indices // to build + short build_flags; + char pad[6]; } StripProxy; typedef struct Strip { @@ -398,6 +400,11 @@ enum { #define SEQ_PROXY_TC_RECORD_RUN_NO_GAPS 8 #define SEQ_PROXY_TC_ALL 15 +/* SeqProxy->build_flags */ +enum { + SEQ_PROXY_SKIP_EXISTING = 1, +}; + /* seq->alpha_mode */ enum { SEQ_ALPHA_STRAIGHT = 0, diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index dda0e8493d9..d4a98fe8b5d 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -1187,6 +1187,10 @@ static void rna_def_strip_proxy(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceProxy_update"); + prop = RNA_def_property(srna, "use_overwrite", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "build_flags", SEQ_PROXY_SKIP_EXISTING); + RNA_def_property_ui_text(prop, "Overwite", "Overwrite existing proxy files when building"); + prop = RNA_def_property(srna, "build_25", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "build_size_flags", SEQ_PROXY_IMAGE_SIZE_25); RNA_def_property_ui_text(prop, "25%", "Build 25% proxy resolution");