From 995a19a983b2c44ec9afec049395d7c1b4320137 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 19 Aug 2012 15:41:56 +0000 Subject: Sequencer: per-sequence modifier stack for color grading This implements basic color grading modifiers in sequencer, supporting color balance, RGB curves and HUE corrections. Implementation is close to object modifiers, some details are there: http://wiki.blender.org/index.php/User:Nazg-gul/SequencerModifiers Modifiers supports multi-threaded calculation, masks and instant parameter changes. Also added cache for pre-processed image buffers for current frame, so changing sequence properties does not require rendering of original sequence (like rendering scene, loading file from disk and so) --- source/blender/blenkernel/intern/seqcache.c | 120 ++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) (limited to 'source/blender/blenkernel/intern/seqcache.c') diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c index 387ec67eb1c..d79f23e8979 100644 --- a/source/blender/blenkernel/intern/seqcache.c +++ b/source/blender/blenkernel/intern/seqcache.c @@ -37,8 +37,11 @@ #include "BKE_sequencer.h" #include "IMB_moviecache.h" +#include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "BLI_listbase.h" + typedef struct SeqCacheKey { struct Sequence *seq; SeqRenderData context; @@ -46,7 +49,25 @@ typedef struct SeqCacheKey { seq_stripelem_ibuf_t type; } SeqCacheKey; +typedef struct SeqPreprocessCacheElem { + struct SeqPreprocessCacheElem *next, *prev; + + struct Sequence *seq; + SeqRenderData context; + seq_stripelem_ibuf_t type; + + ImBuf *ibuf; +} SeqPreprocessCacheElem; + +typedef struct SeqPreprocessCache { + int cfra; + ListBase elems; +} SeqPreprocessCache; + static struct MovieCache *moviecache = NULL; +static struct SeqPreprocessCache *preprocess_cache = NULL; + +static void preprocessed_cache_destruct(void); static int seq_cmp_render_data(const SeqRenderData *a, const SeqRenderData *b) { @@ -160,6 +181,8 @@ void BKE_sequencer_cache_destruct(void) { if (moviecache) IMB_moviecache_free(moviecache); + + preprocessed_cache_destruct(); } void BKE_sequencer_cache_cleanup(void) @@ -219,3 +242,100 @@ void BKE_sequencer_cache_put(SeqRenderData context, Sequence *seq, float cfra, s IMB_moviecache_put(moviecache, &key, i); } + +static void preprocessed_cache_clean(void) +{ + SeqPreprocessCacheElem *elem; + + if (!preprocess_cache) + return; + + for (elem = preprocess_cache->elems.first; elem; elem = elem->next) { + IMB_freeImBuf(elem->ibuf); + } + BLI_freelistN(&preprocess_cache->elems); + + preprocess_cache->elems.first = preprocess_cache->elems.last = NULL; +} + +static void preprocessed_cache_destruct(void) +{ + if (!preprocess_cache) + return; + + preprocessed_cache_clean(); + + MEM_freeN(preprocess_cache); + preprocess_cache = NULL; +} + +ImBuf *BKE_sequencer_preprocessed_cache_get(SeqRenderData context, Sequence *seq, float cfra, seq_stripelem_ibuf_t type) +{ + SeqPreprocessCacheElem *elem; + + if (!preprocess_cache) + return NULL; + + if (preprocess_cache->cfra != cfra) + return NULL; + + for (elem = preprocess_cache->elems.first; elem; elem = elem->next) { + if (elem->seq != seq) + continue; + + if (elem->type != type) + continue; + + if (seq_cmp_render_data(&elem->context, &context) != 0) + continue; + + IMB_refImBuf(elem->ibuf); + return elem->ibuf; + } + + return NULL; +} + +void BKE_sequencer_preprocessed_cache_put(SeqRenderData context, Sequence *seq, float cfra, seq_stripelem_ibuf_t type, ImBuf *ibuf) +{ + SeqPreprocessCacheElem *elem; + + if (!preprocess_cache) { + preprocess_cache = MEM_callocN(sizeof(SeqPreprocessCache), "sequencer preprocessed cache"); + } + else { + if (preprocess_cache->cfra != cfra) + preprocessed_cache_clean(); + } + + elem = MEM_callocN(sizeof(SeqPreprocessCacheElem), "sequencer preprocessed cache element"); + + elem->seq = seq; + elem->type = type; + elem->context = context; + elem->ibuf = ibuf; + + preprocess_cache->cfra = cfra; + + IMB_refImBuf(ibuf); + + BLI_addtail(&preprocess_cache->elems, elem); +} + +void BKE_sequencer_preprocessed_cache_cleanup_sequence(Sequence *seq) +{ + SeqPreprocessCacheElem *elem, *elem_next; + + if (!preprocess_cache) + return; + + for (elem = preprocess_cache->elems.first; elem; elem = elem_next) { + elem_next = elem->next; + + if (elem->seq == seq) { + IMB_freeImBuf(elem->ibuf); + + BLI_freelinkN(&preprocess_cache->elems, elem); + } + } +} -- cgit v1.2.3