diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-08-19 19:41:56 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-08-19 19:41:56 +0400 |
commit | 995a19a983b2c44ec9afec049395d7c1b4320137 (patch) | |
tree | 8333563ae983641434179839755aab67ecdc2aad /source/blender/blenkernel/intern/seqcache.c | |
parent | 994d75b6ae78fee99afd949292e48c4f32292995 (diff) |
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)
Diffstat (limited to 'source/blender/blenkernel/intern/seqcache.c')
-rw-r--r-- | source/blender/blenkernel/intern/seqcache.c | 120 |
1 files changed, 120 insertions, 0 deletions
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); + } + } +} |