General cleanup in sequencer:
authorPeter Schlaile <peter@schlaile.de>
Sun, 18 Nov 2007 17:39:30 +0000 (17:39 +0000)
committerPeter Schlaile <peter@schlaile.de>
Sun, 18 Nov 2007 17:39:30 +0000 (17:39 +0000)
- Seperated StripData into
  StripData
  TStripData
  where StripData holds only image-filenames and TStripData holds
  the working information needed for ImBuf caching.
  => Large drop in memory usage, if you used a lot of movie and meta strips.
  => Fixed bugs in "duplicate" on the way (imbufs where copied around without
     taking reference counting seriously...)
  => Code is much cleaner now
- Added defines for TStripData->ok
  Finally figured out, what the magic values ment and named them properly :)
- Got rid of Sequence->curelem.
  Reason: very bad idea(tm) for multi threading with more than one render
  thread. Still not there, but this was a real show stopper on the way.

source/blender/blenloader/intern/readfile.c
source/blender/include/BSE_sequence.h
source/blender/makesdna/DNA_sequence_types.h
source/blender/python/api2_2x/sceneSequence.c
source/blender/src/drawseq.c
source/blender/src/editseq.c
source/blender/src/sequence.c

index 75c746f7213c563a86283e15134a4c4bdc862e15..0903062461b3ec95477c5e335e8e46ebfb259482 100644 (file)
@@ -3204,7 +3204,6 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        Editing *ed;
        Sequence *seq;
        MetaStack *ms;
-       StripElem *se;
        int a;
 
        sce->theDag = NULL;
@@ -3240,8 +3239,6 @@ static void direct_link_scene(FileData *fd, Scene *sce)
                        /* a patch: after introduction of effects with 3 input strips */
                        if(seq->seq3==0) seq->seq3= seq->seq2;
 
-                       seq->curelem= 0;
-
                        seq->plugin= newdataadr(fd, seq->plugin);
                        seq->effectdata= newdataadr(fd, seq->effectdata);
                        
@@ -3252,59 +3249,17 @@ static void direct_link_scene(FileData *fd, Scene *sce)
                        seq->strip= newdataadr(fd, seq->strip);
                        if(seq->strip && seq->strip->done==0) {
                                seq->strip->done= 1;
-
-                               /* standard: strips from effects/metas are not written, but are mallocced */
-
-                               if(seq->type==SEQ_IMAGE) {
-                                       seq->strip->stripdata= newdataadr(fd, seq->strip->stripdata);
-                                       se= seq->strip->stripdata;
-                                       if(se) {
-                                               for(a=0; a<seq->strip->len; a++, se++) {
-                                                       se->ok= 1;
-                                                       se->ibuf= 0;
-                                               }
-                                       }
-                               }
-                               else if(seq->type==SEQ_MOVIE) {
-                                       /* only first stripelem is in file */
-                                       se= newdataadr(fd, seq->strip->stripdata);
-
-                                       if(se) {
-                                               seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
-                                               *seq->strip->stripdata= *se;
-                                               MEM_freeN(se);
-
-                                               se= seq->strip->stripdata;
-
-                                               for(a=0; a<seq->strip->len; a++, se++) {
-                                                       se->ok= 1;
-                                                       se->ibuf= 0;
-                                                       se->nr= a + 1;
-                                               }
-                                       }
-                               }
-                               else if(seq->type==SEQ_RAM_SOUND
-                                       || seq->type == SEQ_HD_SOUND) {
-                                       /* only first stripelem is in file */
-                                       se= newdataadr(fd, seq->strip->stripdata);
-
-                                       if(se) {
-                                               seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
-                                               *seq->strip->stripdata= *se;
-                                               MEM_freeN(se);
-
-                                               se= seq->strip->stripdata;
-
-                                               for(a=0; a<seq->strip->len; a++, se++) {
-                                                       se->ok= 2; /* why? */
-                                                       se->ibuf= 0;
-                                                       se->nr= a + 1;
-                                               }
-                                       }
+                               seq->strip->tstripdata = 0;
+
+                               if(seq->type == SEQ_IMAGE ||
+                                  seq->type == SEQ_MOVIE ||
+                                  seq->type == SEQ_RAM_SOUND ||
+                                  seq->type == SEQ_HD_SOUND) {
+                                       seq->strip->stripdata = newdataadr(
+                                               fd, seq->strip->stripdata);
+                               } else {
+                                       seq->strip->stripdata = 0;
                                }
-                               else if(seq->len>0)
-                                       seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
-
                        }
                }
                END_SEQ
index ff79d417537ac6f624528a1b3f13cb4e1806cba2..fdf584b38f40daa64ef57296b3d8a01d0e498221 100644 (file)
@@ -37,6 +37,7 @@
 
 struct PluginSeq;
 struct StripElem;
+struct TStripElem;
 struct Strip;
 struct Sequence;
 struct ListBase;
@@ -44,9 +45,9 @@ struct Editing;
 struct ImBuf;
 struct Scene;
 
-void free_stripdata(int len, struct StripElem *se);
+void free_tstripdata(int len, struct TStripElem *se);
 void free_strip(struct Strip *strip);
-void new_stripdata(struct Sequence *seq);
+void new_tstripdata(struct Sequence *seq);
 void free_sequence(struct Sequence *seq);
 void build_seqar(struct ListBase *seqbase, struct Sequence  ***seqar, int *totseq);
 void free_editing(struct Editing *ed);
@@ -57,17 +58,20 @@ void clear_scene_in_allseqs(struct Scene *sce);
 
 int evaluate_seq_frame(int cfra);
 struct StripElem *give_stripelem(struct Sequence *seq, int cfra);
+struct TStripElem *give_tstripelem(struct Sequence *seq, int cfra);
 void set_meta_stripdata(struct Sequence *seqm);
 struct ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chansel); 
 /* chansel: render this channel. Default=0 (renders end result)*/
+struct ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra,
+                                  struct Sequence * seq);
 
 /* sequence prefetch API */
 void seq_start_threads();
 void seq_stop_threads();
 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown);
 void seq_wait_for_prefetch_ready();
-struct ImBuf * give_ibuf_threaded(int rectx, int recty, int cfra, 
-                                 int chanshown);
+struct ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, 
+                                     int chanshown);
 
 
 void free_imbuf_seq_except(int cfra);
