From 7c72ba60d7556f611501e288adc5cc1ee5f214c1 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 28 Jan 2015 17:30:15 +0500 Subject: [PATCH] Sequencer: Option to skip strip proxy generation if they already exists This is a per-strip option next to the build proxy size which tells blender whether to skip building proxy size if the file for it already exists or not. The option is called "Overwrite" for simplicity. This option is enabled by default to avoid changes in the file behavior. TODO: Would be nice to do something like that for movie clips as well. --- .../scripts/startup/bl_ui/space_sequencer.py | 1 + source/blender/blenkernel/intern/sequencer.c | 21 ++++++++---- source/blender/editors/space_clip/clip_ops.c | 3 +- source/blender/imbuf/IMB_imbuf.h | 5 ++- source/blender/imbuf/intern/indexer.c | 32 +++++++++++++++++-- source/blender/makesdna/DNA_sequence_types.h | 7 ++++ .../blender/makesrna/intern/rna_sequencer.c | 4 +++ 7 files changed, 62 insertions(+), 11 deletions(-) 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");