diff options
-rw-r--r-- | source/blender/blenkernel/BKE_sequencer.h | 22 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/blender.c | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/seqcache.c | 267 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/seqeffects.c | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/sequencer.c | 1731 | ||||
-rw-r--r-- | source/blender/editors/space_sequencer/sequencer_draw.c | 27 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 1 |
7 files changed, 858 insertions, 1192 deletions
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index c5417e04780..81ae83cafb6 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -164,6 +164,28 @@ struct StripElem *give_stripelem(struct Sequence *seq, int cfra); // intern? void update_changed_seq_and_deps(struct Scene *scene, struct Sequence *changed_seq, int len_change, int ibuf_change); +/* seqcache.c */ + +typedef enum { + SEQ_STRIPELEM_IBUF, + SEQ_STRIPELEM_IBUF_COMP, + SEQ_STRIPELEM_IBUF_STARTSTILL, + SEQ_STRIPELEM_IBUF_ENDSTILL +} seq_stripelem_ibuf_t; + +void seq_stripelem_cache_init(); +void seq_stripelem_cache_destruct(); + +void seq_stripelem_cache_cleanup(); + +struct ImBuf * seq_stripelem_cache_get( + struct Sequence * seq, int rectx, int recty, + float cfra, seq_stripelem_ibuf_t type); +void seq_stripelem_cache_put( + struct Sequence * seq, int rectx, int recty, + float cfra, seq_stripelem_ibuf_t type, struct ImBuf * nval); + + /* seqeffects.c */ // intern? struct SeqEffectHandle get_sequence_blend(struct Sequence *seq); diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 101c7a3bbbd..9a624017a16 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -102,6 +102,7 @@ void free_blender(void) BKE_spacetypes_free(); /* after free main, it uses space callbacks */ IMB_exit(); + seq_stripelem_cache_destruct(); free_nodesystem(); } diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c new file mode 100644 index 00000000000..c2b689195f6 --- /dev/null +++ b/source/blender/blenkernel/intern/seqcache.c @@ -0,0 +1,267 @@ +/** +* $Id: seqcache.c 29923 2010-07-04 10:51:10Z schlaile $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Peter Schlaile <peter [at] schlaile [dot] de> 2010 + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "MEM_guardedalloc.h" +#include "MEM_CacheLimiterC-Api.h" + +#include "DNA_sequence_types.h" +#include "BKE_sequencer.h" +#include "BLI_ghash.h" +#include "BLI_mempool.h" +#include <pthread.h> + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +typedef struct seqCacheKey +{ + struct Sequence * seq; + int rectx; + int recty; + float cfra; + seq_stripelem_ibuf_t type; +} seqCacheKey; + +typedef struct seqCacheEntry +{ + ImBuf * ibuf; + MEM_CacheLimiterHandleC * c_handle; +} seqCacheEntry; + +static GHash * hash = 0; +static MEM_CacheLimiterC * limitor = 0; +static struct BLI_mempool * entrypool = 0; +static struct BLI_mempool * keypool = 0; +static int ibufs_in = 0; +static int ibufs_rem = 0; + +static unsigned int HashHash(void *key_) +{ + seqCacheKey * key = (seqCacheKey*) key_; + unsigned int rval = key->rectx + key->recty; + + rval ^= *(unsigned int*) &key->cfra; + rval += key->type; + rval ^= (unsigned int) key->seq; + + return rval; +} + +static int HashCmp(void *a_, void *b_) +{ + seqCacheKey * a = (seqCacheKey*) a_; + seqCacheKey * b = (seqCacheKey*) b_; + + if (a->seq < b->seq) { + return -1; + } + if (a->seq > b->seq) { + return 1; + } + + if (a->cfra < b->cfra) { + return -1; + } + if (a->cfra > b->cfra) { + return 1; + } + + if (a->type < b->type) { + return -1; + } + if (a->type > b->type) { + return 1; + } + + if (a->rectx < b->rectx) { + return -1; + } + if (a->rectx > b->rectx) { + return 1; + } + + if (a->recty < b->recty) { + return -1; + } + if (a->recty > b->recty) { + return 1; + } + + return 0; +} + +static void HashKeyFree(void *key) +{ + BLI_mempool_free(keypool, key); +} + +static void HashValFree(void *val) +{ + seqCacheEntry* e = (seqCacheEntry*) val; + + if (e->ibuf) { + /* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf, + e->ibuf->refcounter); */ + IMB_freeImBuf(e->ibuf); + MEM_CacheLimiter_unmanage(e->c_handle); + ibufs_rem++; + } + + e->ibuf = 0; + e->c_handle = 0; + + BLI_mempool_free(entrypool, e); +} + +static void IMB_seq_cache_destructor(void * p) +{ + seqCacheEntry* e = (seqCacheEntry*) p; + + if (e && e->ibuf) { + /* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf, + e->ibuf->refcounter); */ + IMB_freeImBuf(e->ibuf); + ibufs_rem++; + + e->ibuf = 0; + e->c_handle = 0; + } +} + +void seq_stripelem_cache_init() +{ + hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash"); + limitor = new_MEM_CacheLimiter( IMB_seq_cache_destructor ); + + entrypool = BLI_mempool_create(sizeof(seqCacheEntry), 64, 64, 0); + keypool = BLI_mempool_create(sizeof(seqCacheKey), 64, 64, 0); +} + +void seq_stripelem_cache_destruct() +{ + if (!entrypool) { + return; + } + BLI_ghash_free(hash, HashKeyFree, HashValFree); + delete_MEM_CacheLimiter(limitor); + BLI_mempool_destroy(entrypool); + BLI_mempool_destroy(keypool); +} + +void seq_stripelem_cache_cleanup() +{ + if (!entrypool) { + seq_stripelem_cache_init(); + } + + /* fprintf(stderr, "Stats before cleanup: in: %d rem: %d\n", + ibufs_in, ibufs_rem); */ + + BLI_ghash_free(hash, HashKeyFree, HashValFree); + hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash"); + + /* fprintf(stderr, "Stats after cleanup: in: %d rem: %d\n", + ibufs_in, ibufs_rem); */ + +} + +struct ImBuf * seq_stripelem_cache_get( + struct Sequence * seq, int rectx, int recty, + float cfra, seq_stripelem_ibuf_t type) +{ + seqCacheKey key; + seqCacheEntry * e; + + if (!seq) { + return 0; + } + + if (!entrypool) { + seq_stripelem_cache_init(); + } + + key.seq = seq; + key.rectx = rectx; + key.recty = recty; + key.cfra = cfra - seq->start; + key.type = type; + + e = (seqCacheEntry*) BLI_ghash_lookup(hash, &key); + + if (e && e->ibuf) { + IMB_refImBuf(e->ibuf); + + MEM_CacheLimiter_touch(e->c_handle); + return e->ibuf; + } + return 0; +} + +void seq_stripelem_cache_put( + struct Sequence * seq, int rectx, int recty, + float cfra, seq_stripelem_ibuf_t type, struct ImBuf * i) +{ + seqCacheKey * key; + seqCacheEntry * e; + + if (!i) { + return; + } + + ibufs_in++; + + if (!entrypool) { + seq_stripelem_cache_init(); + } + + key = (seqCacheKey*) BLI_mempool_alloc(keypool); + + key->seq = seq; + key->rectx = rectx; + key->recty = recty; + key->cfra = cfra - seq->start; + key->type = type; + + /* we want our own version */ + IMB_refImBuf(i); + + e = (seqCacheEntry*) BLI_mempool_alloc(entrypool); + + e->ibuf = i; + e->c_handle = 0; + + BLI_ghash_remove(hash, key, HashKeyFree, HashValFree); + BLI_ghash_insert(hash, key, e); + + e->c_handle = MEM_CacheLimiter_insert(limitor, e); + + MEM_CacheLimiter_ref(e->c_handle); + MEM_CacheLimiter_enforce_limits(limitor); + MEM_CacheLimiter_unref(e->c_handle); +} diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 73c19772c69..efebca0f780 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -2786,6 +2786,7 @@ static void do_multicam(Scene *scene, Sequence *seq, int cfra, IMB_float_from_rect_simple(i); memcpy(out->rect_float, i->rect_float, out->x * out->y *4*sizeof(float)); } + IMB_freeImBuf(i); } /* ********************************************************************** diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 61415eb4a52..5f41debbbe9 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -116,53 +116,11 @@ int seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), vo alloc / free functions ********************************************************************** */ -static void free_tstripdata(int len, TStripElem *se) -{ - TStripElem *seo; - int a; - - seo= se; - if (!se) - return; - - for(a=0; a<len; a++, se++) { - if(se->ibuf) { - IMB_freeImBuf(se->ibuf); - se->ibuf = 0; - } - if(se->ibuf_comp) { - IMB_freeImBuf(se->ibuf_comp); - se->ibuf_comp = 0; - } - } - - MEM_freeN(seo); -} void new_tstripdata(Sequence *seq) { if(seq->strip) { - free_tstripdata(seq->strip->len, seq->strip->tstripdata); - free_tstripdata(seq->strip->endstill, - seq->strip->tstripdata_endstill); - free_tstripdata(seq->strip->startstill, - seq->strip->tstripdata_startstill); - - seq->strip->tstripdata= 0; - seq->strip->tstripdata_endstill= 0; - seq->strip->tstripdata_startstill= 0; - - if(seq->strip->ibuf_startstill) { - IMB_freeImBuf(seq->strip->ibuf_startstill); - seq->strip->ibuf_startstill = 0; - } - - if(seq->strip->ibuf_endstill) { - IMB_freeImBuf(seq->strip->ibuf_endstill); - seq->strip->ibuf_endstill = 0; - } - seq->strip->len= seq->len; } } @@ -208,20 +166,6 @@ void seq_free_strip(Strip *strip) MEM_freeN(strip->color_balance); } - free_tstripdata(strip->len, strip->tstripdata); - free_tstripdata(strip->endstill, strip->tstripdata_endstill); - free_tstripdata(strip->startstill, strip->tstripdata_startstill); - - if(strip->ibuf_startstill) { - IMB_freeImBuf(strip->ibuf_startstill); - strip->ibuf_startstill = 0; - } - - if(strip->ibuf_endstill) { - IMB_freeImBuf(strip->ibuf_endstill); - strip->ibuf_endstill = 0; - } - MEM_freeN(strip); } @@ -950,137 +894,9 @@ static void multibuf(ImBuf *ibuf, float fmul) } } -static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se, - int render_size) -{ - TStripElem *se1, *se2, *se3; - float fac, facf; - int x, y; - int early_out; - struct SeqEffectHandle sh = get_sequence_effect(seq); - FCurve *fcu= NULL; - - if (!sh.execute) { /* effect not supported in this version... */ - make_black_ibuf(se->ibuf); - return; - } - - if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) { - sh.get_default_fac(seq, cfra, &fac, &facf); - if( scene->r.mode & R_FIELDS ); else facf= fac; - } else { - fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, - "effect_fader", 0); - if (fcu) { - fac = facf = evaluate_fcurve(fcu, cfra); - if( scene->r.mode & R_FIELDS ) { - facf = evaluate_fcurve(fcu, cfra + 0.5); - } - } else { - fac = facf = seq->effect_fader; - } - } - - early_out = sh.early_out(seq, fac, facf); - - if (early_out == -1) { /* no input needed */ - sh.execute(scene, seq, cfra, fac, facf, - se->ibuf->x, se->ibuf->y, render_size, - 0, 0, 0, se->ibuf); - return; - } - - switch (early_out) { - case 0: - if (se->se1==0 || se->se2==0 || se->se3==0) { - make_black_ibuf(se->ibuf); - return; - } - - se1= se->se1; - se2= se->se2; - se3= se->se3; - - if ( (se1==0 || se2==0 || se3==0) - || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) { - make_black_ibuf(se->ibuf); - return; - } - - break; - case 1: - if (se->se1 == 0) { - make_black_ibuf(se->ibuf); - return; - } - - se1= se->se1; - - if (se1 == 0 || se1->ibuf == 0) { - make_black_ibuf(se->ibuf); - return; - } - - if (se->ibuf != se1->ibuf) { - IMB_freeImBuf(se->ibuf); - se->ibuf = se1->ibuf; - IMB_refImBuf(se->ibuf); - } - return; - case 2: - if (se->se2 == 0) { - make_black_ibuf(se->ibuf); - return; - } - - se2= se->se2; - - if (se2 == 0 || se2->ibuf == 0) { - make_black_ibuf(se->ibuf); - return; - } - if (se->ibuf != se2->ibuf) { - IMB_freeImBuf(se->ibuf); - se->ibuf = se2->ibuf; - IMB_refImBuf(se->ibuf); - } - return; - default: - make_black_ibuf(se->ibuf); - return; - } - - x= se2->ibuf->x; - y= se2->ibuf->y; - - if (!se1->ibuf->rect_float && se->ibuf->rect_float) { - IMB_float_from_rect_simple(se1->ibuf); - } - if (!se2->ibuf->rect_float && se->ibuf->rect_float) { - IMB_float_from_rect_simple(se2->ibuf); - } - if (!se3->ibuf->rect_float && se->ibuf->rect_float) { - IMB_float_from_rect_simple(se3->ibuf); - } - - if (!se1->ibuf->rect && !se->ibuf->rect_float) { - IMB_rect_from_float(se1->ibuf); - } - if (!se2->ibuf->rect && !se->ibuf->rect_float) { - IMB_rect_from_float(se2->ibuf); - } - if (!se3->ibuf->rect && !se->ibuf->rect_float) { - IMB_rect_from_float(se3->ibuf); - } - - sh.execute(scene, seq, cfra, fac, facf, x, y, render_size, - se1->ibuf, se2->ibuf, se3->ibuf, - se->ibuf); -} - -static int give_stripelem_index(Sequence *seq, int cfra) +static float give_stripelem_index(Sequence *seq, float cfra) { - int nr; + float nr; if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1; if(seq->len == 0) return -1; @@ -1096,93 +912,12 @@ static int give_stripelem_index(Sequence *seq, int cfra) } if (seq->strobe < 1.0) seq->strobe = 1.0; if (seq->strobe > 1.0) { - nr -= (int)fmod((double)nr, (double)seq->strobe); + nr -= fmod((double)nr, (double)seq->strobe); } return nr; } -static TStripElem* alloc_tstripdata(int len, const char * name) -{ - int i; - TStripElem *se = MEM_callocN(len * sizeof(TStripElem), name); - for (i = 0; i < len; i++) { - se[i].ok = STRIPELEM_OK; - } - return se; -} - -static TStripElem *give_tstripelem(Sequence *seq, int cfra) -{ - TStripElem *se; - int nr; - - se = seq->strip->tstripdata; - if (se == 0 && seq->len > 0) { - se = seq->strip->tstripdata = alloc_tstripdata(seq->len, - "tstripelems"); - } - nr = give_stripelem_index(seq, cfra); - - if (nr == -1) return 0; - if (se == 0) return 0; - - se += nr; - - /* if there are IPOs with blend modes active, one has to watch out - for startstill + endstill area: we can't use the same tstripelem - here for all ibufs, since then, blending with IPOs won't work! - - Rather common case, if you use a single image and try to fade - it in and out... or want to use your strip as a watermark in - alpha over mode... - */ - if (seq->blend_mode != SEQ_BLEND_REPLACE || - (/*seq->ipo && seq->ipo->curve.first &&*/ - (!(seq->type & SEQ_EFFECT) || !seq->seq1))) { - Strip * s = seq->strip; - if (cfra < seq->start) { - se = s->tstripdata_startstill; - if (seq->startstill != s->startstill) { - free_tstripdata(s->startstill, - s->tstripdata_startstill); - se = 0; - } - - if (se == 0) { - s->startstill = seq->startstill; - se = seq->strip->tstripdata_startstill - = alloc_tstripdata( - s->startstill, - "tstripelems_startstill"); - } - se += seq->start - cfra - 1; - - } else if (cfra > seq->start + seq->len-1) { - se = s->tstripdata_endstill; - if (seq->endstill != s->endstill) { - free_tstripdata(s->endstill, - s->tstripdata_endstill); - se = 0; - } - - if (se == 0) { - s->endstill = seq->endstill; - se = seq->strip->tstripdata_endstill - = alloc_tstripdata( - s->endstill, - "tstripelems_endstill"); - } - se += cfra - (seq->start + seq->len-1) - 1; - } - } - - - se->nr= nr; - - return se; -} - StripElem *give_stripelem(Sequence *seq, int cfra) { StripElem *se= seq->strip->stripdata; @@ -1191,7 +926,7 @@ StripElem *give_stripelem(Sequence *seq, int cfra) /* use the first */ } else { - int nr = give_stripelem_index(seq, cfra); + int nr = (int) give_stripelem_index(seq, cfra); if (nr == -1) return 0; if (se == 0) return 0; @@ -1322,17 +1057,15 @@ static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * na dir, render_size, se->name); frameno = 1; } else if (seq->type == SEQ_MOVIE) { - TStripElem * tse = give_tstripelem(seq, cfra); - - frameno = tse->nr + seq->anim_startofs; + frameno = (int) give_stripelem_index(seq, cfra) + + seq->anim_startofs; snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir, seq->strip->stripdata->name, render_size); } else { - TStripElem * tse = give_tstripelem(seq, cfra); - - frameno = tse->nr + seq->anim_startofs; + frameno = (int) give_stripelem_index(seq, cfra) + + seq->anim_startofs; snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir, render_size); @@ -1361,10 +1094,11 @@ static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra, in } if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { - TStripElem * tse = give_tstripelem(seq, cfra); - int frameno = tse->nr + seq->anim_startofs; + int frameno = (int) give_stripelem_index(seq, cfra) + + seq->anim_startofs; if (!seq->strip->proxy->anim) { - if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) { + if (!seq_proxy_get_fname( + scene, seq, cfra, name, render_size)) { return 0; } @@ -1607,12 +1341,12 @@ static void make_cb_table_float(float lift, float gain, float gamma, } } -static void color_balance_byte_byte(Sequence * seq, TStripElem* se, float mul) +static void color_balance_byte_byte(Sequence * seq, ImBuf* ibuf, float mul) { unsigned char cb_tab[3][256]; int c; - unsigned char * p = (unsigned char*) se->ibuf->rect; - unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y; + unsigned char * p = (unsigned char*) ibuf->rect; + unsigned char * e = p + ibuf->x * 4 * ibuf->y; StripColorBalance cb = calc_cb(seq->strip->color_balance); @@ -1630,24 +1364,24 @@ static void color_balance_byte_byte(Sequence * seq, TStripElem* se, float mul) } } -static void color_balance_byte_float(Sequence * seq, TStripElem* se, float mul) +static void color_balance_byte_float(Sequence * seq, ImBuf* ibuf, float mul) { float cb_tab[4][256]; int c,i; - unsigned char * p = (unsigned char*) se->ibuf->rect; - unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y; + unsigned char * p = (unsigned char*) ibuf->rect; + unsigned char * e = p + ibuf->x * 4 * ibuf->y; float * o; StripColorBalance cb; - imb_addrectfloatImBuf(se->ibuf); + imb_addrectfloatImBuf(ibuf); - o = se->ibuf->rect_float; + o = ibuf->rect_float; cb = calc_cb(seq->strip->color_balance); for (c = 0; c < 3; c++) { make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], - cb_tab[c], mul); + cb_tab[c], mul); } for (i = 0; i < 256; i++) { @@ -1664,10 +1398,10 @@ static void color_balance_byte_float(Sequence * seq, TStripElem* se, float mul) } } -static void color_balance_float_float(Sequence * seq, TStripElem* se, float mul) +static void color_balance_float_float(Sequence * seq, ImBuf* ibuf, float mul) { - float * p = se->ibuf->rect_float; - float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y; + float * p = ibuf->rect_float; + float * e = ibuf->rect_float + ibuf->x * 4* ibuf->y; StripColorBalance cb = calc_cb(seq->strip->color_balance); while (p < e) { @@ -1679,14 +1413,14 @@ static void color_balance_float_float(Sequence * seq, TStripElem* se, float mul) } } -static void color_balance(Sequence * seq, TStripElem* se, float mul) +static void color_balance(Sequence * seq, ImBuf* ibuf, float mul) { - if (se->ibuf->rect_float) { - color_balance_float_float(seq, se, mul); + if (ibuf->rect_float) { + color_balance_float_float(seq, ibuf, mul); } else if(seq->flag & SEQ_MAKE_FLOAT) { - color_balance_byte_float(seq, se, mul); + color_balance_byte_float(seq, ibuf, mul); } else { - color_balance_byte_byte(seq, se, mul); + color_balance_byte_byte(seq, ibuf, mul); } } @@ -1709,18 +1443,18 @@ static void color_balance(Sequence * seq, TStripElem* se, float mul) */ -static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se, int cfra, int seqrectx, int seqrecty) +static int input_have_to_preprocess( + Scene *scene, Sequence * seq, float cfra, int seqrectx, int seqrecty) { float mul; if ((seq->flag & SEQ_FILTERY) || - (seq->flag & SEQ_USE_CROP) || - (seq->flag & SEQ_USE_TRANSFORM) || - (seq->flag & SEQ_FLIPX) || - (seq->flag & SEQ_FLIPY) || - (seq->flag & SEQ_USE_COLOR_BALANCE) || - (seq->flag & SEQ_MAKE_PREMUL) || - (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) { + (seq->flag & SEQ_USE_CROP) || + (seq->flag & SEQ_USE_TRANSFORM) || + (seq->flag & SEQ_FLIPX) || + (seq->flag & SEQ_FLIPY) || + (seq->flag & SEQ_USE_COLOR_BALANCE) || + (seq->flag & SEQ_MAKE_PREMUL)) { return TRUE; } @@ -1734,19 +1468,25 @@ static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se if (mul != 1.0) { return TRUE; } + + if (seq->sat != 1.0) { + return TRUE; + } return FALSE; } -static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int seqrectx, int seqrecty) +static ImBuf * input_preprocess( + Scene *scene, Sequence *seq, float cfra, int seqrectx, int seqrecty, + ImBuf * ibuf) { float mul; - seq->strip->orx= se->ibuf->x; - seq->strip->ory= se->ibuf->y; + seq->strip->orx= ibuf->x; + seq->strip->ory= ibuf->y; if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) { - IMB_filtery(se->ibuf); + IMB_filtery(ibuf); } if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) { @@ -1764,8 +1504,8 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf t = *seq->strip->transform; } - sx = se->ibuf->x - c.left - c.right; - sy = se->ibuf->y - c.top - c.bottom; + sx = ibuf->x - c.left - c.right; + sy = ibuf->y - c.top - c.bottom; dx = sx; dy = sy; @@ -1774,49 +1514,49 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf dy = scene->r.ysch; } - if (c.top + c.bottom >= se->ibuf->y || - c.left + c.right >= se->ibuf->x || + if (c.top + c.bottom >= ibuf->y || + c.left + c.right >= ibuf->x || t.xofs >= dx || t.yofs >= dy) { - make_black_ibuf(se->ibuf); + make_black_ibuf(ibuf); } else { ImBuf * i; - if (se->ibuf->rect_float) { + if (ibuf->rect_float) { i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0); } else { i = IMB_allocImBuf(dx, dy,32, IB_rect, 0); } - IMB_rectcpy(i, se->ibuf, - t.xofs, t.yofs, - c.left, c.bottom, - sx, sy); - - IMB_freeImBuf(se->ibuf); + IMB_rectcpy(i, ibuf, + t.xofs, t.yofs, + c.left, c.bottom, + sx, sy); + + IMB_freeImBuf(ibuf); - se->ibuf = i; + ibuf = i; } } if(seq->flag & SEQ_FLIPX) { - IMB_flipx(se->ibuf); + IMB_flipx(ibuf); } if(seq->flag & SEQ_FLIPY) { - IMB_flipy(se->ibuf); + IMB_flipy(ibuf); } if(seq->sat != 1.0f) { /* inline for now, could become an imbuf function */ int i; - char *rct= (char *)se->ibuf->rect; - float *rctf= se->ibuf->rect_float; + char *rct= (char *)ibuf->rect; + float *rctf= ibuf->rect_float; const float sat= seq->sat; float hsv[3]; if(rct) { float rgb[3]; - for (i = se->ibuf->x * se->ibuf->y; i > 0; i--, rct+=4) { + for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) { rgb_byte_to_float(rct, rgb); rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb+1, rgb+2); @@ -1825,7 +1565,7 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf } if(rctf) { - for (i = se->ibuf->x * se->ibuf->y; i > 0; i--, rctf+=4) { + for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) { rgb_to_hsv(rctf[0], rctf[1], rctf[2], hsv, hsv+1, hsv+2); hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rctf, rctf+1, rctf+2); } @@ -1839,725 +1579,544 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf } if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) { - color_balance(seq, se, mul); + color_balance(seq, ibuf, mul); mul = 1.0; } if(seq->flag & SEQ_MAKE_FLOAT) { - if (!se->ibuf->rect_float) - IMB_float_from_rect_simple(se->ibuf); + if (!ibuf->rect_float) + IMB_float_from_rect_simple(ibuf); - if (se->ibuf->rect) { - imb_freerectImBuf(se->ibuf); + if (ibuf->rect) { + imb_freerectImBuf(ibuf); } } if(mul != 1.0) { - multibuf(se->ibuf, mul); + multibuf(ibuf, mul); } if(seq->flag & SEQ_MAKE_PREMUL) { - if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) { - IMB_premultiply_alpha(se->ibuf); + if(ibuf->depth == 32 && ibuf->zbuf == 0) { + IMB_premultiply_alpha(ibuf); } } - if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) { + if(ibuf->x != seqrectx || ibuf->y != seqrecty ) { if(scene->r.mode & R_OSA) { - IMB_scaleImBuf(se->ibuf, - (short)seqrectx, (short)seqrecty); + IMB_scaleImBuf(ibuf, + (short)seqrectx, (short)seqrecty); } else { - IMB_scalefastImBuf(se->ibuf, + IMB_scalefastImBuf(ibuf, (short)seqrectx, (short)seqrecty); } } + return ibuf; } -/* test if image too small or discarded from cache: reload */ - -static void test_and_auto_discard_ibuf(TStripElem * se, - int seqrectx, int seqrecty) +static ImBuf * copy_from_ibuf_still(Sequence * seq, float nr, + int seqrectx, int seqrecty) { - if (se->ibuf) { - if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty - || !(se->ibuf->rect || se->ibuf->rect_float)) { - IMB_freeImBuf(se->ibuf); + ImBuf * rval = 0; + ImBuf * ibuf = 0; - se->ibuf= 0; - se->ok= STRIPELEM_OK; - } + if (nr == 0) { + ibuf = seq_stripelem_cache_get( + seq, seqrectx, seqrecty, seq->start, + SEQ_STRIPELEM_IBUF_STARTSTILL); + } + if (nr == seq->len - 1) { + ibuf = seq_stripelem_cache_get( + seq, seqrectx, seqrecty, seq->start, + SEQ_STRIPELEM_IBUF_ENDSTILL); } - if (se->ibuf_comp) { - if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty - || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) { - IMB_freeImBuf(se->ibuf_comp); - se->ibuf_comp = 0; - } + if (ibuf) { + rval = IMB_dupImBuf(ibuf); + IMB_freeImBuf(ibuf); } + + return rval; } -static void test_and_auto_discard_ibuf_stills(Strip * strip) +static void copy_to_ibuf_still(Sequence * seq, float nr, + ImBuf * ibuf) { - if (strip->ibuf_startstill) { - if (!strip->ibuf_startstill->rect && - !strip->ibuf_startstill->rect_float) { - IMB_freeImBuf(strip->ibuf_startstill); - strip->ibuf_startstill = 0; - } + if (nr == 0) { + seq_stripelem_cache_put( + seq, 0, 0, seq->start, + SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf); } - if (strip->ibuf_endstill) { - if (!strip->ibuf_endstill->rect && - !strip->ibuf_endstill->rect_float) { - IMB_freeImBuf(strip->ibuf_endstill); - strip->ibuf_endstill = 0; - } + if (nr == seq->len - 1) { + seq_stripelem_cache_put( + seq, 0, 0, seq->start, + SEQ_STRIPELEM_IBUF_ENDSTILL, ibuf); } } -static void copy_from_ibuf_still(Sequence * seq, TStripElem * se) -{ - if (!se->ibuf) { - if (se->nr == 0 && seq->strip->ibuf_startstill) { - IMB_cache_limiter_touch(seq->strip->ibuf_startstill); - - se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill); - } - if (se->nr == seq->len - 1 - && (seq->len != 1) - && seq->strip->ibuf_endstill) { - IMB_cache_limiter_touch(seq->strip->ibuf_endstill); - - se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill); - } - } -} +/* ********************************************************************** + strip rendering functions + ********************************************************************** */ -static void copy_to_ibuf_still(Sequence * seq, TStripElem * se) -{ - if (se->ibuf) { - if (se->nr == 0) { - seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf); +static ImBuf* seq_render_strip_stack( + Scene *scene, + ListBase *seqbasep, float cfra, int chanshown, int render_size, + int seqrectx, int seqrecty); - IMB_cache_limiter_insert(seq->strip->ibuf_startstill); - IMB_cache_limiter_touch(seq->strip->ibuf_startstill); - } - if (se->nr == seq->len - 1 && seq->len != 1) { - seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf); +static ImBuf * seq_render_strip(Scene *scene, Sequence * seq, float cfra, + int render_size, + int seqrectx, int seqrecty); - IMB_cache_limiter_insert(seq->strip->ibuf_endstill); - IMB_cache_limiter_touch(seq->strip->ibuf_endstill); - } - } -} -static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown) +static ImBuf* seq_render_effect_strip_impl( + Scene *scene, float cfra, Sequence *seq, int render_size, + int seqrectx, int seqrecty) { - Sequence* seq_arr[MAXSEQ+1]; + float fac, facf; + int early_out; int i; - TStripElem* se = 0; - - evaluate_seq_frame_gen(seq_arr, seqbasep, cfra); - - for (i = 0; i < MAXSEQ; i++) { - if (!video_seq_is_rendered(seq_arr[i])) { - continue; - } - se = give_tstripelem(seq_arr[i], cfra); - if (se) { - if (se->ibuf) { - IMB_freeImBuf(se->ibuf); + int must_preprocess = FALSE; - se->ibuf= 0; - se->ok= STRIPELEM_OK; - } + struct SeqEffectHandle sh = get_sequence_effect(seq); + FCurve *fcu= NULL; + ImBuf * ibuf[3]; + ImBuf * out = 0; - if (se->ibuf_comp) { - IMB_freeImBuf(se->ibuf_comp); + ibuf[0] = ibuf[1] = ibuf[2] = 0; - se->ibuf_comp = 0; - } - } + if (!sh.execute) { /* effect not supported in this version... */ + goto finish; } - -} -static void check_limiter_refcount(const char * func, TStripElem *se) -{ - if (se && se->ibuf) { - int refcount = IMB_cache_limiter_get_refcount(se->ibuf); - if (refcount != 1) { - /* can happen on complex pipelines */ - if (refcount > 1 && (G.f & G_DEBUG) == 0) { - return; - } - - fprintf(stderr, - "sequencer: (ibuf) %s: " - "suspicious memcache " - "limiter refcount: %d\n", func, refcount); - } - } -} - -static void check_limiter_refcount_comp(const char * func, TStripElem *se) -{ - if (se && se->ibuf_comp) { - int refcount = IMB_cache_limiter_get_refcount(se->ibuf_comp); - if (refcount != 1) { - /* can happen on complex pipelines */ - if (refcount > 1 && (G.f & G_DEBUG) == 0) { - return; + if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) { + sh.get_default_fac(seq, cfra, &fac, &facf); + if( scene->r.mode & R_FIELDS ); else facf= fac; + } else { + fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, + "effect_fader", 0); + if (fcu) { + fac = facf = evaluate_fcurve(fcu, cfra); + if( scene->r.mode & R_FIELDS ) { + facf = evaluate_fcurve(fcu, cfra + 0.5); } - fprintf(stderr, - "sequencer: (ibuf comp) %s: " - "suspicious memcache " - "limiter refcount: %d\n", func, refcount); + } else { + fac = facf = seq->effect_fader; } } -} -static TStripElem* do_build_seq_array_recursively( - Scene *scene, - ListBase *seqbasep, int cfra, int chanshown, int render_size, - int seqrectx, int seqrecty); + early_out = sh.early_out(seq, fac, facf); -static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra, - int build_proxy_run, int render_size, int seqrectx, int seqrecty) -{ - char name[FILE_MAXDIR+FILE_MAXFILE]; - int use_limiter = TRUE; + if (early_out == -1) { /* no input needed */ + /* hmmm, global float option ? */ + out = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, 32, IB_rect, 0); - test_and_auto_discard_ibuf(se, seqrectx, seqrecty); - test_and_auto_discard_ibuf_stills(seq->strip); + sh.execute(scene, seq, cfra, fac, facf, + out->x, out->y, render_size, + 0, 0, 0, out); + goto finish; + } - if(seq->type == SEQ_META) { - TStripElem * meta_se = 0; - int use_preprocess = FALSE; - use_limiter = FALSE; - - if (!build_proxy_run && se->ibuf == 0) { - se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); - if (se->ibuf) { - use_limiter = TRUE; - use_preprocess = TRUE; - } - } - if(!se->ibuf && seq->seqbase.first) { - meta_se = do_build_seq_array_recursively(scene, - &seq->seqbase, seq->start + se->nr, 0, - render_size, seqrectx, seqrecty); + must_preprocess = input_have_to_preprocess( + scene, seq, cfra, seqrectx, seqrecty); - check_limiter_refcount("do_build_seq_ibuf: for META", meta_se); + switch (early_out) { + case 0: + break; + case 1: + if (seq->seq1) { + ibuf[0] = seq_render_strip(scene, seq->seq1, cfra, + render_size, + seqrectx, seqrecty); } - - se->ok = STRIPELEM_OK; - - if(!se->ibuf && meta_se) { - se->ibuf = meta_se->ibuf_comp; - if(se->ibuf && - (!input_have_to_preprocess(scene, seq, se, cfra, - seqrectx, seqrecty) || - build_proxy_run)) { - IMB_refImBuf(se->ibuf); - if (build_proxy_run) { - IMB_cache_limiter_unref(se->ibuf); - } - } else if (se->ibuf) { - struct ImBuf * i = IMB_dupImBuf(se->ibuf); - - IMB_cache_limiter_unref(se->ibuf); - - se->ibuf = i; - - use_limiter = TRUE; - use_preprocess = TRUE; + if (ibuf[0]) { + if (must_preprocess) { + out = IMB_dupImBuf(ibuf[0]); + } else { + out = ibuf[0]; + IMB_refImBuf(out); } - } else if (se->ibuf) { - use_limiter = TRUE; - } - if (meta_se) { - free_metastrip_imbufs( - &seq->seqbase, seq->start + se->nr, 0); } - - if (use_preprocess) { - input_preprocess(scene, seq, se, cfra, seqrectx, - seqrecty); - } - } else if(seq->type & SEQ_EFFECT) { - int use_preprocess = FALSE; - /* should the effect be recalculated? */ - - if (!build_proxy_run && se->ibuf == 0) { - se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); - if (se->ibuf) { - use_preprocess = TRUE; + goto finish; + case 2: + if (seq->seq2) { + ibuf[1] = seq_render_strip(scene, seq->seq2, cfra, + render_size, + seqrectx, seqrecty); + } + if (ibuf[1]) { + if (must_preprocess) { + out = IMB_dupImBuf(ibuf[1]); + } else { + out = ibuf[1]; + IMB_refImBuf(out); } } + goto finish; + default: + goto finish; + } - if(se->ibuf == 0) { - /* if any inputs are rectfloat, output is float too */ - if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) || - (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float) || - (se->se3 && se->se3->ibuf && se->se3->ibuf->rect_float)) - se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0); - else - se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0); - - do_effect(scene, cfra, seq, se, render_size); - if (input_have_to_preprocess(scene, seq, se, cfra, - seqrectx, seqrecty) && - !build_proxy_run) { - if ((se->se1 && (se->ibuf == se->se1->ibuf)) || - (se->se2 && (se->ibuf == se->se2->ibuf))) { - struct ImBuf * i - = IMB_dupImBuf(se->ibuf); - - IMB_freeImBuf(se->ibuf); - - se->ibuf = i; - } - use_preprocess = TRUE; - } - } - if (use_preprocess) { - input_preprocess(scene, seq, se, cfra, seqrectx, - seqrecty); - } - } else if(seq->type == SEQ_IMAGE) { - if(se->ok == STRIPELEM_OK && se->ibuf == 0) { - StripElem * s_elem = give_stripelem(seq, cfra); - BLI_join_dirfile(name, seq->strip->dir, s_elem->name); - BLI_path_abs(name, G.sce); - if (!build_proxy_run) { - se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); - } - copy_from_ibuf_still(seq, se); + if (seq->seq1) { + ibuf[0] = seq_render_strip(scene, seq->seq1, cfra, + render_size, + seqrectx, seqrecty); + } - if (se->ibuf==NULL && (se->ibuf= IMB_loadiffname(name, IB_rect))) { - /* we don't need both (speed reasons)! */ - if (se->ibuf->rect_float && se->ibuf->rect) - imb_freerectImBuf(se->ibuf); + if (seq->seq2) { + ibuf[1] = seq_render_strip(scene, seq->seq2, cfra, + render_size, + seqrectx, seqrecty); + } - /* all sequencer color is done in SRGB space, linear gives odd crossfades */ - if(se->ibuf->profile == IB_PROFILE_LINEAR_RGB) - IMB_convert_profile(se->ibuf, IB_PROFILE_NONE); + if (seq->seq3) { + ibuf[2] = seq_render_strip(scene, seq->seq3, cfra, + render_size, + seqrectx, seqrecty); + } - copy_to_ibuf_still(seq, se); - } - - if(se->ibuf == 0) { - se->ok = STRIPELEM_FAILED; - } else if (!build_proxy_run) { - input_preprocess(scene, seq, se, cfra, - seqrectx, seqrecty); - } - } - } else if(seq->type == SEQ_MOVIE) { - if(se->ok == STRIPELEM_OK && se->ibuf==0) { - if(!build_proxy_run) { - se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); - } - copy_from_ibuf_still(seq, se); + if (!ibuf[0] || !ibuf[1]) { + goto finish; + } - if (se->ibuf == 0) { - if(seq->anim==0) { - BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name); - BLI_path_abs(name, G.sce); - - seq->anim = openanim( - name, IB_rect | - ((seq->flag & SEQ_FILTERY) - ? IB_animdeinterlace : 0)); - } - if(seq->anim) { - IMB_anim_set_preseek(seq->anim, seq->anim_preseek); - se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs); - /* we don't need both (speed reasons)! */ - if (se->ibuf - && se->ibuf->rect_float - && se->ibuf->rect) { - imb_freerectImBuf(se->ibuf); - } + /* if any inputs are rectfloat, output is float too */ + if((ibuf[0] && ibuf[0]->rect_float) || + (ibuf[1] && ibuf[1]->rect_float) || + (ibuf[2] && ibuf[2]->rect_float)) { + out = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0); + } else { + out = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, 32, IB_rect, 0); + } - } - copy_to_ibuf_still(seq, se); - } - - if(se->ibuf == 0) { - se->ok = STRIPELEM_FAILED; - } else if (!build_proxy_run) { - input_preprocess(scene, seq, se, cfra, - seqrectx, seqrecty); + for (i = 0; i < 3; i++) { + ImBuf * b = ibuf[i]; + if (b) { + if (!b->rect_float && out->rect_float) { + IMB_float_from_rect_simple(b); } - } - } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions - Scene *sce= seq->scene;// *oldsce= scene; - int have_seq= FALSE; - int sce_valid= FALSE; - - if(sce) { - have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first; - sce_valid= (sce->camera || have_seq); - } - - if (se->ibuf == NULL && sce_valid && !build_proxy_run) { - se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); - if (se->ibuf) { - input_preprocess(scene, seq, se, cfra, - seqrectx, seqrecty); + if (!b->rect && !out->rect_float) { + IMB_rect_from_float(b); } } + } - if (se->ibuf == NULL && sce_valid) { - copy_from_ibuf_still(seq, se); - if (se->ibuf) { - input_preprocess(scene, seq, se, cfra, - seqrectx, seqrecty); - } - } - - if (!sce_valid) { - se->ok = STRIPELEM_FAILED; - } - else if (se->ibuf==NULL && sce_valid) { - int frame= seq->sfra + se->nr + seq->anim_startofs; - int oldcfra = seq->scene->r.cfra; - Object *oldcamera= seq->scene->camera; - ListBase oldmarkers; - - /* Hack! This function can be called from do_render_seq(), in that case - the seq->scene can already have a Render initialized with same name, - so we have to use a default name. (compositor uses scene name to - find render). - However, when called from within the UI (image preview in sequencer) - we do want to use scene Render, that way the render result is defined - for display in render/imagewindow - - Hmm, don't see, why we can't do that all the time, - and since G.rendering is uhm, gone... (Peter) - */ - - int rendering = G.rendering; - int doseq; - int doseq_gl= G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : (scene->r.seq_flag & R_SEQ_GL_PREV); - - /* prevent eternal loop */ - doseq= scene->r.scemode & R_DOSEQ; - scene->r.scemode &= ~R_DOSEQ; - - seq->scene->r.cfra= frame; - if(seq->scene_camera) seq->scene->camera= seq->scene_camera; - else scene_camera_switch_update(seq->scene); + sh.execute(scene, seq, cfra, fac, facf, out->x, out->y, render_size, + ibuf[0], ibuf[1], ibuf[2], out); -#ifdef DURIAN_CAMERA_SWITCH - /* stooping to new low's in hackyness :( */ - oldmarkers= seq->scene->markers; - seq->scene->markers.first= seq->scene->markers.last= NULL; -#endif +finish: + for (i = 0; i < 3; i++) { + IMB_freeImBuf(ibuf[i]); + } - if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (seq->scene == scene || have_seq==0) && seq->scene->camera) { - /* opengl offscreen render */ - scene_update_for_newframe(seq->scene, seq->scene->lay); - se->ibuf= sequencer_view3d_cb(seq->scene, seqrectx, seqrecty, scene->r.seq_prev_type); - } - else { - Render *re; - RenderResult rres; + if (!out) { + out = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, 32, IB_rect, 0); + } - if(rendering) - re= RE_NewRender(" do_build_seq_ibuf"); - else - re= RE_NewRender(sce->id.name); + return out; +} - RE_BlenderFrame(re, sce, NULL, sce->lay, frame); - RE_AcquireResultImage(re, &rres); +static ImBuf * seq_render_scene_strip_impl( + Scene * scene, Sequence * seq, float nr, int seqrectx, int seqrecty) +{ + ImBuf * ibuf = 0; + float frame= seq->sfra + nr + seq->anim_startofs; + float oldcfra = seq->scene->r.cfra; + Object *oldcamera= seq->scene->camera; + ListBase oldmarkers; + + /* Hack! This function can be called from do_render_seq(), in that case + the seq->scene can already have a Render initialized with same name, + so we have to use a default name. (compositor uses scene name to + find render). + However, when called from within the UI (image preview in sequencer) + we do want to use scene Render, that way the render result is defined + for display in render/imagewindow + + Hmm, don't see, why we can't do that all the time, + and since G.rendering is uhm, gone... (Peter) + */ - if(rres.rectf) { - se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0); - memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty); - if(rres.rectz) { - addzbuffloatImBuf(se->ibuf); - memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty); - } + int rendering = G.rendering; + int doseq; + int doseq_gl= G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : (scene->r.seq_flag & R_SEQ_GL_PREV); + int have_seq= FALSE; + Scene *sce= seq->scene;// *oldsce= scene; + int sce_valid= FALSE; - /* { - ImBuf *imb= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0); - IMB_saveiff(imb, "/tmp/foo.image", IB_rect | IB_metadata); - IMB_freeImBuf(imb); - } */ + have_seq= (sce->r.scemode & R_DOSEQ) + && sce->ed && sce->ed->seqbase.first; - } else if (rres.rect32) { - se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0); - memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty); - } + if(sce) { + sce_valid= (sce->camera || have_seq); + } - RE_ReleaseResultImage(re); + if (!sce_valid) { + return 0; + } - // BIF_end_render_callbacks(); + + /* prevent eternal loop */ + doseq= scene->r.scemode & R_DOSEQ; + scene->r.scemode &= ~R_DOSEQ; + + seq->scene->r.cfra= frame; + if(seq->scene_camera) + seq->scene->camera= seq->scene_camera; + else + scene_camera_switch_update(seq->scene); + +#ifdef DURIAN_CAMERA_SWITCH + /* stooping to new low's in hackyness :( */ + oldmarkers= seq->scene->markers; + seq->scene->markers.first= seq->scene->markers.last= NULL; +#endif + + if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (seq->scene == scene || have_seq==0) && seq->scene->camera) { + /* opengl offscreen render */ + scene_update_for_newframe(seq->scene, seq->scene->lay); + ibuf= sequencer_view3d_cb(seq->scene, seqrectx, seqrecty, + scene->r.seq_prev_type); + } + else { + Render *re; + RenderResult rres; + + if(rendering) + re= RE_NewRender(" do_build_seq_ibuf"); + else + re= RE_NewRender(sce->id.name); + + RE_BlenderFrame(re, sce, NULL, sce->lay, frame); + + RE_AcquireResultImage(re, &rres); + + if(rres.rectf) { + ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0); + memcpy(ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty); + if(rres.rectz) { + addzbuffloatImBuf(ibuf); + memcpy(ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty); } - /* restore */ - scene->r.scemode |= doseq; - - seq->scene->r.cfra = oldcfra; - seq->scene->camera= oldcamera; - + /* { + ImBuf *imb= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0); + IMB_saveiff(imb, "/tmp/foo.image", IB_rect | IB_metadata); + IMB_freeImBuf(imb); + } */ + + } else if (rres.rect32) { + ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0); + memcpy(ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty); + } + + RE_ReleaseResultImage(re); + + // BIF_end_render_callbacks(); + } + + /* restore */ + scene->r.scemode |= doseq; + + seq->scene->r.cfra = oldcfra; + seq->scene->camera= oldcamera; + #ifdef DURIAN_CAMERA_SWITCH - /* stooping to new low's in hackyness :( */ - seq->scene->markers= oldmarkers; + /* stooping to new low's in hackyness :( */ + seq->scene->markers= oldmarkers; #endif - copy_to_ibuf_still(seq, se); + return ibuf; +} - if (!build_proxy_run) { - if(se->ibuf == NULL) { - se->ok = STRIPELEM_FAILED; - } else { - input_preprocess(scene, seq, se, cfra, - seqrectx, seqrecty); - } - } +static ImBuf * seq_render_strip(Scene *scene, Sequence * seq, float cfra, + int render_size, + int seqrectx, int seqrecty) +{ + char name[FILE_MAXDIR+FILE_MAXFILE]; + int use_preprocess = input_have_to_preprocess( + scene, seq, cfra, seqrectx, seqrecty); + ImBuf * ibuf = seq_stripelem_cache_get( + seq, seqrectx, seqrecty, cfra, SEQ_STRIPELEM_IBUF); + float nr = give_stripelem_index(seq, cfra); - } + /* currently, we cache preprocessed images */ + if (ibuf) { + use_preprocess = FALSE; } - if (!build_proxy_run) { - if (se->ibuf && use_limiter) { - IMB_cache_limiter_insert(se->ibuf); - IMB_cache_limiter_ref(se->ibuf); - IMB_cache_limiter_touch(se->ibuf); + + if(seq->type == SEQ_META) { + ImBuf * meta_ibuf = 0; + + if (ibuf == 0) { + ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); } - } -} -static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size, int seqrectx, int seqrecty); + if(!ibuf && seq->seqbase.first) { + meta_ibuf = seq_render_strip_stack( + scene, + &seq->seqbase, seq->start + nr, 0, + render_size, seqrectx, seqrecty); + } -static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size, int seqrectx, int seqrecty) -{ - float fac, facf; - struct SeqEffectHandle sh = get_sequence_effect(seq); - int early_out; - FCurve *fcu= NULL; + if(!ibuf && meta_ibuf) { + ibuf = meta_ibuf; + if(ibuf && use_preprocess) { + struct ImBuf * i = IMB_dupImBuf(ibuf); - se->se1 = 0; - se->se2 = 0; - se->se3 = 0; + IMB_freeImBuf(ibuf); - if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) { - sh.get_default_fac(seq, cfra, &fac, &facf); - if( scene->r.mode & R_FIELDS ); else facf= fac; - } else { - fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, - "effect_fader", 0); - if (fcu) { - fac = facf = evaluate_fcurve(fcu, cfra); - if( scene->r.mode & R_FIELDS ) { - facf = evaluate_fcurve(fcu, cfra + 0.5); + ibuf = i; } - } else { - fac = facf = seq->effect_fader; } - } + } else if(seq->type == SEQ_SPEED) { + ImBuf * child_ibuf = 0; - early_out = sh.early_out(seq, fac, facf); - switch (early_out) { - case -1: - /* no input needed */ - break; - case 0: - se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size, seqrectx, seqrecty); - se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size, seqrectx, seqrecty); - if (seq->seq3) { - se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size, seqrectx, seqrecty); + if (ibuf == 0) { + ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); } - break; - case 1: - se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size, seqrectx, seqrecty); - break; - case 2: - se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size, seqrectx, seqrecty); - break; - } + if (ibuf == 0) { + float f_cfra; + SpeedControlVars * s + = (SpeedControlVars *)seq->effectdata; - do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size, seqrectx, seqrecty); + sequence_effect_speed_rebuild_map(scene, seq, 0); - /* children are not needed anymore ... */ + /* weeek! */ + f_cfra = seq->start + s->frameMap[(int) nr]; - if (se->se1 && se->se1->ibuf) { - IMB_cache_limiter_unref(se->se1->ibuf); - } - if (se->se2 && se->se2->ibuf) { - IMB_cache_limiter_unref(se->se2->ibuf); - } - if (se->se3 && se->se3->ibuf) { - IMB_cache_limiter_unref(se->se3->ibuf); - } - check_limiter_refcount("do_effect_seq_recursively", se); -} + child_ibuf = seq_render_strip(scene, seq->seq1, f_cfra, + render_size, + seqrectx, seqrecty); + } -static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty) -{ - TStripElem *se; + if (!ibuf && child_ibuf) { + ibuf = child_ibuf; + if(ibuf && use_preprocess) { + struct ImBuf * i = IMB_dupImBuf(ibuf); - se = give_tstripelem(seq, cfra); + IMB_freeImBuf(ibuf); - if(se) { - if (seq->type & SEQ_EFFECT) { - do_effect_seq_recursively(scene, seq, se, cfra, render_size, seqrectx, seqrecty); - } else { - do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size, seqrectx, seqrecty); + ibuf = i; + } + } + } else if(seq->type & SEQ_EFFECT) { + /* should the effect be recalculated? */ + + if (ibuf == 0) { + ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); } - } - return se; -} - -/* FIXME: - -If cfra was float throughout blender (especially in the render -pipeline) one could even _render_ with subframe precision -instead of faking using the blend code below... - -*/ -static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty) -{ - SpeedControlVars * s = (SpeedControlVars *)seq->effectdata; - int nr = cfra - seq->start; - float f_cfra; - int cfra_left; - int cfra_right; - TStripElem * se = 0; - TStripElem * se1 = 0; - TStripElem * se2 = 0; - - sequence_effect_speed_rebuild_map(scene, seq, 0); - - f_cfra = seq->start + s->frameMap[nr]; - - cfra_left = (int) floor(f_cfra); - cfra_right = (int) ceil(f_cfra); + if(ibuf == 0) { + ibuf = seq_render_effect_strip_impl( + scene, cfra, seq, render_size, + seqrectx, seqrecty); + } + } else if(seq->type == SEQ_IMAGE) { + StripElem * s_elem = give_stripelem(seq, cfra); - se = give_tstripelem(seq, cfra); + if(ibuf == 0) { + BLI_join_dirfile(name, seq->strip->dir, s_elem->name); + BLI_path_abs(name, G.sce); - if (!se) { - return se; - } + ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); + } - if (cfra_left == cfra_right || - (s->flags & SEQ_SPEED_BLEND) == 0) { - test_and_auto_discard_ibuf(se, seqrectx, seqrecty); + if (ibuf == 0) { + ibuf = copy_from_ibuf_still(seq,nr,seqrectx,seqrecty); + } - if (se->ibuf == NULL) { - se1 = do_build_seq_recursively(scene, seq->seq1, cfra_left, render_size, seqrectx, seqrecty); + if (ibuf == 0 && (ibuf=IMB_loadiffname(name, IB_rect))) { + /* we don't need both (speed reasons)! */ + if (ibuf->rect_float && ibuf->rect) + imb_freerectImBuf(ibuf); - if((se1 && se1->ibuf && se1->ibuf->rect_float)) - se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0); - else - se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0); + /* all sequencer color is done in SRGB space, linear gives odd crossfades */ + if(ibuf->profile == IB_PROFILE_LINEAR_RGB) + IMB_convert_profile(ibuf, IB_PROFILE_NONE); - if (se1 == 0 || se1->ibuf == 0) { - make_black_ibuf(se->ibuf); - } else { - if (se->ibuf != se1->ibuf) { - if (se->ibuf) { - IMB_freeImBuf(se->ibuf); - } + copy_to_ibuf_still(seq, nr, ibuf); + } + } else if(seq->type == SEQ_MOVIE) { + if(ibuf == 0) { + ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); + + } + + if (ibuf == 0) { + ibuf = copy_from_ibuf_still(seq, nr,seqrectx,seqrecty); + } - se->ibuf = se1->ibuf; - IMB_refImBuf(se->ibuf); + if (ibuf == 0) { + if(seq->anim==0) { + BLI_join_dirfile(name, + seq->strip->dir, + seq->strip->stripdata->name); + BLI_path_abs(name, G.sce); + + seq->anim = openanim( + name, IB_rect | + ((seq->flag & SEQ_FILTERY) + ? IB_animdeinterlace : 0)); + } + if(seq->anim) { + IMB_anim_set_preseek(seq->anim, + seq->anim_preseek); + ibuf = IMB_anim_absolute(seq->anim, + nr + + seq->anim_startofs); + /* we don't need both (speed reasons)! */ + if (ibuf && ibuf->rect_float + && ibuf->rect) { + imb_freerectImBuf(ibuf); } - } - } - } else { - struct SeqEffectHandle sh; - if(se->ibuf) { - if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty - || !(se->ibuf->rect || se->ibuf->rect_float)) { - IMB_freeImBuf(se->ibuf); - se->ibuf= 0; } + copy_to_ibuf_still(seq, nr, ibuf); } - - if (se->ibuf == NULL) { - se1 = do_build_seq_recursively(scene, seq->seq1, cfra_left, render_size, seqrectx, seqrecty); - se2 = do_build_seq_recursively(scene, seq->seq1, cfra_right, render_size, seqrectx, seqrecty); - - if((se1 && se1->ibuf && se1->ibuf->rect_float)) - se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0); - else - se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0); - if (!se1 || !se2) { - make_black_ibuf(se->ibuf); - } else { - sh = get_sequence_effect(seq); - - sh.execute(scene, seq, cfra, - f_cfra - (float) cfra_left, - f_cfra - (float) cfra_left, - se->ibuf->x, se->ibuf->y, - render_size, - se1->ibuf, se2->ibuf, 0, se->ibuf); - } + } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions + if (ibuf == 0) { + ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); + } + if (ibuf == 0) { + ibuf = copy_from_ibuf_still(seq, nr,seqrectx,seqrecty); } + + if (ibuf == 0) { + ibuf = seq_render_scene_strip_impl(scene, seq, nr, + seqrectx, seqrecty); + copy_to_ibuf_still(seq, nr, ibuf); + } } - /* caller expects this to be referenced, so do it! */ - if (se->ibuf) { - IMB_cache_limiter_insert(se->ibuf); - IMB_cache_limiter_ref(se->ibuf); - IMB_cache_limiter_touch(se->ibuf); + if (!ibuf) { + ibuf = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, 32, IB_rect, 0); } - /* children are no longer needed */ - if (se1 && se1->ibuf) - IMB_cache_limiter_unref(se1->ibuf); - if (se2 && se2->ibuf) - IMB_cache_limiter_unref(se2->ibuf); - - check_limiter_refcount("do_handle_speed_effect", se); - - return se; -} - -/* - * build all ibufs recursively - * - * if successfull, the returned TStripElem contains the (referenced!) imbuf - * that means: you _must_ call - * - * IMB_cache_limiter_unref(rval); - * - * if rval != 0 - * - */ - -static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty) -{ - TStripElem *se; - - /* BAD HACK! Seperate handling for speed effects needed, since - a) you can't just fetch a different cfra within an effect strip - b) we have to blend two frames, and CFRA is not float... - */ - if (seq->type == SEQ_SPEED) { - se = do_handle_speed_effect(scene, seq, cfra, render_size, seqrectx, seqrecty); - } else { - se = do_build_seq_recursively_impl(scene, seq, cfra, render_size, seqrectx, seqrecty); + if (use_preprocess) { + ibuf = input_preprocess(scene, seq, cfra, seqrectx, + seqrecty, ibuf); } - check_limiter_refcount("do_build_seq_recursively", se); + seq_stripelem_cache_put( + seq, seqrectx, seqrecty, cfra, SEQ_STRIPELEM_IBUF, ibuf); - return se; + return ibuf; } +/* ********************************************************************** + strip stack rendering functions + ********************************************************************** */ + static int seq_must_swap_input_in_blend_mode(Sequence * seq) { int swap_input = FALSE; @@ -2594,28 +2153,22 @@ static int seq_get_early_out_for_blend_mode(Sequence * seq) return early_out; } -static TStripElem* do_build_seq_array_recursively( - Scene *scene, ListBase *seqbasep, int cfra, int chanshown, +static ImBuf* seq_render_strip_stack( + Scene *scene, ListBase *seqbasep, float cfra, int chanshown, int render_size, int seqrectx, int seqrecty) { Sequence* seq_arr[MAXSEQ+1]; int count; int i; - TStripElem* se = 0; + ImBuf* out = 0; count = get_shown_sequences(seqbasep, cfra, chanshown, - (Sequence **)&seq_arr); + (Sequence **)&seq_arr); if (!count) { return 0; } - se = give_tstripelem(seq_arr[count - 1], cfra); - - if (!se) { - return 0; - } - #if 0 /* commentind since this breaks keyframing, since it resets the value on draw */ if(scene->r.cfra != cfra) { // XXX for prefetch and overlay offset!..., very bad!!! @@ -2624,25 +2177,24 @@ static TStripElem* do_build_seq_array_recursively( } #endif - test_and_auto_discard_ibuf(se, seqrectx, seqrecty); + out = seq_stripelem_cache_get( + seq_arr[count - 1], + seqrectx, seqrecty, cfra, SEQ_STRIPELEM_IBUF_COMP); - if (se->ibuf_comp != 0) { - IMB_cache_limiter_insert(se->ibuf_comp); - IMB_cache_limiter_ref(se->ibuf_comp); - IMB_cache_limiter_touch(se->ibuf_comp); - return se; + if (out) { + return out; } - if(count == 1) { - se = do_build_seq_recursively(scene, seq_arr[0], - cfra, render_size, - seqrectx, seqrecty); - if (se->ibuf) { - se->ibuf_comp = se->ibuf; - IMB_refImBuf(se->ibuf_comp); - } - return se; + out = seq_render_strip(scene, seq_arr[0], + cfra, render_size, + seqrectx, seqrecty); + seq_stripelem_cache_put( + seq_arr[0], + seqrectx, seqrecty, cfra, + SEQ_STRIPELEM_IBUF_COMP, out); + + return out; } @@ -2650,29 +2202,17 @@ static TStripElem* do_build_seq_array_recursively( int early_out; Sequence * seq = seq_arr[i]; - se = give_tstripelem(seq, cfra); + out = seq_stripelem_cache_get( + seq, + seqrectx, seqrecty, cfra, SEQ_STRIPELEM_IBUF_COMP); - test_and_auto_discard_ibuf(se, seqrectx, seqrecty); - - if (se->ibuf_comp != 0) { + if (out) { break; } if (seq->blend_mode == SEQ_BLEND_REPLACE) { - do_build_seq_recursively( - scene, seq, cfra, render_size, - seqrectx, seqrecty); - - if (se->ibuf) { - se->ibuf_comp = se->ibuf; - IMB_refImBuf(se->ibuf); - } else { - se->ibuf_comp = IMB_allocImBuf( - (short)seqrectx, (short)seqrecty, - 32, IB_rect, 0); - IMB_cache_limiter_insert(se->ibuf_comp); - IMB_cache_limiter_ref(se->ibuf_comp); - IMB_cache_limiter_touch(se->ibuf_comp); - } + out = seq_render_strip(scene, seq, cfra, + render_size, + seqrectx, seqrecty); break; } @@ -2681,154 +2221,111 @@ static TStripElem* do_build_seq_array_recursively( switch (early_out) { case -1: case 2: - do_build_seq_recursively( - scene, seq, cfra, render_size, - seqrectx, seqrecty); - - if (se->ibuf) { - se->ibuf_comp = se->ibuf; - IMB_refImBuf(se->ibuf_comp); - } else { - se->ibuf_comp = IMB_allocImBuf( - (short)seqrectx, (short)seqrecty, - 32, IB_rect, 0); - IMB_cache_limiter_insert(se->ibuf_comp); - IMB_cache_limiter_ref(se->ibuf_comp); - IMB_cache_limiter_touch(se->ibuf_comp); - } + out = seq_render_strip(scene, seq, cfra, + render_size, + seqrectx, seqrecty); break; case 1: if (i == 0) { - se->ibuf_comp = IMB_allocImBuf( + out = IMB_allocImBuf( (short)seqrectx, (short)seqrecty, 32, IB_rect, 0); - IMB_cache_limiter_insert(se->ibuf_comp); - IMB_cache_limiter_ref(se->ibuf_comp); - IMB_cache_limiter_touch(se->ibuf_comp); } break; case 0: - do_build_seq_recursively( - scene, seq, cfra, render_size, - seqrectx, seqrecty); - - if (!se->ibuf) { - se->ibuf = IMB_allocImBuf( - (short)seqrectx, (short)seqrecty, - 32, IB_rect, 0); - IMB_cache_limiter_insert(se->ibuf); - IMB_cache_limiter_ref(se->ibuf); - IMB_cache_limiter_touch(se->ibuf); - } if (i == 0) { - se->ibuf_comp = se->ibuf; - IMB_refImBuf(se->ibuf_comp); + out = seq_render_strip(scene, seq, cfra, + render_size, + seqrectx, seqrecty); } + break; } - - if (se->ibuf_comp) { + if (out) { break; } } + seq_stripelem_cache_put( + seq_arr[i], seqrectx, seqrecty, cfra, + SEQ_STRIPELEM_IBUF_COMP, out); + + i++; for (; i < count; i++) { Sequence * seq = seq_arr[i]; - struct SeqEffectHandle sh = get_sequence_blend(seq); - TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra); - TStripElem* se2 = give_tstripelem(seq_arr[i], cfra); - float facf = seq->blend_opacity / 100.0; - int swap_input = seq_must_swap_input_in_blend_mode(seq); - int early_out = seq_get_early_out_for_blend_mode(seq); + if (seq_get_early_out_for_blend_mode(seq) == 0) { + struct SeqEffectHandle sh = get_sequence_blend(seq); + ImBuf * ibuf1 = out; + ImBuf * ibuf2 = seq_render_strip(scene, seq, cfra, + render_size, + seqrectx, seqrecty); - switch (early_out) { - case 0: { - int x= se2->ibuf->x; - int y= se2->ibuf->y; + float facf = seq->blend_opacity / 100.0; + int swap_input + = seq_must_swap_input_in_blend_mode(seq); - if(se1->ibuf_comp == NULL) - continue; + int x= out->x; + int y= out->y; - if (se1->ibuf_comp->rect_float || - se2->ibuf->rect_float) { - se2->ibuf_comp = IMB_allocImBuf( + if (ibuf1->rect_float || ibuf2->rect_float) { + out = IMB_allocImBuf( (short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0); } else { - se2->ibuf_comp = IMB_allocImBuf( + out = IMB_allocImBuf( (short)seqrectx, (short)seqrecty, 32, IB_rect, 0); } - - if (!se1->ibuf_comp->rect_float && - se2->ibuf_comp->rect_float) { - IMB_float_from_rect_simple(se1->ibuf_comp); + if (!ibuf1->rect_float && out->rect_float) { + IMB_float_from_rect_simple(ibuf1); } - if (!se2->ibuf->rect_float && - se2->ibuf_comp->rect_float) { - IMB_float_from_rect_simple(se2->ibuf); + if (!ibuf2->rect_float && out->rect_float) { + IMB_float_from_rect_simple(ibuf2); } - if (!se1->ibuf_comp->rect && - !se2->ibuf_comp->rect_float) { - IMB_rect_from_float(se1->ibuf_comp); + if (!ibuf1->rect && !out->rect_float) { + IMB_rect_from_float(ibuf1); } - if (!se2->ibuf->rect && - !se2->ibuf_comp->rect_float) { - IMB_rect_from_float(se2->ibuf); + if (!ibuf2->rect && !out->rect_float) { + IMB_rect_from_float(ibuf2); } if (swap_input) { sh.execute(scene, seq, cfra, facf, facf, x, y, render_size, - se2->ibuf, se1->ibuf_comp, 0, - se2->ibuf_comp); + ibuf2, ibuf1, 0, out); } else { sh.execute(scene, seq, cfra, facf, facf, x, y, render_size, - se1->ibuf_comp, se2->ibuf, 0, - se2->ibuf_comp); + ibuf1, ibuf2, 0, out); } - - IMB_cache_limiter_insert(se2->ibuf_comp); - IMB_cache_limiter_ref(se2->ibuf_comp); - IMB_cache_limiter_touch(se2->ibuf_comp); - - IMB_cache_limiter_unref(se1->ibuf_comp); - IMB_cache_limiter_unref(se2->ibuf); - - break; + + IMB_freeImBuf(ibuf1); + IMB_freeImBuf(ibuf2); } - case 1: { - se2->ibuf_comp = se1->ibuf_comp; - if(se2->ibuf_comp) - IMB_refImBuf(se2->ibuf_comp); - break; - } - } - se = se2; + seq_stripelem_cache_put( + seq_arr[i], seqrectx, seqrecty, cfra, + SEQ_STRIPELEM_IBUF_COMP, out); } - return se; + return out; } /* * returned ImBuf is refed! - * you have to unref after usage! + * you have to free after usage! */ -static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size) +ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size) { Editing *ed= seq_give_editing(scene, FALSE); int count; ListBase *seqbasep; - TStripElem *se; - if(ed==NULL) return NULL; @@ -2840,64 +2337,19 @@ static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, i seqbasep= ed->seqbasep; } - se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size, rectx, recty); - - if(!se) { - return 0; - } - - check_limiter_refcount_comp("give_ibuf_seq_impl", se); - - return se->ibuf_comp; + return seq_render_strip_stack( + scene, seqbasep, cfra, chanshown, render_size, rectx, recty); } ImBuf *give_ibuf_seqbase(struct Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size, ListBase *seqbasep) { - TStripElem *se; - - se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size, rectx, recty); - - if(!se) { - return 0; - } - - check_limiter_refcount_comp("give_ibuf_seqbase", se); - - if (se->ibuf_comp) { - IMB_cache_limiter_unref(se->ibuf_comp); - } - - return se->ibuf_comp; + return seq_render_strip_stack(scene, seqbasep, cfra, chanshown, render_size, rectx, recty); } ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq) { - TStripElem* se; - - se = do_build_seq_recursively(scene, seq, cfra, render_size, rectx, recty); - - if(!se) { - return 0; - } - - check_limiter_refcount("give_ibuf_seq_direct", se); - - if (se->ibuf) { - IMB_cache_limiter_unref(se->ibuf); - } - - return se->ibuf; -} - -ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size) -{ - ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size); - - if (i) { - IMB_cache_limiter_unref(i); - } - return i; + return seq_render_strip(scene, seq, cfra, render_size, rectx, recty); } #if 0 @@ -3246,20 +2698,6 @@ ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int /* Functions to free imbuf and anim data on changes */ -static void free_imbuf_strip_elem(TStripElem *se) -{ - if(se->ibuf) { - IMB_freeImBuf(se->ibuf); - } - if(se->ibuf_comp) { - IMB_freeImBuf(se->ibuf_comp); - } - se->ibuf_comp = 0; - se->ibuf= 0; - se->ok= STRIPELEM_OK; - se->se1= se->se2= se->se3= 0; -} - static void free_anim_seq(Sequence *seq) { if(seq->anim) { @@ -3272,8 +2710,6 @@ void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage, int keep_file_handles) { Sequence *seq; - TStripElem *se; - int a; if (check_mem_usage) { /* Let the cache limitor take care of this (schlaile) */ @@ -3299,31 +2735,10 @@ void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage, } } + seq_stripelem_cache_cleanup(); for(seq= seqbase->first; seq; seq= seq->next) { if(seq->strip) { - for(a = 0, se = seq->strip->tstripdata; - a < seq->strip->len && se; a++, se++) { - free_imbuf_strip_elem(se); - } - for(a = 0, se = seq->strip->tstripdata_startstill; - a < seq->strip->startstill && se; a++, se++) { - free_imbuf_strip_elem(se); - } - for(a = 0, se = seq->strip->tstripdata_endstill; - a < seq->strip->endstill && se; a++, se++) { - free_imbuf_strip_elem(se); - } - if(seq->strip->ibuf_startstill) { - IMB_freeImBuf(seq->strip->ibuf_startstill); - seq->strip->ibuf_startstill = 0; - } - - if(seq->strip->ibuf_endstill) { - IMB_freeImBuf(seq->strip->ibuf_endstill); - seq->strip->ibuf_endstill = 0; - } - if(seq->type==SEQ_MOVIE && !keep_file_handles) free_anim_seq(seq); if(seq->type==SEQ_SPEED) { @@ -3345,8 +2760,7 @@ void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage, static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change) { Sequence *subseq; - int a, free_imbuf = 0; - TStripElem *se; + int free_imbuf = 0; /* recurs downwards to see if this seq depends on the changed seq */ @@ -3372,12 +2786,6 @@ static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *chan if(free_imbuf) { if(ibuf_change) { - se= seq->strip->tstripdata; - if (se) { - for(a=0; a<seq->len; a++, se++) - free_imbuf_strip_elem(se); - } - if(seq->type == SEQ_MOVIE) free_anim_seq(seq); if(seq->type == SEQ_SPEED) { @@ -3403,39 +2811,6 @@ void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_ch update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change); } -#if 0 // XXX from 2.4x, needs updating -void free_imbuf_seq() -{ - Scene * sce = G.main->scene.first; - while(sce) { - free_imbuf_seq_editing(sce->ed); - sce= sce->id.next; - } -} -#endif - -#if 0 // XXX old animation system -static void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo) -{ - /* force update of all sequences with this ipo, on ipo changes */ - Editing *ed= seq_give_editing(scene, FALSE); - Sequence *seq; - - if(ed==NULL) return; - - SEQ_BEGIN(ed, seq) { - if(seq->ipo == ipo) { - update_changed_seq_and_deps(scene, seq, 0, 1); - if(seq->type == SEQ_SPEED) { - sequence_effect_speed_rebuild_map(seq, 1); - } - free_proxy_seq(seq); - } - } - SEQ_END -} -#endif - /* seq funcs's for transforming internally notice the difference between start/end and left/right. diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 0d49f853a82..11881ab50d2 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -696,11 +696,11 @@ void set_special_seq_update(int val) void draw_image_seq(const bContext* C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs) { extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad); - struct ImBuf *ibuf; + struct ImBuf *ibuf = 0; + struct ImBuf *scope = 0; struct View2D *v2d = &ar->v2d; int rectx, recty; float viewrectx, viewrecty; - int free_ibuf = 0; static int recursive= 0; float render_size = 0.0; float proxy_size = 100.0; @@ -778,28 +778,29 @@ void draw_image_seq(const bContext* C, Scene *scene, ARegion *ar, SpaceSeq *sseq switch(sseq->mainb) { case SEQ_DRAW_IMG_IMBUF: if (sseq->zebra != 0) { - ibuf = make_zebra_view_from_ibuf(ibuf, sseq->zebra); - free_ibuf = 1; + scope = make_zebra_view_from_ibuf(ibuf, sseq->zebra); } break; case SEQ_DRAW_IMG_WAVEFORM: if ((sseq->flag & SEQ_DRAW_COLOR_SEPERATED) != 0) { - ibuf = make_sep_waveform_view_from_ibuf(ibuf); + scope = make_sep_waveform_view_from_ibuf(ibuf); } else { - ibuf = make_waveform_view_from_ibuf(ibuf); + scope = make_waveform_view_from_ibuf(ibuf); } - free_ibuf = 1; break; case SEQ_DRAW_IMG_VECTORSCOPE: - ibuf = make_vectorscope_view_from_ibuf(ibuf); - free_ibuf = 1; + scope = make_vectorscope_view_from_ibuf(ibuf); break; case SEQ_DRAW_IMG_HISTOGRAM: - ibuf = make_histogram_view_from_ibuf(ibuf); - free_ibuf = 1; + scope = make_histogram_view_from_ibuf(ibuf); break; } + if (scope) { + IMB_freeImBuf(ibuf); + ibuf = scope; + } + if(ibuf->rect_float && ibuf->rect==NULL) { IMB_rect_from_float(ibuf); } @@ -889,9 +890,7 @@ void draw_image_seq(const bContext* C, Scene *scene, ARegion *ar, SpaceSeq *sseq // if (sseq->flag & SEQ_DRAW_GPENCIL) // XXX draw_gpencil_2dimage(sa, ibuf); - if (free_ibuf) { - IMB_freeImBuf(ibuf); - } + IMB_freeImBuf(ibuf); /* draw grease-pencil (screen aligned) */ // if (sseq->flag & SEQ_DRAW_GPENCIL) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index f27698752f1..64932313259 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -2513,6 +2513,7 @@ static void do_render_seq(Render * re) free_imbuf_seq(re->scene, &ed->seqbase, TRUE, TRUE); } } + IMB_freeImBuf(ibuf); } else { /* render result is delivered empty in most cases, nevertheless we handle all cases */ |