index 839d804fbea98dba880a06a4633bddb6c1e26c04..bc574228cca6333721c0cd6b3478d4ef0e331433 100644 (file)
@@ -46,12 +46,15 @@ struct Scene;
 
 typedef struct StripElem {
        char name[80];
+} StripElem;
+
+typedef struct TStripElem {
        struct ImBuf *ibuf;
-       struct StripElem *se1, *se2, *se3;
+       struct TStripElem *se1, *se2, *se3;
        short ok;
        short pad;
        int nr;
-} StripElem;
+} TStripElem;
 
 typedef struct Strip {
        struct Strip *next, *prev;
@@ -59,6 +62,7 @@ typedef struct Strip {
        StripElem *stripdata;
        char dir[160];
        int orx, ory;
+       TStripElem *tstripdata;
 } Strip;
 
 
@@ -87,7 +91,6 @@ typedef struct PluginSeq {
 /* WATCH IT: first part identical to ID (for use in ipo's) */
 
 typedef struct Sequence {
-
        struct Sequence *next, *prev;
        void *tmp; /* tmp var for copying, and tagging for linked selection */
        void *lib; /* needed (to be like ipo), else it will raise libdata warnings, this should never be used */
@@ -104,7 +107,8 @@ typedef struct Sequence {
        int sfra;               /* starting frame according to the timeline of the scene. */
 
        Strip *strip;
-       StripElem *curelem;     /* reference the current frame - value from give_stripelem */
+       int pad2;
+       int pad3;
 
        struct Ipo *ipo;
        struct Scene *scene;
@@ -234,6 +238,9 @@ typedef struct SpeedControlVars {
 #define SEQ_COLOR               28
 #define SEQ_SPEED               29
 
+#define STRIPELEM_FAILED       0
+#define STRIPELEM_OK           1
+#define STRIPELEM_META         2
 
 #endif
 
index 6ddaaf345c39b3a2a89c73df55ea63ee21991e20..fee1bde149cf048979387ab875d28b515f14c2fd 100644 (file)
@@ -156,7 +156,6 @@ static PyObject *NewSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
                for(a=0; a<seq->len; a++) {
                        name = PyString_AsString(PyList_GetItem( list, a ));
                        strncpy(se->name, name, FILE_MAXFILE-1);
-                       se->ok= 1;
                        se++;
                }               
                
@@ -179,16 +178,10 @@ static PyObject *NewSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
                strip->len= totframe;
                strip->us= 1;
                strncpy(strip->dir, sound->name, FILE_MAXDIR-1);
-               strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
+               strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem");
 
                /* name sound in first strip */
                strncpy(se->name, sound->name, FILE_MAXFILE-1);
-
-               for(a=1; a<=totframe; a++, se++) {
-                       se->ok= 2; /* why? */
-                       se->ibuf= 0;
-                       se->nr= a;
-               }
                
        } else if (BPy_Scene_Check(py_data)) {
                /* scene */
@@ -205,8 +198,6 @@ static PyObject *NewSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
                        sizeof(seq->name) - 2);
                strip->len= seq->len;
                strip->us= 1;
-               if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
-               
        } else {
                /* movie, pydata is a path to a movie file */
                char *name = PyString_AsString ( py_data );
index 36a857abfe15d15d60364d61a0f34d4254d2081d..770063536404b5e124a12c7eac3298f6274ff201 100644 (file)
@@ -775,7 +775,6 @@ void set_special_seq_update(int val)
 static void draw_image_seq(ScrArea *sa)
 {
        SpaceSeq *sseq;
-       StripElem *se;
        struct ImBuf *ibuf;
        int x1, y1, rectx, recty;
        int free_ibuf = 0;
@@ -800,10 +799,18 @@ static void draw_image_seq(ScrArea *sa)
                return;
        else {
                recursive= 1;
-               if (!U.prefetchframes || (G.f & G_PLAYANIM) == 0) {
-                       ibuf= (ImBuf *)give_ibuf_seq(rectx, recty, (G.scene->r.cfra), sseq->chanshown);
+               if (special_seq_update) {
+                       ibuf= give_ibuf_seq_direct(
+                               rectx, recty, (G.scene->r.cfra),
+                               special_seq_update);
+               } else if (!U.prefetchframes || (G.f & G_PLAYANIM) == 0) {
+                       ibuf= (ImBuf *)give_ibuf_seq(
+                               rectx, recty, (G.scene->r.cfra), 
+                               sseq->chanshown);
                } else {
-                       ibuf= (ImBuf *)give_ibuf_threaded(rectx, recty, (G.scene->r.cfra), sseq->chanshown);
+                       ibuf= (ImBuf *)give_ibuf_seq_threaded(
+                               rectx, recty, (G.scene->r.cfra), 
+                               sseq->chanshown);
                }
                recursive= 0;
                
@@ -815,16 +822,6 @@ static void draw_image_seq(ScrArea *sa)
                }
        }
        
-       if(special_seq_update) {
-               se = special_seq_update->curelem;
-               if(se) {
-                       if(se->ok==2) {
-                               if(se->se1)
-                                       ibuf= se->se1->ibuf;
-                       }
-                       else ibuf= se->ibuf;
-               }
-       }
        if(ibuf==NULL) 
                return;
        if(ibuf->rect_float && ibuf->rect==NULL)
@@ -862,7 +859,7 @@ static void draw_image_seq(ScrArea *sa)
 
        if (free_ibuf) {
                IMB_freeImBuf(ibuf);
-       }
+       } 
 
        sa->win_swap= WIN_BACK_OK;
 }
@@ -917,7 +914,7 @@ static void draw_extra_seqinfo(void)
        if(last_seq->type==SEQ_IMAGE) {
                if (last_seq->len > 1) {
                        /* CURRENT */
-                       se= (StripElem *)give_stripelem(last_seq,  (G.scene->r.cfra));
+                       se= give_stripelem(last_seq,  (G.scene->r.cfra));
                        if(se) {
                                sprintf(str, "Cur: %s", se->name);
                                glRasterPos3f(xco,  yco, 0.0);
@@ -966,7 +963,7 @@ static void draw_extra_seqinfo(void)
                BMF_DrawString(G.font, str);
        }
        else if(last_seq->type==SEQ_SCENE) {
-               se= (StripElem *)give_stripelem(last_seq,  (G.scene->r.cfra));
+               TStripElem * se= give_tstripelem(last_seq,  (G.scene->r.cfra));
                if(se && last_seq->scene) {
                        sprintf(str, "Cur: %d  First: %d  Last: %d", last_seq->sfra+se->nr, last_seq->sfra, last_seq->sfra+last_seq->len-1); 
                        glRasterPos3f(xco,  yco, 0.0);
index 8f328afc222012199050600eb0e865ab7fa9c3aa..8565a302f45a62a712609fa5d14cd81032e61ec6 100644 (file)
@@ -985,7 +985,6 @@ static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int
                if(sfile->filelist[a].flags & ACTIVE) {
                        if( (sfile->filelist[a].type & S_IFDIR)==0 ) {
                                strncpy(se->name, sfile->filelist[a].relname, FILE_MAXFILE-1);
-                               se->ok= 1;
                                se++;
                        }
                }
@@ -993,7 +992,6 @@ static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int
        /* no selected file: */
        if(totsel==1 && se==strip->stripdata) {
                strncpy(se->name, sfile->file, FILE_MAXFILE-1);
-               se->ok= 1;
        }
 
        /* last active name */
@@ -1010,7 +1008,7 @@ static int sfile_to_mv_sequence_load(SpaceFile *sfile, int cfra,
        struct anim *anim;
        Strip *strip;
        StripElem *se;
-       int totframe, a;
+       int totframe;
        char name[160], rel[160];
        char str[FILE_MAXDIR+FILE_MAXFILE];
 
@@ -1054,7 +1052,7 @@ static int sfile_to_mv_sequence_load(SpaceFile *sfile, int cfra,
        strip->len= totframe;
        strip->us= 1;
        strncpy(strip->dir, name, FILE_MAXDIR-1);
-       strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
+       strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem");
 
        /* name movie in first strip */
        if(index<0)
@@ -1062,11 +1060,6 @@ static int sfile_to_mv_sequence_load(SpaceFile *sfile, int cfra,
        else
                strncpy(se->name, sfile->filelist[index].relname, FILE_MAXFILE-1);
 
-       for(a=1; a<=totframe; a++, se++) {
-               se->ok= 1;
-               se->nr= a;
-       }
-
        /* last active name */
        strncpy(last_imagename, seq->strip->dir, FILE_MAXDIR-1);
        return(cfra+totframe);
@@ -1111,7 +1104,6 @@ static Sequence *sfile_to_ramsnd_sequence(SpaceFile *sfile,
        Strip *strip;
        StripElem *se;
        double totframe;
-       int a;
        char name[160], rel[160];
        char str[256];
 
@@ -1157,17 +1149,11 @@ static Sequence *sfile_to_ramsnd_sequence(SpaceFile *sfile,
        strip->len= totframe;
        strip->us= 1;
        strncpy(strip->dir, name, FILE_MAXDIR-1);
-       strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
+       strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem");
 
        /* name sound in first strip */
        strncpy(se->name, sfile->file, FILE_MAXFILE-1);
 
-       for(a=1; a<=totframe; a++, se++) {
-               se->ok= 2; /* why? */
-               se->ibuf= 0;
-               se->nr= a;
-       }
-
        /* last active name */
        strncpy(last_sounddir, seq->strip->dir, FILE_MAXDIR-1);
 
@@ -1181,7 +1167,7 @@ static int sfile_to_hdsnd_sequence_load(SpaceFile *sfile, int cfra,
        struct hdaudio *hdaudio;
        Strip *strip;
        StripElem *se;
-       int totframe, a;
+       int totframe;
        char name[160], rel[160];
        char str[FILE_MAXDIR+FILE_MAXFILE];
 
@@ -1224,7 +1210,7 @@ static int sfile_to_hdsnd_sequence_load(SpaceFile *sfile, int cfra,
        strip->len= totframe;
        strip->us= 1;
        strncpy(strip->dir, name, FILE_MAXDIR-1);
-       strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
+       strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem");
 
        /* name movie in first strip */
        if(index<0)
@@ -1232,12 +1218,6 @@ static int sfile_to_hdsnd_sequence_load(SpaceFile *sfile, int cfra,
        else
                strncpy(se->name, sfile->filelist[index].relname, FILE_MAXFILE-1);
 
-       for(a=1; a<=totframe; a++, se++) {
-               se->ok= 2;
-               se->ibuf = 0;
-               se->nr= a;
-       }
-
        /* last active name */
        strncpy(last_sounddir, seq->strip->dir, FILE_MAXDIR-1);
        return(cfra+totframe);
@@ -2013,7 +1993,7 @@ void change_sequence(void)
                        last_seq->sfra= sce->r.sfra;
                        
                        /* bad code to change seq->len? update_changed_seq_and_deps() expects the strip->len to be OK */
-                       new_stripdata(last_seq);
+                       new_tstripdata(last_seq);
                        
                        update_changed_seq_and_deps(last_seq, 1, 1);
 
@@ -2169,25 +2149,23 @@ void del_seq(void)
 
 static void recurs_dupli_seq(ListBase *old, ListBase *new)
 {
-       Sequence *seq, *seqn;
+       Sequence *seq;
+       Sequence *seqn = 0;
        Sequence *last_seq = get_last_seq();
-       StripElem *se;
-       int a;
 
        seq= old->first;
 
        while(seq) {
                seq->tmp= NULL;
                if(seq->flag & SELECT) {
-
                        if(seq->type==SEQ_META) {
                                seqn= MEM_dupallocN(seq);
                                seq->tmp= seqn;
                                BLI_addtail(new, seqn);
 
                                seqn->strip= MEM_dupallocN(seq->strip);
-
-                               if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
+                               seqn->strip->stripdata = 0;
+                               seqn->strip->tstripdata = 0;
 
                                seq->flag &= SEQ_DESEL;
                                seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
@@ -2202,8 +2180,8 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
                                BLI_addtail(new, seqn);
 
                                seqn->strip= MEM_dupallocN(seq->strip);
-
-                               if(seq->len>0) seqn->strip->stripdata = MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
+                               seqn->strip->stripdata = 0;
+                               seqn->strip->tstripdata = 0;
 
                                seq->flag &= SEQ_DESEL;
                                seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
@@ -2214,20 +2192,11 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
                                BLI_addtail(new, seqn);
 
                                seqn->strip= MEM_dupallocN(seq->strip);
+                               seqn->strip->stripdata = 
+                                       MEM_dupallocN(seq->strip->stripdata);
+                               seqn->strip->tstripdata = 0;
                                seqn->anim= 0;
 
-                               if(seqn->len>0) {
-                                       seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
-                                       /* copy first elem */
-                                       *seqn->strip->stripdata= *seq->strip->stripdata;
-                                       se= seqn->strip->stripdata;
-                                       a= seq->len;
-                                       while(a--) {
-                                               se->ok= 1;
-                                               se++;
-                                       }
-                               }
-
                                seq->flag &= SEQ_DESEL;
                                seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
                        }
@@ -2237,22 +2206,14 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
                                BLI_addtail(new, seqn);
 
                                seqn->strip= MEM_dupallocN(seq->strip);
+                               seqn->strip->stripdata = 
+                                       MEM_dupallocN(seq->strip->stripdata);
+                               seqn->strip->tstripdata = 0;
+
                                seqn->anim= 0;
                                seqn->sound->id.us++;
                                if(seqn->ipo) seqn->ipo->id.us++;
 
-                               if(seqn->len>0) {
-                                       seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
-                                       /* copy first elem */
-                                       *seqn->strip->stripdata= *seq->strip->stripdata;
-                                       se= seqn->strip->stripdata;
-                                       a= seq->len;
-                                       while(a--) {
-                                               se->ok= 1;
-                                               se++;
-                                       }
-                               }
-
                                seq->flag &= SEQ_DESEL;
                                seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
                        }
@@ -2262,36 +2223,29 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
                                BLI_addtail(new, seqn);
 
                                seqn->strip= MEM_dupallocN(seq->strip);
+                               seqn->strip->stripdata = 
+                                       MEM_dupallocN(seq->strip->stripdata);
+                               seqn->strip->tstripdata = 0;
                                seqn->anim= 0;
                                seqn->hdaudio = 0;
                                if(seqn->ipo) seqn->ipo->id.us++;
 
-                               if(seqn->len>0) {
-                                       seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
-                                       /* copy first elem */
-                                       *seqn->strip->stripdata= *seq->strip->stripdata;
-                                       se= seqn->strip->stripdata;
-                                       a= seq->len;
-                                       while(a--) {
-                                               se->ok= 1;
-                                               se++;
-                                       }
-                               }
-
                                seq->flag &= SEQ_DESEL;
                                seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
-                       }
-                       else if(seq->type < SEQ_EFFECT) {
+                       } else if(seq->type == SEQ_IMAGE) {
                                seqn= MEM_dupallocN(seq);
                                seq->tmp= seqn;
                                BLI_addtail(new, seqn);
 
-                               seqn->strip->us++;
+                               seqn->strip= MEM_dupallocN(seq->strip);
+                               seqn->strip->stripdata = 
+                                       MEM_dupallocN(seq->strip->stripdata);
+                               seqn->strip->tstripdata = 0;
+
                                seq->flag &= SEQ_DESEL;
 
                                seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
-                       }
-                       else {
+                       } else if(seq->type >= SEQ_EFFECT) {
                                seqn= MEM_dupallocN(seq);
                                seq->tmp= seqn;
                                BLI_addtail(new, seqn);
@@ -2310,12 +2264,16 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
                                }
 
                                seqn->strip= MEM_dupallocN(seq->strip);
-
-                               if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
+                               seqn->strip->stripdata = 0;
+                               seqn->strip->tstripdata = 0;
 
                                seq->flag &= SEQ_DESEL;
                                
                                seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
+                       } else {
+                               fprintf(stderr, "Aiiiiekkk! sequence type not "
+                                       "handled in duplicate!\nExpect a crash"
+                                       " now...\n");
                        }
                        if (seq == last_seq) {
                                set_last_seq(seqn);
@@ -2564,7 +2522,7 @@ void make_meta(void)
        seqm->strip= MEM_callocN(sizeof(Strip), "metastrip");
        seqm->strip->len= seqm->len;
        seqm->strip->us= 1;
-       if(seqm->len) seqm->strip->stripdata= MEM_callocN(seqm->len*sizeof(StripElem), "metastripdata");
+
        set_meta_stripdata(seqm);
 
        BIF_undo_push("Make Meta Strip, Sequencer");
@@ -3496,8 +3454,6 @@ void seq_separate_images(void)
                                /* new stripdata */
                                strip_new->stripdata= se_new= MEM_callocN(sizeof(StripElem)*1, "stripelem");
                                strncpy(se_new->name, se->name, FILE_MAXFILE-1);
-                               se_new->ok= 1;
-                               
                                calc_sequence(seq_new);
                                seq_new->flag &= ~SEQ_OVERLAP;
                                if (test_overlap_seq(seq_new)) {
index e93cc1b107550885cf65b62ff537cb505bc8849d..1e0026cde935c2503ab99af8841c8c4d229252fc 100644 (file)
 
 int seqrectx, seqrecty;
 
-void free_stripdata(int len, StripElem *se)
+void free_tstripdata(int len, TStripElem *se)
 {
-       StripElem *seo;
+       TStripElem *seo;
        int a;
 
        seo= se;
+       if (!se) {
+               return;
+       }
 
        for(a=0; a<len; a++, se++) {
-               if(se->ibuf && se->ok!=2) {
+               if(se->ibuf && se->ok != STRIPELEM_META) {
                        IMB_freeImBuf(se->ibuf);
                        se->ibuf = 0;
                }
@@ -103,18 +106,20 @@ void free_strip(Strip *strip)
        }
 
        if(strip->stripdata) {
-               free_stripdata(strip->len, strip->stripdata);
+               MEM_freeN(strip->stripdata);
        }
+
+       free_tstripdata(strip->len, strip->tstripdata);
+
        MEM_freeN(strip);
 }
 
-void new_stripdata(Sequence *seq)
+void new_tstripdata(Sequence *seq)
 {
        if(seq->strip) {
-               if(seq->strip->stripdata) free_stripdata(seq->strip->len, seq->strip->stripdata);
-               seq->strip->stripdata= 0;
+               free_tstripdata(seq->strip->len, seq->strip->tstripdata);
+               seq->strip->tstripdata= 0;
                seq->strip->len= seq->len;
-               if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelems");
        }
 }
 
@@ -265,7 +270,7 @@ void calc_sequence(Sequence *seq)
                }
 
                if(seq->strip && seq->len!=seq->strip->len) {
-                       new_stripdata(seq);
+                       new_tstripdata(seq);
                }
 
        }
@@ -284,7 +289,7 @@ void calc_sequence(Sequence *seq)
                                seq->len= max-min;
 
                                if(seq->strip && seq->len!=seq->strip->len) {
-                                       new_stripdata(seq);
+                                       new_tstripdata(seq);
                                }
                        }
                }
@@ -426,9 +431,9 @@ static void multibuf(ImBuf *ibuf, float fmul)
        }
 }
 
-static void do_effect(int cfra, Sequence *seq, StripElem *se)
+static void do_effect(int cfra, Sequence *seq, TStripElem *se)
 {
-       StripElem *se1, *se2, *se3;
+       TStripElem *se1, *se2, *se3;
        float fac, facf;
        int x, y;
        int early_out;
@@ -464,14 +469,13 @@ static void do_effect(int cfra, Sequence *seq, StripElem *se)
                        return;
                }
 
-               /* if metastrip: other se's */
-               if(se->se1->ok==2) se1= se->se1->se1;
+               if(se->se1->ok == STRIPELEM_META) se1= se->se1->se1;
                else se1= se->se1;
                
-               if(se->se2->ok==2) se2= se->se2->se1;
+               if(se->se2->ok == STRIPELEM_META) se2= se->se2->se1;
                else se2= se->se2;
                
-               if(se->se3->ok==2) se3= se->se3->se1;
+               if(se->se3->ok == STRIPELEM_META) se3= se->se3->se1;
                else se3= se->se3;
 
                if (   (se1==0 || se2==0 || se3==0)
@@ -487,8 +491,7 @@ static void do_effect(int cfra, Sequence *seq, StripElem *se)
                        return;
                }
 
-               /* if metastrip: other se's */
-               if(se->se1->ok==2) se1= se->se1->se1;
+               if(se->se1->ok == STRIPELEM_META) se1= se->se1->se1;
                else se1= se->se1;
 
                if (se1 == 0 || se1->ibuf == 0) {
@@ -508,8 +511,7 @@ static void do_effect(int cfra, Sequence *seq, StripElem *se)
                        return;
                }
 
-               /* if metastrip: other se's */
-               if(se->se2->ok==2) se2= se->se2->se1;
+               if(se->se2->ok == STRIPELEM_META) se2= se->se2->se1;
                else se2= se->se2;
 
                if (se2 == 0 || se2->ibuf == 0) {
@@ -548,17 +550,11 @@ static void do_effect(int cfra, Sequence *seq, StripElem *se)
                   se->ibuf);
 }
 
-StripElem *give_stripelem(Sequence *seq, int cfra)
+static int give_stripelem_index(Sequence *seq, int cfra)
 {
-       Strip *strip;
-       StripElem *se;
        int nr;
 
-       strip= seq->strip;
-       se= strip->stripdata;
-
-       if(se==0) return 0;
-       if(seq->startdisp >cfra || seq->enddisp <= cfra) return 0;
+       if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1;
 
        if(seq->flag&SEQ_REVERSE_FRAMES)        {       
                /*reverse frame in this sequence */
@@ -574,13 +570,51 @@ StripElem *give_stripelem(Sequence *seq, int cfra)
        if (seq->strobe > 1.0) {
                nr -= (int)fmod((double)nr, (double)seq->strobe);
        }
+
+       return nr;
+}
+
+TStripElem *give_tstripelem(Sequence *seq, int cfra)
+{
+       TStripElem *se;
+       int nr;
+
+       se = seq->strip->tstripdata;
+       if (se == 0 && seq->len > 0) {
+               int i;
+               se = seq->strip->tstripdata = MEM_callocN(
+                       seq->len*sizeof(TStripElem), "tstripelems");
+               for (i = 0; i < seq->len; i++) {
+                       se[i].ok = STRIPELEM_OK;
+               }
+       }
+       nr = give_stripelem_index(seq, cfra);
+
+       if (nr == -1) return 0;
+       if (se == 0) return 0;
        
-       se+= nr; /* don't get confused by the increment, this is the same as strip->stripdata[nr], which works on some compilers...*/
+       se+= nr; 
        se->nr= nr;
        
        return se;
 }
 
+StripElem *give_stripelem(Sequence *seq, int cfra)
+{
+       StripElem *se;
+       int nr;
+
+       se = seq->strip->stripdata;
+       nr = give_stripelem_index(seq, cfra);
+
+       if (nr == -1) return 0;
+       if (se == 0) return 0;
+
+       se += nr; 
+       
+       return se;
+}
+
 static int evaluate_seq_frame_gen(
        Sequence ** seq_arr, ListBase *seqbase, int cfra)
 {
@@ -664,36 +698,57 @@ static Sequence * get_shown_seq_from_metastrip(Sequence * seqm, int cfra)
 void set_meta_stripdata(Sequence *seqm)
 {
        Sequence *seq;
-       StripElem *se;
+       TStripElem *se;
        int a, cfra;
 
+       se= seqm->strip->tstripdata;
+
+       if (se == 0 && seqm->len > 0) {
+               int i;
+               se = seqm->strip->tstripdata = MEM_callocN(
+                       seqm->len*sizeof(TStripElem), "tstripelems");
+               for (i = 0; i < seqm->len; i++) {
+                       se[i].ok = STRIPELEM_META;
+               }
+       }
+
        /* sets all ->se1 pointers in stripdata, to read the ibuf from it */
 
-       se= seqm->strip->stripdata;
        for(a=0; a<seqm->len; a++, se++) {
                cfra= a+seqm->start;
                seq = get_shown_seq_from_metastrip(seqm, cfra);
                if (seq) {
-                       se->se1= give_stripelem(seq, cfra);
+                       se->se1= give_tstripelem(seq, cfra);
                } else { 
                        se->se1= 0;
                }
        }
 }
 
-static void do_build_seq_ibuf(Sequence * seq, int cfra)
+static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra);
+
+static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra)
 {
-       StripElem *se = seq->curelem;
        char name[FILE_MAXDIR+FILE_MAXFILE];
 
        if(seq->type == SEQ_META) {
-               se->ok= 2;
-               if(se->se1==0) set_meta_stripdata(seq);
+               if(seq->seqbase.first) {
+                       Sequence * seqmshown= 
+                               get_shown_seq_from_metastrip(seq, cfra);
+                       if (seqmshown) {
+                               if(cfra< seq->start) 
+                                       do_build_seq_recursively(seqmshown, seq->start);
+                               else if(cfra> seq->start+seq->len-1) 
+                                       do_build_seq_recursively(seqmshown, seq->start + seq->len-1);
+                               else do_build_seq_recursively(seqmshown, cfra);
+                       }
+               }
+
+               se->ok = STRIPELEM_META;
+               if(se->se1 == 0) set_meta_stripdata(seq);
                if(se->se1) {
                        se->ibuf= se->se1->ibuf;
                }
-       } else if(seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) {
-               se->ok= 2;
        } else if(seq->type & SEQ_EFFECT) {
                        
                /* test if image is too small or discarded from cache: reload */
@@ -706,22 +761,13 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra)
                        
                /* should the effect be recalculated? */
                
-               if(se->ibuf==0 
-                  || (seq->seq1 && se->se1 != seq->seq1->curelem) 
-                  || (seq->seq2 && se->se2 != seq->seq2->curelem) 
-                  || (seq->seq3 && se->se3 != seq->seq3->curelem)) {
-                       if (seq->seq1) se->se1= seq->seq1->curelem;
-                       if (seq->seq2) se->se2= seq->seq2->curelem;
-                       if (seq->seq3) se->se3= seq->seq3->curelem;
-                       
-                       if(se->ibuf==NULL) {
-                               /* if one of two first 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->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(se->ibuf == 0) {
+                       /* if one of two first 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->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(cfra, seq, se);
                }
@@ -743,27 +789,30 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra)
                        if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty || !(se->ibuf->rect || se->ibuf->rect_float)) {
                                IMB_freeImBuf(se->ibuf);
                                se->ibuf= 0;
-                               se->ok= 1;
+                               se->ok= STRIPELEM_OK;
                        }
                }
                
                if(seq->type==SEQ_IMAGE) {
-                       if(se->ok && se->ibuf==0) {
+                       if(se->ok == STRIPELEM_OK && se->ibuf==0) {
+                               StripElem * s_elem = give_stripelem(seq, cfra);
+
                                /* if playanim or render: 
                                   no waitcursor */
                                if((G.f & G_PLAYANIM)==0) 
                                        waitcursor(1);
                                
                                strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
-                               strncat(name, se->name, FILE_MAXFILE);
+                               strncat(name, s_elem->name, FILE_MAXFILE);
                                BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
                                se->ibuf= IMB_loadiffname(name, IB_rect);
                                
                                if((G.f & G_PLAYANIM)==0) 
                                        waitcursor(0);
                                
-                               if(se->ibuf==0) se->ok= 0;
-                               else {
+                               if(se->ibuf == 0) {
+                                       se->ok = STRIPELEM_FAILED;
+                               } else {
                                        if(seq->flag & SEQ_MAKE_PREMUL) {
                                                if(se->ibuf->depth==32 && se->ibuf->zbuf==0) converttopremul(se->ibuf);
                                        }
@@ -778,7 +827,7 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra)
                        }
                }
                else if(seq->type==SEQ_MOVIE) {
-                       if(se->ok && se->ibuf==0) {
+                       if(se->ok == STRIPELEM_OK && se->ibuf==0) {
                                if(seq->anim==0) {
                                        strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
                                        strncat(name, seq->strip->stripdata->name, FILE_MAXFILE-1);
@@ -791,8 +840,9 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra)
                                        se->ibuf = IMB_anim_absolute(seq->anim, se->nr);
                                }
                                
-                               if(se->ibuf==0) se->ok= 0;
-                               else {
+                               if(se->ibuf == 0) {
+                                       se->ok = STRIPELEM_FAILED;
+                               } else {
                                        if(seq->flag & SEQ_MAKE_PREMUL) {
                                                if(se->ibuf->depth==32) converttopremul(se->ibuf);
                                        }
@@ -893,21 +943,23 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra)
                        
                }
        }
-       if (se->ibuf) {
+       if (se->ibuf && seq->type != SEQ_META) {
                IMB_cache_limiter_insert(se->ibuf);
                IMB_cache_limiter_ref(se->ibuf);
                IMB_cache_limiter_touch(se->ibuf);
        }
 }
 
-static void do_build_seq_recursively(Sequence * seq, int cfra);
-
-static void do_effect_seq_recursively(int cfra, Sequence * seq, StripElem *se)
+static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra)
 {
        float fac, facf;
        struct SeqEffectHandle sh = get_sequence_effect(seq);
        int early_out;
 
+       se->se1 = 0;
+       se->se2 = 0;
+       se->se3 = 0;
+
        if(seq->ipo && seq->ipo->curve.first) {
                do_seq_ipo(seq);
                fac= seq->facf0;
@@ -924,79 +976,50 @@ static void do_effect_seq_recursively(int cfra, Sequence * seq, StripElem *se)
                /* no input needed */
                break;
        case 0:
-               do_build_seq_recursively(seq->seq1, cfra);
-               do_build_seq_recursively(seq->seq2, cfra);
+               se->se1 = do_build_seq_recursively(seq->seq1, cfra);
+               se->se2 = do_build_seq_recursively(seq->seq2, cfra);
                if (seq->seq3) {
-                       do_build_seq_recursively(seq->seq3, cfra);
+                       se->se3 = do_build_seq_recursively(seq->seq3, cfra);
                }
                break;
        case 1:
-               do_build_seq_recursively(seq->seq1, cfra);
+               se->se1 = do_build_seq_recursively(seq->seq1, cfra);
                break;
        case 2:
-               do_build_seq_recursively(seq->seq2, cfra);
+               se->se2 = do_build_seq_recursively(seq->seq2, cfra);
                break;
        }
 
 
-       do_build_seq_ibuf(seq, cfra);
+       do_build_seq_ibuf(seq, se, cfra);
 
        /* children are not needed anymore ... */
 
-       switch (early_out) {
-       case 0:
-               if (seq->seq1->curelem && seq->seq1->curelem->ibuf)
-                       IMB_cache_limiter_unref(seq->seq1->curelem->ibuf);
-               if (seq->seq2->curelem && seq->seq2->curelem->ibuf)
-                       IMB_cache_limiter_unref(seq->seq2->curelem->ibuf);
-               if (seq->seq3) {
-                       if (seq->seq3->curelem && seq->seq3->curelem->ibuf)
-                               IMB_cache_limiter_unref(
-                                       seq->seq3->curelem->ibuf);
-               }
-               break;
-       case 1:
-               if (seq->seq1->curelem && seq->seq1->curelem->ibuf)
-                       IMB_cache_limiter_unref(seq->seq1->curelem->ibuf);
-               break;
-       case 2:
-               if (seq->seq2->curelem && seq->seq2->curelem->ibuf)
-                       IMB_cache_limiter_unref(seq->seq2->curelem->ibuf);
-               break;
+       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);
        }
 }
 
-static void do_build_seq_recursively_impl(Sequence * seq, int cfra)
+static TStripElem* do_build_seq_recursively_impl(Sequence * seq, int cfra)
 {
-       StripElem *se;
+       TStripElem *se;
 
-       se = seq->curelem = give_stripelem(seq, cfra);
+       se = give_tstripelem(seq, cfra);
 
        if(se) {
-               int unref_meta = FALSE;
-               if(seq->seqbase.first) {
-                       Sequence * seqmshown= get_shown_seq_from_metastrip(seq, cfra);
-                       if (seqmshown) {
-                               if(cfra< seq->start) 
-                                       do_build_seq_recursively(seqmshown, seq->start);
-                               else if(cfra> seq->start+seq->len-1) 
-                                       do_build_seq_recursively(seqmshown, seq->start + seq->len-1);
-                               else do_build_seq_recursively(seqmshown, cfra);
-
-                               unref_meta = TRUE;
-                       }
-               }
-
                if (seq->type & SEQ_EFFECT) {
-                       do_effect_seq_recursively(cfra, seq, se);
+                       do_effect_seq_recursively(seq, se, cfra);
                } else {
-                       do_build_seq_ibuf(seq, cfra);
-               }
-
-               if(unref_meta && seq->curelem->ibuf) {
-                       IMB_cache_limiter_unref(seq->curelem->ibuf);
+                       do_build_seq_ibuf(seq, se, cfra);
                }
        }
+       return se;
 }
 
 /* FIXME:
@@ -1007,16 +1030,16 @@ instead of faking using the blend code below...
 
 */
 
-static void do_handle_speed_effect(Sequence * seq, int cfra)
+static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra)
 {
        SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
        int nr = cfra - seq->start;
        float f_cfra;
        int cfra_left;
        int cfra_right;
-       StripElem * se = 0;
-       StripElem * se1 = 0;
-       StripElem * se2 = 0;
+       TStripElem * se = 0;
+       TStripElem * se1 = 0;
+       TStripElem * se2 = 0;
        
        sequence_effect_speed_rebuild_map(seq, 0);
        
@@ -1025,7 +1048,7 @@ static void do_handle_speed_effect(Sequence * seq, int cfra)
        cfra_left = (int) floor(f_cfra);
        cfra_right = (int) ceil(f_cfra);
 
-       se = seq->curelem = give_stripelem(seq, cfra);
+       se = give_tstripelem(seq, cfra);
 
        if (cfra_left == cfra_right || 
            (s->flags & SEQ_SPEED_BLEND) == 0) {
@@ -1038,9 +1061,8 @@ static void do_handle_speed_effect(Sequence * seq, int cfra)
                }
 
                if (se->ibuf == NULL) {
-                       do_build_seq_recursively_impl(seq->seq1, cfra_left);
-
-                       se1 = seq->seq1->curelem;
+                       se1 = do_build_seq_recursively_impl(
+                               seq->seq1, cfra_left);
 
                        if((se1 && se1->ibuf && se1->ibuf->rect_float))
                                se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
@@ -1072,11 +1094,10 @@ static void do_handle_speed_effect(Sequence * seq, int cfra)
                }
 
                if (se->ibuf == NULL) {
-                       do_build_seq_recursively_impl(seq->seq1, cfra_left);
-                       se1 = seq->seq1->curelem;
-                       do_build_seq_recursively_impl(seq->seq1, cfra_right);
-                       se2 = seq->seq1->curelem;
-
+                       se1 = do_build_seq_recursively_impl(
+                               seq->seq1, cfra_left);
+                       se2 = do_build_seq_recursively_impl(
+                               seq->seq1, cfra_right);
 
                        if((se1 && se1->ibuf && se1->ibuf->rect_float))
                                se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
@@ -1110,35 +1131,43 @@ static void do_handle_speed_effect(Sequence * seq, int cfra)
                IMB_cache_limiter_unref(se1->ibuf);
        if (se2 && se2->ibuf)
                IMB_cache_limiter_unref(se2->ibuf);
+
+       return se;
 }
 
 /* 
  * build all ibufs recursively
  * 
- * if successfull, seq->curelem->ibuf contains the (referenced!) imbuf
+ * if successfull, the returned TStripElem contains the (referenced!) imbuf
  * that means: you _must_ call 
  *
- * IMB_cache_limiter_unref(seq->curelem->ibuf);
+ * IMB_cache_limiter_unref(rval);
  * 
- * if seq->curelem exists!
+ * if rval != 0
  * 
  */
 
-static void do_build_seq_recursively(Sequence * seq, int cfra)
+static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra)
 {
        if (seq->type == SEQ_SPEED) {
-               do_handle_speed_effect(seq, cfra);
+               return do_handle_speed_effect(seq, cfra);
        } else {
-               do_build_seq_recursively_impl(seq, cfra);
+               return do_build_seq_recursively_impl(seq, cfra);
        }
 }
 
-ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
+/*
+ * returned ImBuf is refed!
+ * you have to unref after usage!
+ */
+
+static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown)
 {
        Sequence *seqfirst=0;
        Editing *ed;
        int count;
        ListBase *seqbasep;
+       TStripElem *se;
 
        ed= G.scene->ed;
        if(ed==0) return 0;
@@ -1160,18 +1189,44 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
                return 0;
        }
 
-       do_build_seq_recursively(seqfirst, cfra);
+       se = do_build_seq_recursively(seqfirst, cfra);
 
-       if(!seqfirst->curelem) { 
+       if(!se) { 
                return 0;
        }
 
-       if (seqfirst->curelem->ibuf) {
-               IMB_cache_limiter_unref(seqfirst->curelem->ibuf);
+       return se->ibuf;
+}
+
+ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra,
+                           Sequence * seq)
+{
+       TStripElem* se;
+
+       seqrectx= rectx;        /* bad bad global! */
+       seqrecty= recty;
+
+       se = do_build_seq_recursively(seq, cfra);
+
+       if(!se) { 
+               return 0;
+       }
+
+       if (se->ibuf) {
+               IMB_cache_limiter_unref(se->ibuf);
        }
 
-       return seqfirst->curelem->ibuf;
+       return se->ibuf;
+}
+
+ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
+{
+       ImBuf* i = give_ibuf_seq_impl(rectx, recty, cfra, chanshown);
 
+       if (i) {
+               IMB_cache_limiter_unref(i);
+       }
+       return i;
 }
 
 /* threading api */
@@ -1253,12 +1308,8 @@ static void * seq_prefetch_thread(void * This_)
                This->running = TRUE;
                
                if (e->cfra >= s_last) { 
-                       e->ibuf = give_ibuf_seq(e->rectx, e->recty, e->cfra, 
-                                               e->chanshown);
-               }
-
-               if (e->ibuf) {
-                       IMB_cache_limiter_ref(e->ibuf);
+                       e->ibuf = give_ibuf_seq_impl(
+                               e->rectx, e->recty, e->cfra, e->chanshown);
                }
 
                pthread_mutex_lock(&queue_lock);
@@ -1413,7 +1464,7 @@ void seq_wait_for_prefetch_ready()
        fprintf(stderr, "SEQ-THREAD: prefetch done\n");
 }
 
-ImBuf * give_ibuf_threaded(int rectx, int recty, int cfra, int chanshown)
+ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, int chanshown)
 {
        PrefetchQueueElem * e = 0;
        int found_something = FALSE;
@@ -1493,13 +1544,13 @@ ImBuf * give_ibuf_threaded(int rectx, int recty, int cfra, int chanshown)
 
 /* Functions to free imbuf and anim data on changes */
 
-static void free_imbuf_strip_elem(StripElem *se)
+static void free_imbuf_strip_elem(TStripElem *se)
 {
        if (se->ibuf) {
-               if (se->ok != 2)
+               if (se->ok != STRIPELEM_META && se->ibuf != 0)
                        IMB_freeImBuf(se->ibuf);
                se->ibuf= 0;
-               se->ok= 1;
+               se->ok= STRIPELEM_OK;
                se->se1= se->se2= se->se3= 0;
        }
 }
@@ -1516,15 +1567,17 @@ void free_imbuf_seq_except(int cfra)
 {
        Editing *ed= G.scene->ed;
        Sequence *seq;
-       StripElem *se;
+       TStripElem *se;
        int a;
 
        if(ed==0) return;
 
        WHILE_SEQ(&ed->seqbase) {
                if(seq->strip) {
-                       for(a=0, se= seq->strip->stripdata; a<seq->len; a++, se++)
-                               if(se!=seq->curelem)
+                       TStripElem * curelem = give_tstripelem(seq, cfra);
+
+                       for(a=0, se= seq->strip->tstripdata; a<seq->len; a++, se++)
+                               if(se != curelem)
                                        free_imbuf_strip_elem(se);
 
                        if(seq->type==SEQ_MOVIE)
@@ -1539,15 +1592,17 @@ void free_imbuf_seq()
 {
        Editing *ed= G.scene->ed;
        Sequence *seq;
-       StripElem *se;
+       TStripElem *se;
        int a;
 
        if(ed==0) return;
 
        WHILE_SEQ(&ed->seqbase) {
                if(seq->strip) {
-                       for(a=0, se= seq->strip->stripdata; a<seq->len; a++, se++)
-                               free_imbuf_strip_elem(se);
+                       if (seq->strip->tstripdata) {
+                               for(a=0, se= seq->strip->tstripdata; a<seq->len; a++, se++)
+                                       free_imbuf_strip_elem(se);
+                       }
 
                        if(seq->type==SEQ_MOVIE)
                                free_anim_seq(seq);
@@ -1582,7 +1637,7 @@ static int update_changed_seq_recurs(Sequence *seq, Sequence *changed_seq, int l
 {
        Sequence *subseq;
        int a, free_imbuf = 0;
-       StripElem *se;
+       TStripElem *se;
 
        /* recurs downwards to see if this seq depends on the changed seq */
 
@@ -1594,24 +1649,27 @@ static int update_changed_seq_recurs(Sequence *seq, Sequence *changed_seq, int l
        
        for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
                if(update_changed_seq_recurs(subseq, changed_seq, len_change, ibuf_change))
-                       free_imbuf = 1;
+                       free_imbuf = TRUE;
        
        if(seq->seq1)
                if(update_changed_seq_recurs(seq->seq1, changed_seq, len_change, ibuf_change))
-                       free_imbuf = 1;
+                       free_imbuf = TRUE;
        if(seq->seq2 && (seq->seq2 != seq->seq1))
                if(update_changed_seq_recurs(seq->seq2, changed_seq, len_change, ibuf_change))
-                       free_imbuf = 1;
+                       free_imbuf = TRUE;
        if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
                if(update_changed_seq_recurs(seq->seq3, changed_seq, len_change, ibuf_change))
-                       free_imbuf = 1;
+                       free_imbuf = TRUE;
        
        if(free_imbuf) {
                if(ibuf_change) {
-                       for(a=0, se= seq->strip->stripdata; a<seq->len; a++, se++)
-                               free_imbuf_strip_elem(se);
+                       se= seq->strip->tstripdata;
+                       if (se) {
+                               for(a=0; a<seq->len; a++, se++)
+                                       free_imbuf_strip_elem(se);
+                       }
                
-                       if(seq->type==SEQ_MOVIE)
+                       if(seq->type == SEQ_MOVIE)
                                free_anim_seq(seq);
                        if(seq->type == SEQ_SPEED) {
                                sequence_effect_speed_rebuild_map(seq, 1);
@@ -1646,7 +1704,6 @@ void do_render_seq(RenderResult *rr, int cfra)
        ibuf= give_ibuf_seq(rr->rectx, rr->recty, cfra, 0);
        
        if(ibuf) {
-               
                if(ibuf->rect_float) {
                        if (!rr->rectf)
                                rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf");