== Sequencer ==
[blender-staging.git] / source / blender / src / sequence.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * Contributor(s): Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
27  *
28  * ***** END GPL/BL DUAL LICENSE BLOCK *****
29  */
30
31 #include <string.h>
32 #include <math.h>
33 #include <stdlib.h>
34
35 #include "MEM_guardedalloc.h"
36 #include "MEM_CacheLimiterC-Api.h"
37
38 #include "BLI_blenlib.h"
39 #include "BLI_arithb.h"
40
41 #include "IMB_imbuf_types.h"
42 #include "IMB_imbuf.h"
43
44 #include "DNA_ipo_types.h"
45 #include "DNA_scene_types.h"
46 #include "DNA_sequence_types.h"
47 #include "DNA_view3d_types.h"
48
49 #include "BKE_global.h"
50 #include "BKE_image.h"
51 #include "BKE_ipo.h"
52 #include "BKE_main.h"
53 #include "BKE_scene.h"
54 #include "BKE_texture.h"
55 #include "BKE_utildefines.h"
56
57 #include "BIF_editsound.h"
58 #include "BIF_editseq.h"
59 #include "BSE_filesel.h"
60 #include "BSE_headerbuttons.h"
61 #include "BIF_interface.h"
62 #include "BIF_renderwin.h"
63 #include "BIF_screen.h"
64 #include "BIF_space.h"
65 #include "BIF_toolbox.h"
66
67 #include "BSE_sequence.h"
68 #include "BSE_seqeffects.h"
69
70 #include "RE_pipeline.h"                // talks to entire render API
71
72 #include "blendef.h"
73
74 #include "BLI_threads.h"
75 #include <pthread.h>
76
77 #ifdef WIN32
78 #define snprintf _snprintf
79 #endif
80
81 int seqrectx, seqrecty;
82
83 /* **********************************************************************
84    alloc / free functions
85    ********************************************************************** */
86
87 void free_tstripdata(int len, TStripElem *se)
88 {
89         TStripElem *seo;
90         int a;
91
92         seo= se;
93         if (!se) {
94                 return;
95         }
96
97         for(a=0; a<len; a++, se++) {
98                 if(se->ibuf) {
99                         IMB_freeImBuf(se->ibuf);
100                         se->ibuf = 0;
101                 }
102                 if(se->ibuf_comp) {
103                         IMB_freeImBuf(se->ibuf_comp);
104                         se->ibuf_comp = 0;
105                 }
106         }
107
108         MEM_freeN(seo);
109
110 }
111
112 void free_strip(Strip *strip)
113 {
114         strip->us--;
115         if(strip->us>0) return;
116         if(strip->us<0) {
117                 printf("error: negative users in strip\n");
118                 return;
119         }
120
121         if (strip->stripdata) {
122                 MEM_freeN(strip->stripdata);
123         }
124
125         if (strip->proxy) {
126                 MEM_freeN(strip->proxy);
127         }
128         if (strip->crop) {
129                 MEM_freeN(strip->crop);
130         }
131         if (strip->transform) {
132                 MEM_freeN(strip->transform);
133         }
134         if (strip->color_balance) {
135                 MEM_freeN(strip->color_balance);
136         }
137
138         free_tstripdata(strip->len, strip->tstripdata);
139         free_tstripdata(strip->endstill, strip->tstripdata_endstill);
140         free_tstripdata(strip->startstill, strip->tstripdata_startstill);
141
142         if(strip->ibuf_startstill) {
143                 IMB_freeImBuf(strip->ibuf_startstill);
144                 strip->ibuf_startstill = 0;
145         }
146
147         if(strip->ibuf_endstill) {
148                 IMB_freeImBuf(strip->ibuf_endstill);
149                 strip->ibuf_endstill = 0;
150         }
151
152         MEM_freeN(strip);
153 }
154
155 void new_tstripdata(Sequence *seq)
156 {
157         if(seq->strip) {
158                 free_tstripdata(seq->strip->len, seq->strip->tstripdata);
159                 free_tstripdata(seq->strip->endstill, 
160                                 seq->strip->tstripdata_endstill);
161                 free_tstripdata(seq->strip->startstill, 
162                                 seq->strip->tstripdata_startstill);
163
164                 seq->strip->tstripdata= 0;
165                 seq->strip->tstripdata_endstill= 0;
166                 seq->strip->tstripdata_startstill= 0;
167
168                 if(seq->strip->ibuf_startstill) {
169                         IMB_freeImBuf(seq->strip->ibuf_startstill);
170                         seq->strip->ibuf_startstill = 0;
171                 }
172
173                 if(seq->strip->ibuf_endstill) {
174                         IMB_freeImBuf(seq->strip->ibuf_endstill);
175                         seq->strip->ibuf_endstill = 0;
176                 }
177
178                 seq->strip->len= seq->len;
179         }
180 }
181
182 void free_sequence(Sequence *seq)
183 {
184         Sequence *last_seq = get_last_seq();
185
186         if(seq->strip) free_strip(seq->strip);
187
188         if(seq->anim) IMB_free_anim(seq->anim);
189         if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio);
190
191         if (seq->type & SEQ_EFFECT) {
192                 struct SeqEffectHandle sh = get_sequence_effect(seq);
193
194                 sh.free(seq);
195         }
196
197         if(seq==last_seq) set_last_seq(NULL);
198
199         MEM_freeN(seq);
200 }
201
202 /*
203   **********************************************************************
204   * build_seqar
205   **********************************************************************
206   * Build a complete array of _all_ sequencies (including those
207   * in metastrips!)
208   **********************************************************************
209 */
210
211 static void do_seq_count(ListBase *seqbase, int *totseq)
212 {
213         Sequence *seq;
214
215         seq= seqbase->first;
216         while(seq) {
217                 (*totseq)++;
218                 if(seq->seqbase.first) do_seq_count(&seq->seqbase, totseq);
219                 seq= seq->next;
220         }
221 }
222
223 static void do_build_seqar(ListBase *seqbase, Sequence ***seqar, int depth)
224 {
225         Sequence *seq;
226
227         seq= seqbase->first;
228         while(seq) {
229                 seq->depth= depth;
230                 if(seq->seqbase.first) do_build_seqar(&seq->seqbase, seqar, depth+1);
231                 **seqar= seq;
232                 (*seqar)++;
233                 seq= seq->next;
234         }
235 }
236
237 void build_seqar(ListBase *seqbase, Sequence  ***seqar, int *totseq)
238 {
239         Sequence **tseqar;
240
241         *totseq= 0;
242         do_seq_count(seqbase, totseq);
243
244         if(*totseq==0) {
245                 *seqar= 0;
246                 return;
247         }
248         *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
249         tseqar= *seqar;
250
251         do_build_seqar(seqbase, seqar, 0);
252         *seqar= tseqar;
253 }
254
255 static void do_seq_count_cb(ListBase *seqbase, int *totseq,
256                             int (*test_func)(Sequence * seq))
257 {
258         Sequence *seq;
259
260         seq= seqbase->first;
261         while(seq) {
262                 int test = test_func(seq);
263                 if (test & BUILD_SEQAR_COUNT_CURRENT) {
264                         (*totseq)++;
265                 }
266                 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
267                         do_seq_count_cb(&seq->seqbase, totseq, test_func);
268                 }
269                 seq= seq->next;
270         }
271 }
272
273 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
274                               int (*test_func)(Sequence * seq))
275 {
276         Sequence *seq;
277
278         seq= seqbase->first;
279         while(seq) {
280                 int test = test_func(seq);
281                 seq->depth= depth;
282
283                 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
284                         do_build_seqar_cb(&seq->seqbase, seqar, depth+1, 
285                                           test_func);
286                 }
287                 if (test & BUILD_SEQAR_COUNT_CURRENT) {
288                         **seqar= seq;
289                         (*seqar)++;
290                 }
291                 seq= seq->next;
292         }
293 }
294
295 void build_seqar_cb(ListBase *seqbase, Sequence  ***seqar, int *totseq,
296                     int (*test_func)(Sequence * seq))
297 {
298         Sequence **tseqar;
299
300         *totseq= 0;
301         do_seq_count_cb(seqbase, totseq, test_func);
302
303         if(*totseq==0) {
304                 *seqar= 0;
305                 return;
306         }
307         *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
308         tseqar= *seqar;
309
310         do_build_seqar_cb(seqbase, seqar, 0, test_func);
311         *seqar= tseqar;
312 }
313
314
315 void free_editing(Editing *ed)
316 {
317         MetaStack *ms;
318         Sequence *seq;
319
320         if(ed==NULL) return;
321         set_last_seq(NULL);     /* clear_last_seq doesnt work, it screws up free_sequence */
322
323         WHILE_SEQ(&ed->seqbase) {
324                 free_sequence(seq);
325         }
326         END_SEQ
327
328         while( (ms= ed->metastack.first) ) {
329                 BLI_remlink(&ed->metastack, ms);
330                 MEM_freeN(ms);
331         }
332
333         MEM_freeN(ed);
334
335 }
336
337 void calc_sequence_disp(Sequence *seq)
338 {
339         if(seq->startofs && seq->startstill) seq->startstill= 0;
340         if(seq->endofs && seq->endstill) seq->endstill= 0;
341         
342         seq->startdisp= seq->start + seq->startofs - seq->startstill;
343         seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
344         
345         seq->handsize= 10.0;    /* 10 frames */
346         if( seq->enddisp-seq->startdisp < 10 ) {
347                 seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
348         }
349         else if(seq->enddisp-seq->startdisp > 250) {
350                 seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
351         }
352 }
353
354 void calc_sequence(Sequence *seq)
355 {
356         Sequence *seqm;
357         int min, max;
358
359         /* check all metas recursively */
360         seqm= seq->seqbase.first;
361         while(seqm) {
362                 if(seqm->seqbase.first) calc_sequence(seqm);
363                 seqm= seqm->next;
364         }
365
366         /* effects and meta: automatic start and end */
367
368         if(seq->type & SEQ_EFFECT) {
369                 /* pointers */
370                 if(seq->seq2==0) seq->seq2= seq->seq1;
371                 if(seq->seq3==0) seq->seq3= seq->seq1;
372
373                 /* effecten go from seq1 -> seq2: test */
374
375                 /* we take the largest start and smallest end */
376
377                 // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
378                 // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
379
380                 if (seq->seq1) {
381                         seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
382                         seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
383                         seq->len= seq->enddisp - seq->startdisp;
384                 } else {
385                         calc_sequence_disp(seq);
386                 }
387
388                 if(seq->strip && seq->len!=seq->strip->len) {
389                         new_tstripdata(seq);
390                 }
391
392         }
393         else {
394                 if(seq->type==SEQ_META) {
395                         seqm= seq->seqbase.first;
396                         if(seqm) {
397                                 min= 1000000;
398                                 max= -1000000;
399                                 while(seqm) {
400                                         if(seqm->startdisp < min) min= seqm->startdisp;
401                                         if(seqm->enddisp > max) max= seqm->enddisp;
402                                         seqm= seqm->next;
403                                 }
404                                 seq->start= min + seq->anim_startofs;
405                                 seq->len = max-min;
406                                 seq->len -= seq->anim_startofs;
407                                 seq->len -= seq->anim_endofs;
408
409                                 if(seq->strip && seq->len!=seq->strip->len) {
410                                         new_tstripdata(seq);
411                                 }
412                         }
413                 }
414                 calc_sequence_disp(seq);
415         }
416 }
417
418 void reload_sequence_new_file(Sequence * seq)
419 {
420         char str[FILE_MAXDIR+FILE_MAXFILE];
421
422         if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
423               seq->type == SEQ_HD_SOUND || seq->type == SEQ_SCENE ||
424               seq->type == SEQ_META)) {
425                 return;
426         }
427
428         new_tstripdata(seq);
429
430         if (seq->type == SEQ_IMAGE) {
431                 return;
432         }
433
434         if (seq->type != SEQ_SCENE && seq->type != SEQ_META) {
435                 strncpy(str, seq->strip->dir, FILE_MAXDIR-1);
436                 strncat(str, seq->strip->stripdata->name, FILE_MAXFILE-1);
437         }
438
439         if (seq->type == SEQ_MOVIE) {
440                 if(seq->anim) IMB_free_anim(seq->anim);
441                 seq->anim = openanim(str, IB_rect);
442
443                 if (!seq->anim) {
444                         return;
445                 }
446         
447                 seq->len = IMB_anim_get_duration(seq->anim);
448                 
449                 seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
450
451                 seq->len -= seq->anim_startofs;
452                 seq->len -= seq->anim_endofs;
453                 if (seq->len < 0) {
454                         seq->len = 0;
455                 }
456                 seq->strip->len = seq->len;
457         } else if (seq->type == SEQ_HD_SOUND) {
458                 if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio);
459                 seq->hdaudio = sound_open_hdaudio(str);
460
461                 if (!seq->hdaudio) {
462                         return;
463                 }
464
465                 seq->strip->len = seq->len 
466                         = sound_hdaudio_get_duration(seq->hdaudio, FPS);
467         } else if (seq->type == SEQ_SCENE) {
468                 Scene * sce = G.main->scene.first;
469                 int nr = 1;
470                 while(sce) {
471                         if(nr == seq->scenenr) {
472                                 break;
473                         }
474                         nr++;
475                         sce= sce->id.next;
476                 }
477
478                 if (sce) {
479                         seq->scene = sce;
480                 }
481
482                 strncpy(seq->name + 2, sce->id.name + 2, 
483                         sizeof(seq->name) - 2);
484
485                 seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
486                 seq->len -= seq->anim_startofs;
487                 seq->len -= seq->anim_endofs;
488                 if (seq->len < 0) {
489                         seq->len = 0;
490                 }
491                 seq->strip->len = seq->len;
492         }
493
494         calc_sequence(seq);
495 }
496
497 void sort_seq()
498 {
499         /* all strips together per kind, and in order of y location ("machine") */
500         ListBase seqbase, effbase;
501         Editing *ed;
502         Sequence *seq, *seqt;
503
504         ed= G.scene->ed;
505         if(ed==0) return;
506
507         seqbase.first= seqbase.last= 0;
508         effbase.first= effbase.last= 0;
509
510         while( (seq= ed->seqbasep->first) ) {
511                 BLI_remlink(ed->seqbasep, seq);
512
513                 if(seq->type & SEQ_EFFECT) {
514                         seqt= effbase.first;
515                         while(seqt) {
516                                 if(seqt->machine>=seq->machine) {
517                                         BLI_insertlinkbefore(&effbase, seqt, seq);
518                                         break;
519                                 }
520                                 seqt= seqt->next;
521                         }
522                         if(seqt==0) BLI_addtail(&effbase, seq);
523                 }
524                 else {
525                         seqt= seqbase.first;
526                         while(seqt) {
527                                 if(seqt->machine>=seq->machine) {
528                                         BLI_insertlinkbefore(&seqbase, seqt, seq);
529                                         break;
530                                 }
531                                 seqt= seqt->next;
532                         }
533                         if(seqt==0) BLI_addtail(&seqbase, seq);
534                 }
535         }
536
537         addlisttolist(&seqbase, &effbase);
538         *(ed->seqbasep)= seqbase;
539 }
540
541
542 void clear_scene_in_allseqs(Scene *sce)
543 {
544         Scene *sce1;
545         Editing *ed;
546         Sequence *seq;
547
548         /* when a scene is deleted: test all seqs */
549
550         sce1= G.main->scene.first;
551         while(sce1) {
552                 if(sce1!=sce && sce1->ed) {
553                         ed= sce1->ed;
554
555                         WHILE_SEQ(&ed->seqbase) {
556
557                                 if(seq->scene==sce) seq->scene= 0;
558
559                         }
560                         END_SEQ
561                 }
562
563                 sce1= sce1->id.next;
564         }
565 }
566
567 char *give_seqname_by_type(int type)
568 {
569         switch(type) {
570         case SEQ_META:       return "Meta";
571         case SEQ_IMAGE:      return "Image";
572         case SEQ_SCENE:      return "Scene";
573         case SEQ_MOVIE:      return "Movie";
574         case SEQ_RAM_SOUND:  return "Audio (RAM)";
575         case SEQ_HD_SOUND:   return "Audio (HD)";
576         case SEQ_CROSS:      return "Cross";
577         case SEQ_GAMCROSS:   return "Gamma Cross";
578         case SEQ_ADD:        return "Add";
579         case SEQ_SUB:        return "Sub";
580         case SEQ_MUL:        return "Mul";
581         case SEQ_ALPHAOVER:  return "Alpha Over";
582         case SEQ_ALPHAUNDER: return "Alpha Under";
583         case SEQ_OVERDROP:   return "Over Drop";
584         case SEQ_WIPE:       return "Wipe";
585         case SEQ_GLOW:       return "Glow";
586         case SEQ_TRANSFORM:  return "Transform";
587         case SEQ_COLOR:      return "Color";
588         case SEQ_SPEED:      return "Speed";
589         default:
590                 return 0;
591         }
592 }
593
594 char *give_seqname(Sequence *seq)
595 {
596         char * name = give_seqname_by_type(seq->type);
597
598         if (!name) {
599                 if(seq->type<SEQ_EFFECT) {
600                         return seq->strip->dir;
601                 } else if(seq->type==SEQ_PLUGIN) {
602                         if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
603                            seq->plugin && seq->plugin->doit) {
604                                 return seq->plugin->pname;
605                         } else {
606                                 return "Plugin";
607                         }
608                 } else {
609                         return "Effect";
610                 }
611         }
612         return name;
613 }
614
615 /* ***************** DO THE SEQUENCE ***************** */
616
617 static void make_black_ibuf(ImBuf *ibuf)
618 {
619         unsigned int *rect;
620         float *rect_float;
621         int tot;
622
623         if(ibuf==0 || (ibuf->rect==0 && ibuf->rect_float==0)) return;
624
625         tot= ibuf->x*ibuf->y;
626
627         rect= ibuf->rect;
628         rect_float = ibuf->rect_float;
629
630         if (rect) {
631                 memset(rect,       0, tot * sizeof(char) * 4);
632         }
633
634         if (rect_float) {
635                 memset(rect_float, 0, tot * sizeof(float) * 4);
636         }
637 }
638
639 static void multibuf(ImBuf *ibuf, float fmul)
640 {
641         char *rt;
642         float *rt_float;
643
644         int a, mul, icol;
645
646         mul= (int)(256.0*fmul);
647
648         a= ibuf->x*ibuf->y;
649         rt= (char *)ibuf->rect;
650         rt_float = ibuf->rect_float;
651
652         if (rt) {
653                 while(a--) {
654
655                         icol= (mul*rt[0])>>8;
656                         if(icol>254) rt[0]= 255; else rt[0]= icol;
657                         icol= (mul*rt[1])>>8;
658                         if(icol>254) rt[1]= 255; else rt[1]= icol;
659                         icol= (mul*rt[2])>>8;
660                         if(icol>254) rt[2]= 255; else rt[2]= icol;
661                         icol= (mul*rt[3])>>8;
662                         if(icol>254) rt[3]= 255; else rt[3]= icol;
663                         
664                         rt+= 4;
665                 }
666         }
667         if (rt_float) {
668                 while(a--) {
669                         rt_float[0] *= fmul;
670                         rt_float[1] *= fmul;
671                         rt_float[2] *= fmul;
672                         rt_float[3] *= fmul;
673                         
674                         rt_float += 4;
675                 }
676         }
677 }
678
679 static void do_effect(int cfra, Sequence *seq, TStripElem * se)
680 {
681         TStripElem *se1, *se2, *se3;
682         float fac, facf;
683         int x, y;
684         int early_out;
685         struct SeqEffectHandle sh = get_sequence_effect(seq);
686
687         if (!sh.execute) { /* effect not supported in this version... */
688                 make_black_ibuf(se->ibuf);
689                 return;
690         }
691
692         if(seq->ipo && seq->ipo->curve.first) {
693                 do_seq_ipo(seq, cfra);
694                 fac= seq->facf0;
695                 facf= seq->facf1;
696         } else {
697                 sh.get_default_fac(seq, cfra, &fac, &facf);
698         }
699
700         if( !(G.scene->r.mode & R_FIELDS) ) facf = fac;
701
702         early_out = sh.early_out(seq, fac, facf);
703
704         if (early_out == -1) { /* no input needed */
705                 sh.execute(seq, cfra, fac, facf, 
706                            se->ibuf->x, se->ibuf->y, 
707                            0, 0, 0, se->ibuf);
708                 return;
709         }
710
711         switch (early_out) {
712         case 0:
713                 if (se->se1==0 || se->se2==0 || se->se3==0) {
714                         make_black_ibuf(se->ibuf);
715                         return;
716                 }
717
718                 se1= se->se1;
719                 se2= se->se2;
720                 se3= se->se3;
721
722                 if (   (se1==0 || se2==0 || se3==0)
723                     || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) {
724                         make_black_ibuf(se->ibuf);
725                         return;
726                 }
727
728                 break;
729         case 1:
730                 if (se->se1 == 0) {
731                         make_black_ibuf(se->ibuf);
732                         return;
733                 }
734
735                 se1= se->se1;
736
737                 if (se1 == 0 || se1->ibuf == 0) {
738                         make_black_ibuf(se->ibuf);
739                         return;
740                 }
741
742                 if (se->ibuf != se1->ibuf) {
743                         IMB_freeImBuf(se->ibuf);
744                         se->ibuf = se1->ibuf;
745                         IMB_refImBuf(se->ibuf);
746                 }
747                 return;
748         case 2:
749                 if (se->se2 == 0) {
750                         make_black_ibuf(se->ibuf);
751                         return;
752                 }
753
754                 se2= se->se2;
755
756                 if (se2 == 0 || se2->ibuf == 0) {
757                         make_black_ibuf(se->ibuf);
758                         return;
759                 }
760                 if (se->ibuf != se2->ibuf) {
761                         IMB_freeImBuf(se->ibuf);
762                         se->ibuf = se2->ibuf;
763                         IMB_refImBuf(se->ibuf);
764                 }
765                 return;
766         default:
767                 make_black_ibuf(se->ibuf);
768                 return;
769         }
770
771         x= se2->ibuf->x;
772         y= se2->ibuf->y;
773
774         if (!se1->ibuf->rect_float && se->ibuf->rect_float) {
775                 IMB_float_from_rect(se1->ibuf);
776         }
777         if (!se2->ibuf->rect_float && se->ibuf->rect_float) {
778                 IMB_float_from_rect(se2->ibuf);
779         }
780
781         if (!se1->ibuf->rect && !se->ibuf->rect_float) {
782                 IMB_rect_from_float(se1->ibuf);
783         }
784         if (!se2->ibuf->rect && !se->ibuf->rect_float) {
785                 IMB_rect_from_float(se2->ibuf);
786         }
787
788         sh.execute(seq, cfra, fac, facf, x, y, se1->ibuf, se2->ibuf, se3->ibuf,
789                    se->ibuf);
790 }
791
792 static int give_stripelem_index(Sequence *seq, int cfra)
793 {
794         int nr;
795
796         if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1;
797
798         if(seq->flag&SEQ_REVERSE_FRAMES) {      
799                 /*reverse frame in this sequence */
800                 if(cfra <= seq->start) nr= seq->len-1;
801                 else if(cfra >= seq->start+seq->len-1) nr= 0;
802                 else nr= (seq->start + seq->len) - cfra;
803         } else {
804                 if(cfra <= seq->start) nr= 0;
805                 else if(cfra >= seq->start+seq->len-1) nr= seq->len-1;
806                 else nr= cfra-seq->start;
807         }
808         if (seq->strobe < 1.0) seq->strobe = 1.0;
809         if (seq->strobe > 1.0) {
810                 nr -= (int)fmod((double)nr, (double)seq->strobe);
811         }
812
813         return nr;
814 }
815
816 static TStripElem* alloc_tstripdata(int len, const char * name)
817 {
818         int i;
819         TStripElem *se = MEM_callocN(len * sizeof(TStripElem), name);
820         for (i = 0; i < len; i++) {
821                 se[i].ok = STRIPELEM_OK;
822         }
823         return se;
824 }
825
826 TStripElem *give_tstripelem(Sequence *seq, int cfra)
827 {
828         TStripElem *se;
829         int nr;
830
831         se = seq->strip->tstripdata;
832         if (se == 0 && seq->len > 0) {
833                 se = seq->strip->tstripdata = alloc_tstripdata(seq->len,
834                                                                "tstripelems");
835         }
836         nr = give_stripelem_index(seq, cfra);
837
838         if (nr == -1) return 0;
839         if (se == 0) return 0;
840
841         se += nr; 
842
843         /* if there are IPOs with blend modes active, one has to watch out
844            for startstill + endstill area: we can't use the same tstripelem
845            here for all ibufs, since then, blending with IPOs won't work!
846            
847            Rather common case, if you use a single image and try to fade
848            it in and out... or want to use your strip as a watermark in
849            alpha over mode...
850         */
851         if (seq->blend_mode != SEQ_BLEND_REPLACE ||
852             (seq->ipo && seq->ipo->curve.first && !(seq->type & SEQ_EFFECT))) {
853                 Strip * s = seq->strip;
854                 if (cfra < seq->start) {
855                         se = s->tstripdata_startstill;
856                         if (seq->startstill > s->startstill) {
857                                 free_tstripdata(s->startstill, 
858                                                 s->tstripdata_startstill);
859                                 se = 0;
860                         }
861
862                         if (se == 0) {
863                                 s->startstill = seq->startstill;
864                                 se = seq->strip->tstripdata_startstill
865                                         = alloc_tstripdata(
866                                                 s->startstill,
867                                                 "tstripelems_startstill");
868                         }
869                         se += seq->start - cfra - 1;
870
871                 } else if (cfra > seq->start + seq->len-1) {
872                         se = s->tstripdata_endstill;
873                         if (seq->endstill > s->endstill) {
874                                 free_tstripdata(s->endstill, 
875                                                 s->tstripdata_endstill);
876                                 se = 0;
877                         }
878
879                         if (se == 0) {
880                                 s->endstill = seq->endstill;
881                                 se = seq->strip->tstripdata_endstill
882                                         = alloc_tstripdata(
883                                                 s->endstill,
884                                                 "tstripelems_endstill");
885                         }
886                         se += cfra - (seq->start + seq->len-1) - 1;
887                 }
888         }
889
890         
891         se->nr= nr;
892
893         return se;
894 }
895
896 StripElem *give_stripelem(Sequence *seq, int cfra)
897 {
898         StripElem *se;
899         int nr;
900
901         se = seq->strip->stripdata;
902         nr = give_stripelem_index(seq, cfra);
903
904         if (nr == -1) return 0;
905         if (se == 0) return 0;
906
907         se += nr + seq->anim_startofs; 
908         
909         return se;
910 }
911
912 static int evaluate_seq_frame_gen(
913         Sequence ** seq_arr, ListBase *seqbase, int cfra)
914 {
915         Sequence *seq;
916         int totseq=0;
917
918         memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1));
919
920         seq= seqbase->first;
921         while(seq) {
922                 if(seq->startdisp <=cfra && seq->enddisp > cfra) {
923                         seq_arr[seq->machine]= seq;
924                         totseq++;
925                 }
926                 seq= seq->next;
927         }
928
929         return totseq;
930 }
931
932 int evaluate_seq_frame(int cfra)
933 {
934        Editing *ed;
935        Sequence *seq_arr[MAXSEQ+1];
936
937        ed= G.scene->ed;
938        if(ed==0) return 0;
939         
940        return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
941
942 }
943
944 static int video_seq_is_rendered(Sequence * seq)
945 {
946         return (seq 
947                 && !(seq->flag & SEQ_MUTE) 
948                 && seq->type != SEQ_RAM_SOUND 
949                 && seq->type != SEQ_HD_SOUND);
950 }
951
952 static int get_shown_sequences(
953         ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
954 {
955         Sequence *seq_arr[MAXSEQ+1];
956         int b = chanshown;
957         int cnt = 0;
958
959         if (b > MAXSEQ) {
960                 return 0;
961         }
962
963         if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
964                 if (b > 0) {
965                         if (seq_arr[b] == 0) {
966                                 return 0;
967                         }
968                 } else {
969                         for (b = MAXSEQ; b > 0; b--) {
970                                 if (video_seq_is_rendered(seq_arr[b])) {
971                                         break;
972                                 }
973                         }
974                 }
975         }
976         
977         chanshown = b;
978
979         for (;b > 0; b--) {
980                 if (video_seq_is_rendered(seq_arr[b])) {
981                         if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
982                                 break;
983                         }
984                 }
985         }
986
987         for (;b <= chanshown; b++) {
988                 if (video_seq_is_rendered(seq_arr[b])) {
989                         seq_arr_out[cnt++] = seq_arr[b];
990                 }
991         }
992
993         return cnt;
994 }
995  
996
997 /* **********************************************************************
998    proxy management
999    ********************************************************************** */
1000
1001 #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
1002
1003 static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name)
1004 {
1005         int frameno;
1006         char dir[FILE_MAXDIR];
1007
1008         if (!seq->strip->proxy) {
1009                 return FALSE;
1010         }
1011
1012         if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
1013                 strcpy(dir, seq->strip->proxy->dir);
1014         } else {
1015                 if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
1016                         snprintf(dir, FILE_MAXDIR, "%s/BL_proxy", 
1017                                  seq->strip->dir);
1018                 } else {
1019                         return FALSE;
1020                 }
1021         }
1022
1023         /* generate a seperate proxy directory for each preview size */
1024
1025         if (seq->type == SEQ_IMAGE) {
1026                 StripElem * se = give_stripelem(seq, cfra);
1027                 snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy",
1028                          dir, G.scene->r.size, se->name);
1029                 frameno = 1;
1030         } else if (seq->type == SEQ_MOVIE) {
1031                 TStripElem * tse = give_tstripelem(seq, cfra);
1032
1033                 frameno = tse->nr + seq->anim_startofs;
1034
1035                 snprintf(name, PROXY_MAXFILE, "%s/%s/%d/#", dir,
1036                          seq->strip->stripdata->name,
1037                          G.scene->r.size);
1038         } else {
1039                 TStripElem * tse = give_tstripelem(seq, cfra);
1040
1041                 frameno = tse->nr + seq->anim_startofs;
1042
1043                 snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/#", dir,
1044                          G.scene->r.size);
1045         }
1046
1047         BLI_convertstringcode(name, G.sce, frameno);
1048
1049         strcat(name, ".jpg");
1050
1051         return TRUE;
1052 }
1053
1054 static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra)
1055 {
1056         char name[PROXY_MAXFILE];
1057
1058         if (!(seq->flag & SEQ_USE_PROXY)) {
1059                 return 0;
1060         }
1061
1062         /* rendering at 100% ? No real sense in proxy-ing, right? */
1063         if (G.scene->r.size == 100.0) {
1064                 return 0;
1065         }
1066
1067         if (!seq_proxy_get_fname(seq, cfra, name)) {
1068                 return 0;
1069         }
1070
1071         if (BLI_exists(name)) {
1072                 return IMB_loadiffname(name, IB_rect);
1073         } else {
1074                 return 0;
1075         }
1076 }
1077
1078 static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
1079                               int build_proxy_run);
1080
1081 static void seq_proxy_build_frame(Sequence * seq, int cfra)
1082 {
1083         char name[PROXY_MAXFILE];
1084         int quality;
1085         TStripElem * se;
1086         int ok;
1087         int rectx, recty;
1088         struct ImBuf * ibuf;
1089
1090         if (!(seq->flag & SEQ_USE_PROXY)) {
1091                 return;
1092         }
1093
1094         /* rendering at 100% ? No real sense in proxy-ing, right? */
1095         if (G.scene->r.size == 100.0) {
1096                 return;
1097         }
1098
1099         if (!seq_proxy_get_fname(seq, cfra, name)) {
1100                 return;
1101         }
1102
1103         se = give_tstripelem(seq, cfra);
1104
1105         if(se->ibuf) {
1106                 IMB_freeImBuf(se->ibuf);
1107                 se->ibuf = 0;
1108         }
1109         
1110         do_build_seq_ibuf(seq, se, cfra, TRUE);
1111
1112         if (!se->ibuf) {
1113                 return;
1114         }
1115
1116         rectx= (G.scene->r.size*G.scene->r.xsch)/100;
1117         recty= (G.scene->r.size*G.scene->r.ysch)/100;
1118
1119         ibuf = se->ibuf;
1120
1121         if (ibuf->x != rectx || ibuf->y != recty) {
1122                 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1123         }
1124
1125         /* quality is fixed, otherwise one has to generate seperate
1126            directories for every quality...
1127
1128            depth = 32 is intentionally left in, otherwise ALPHA channels
1129            won't work... */
1130         quality = 90;
1131         ibuf->ftype= JPG | quality;
1132
1133         BLI_make_existing_file(name);
1134         
1135         ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
1136         if (ok == 0) {
1137                 perror(name);
1138         }
1139
1140         IMB_freeImBuf(ibuf);
1141         se->ibuf = 0;
1142 }
1143
1144 void seq_proxy_rebuild(Sequence * seq)
1145 {
1146         int cfra;
1147
1148         waitcursor(1);
1149
1150         G.afbreek = 0;
1151
1152         /* flag management tries to account for strobe and 
1153            other "non-linearities", that might come in the future...
1154            better way would be to "touch" the files, so that _really_
1155            no one is rebuild twice.
1156          */
1157
1158         for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
1159                 TStripElem * tse = give_tstripelem(seq, cfra);
1160
1161                 tse->flag &= ~STRIPELEM_PREVIEW_DONE;
1162         }
1163
1164         /* a _lot_ faster for movie files, if we read frames in
1165            sequential order */
1166         if (seq->flag & SEQ_REVERSE_FRAMES) {
1167                 for (cfra = seq->enddisp-seq->endstill-1; 
1168                      cfra >= seq->startdisp + seq->startstill; cfra--) {
1169                         TStripElem * tse = give_tstripelem(seq, cfra);
1170
1171                         if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1172                                 seq_proxy_build_frame(seq, cfra);
1173                                 tse->flag |= STRIPELEM_PREVIEW_DONE;
1174                         }
1175                         if (blender_test_break()) {
1176                                 break;
1177                         }
1178                 }
1179         } else {
1180                 for (cfra = seq->startdisp + seq->startstill; 
1181                      cfra < seq->enddisp - seq->endstill; cfra++) {
1182                         TStripElem * tse = give_tstripelem(seq, cfra);
1183
1184                         if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1185                                 seq_proxy_build_frame(seq, cfra);
1186                                 tse->flag |= STRIPELEM_PREVIEW_DONE;
1187                         }
1188                         if (blender_test_break()) {
1189                                 break;
1190                         }
1191                 }
1192         }
1193         waitcursor(0);
1194 }
1195
1196
1197 /* **********************************************************************
1198    color balance 
1199    ********************************************************************** */
1200
1201 static StripColorBalance calc_cb(StripColorBalance * cb_)
1202 {
1203         StripColorBalance cb = *cb_;
1204         int c;
1205
1206         if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
1207                 for (c = 0; c < 3; c++) {
1208                         cb.lift[c] = 1.0 - cb.lift[c];
1209                 }
1210         } else {
1211                 for (c = 0; c < 3; c++) {
1212                         cb.lift[c] = -(1.0 - cb.lift[c]);
1213                 }
1214         }
1215         if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
1216                 for (c = 0; c < 3; c++) {
1217                         if (cb.gain[c] != 0.0) {
1218                                 cb.gain[c] = 1.0/cb.gain[c];
1219                         } else {
1220                                 cb.gain[c] = 1000000; /* should be enough :) */
1221                         }
1222                 }
1223         }
1224
1225         if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
1226                 for (c = 0; c < 3; c++) {
1227                         if (cb.gamma[c] != 0.0) {
1228                                 cb.gamma[c] = 1.0/cb.gamma[c];
1229                         } else {
1230                                 cb.gamma[c] = 1000000; /* should be enough :) */
1231                         }
1232                 }
1233         }
1234
1235         return cb;
1236 }
1237
1238 static void make_cb_table_byte(float lift, float gain, float gamma,
1239                                unsigned char * table, float mul)
1240 {
1241         int y;
1242
1243         for (y = 0; y < 256; y++) {
1244                 float v = 1.0 * y / 255;
1245                 v += lift; 
1246                 v *= gain;
1247                 v = pow(v, gamma);
1248                 v *= mul;
1249                 if ( v > 1.0) {
1250                         v = 1.0;
1251                 } else if (v < 0.0) {
1252                         v = 0.0;
1253                 }
1254                 table[y] = v * 255;
1255         }
1256
1257 }
1258
1259 static void make_cb_table_float(float lift, float gain, float gamma,
1260                                 float * table, float mul)
1261 {
1262         int y;
1263
1264         for (y = 0; y < 256; y++) {
1265                 float v = (float) y * 1.0 / 255.0;
1266                 v += lift;
1267                 v *= gain;
1268                 v = pow(v, gamma);
1269                 v *= mul;
1270                 table[y] = v;
1271         }
1272 }
1273
1274 static void color_balance_byte_byte(Sequence * seq, TStripElem* se,
1275                                     float mul)
1276 {
1277         unsigned char cb_tab[3][256];
1278         int c;
1279         unsigned char * p = (unsigned char*) se->ibuf->rect;
1280         unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1281
1282         StripColorBalance cb = calc_cb(seq->strip->color_balance);
1283
1284         for (c = 0; c < 3; c++) {
1285                 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1286                                    cb_tab[c], mul);
1287         }
1288
1289         while (p < e) {
1290                 p[0] = cb_tab[0][p[0]];
1291                 p[1] = cb_tab[1][p[1]];
1292                 p[2] = cb_tab[2][p[2]];
1293                 
1294                 p += 4;
1295         }
1296 }
1297
1298 static void color_balance_byte_float(Sequence * seq, TStripElem* se,
1299                                      float mul)
1300 {
1301         float cb_tab[4][256];
1302         int c,i;
1303         unsigned char * p = (unsigned char*) se->ibuf->rect;
1304         unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1305         float * o;
1306         StripColorBalance cb;
1307
1308         imb_addrectfloatImBuf(se->ibuf);
1309
1310         o = se->ibuf->rect_float;
1311
1312         cb = calc_cb(seq->strip->color_balance);
1313
1314         for (c = 0; c < 3; c++) {
1315                 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
1316                                     cb_tab[c], mul);
1317         }
1318
1319         for (i = 0; i < 256; i++) {
1320                 cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
1321         }
1322
1323         while (p < e) {
1324                 o[0] = cb_tab[0][p[0]];
1325                 o[1] = cb_tab[1][p[1]];
1326                 o[2] = cb_tab[2][p[2]];
1327                 o[3] = cb_tab[3][p[3]];
1328
1329                 p += 4; o += 4;
1330         }
1331 }
1332
1333 static void color_balance_float_float(Sequence * seq, TStripElem* se,
1334                                       float mul)
1335 {
1336         float * p = se->ibuf->rect_float;
1337         float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y;
1338         StripColorBalance cb = calc_cb(seq->strip->color_balance);
1339
1340         while (p < e) {
1341                 int c;
1342                 for (c = 0; c < 3; c++) {
1343                         p[c] = pow((p[c] + cb.lift[c]) * cb.gain[c], 
1344                                    cb.gamma[c]) * mul;
1345                 }
1346                 p += 4;
1347         }
1348 }
1349
1350 static void color_balance(Sequence * seq, TStripElem* se, float mul)
1351 {
1352         if (se->ibuf->rect_float) {
1353                 color_balance_float_float(seq, se, mul);
1354         } else if(seq->flag & SEQ_MAKE_FLOAT) {
1355                 color_balance_byte_float(seq, se, mul);
1356         } else {
1357                 color_balance_byte_byte(seq, se, mul);
1358         }
1359 }
1360
1361 /*
1362   input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
1363
1364   Do all the things you can't really do afterwards using sequence effects
1365   (read: before rescaling to render resolution has been done)
1366
1367   Order is important!
1368
1369   - Deinterlace
1370   - Crop and transform in image source coordinate space
1371   - Flip X + Flip Y (could be done afterwards, backward compatibility)
1372   - Promote image to float data (affects pipeline operations afterwards)
1373   - Color balance (is most efficient in the byte -> float 
1374     (future: half -> float should also work fine!)
1375     case, if done on load, since we can use lookup tables)
1376   - Premultiply
1377
1378 */
1379
1380 static int input_have_to_preprocess(Sequence * seq, TStripElem* se, int cfra)
1381 {
1382         float mul;
1383
1384         if ((seq->flag & SEQ_FILTERY) || 
1385             (seq->flag & SEQ_USE_CROP) ||
1386             (seq->flag & SEQ_USE_TRANSFORM) ||
1387             (seq->flag & SEQ_FLIPX) ||
1388             (seq->flag & SEQ_FLIPY) ||
1389             (seq->flag & SEQ_USE_COLOR_BALANCE) ||
1390             (seq->flag & SEQ_MAKE_PREMUL) ||
1391             (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
1392                 return TRUE;
1393         }
1394
1395         mul = seq->mul;
1396
1397         if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1398                 if (seq->ipo && seq->ipo->curve.first) {
1399                         do_seq_ipo(seq, cfra);
1400                         mul *= seq->facf0;
1401                 }
1402                 mul *= seq->blend_opacity / 100.0;
1403         }
1404
1405         if (mul != 1.0) {
1406                 return TRUE;
1407         }
1408                 
1409         return FALSE;
1410 }
1411
1412 static void input_preprocess(Sequence * seq, TStripElem* se, int cfra)
1413 {
1414         float mul;
1415
1416         seq->strip->orx= se->ibuf->x;
1417         seq->strip->ory= se->ibuf->y;
1418
1419         if(seq->flag & SEQ_FILTERY) {
1420                 IMB_filtery(se->ibuf);
1421         }
1422
1423         if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
1424                 StripCrop c;
1425                 StripTransform t;
1426
1427                 memset(&c, 0, sizeof(StripCrop));
1428                 memset(&t, 0, sizeof(StripTransform));
1429
1430                 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1431                         c = *seq->strip->crop;
1432                 }
1433                 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1434                         t = *seq->strip->transform;
1435                 }
1436
1437                 if (c.top + c.bottom >= se->ibuf->y ||
1438                     c.left + c.right >= se->ibuf->x ||
1439                     t.xofs >= se->ibuf->x ||
1440                     t.yofs >= se->ibuf->y) {
1441                         make_black_ibuf(se->ibuf);
1442                 } else {
1443                         ImBuf * i;
1444                         int sx = se->ibuf->x - c.left - c.right;
1445                         int sy = se->ibuf->y - c.top - c.bottom;
1446                         int dx = sx;
1447                         int dy = sy;
1448
1449                         if (seq->flag & SEQ_USE_TRANSFORM) {
1450                                 dx = seqrectx;
1451                                 dy = seqrecty;
1452                         }
1453
1454                         if (se->ibuf->rect_float) {
1455                                 i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0);
1456                         } else {
1457                                 i = IMB_allocImBuf(dx, dy,32, IB_rect, 0);
1458                         }
1459
1460                         IMB_rectcpy(i, se->ibuf, 
1461                                     t.xofs, t.yofs, 
1462                                     c.left, c.bottom, 
1463                                     sx, sy);
1464
1465                         IMB_freeImBuf(se->ibuf);
1466
1467                         se->ibuf = i;
1468                 }
1469         } 
1470
1471         if(seq->flag & SEQ_FLIPX) {
1472                 IMB_flipx(se->ibuf);
1473         }
1474         if(seq->flag & SEQ_FLIPY) {
1475                 IMB_flipy(se->ibuf);
1476         }
1477
1478         if(seq->mul == 0.0) {
1479                 seq->mul = 1.0;
1480         }
1481
1482         mul = seq->mul;
1483
1484         if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1485                 if (seq->ipo && seq->ipo->curve.first) {
1486                         do_seq_ipo(seq, cfra);
1487                         mul *= seq->facf0;
1488                 }
1489                 mul *= seq->blend_opacity / 100.0;
1490         }
1491
1492         if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1493                 color_balance(seq, se, mul);
1494                 mul = 1.0;
1495         }
1496
1497         if(seq->flag & SEQ_MAKE_FLOAT) {
1498                 if (!se->ibuf->rect_float) {
1499                         IMB_float_from_rect(se->ibuf);
1500                 }
1501                 if (se->ibuf->rect) {
1502                         imb_freerectImBuf(se->ibuf);
1503                 }
1504         }
1505
1506         if(mul != 1.0) {
1507                 multibuf(se->ibuf, mul);
1508         }
1509
1510         if(seq->flag & SEQ_MAKE_PREMUL) {
1511                 if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
1512                         converttopremul(se->ibuf);
1513                 }
1514         }
1515
1516
1517         if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
1518                 if(G.scene->r.mode & R_OSA) {
1519                         IMB_scaleImBuf(se->ibuf, 
1520                                        (short)seqrectx, (short)seqrecty);
1521                 } else {
1522                         IMB_scalefastImBuf(se->ibuf, 
1523                                            (short)seqrectx, (short)seqrecty);
1524                 }
1525         }
1526 }
1527
1528 /* test if image too small or discarded from cache: reload */
1529
1530 static void test_and_auto_discard_ibuf(TStripElem * se)
1531 {
1532         if (se->ibuf) {
1533                 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty 
1534                    || !(se->ibuf->rect || se->ibuf->rect_float)) {
1535                         IMB_freeImBuf(se->ibuf);
1536
1537                         se->ibuf= 0;
1538                         se->ok= STRIPELEM_OK;
1539                 }
1540         }
1541         if (se->ibuf_comp) {
1542                 if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty 
1543                    || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) {
1544                         IMB_freeImBuf(se->ibuf_comp);
1545
1546                         se->ibuf_comp = 0;
1547                 }
1548         }
1549 }
1550
1551 static void test_and_auto_discard_ibuf_stills(Strip * strip)
1552 {
1553         if (strip->ibuf_startstill) {
1554                 if (!strip->ibuf_startstill->rect &&
1555                     !strip->ibuf_startstill->rect_float) {
1556                         IMB_freeImBuf(strip->ibuf_startstill);
1557                         strip->ibuf_startstill = 0;
1558                 }
1559         }
1560         if (strip->ibuf_endstill) {
1561                 if (!strip->ibuf_endstill->rect &&
1562                     !strip->ibuf_endstill->rect_float) {
1563                         IMB_freeImBuf(strip->ibuf_endstill);
1564                         strip->ibuf_endstill = 0;
1565                 }
1566         }
1567 }
1568
1569 static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
1570 {
1571         if (!se->ibuf) {
1572                 if (se->nr == 0 && seq->strip->ibuf_startstill) {
1573                         IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1574
1575                         se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
1576                 }
1577                 if (se->nr == seq->len - 1 
1578                     && (seq->len != 1)
1579                     && seq->strip->ibuf_endstill) {
1580                         IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1581
1582                         se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
1583                 }
1584         }
1585 }
1586
1587 static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
1588 {
1589         if (se->ibuf) {
1590                 if (se->nr == 0) {
1591                         seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
1592
1593                         IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
1594                         IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1595                 }
1596                 if (se->nr == seq->len - 1 && seq->len != 1) {
1597                         seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
1598
1599                         IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
1600                         IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1601                 }
1602         }
1603 }
1604
1605
1606 static TStripElem* do_build_seq_array_recursively(
1607         ListBase *seqbasep, int cfra, int chanshown);
1608
1609 static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
1610                               int build_proxy_run)
1611 {
1612         char name[FILE_MAXDIR+FILE_MAXFILE];
1613         int use_limiter = TRUE;
1614
1615         test_and_auto_discard_ibuf(se);
1616         test_and_auto_discard_ibuf_stills(seq->strip);
1617
1618         if(seq->type == SEQ_META) {
1619                 TStripElem * meta_se = 0;
1620                 use_limiter = FALSE;
1621
1622                 if (!build_proxy_run && se->ibuf == 0) {
1623                         se->ibuf = seq_proxy_fetch(seq, cfra);
1624                         if (se->ibuf) {
1625                                 use_limiter = TRUE;
1626                         }
1627                 }
1628
1629                 if(!se->ibuf && seq->seqbase.first) {
1630                         meta_se = do_build_seq_array_recursively(
1631                                 &seq->seqbase, seq->start + se->nr, 0);
1632                 }
1633
1634                 se->ok = STRIPELEM_OK;
1635
1636                 if(!se->ibuf && meta_se) {
1637                         se->ibuf = meta_se->ibuf_comp;
1638                         if(se->ibuf &&
1639                            (!input_have_to_preprocess(seq, se, cfra) ||
1640                             build_proxy_run)) {
1641                                 IMB_refImBuf(se->ibuf);
1642                                 if (build_proxy_run) {
1643                                         IMB_cache_limiter_unref(se->ibuf);
1644                                 }
1645                         } else if (se->ibuf) {
1646                                 struct ImBuf * i = IMB_dupImBuf(se->ibuf);
1647
1648                                 IMB_cache_limiter_unref(se->ibuf);
1649
1650                                 se->ibuf = i;
1651
1652                                 use_limiter = TRUE;
1653                         }
1654                 }
1655
1656                 if (use_limiter) {
1657                         input_preprocess(seq, se, cfra);
1658                 }
1659         } else if(seq->type & SEQ_EFFECT) {
1660                 /* should the effect be recalculated? */
1661                 
1662                 if (!build_proxy_run && se->ibuf == 0) {
1663                         se->ibuf = seq_proxy_fetch(seq, cfra);
1664                 }
1665
1666                 if(se->ibuf == 0) {
1667                         /* if one of two first inputs are rectfloat, output is float too */
1668                         if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
1669                            (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float))
1670                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
1671                         else
1672                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
1673                         
1674                         do_effect(cfra, seq, se);
1675                 }
1676         } else if(seq->type == SEQ_IMAGE) {
1677                 if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
1678                         StripElem * s_elem = give_stripelem(seq, cfra);
1679                         
1680                         strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
1681                         strncat(name, s_elem->name, FILE_MAXFILE);
1682                         BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
1683                         if (!build_proxy_run) {
1684                                 se->ibuf = seq_proxy_fetch(seq, cfra);
1685                         }
1686                         copy_from_ibuf_still(seq, se);
1687
1688                         if (!se->ibuf) {
1689                                 se->ibuf= IMB_loadiffname(
1690                                         name, IB_rect);
1691                                 copy_to_ibuf_still(seq, se);
1692                         }
1693                         
1694                         if(se->ibuf == 0) {
1695                                 se->ok = STRIPELEM_FAILED;
1696                         } else if (!build_proxy_run) {
1697                                 input_preprocess(seq, se, cfra);
1698                         }
1699                 }
1700         } else if(seq->type == SEQ_MOVIE) {
1701                 if(se->ok == STRIPELEM_OK && se->ibuf==0) {
1702                         if(!build_proxy_run) {
1703                                 se->ibuf = seq_proxy_fetch(seq, cfra);
1704                         }
1705                         copy_from_ibuf_still(seq, se);
1706
1707                         if (se->ibuf == 0) {
1708                                 if(seq->anim==0) {
1709                                         strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
1710                                         strncat(name, seq->strip->stripdata->name, FILE_MAXFILE-1);
1711                                         BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
1712                                 
1713                                         seq->anim = openanim(name, IB_rect);
1714                                 }
1715                                 if(seq->anim) {
1716                                         IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
1717                                         se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
1718                                 }
1719                                 copy_to_ibuf_still(seq, se);
1720                         }
1721                         
1722                         if(se->ibuf == 0) {
1723                                 se->ok = STRIPELEM_FAILED;
1724                         } else if (!build_proxy_run) {
1725                                 input_preprocess(seq, se, cfra);
1726                         }
1727                 }
1728         } else if(seq->type == SEQ_SCENE) {     // scene can be NULL after deletions
1729                 int oldcfra = CFRA;
1730                 Scene *sce= seq->scene, *oldsce= G.scene;
1731                 Render *re;
1732                 RenderResult rres;
1733                 int doseq, rendering= G.rendering;
1734                 char scenename[64];
1735                 int sce_valid =sce&& (sce->camera || sce->r.scemode & R_DOSEQ);
1736                         
1737                 if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
1738                         se->ibuf = seq_proxy_fetch(seq, cfra);
1739                         if (se->ibuf) {
1740                                 input_preprocess(seq, se, cfra);
1741                         }
1742                 }
1743
1744                 if (se->ibuf == NULL && sce_valid) {
1745                         copy_from_ibuf_still(seq, se);
1746                         if (se->ibuf) {
1747                                 input_preprocess(seq, se, cfra);
1748                         }
1749                 }
1750                 
1751                 if (!sce_valid) {
1752                         se->ok = STRIPELEM_FAILED;
1753                 } else if (se->ibuf==NULL && sce_valid) {
1754                         waitcursor(1);
1755                         
1756                         /* Hack! This function can be called from do_render_seq(), in that case
1757                            the seq->scene can already have a Render initialized with same name, 
1758                            so we have to use a default name. (compositor uses G.scene name to
1759                            find render).
1760                            However, when called from within the UI (image preview in sequencer)
1761                            we do want to use scene Render, that way the render result is defined
1762                            for display in render/imagewindow */
1763                         if(rendering) {
1764                                 BLI_strncpy(scenename, sce->id.name+2, 64);
1765                                 strcpy(sce->id.name+2, " do_build_seq_ibuf");
1766                         }
1767                         re= RE_NewRender(sce->id.name);
1768                         
1769                         /* prevent eternal loop */
1770                         doseq= G.scene->r.scemode & R_DOSEQ;
1771                         G.scene->r.scemode &= ~R_DOSEQ;
1772                         
1773                         BIF_init_render_callbacks(re, 0);       /* 0= no display callbacks */
1774                         
1775                         /* hrms, set_scene still needed? work on that... */
1776                         if(sce!=oldsce) set_scene_bg(sce);
1777                         RE_BlenderFrame(re, sce,
1778                                         seq->sfra+se->nr+seq->anim_startofs);
1779                         if(sce!=oldsce) set_scene_bg(oldsce);
1780                         
1781                         /* UGLY WARNING, it is set to zero in  RE_BlenderFrame */
1782                         G.rendering= rendering;
1783                         if(rendering)
1784                                 BLI_strncpy(sce->id.name+2, scenename, 64);
1785                         
1786                         RE_GetResultImage(re, &rres);
1787                         
1788                         if(rres.rectf) {
1789                                 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
1790                                 memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
1791                                 if(rres.rectz) {
1792                                         addzbuffloatImBuf(se->ibuf);
1793                                         memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
1794                                 }
1795                         } else if (rres.rect32) {
1796                                 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
1797                                 memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
1798                         }
1799                         
1800                         BIF_end_render_callbacks();
1801                         
1802                         /* restore */
1803                         G.scene->r.scemode |= doseq;
1804                         
1805                         if((G.f & G_PLAYANIM)==0) /* bad, is set on do_render_seq */
1806                                 waitcursor(0);
1807                         CFRA = oldcfra;
1808
1809                         copy_to_ibuf_still(seq, se);
1810
1811                         if (!build_proxy_run) {
1812                                 if(se->ibuf == NULL) {
1813                                         se->ok = STRIPELEM_FAILED;
1814                                 } else {
1815                                         input_preprocess(seq, se, cfra);
1816                                 }
1817                         }
1818
1819                 }       
1820         }
1821         if (!build_proxy_run) {
1822                 if (se->ibuf && use_limiter) {
1823                         IMB_cache_limiter_insert(se->ibuf);
1824                         IMB_cache_limiter_ref(se->ibuf);
1825                         IMB_cache_limiter_touch(se->ibuf);
1826                 }
1827         }
1828 }
1829
1830 static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra);
1831
1832 static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra)
1833 {
1834         float fac, facf;
1835         struct SeqEffectHandle sh = get_sequence_effect(seq);
1836         int early_out;
1837
1838         se->se1 = 0;
1839         se->se2 = 0;
1840         se->se3 = 0;
1841
1842         if(seq->ipo && seq->ipo->curve.first) {
1843                 do_seq_ipo(seq, cfra);
1844                 fac= seq->facf0;
1845                 facf= seq->facf1;
1846         } else {
1847                 sh.get_default_fac(seq, cfra, &fac, &facf);
1848         } 
1849
1850         if( G.scene->r.mode & R_FIELDS ); else facf= fac;
1851         
1852         early_out = sh.early_out(seq, fac, facf);
1853         switch (early_out) {
1854         case -1:
1855                 /* no input needed */
1856                 break;
1857         case 0:
1858                 se->se1 = do_build_seq_recursively(seq->seq1, cfra);
1859                 se->se2 = do_build_seq_recursively(seq->seq2, cfra);
1860                 if (seq->seq3) {
1861                         se->se3 = do_build_seq_recursively(seq->seq3, cfra);
1862                 }
1863                 break;
1864         case 1:
1865                 se->se1 = do_build_seq_recursively(seq->seq1, cfra);
1866                 break;
1867         case 2:
1868                 se->se2 = do_build_seq_recursively(seq->seq2, cfra);
1869                 break;
1870         }
1871
1872
1873         do_build_seq_ibuf(seq, se, cfra, FALSE);
1874
1875         /* children are not needed anymore ... */
1876
1877         if (se->se1 && se->se1->ibuf) {
1878                 IMB_cache_limiter_unref(se->se1->ibuf);
1879         }
1880         if (se->se2 && se->se2->ibuf) {
1881                 IMB_cache_limiter_unref(se->se2->ibuf);
1882         }
1883         if (se->se3 && se->se3->ibuf) {
1884                 IMB_cache_limiter_unref(se->se3->ibuf);
1885         }
1886 }
1887
1888 static TStripElem* do_build_seq_recursively_impl(Sequence * seq, int cfra)
1889 {
1890         TStripElem *se;
1891
1892         se = give_tstripelem(seq, cfra);
1893
1894         if(se) {
1895                 if (seq->type & SEQ_EFFECT) {
1896                         do_effect_seq_recursively(seq, se, cfra);
1897                 } else {
1898                         do_build_seq_ibuf(seq, se, cfra, FALSE);
1899                 }
1900         }
1901         return se;
1902 }
1903
1904 /* FIXME:
1905    
1906 If cfra was float throughout blender (especially in the render
1907 pipeline) one could even _render_ with subframe precision
1908 instead of faking using the blend code below...
1909
1910 */
1911
1912 static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra)
1913 {
1914         SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
1915         int nr = cfra - seq->start;
1916         float f_cfra;
1917         int cfra_left;
1918         int cfra_right;
1919         TStripElem * se = 0;
1920         TStripElem * se1 = 0;
1921         TStripElem * se2 = 0;
1922         
1923         sequence_effect_speed_rebuild_map(seq, 0);
1924         
1925         f_cfra = seq->start + s->frameMap[nr];
1926         
1927         cfra_left = (int) floor(f_cfra);
1928         cfra_right = (int) ceil(f_cfra);
1929
1930         se = give_tstripelem(seq, cfra);
1931
1932         if (cfra_left == cfra_right || 
1933             (s->flags & SEQ_SPEED_BLEND) == 0) {
1934                 test_and_auto_discard_ibuf(se);
1935
1936                 if (se->ibuf == NULL) {
1937                         se1 = do_build_seq_recursively_impl(
1938                                 seq->seq1, cfra_left);
1939
1940                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
1941                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
1942                         else
1943                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
1944
1945                         if (se1 == 0 || se1->ibuf == 0) {
1946                                 make_black_ibuf(se->ibuf);
1947                         } else {
1948                                 if (se->ibuf != se1->ibuf) {
1949                                         if (se->ibuf) {
1950                                                 IMB_freeImBuf(se->ibuf);
1951                                         }
1952
1953                                         se->ibuf = se1->ibuf;
1954                                         IMB_refImBuf(se->ibuf);
1955                                 }
1956                         }
1957                 }
1958         } else {
1959                 struct SeqEffectHandle sh;
1960
1961                 if(se->ibuf) {
1962                         if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty 
1963                            || !(se->ibuf->rect || se->ibuf->rect_float)) {
1964                                 IMB_freeImBuf(se->ibuf);
1965                                 se->ibuf= 0;
1966                         }
1967                 }
1968
1969                 if (se->ibuf == NULL) {
1970                         se1 = do_build_seq_recursively_impl(
1971                                 seq->seq1, cfra_left);
1972                         se2 = do_build_seq_recursively_impl(
1973                                 seq->seq1, cfra_right);
1974
1975                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
1976                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
1977                         else
1978                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
1979                         
1980                         if (!se1 || !se2) {
1981                                 make_black_ibuf(se->ibuf);
1982                         } else {
1983                                 sh = get_sequence_effect(seq);
1984
1985                                 sh.execute(seq, cfra, 
1986                                            f_cfra - (float) cfra_left, 
1987                                            f_cfra - (float) cfra_left, 
1988                                            se->ibuf->x, se->ibuf->y, 
1989                                            se1->ibuf, se2->ibuf, 0, se->ibuf);
1990                         }
1991                 }
1992
1993         }
1994
1995         /* caller expects this to be referenced, so do it! */
1996         if (se->ibuf) {
1997                 IMB_cache_limiter_insert(se->ibuf);
1998                 IMB_cache_limiter_ref(se->ibuf);
1999                 IMB_cache_limiter_touch(se->ibuf);
2000         }
2001
2002         /* children are no longer needed */
2003         if (se1 && se1->ibuf)
2004                 IMB_cache_limiter_unref(se1->ibuf);
2005         if (se2 && se2->ibuf)
2006                 IMB_cache_limiter_unref(se2->ibuf);
2007
2008         return se;
2009 }
2010
2011 /* 
2012  * build all ibufs recursively
2013  * 
2014  * if successfull, the returned TStripElem contains the (referenced!) imbuf
2015  * that means: you _must_ call 
2016  *
2017  * IMB_cache_limiter_unref(rval);
2018  * 
2019  * if rval != 0
2020  * 
2021  */
2022
2023 static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra)
2024 {
2025         if (seq->type == SEQ_SPEED) {
2026                 return do_handle_speed_effect(seq, cfra);
2027         } else {
2028                 return do_build_seq_recursively_impl(seq, cfra);
2029         }
2030 }
2031
2032 static TStripElem* do_build_seq_array_recursively(
2033         ListBase *seqbasep, int cfra, int chanshown)
2034 {
2035         Sequence* seq_arr[MAXSEQ+1];
2036         int count;
2037         int i;
2038         TStripElem* se = 0;
2039
2040         count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
2041
2042         if (!count) {
2043                 return 0;
2044         }
2045
2046         se = give_tstripelem(seq_arr[count - 1], cfra);
2047
2048         test_and_auto_discard_ibuf(se);
2049
2050         if (se->ibuf_comp != 0) {
2051                 IMB_cache_limiter_insert(se->ibuf_comp);
2052                 IMB_cache_limiter_ref(se->ibuf_comp);
2053                 IMB_cache_limiter_touch(se->ibuf_comp);
2054                 return se;
2055         }
2056
2057         
2058         if(count == 1) {
2059                 se = do_build_seq_recursively(seq_arr[0], cfra);
2060                 if (se->ibuf) {
2061                         se->ibuf_comp = se->ibuf;
2062                         IMB_refImBuf(se->ibuf_comp);
2063                 }
2064                 return se;
2065         }
2066
2067
2068         for (i = count - 1; i >= 0; i--) {
2069                 int early_out;
2070                 Sequence * seq = seq_arr[i];
2071                 struct SeqEffectHandle sh;
2072
2073                 se = give_tstripelem(seq, cfra);
2074
2075                 test_and_auto_discard_ibuf(se);
2076
2077                 if (se->ibuf_comp != 0) {
2078                         break;
2079                 }
2080                 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2081                         do_build_seq_recursively(seq, cfra);
2082                         if (se->ibuf) {
2083                                 se->ibuf_comp = se->ibuf;
2084                                 IMB_refImBuf(se->ibuf);
2085                         } else {
2086                                 se->ibuf_comp = IMB_allocImBuf(
2087                                         (short)seqrectx, (short)seqrecty, 
2088                                         32, IB_rect, 0);
2089                         }
2090                         break;
2091                 }
2092
2093                 sh = get_sequence_blend(seq);
2094
2095                 seq->facf0 = seq->facf1 = 1.0;
2096
2097                 if(seq->ipo && seq->ipo->curve.first) {
2098                         do_seq_ipo(seq, cfra);
2099                 } 
2100
2101                 if( G.scene->r.mode & R_FIELDS ); else seq->facf0 = seq->facf1;
2102
2103                 seq->facf0 *= seq->blend_opacity / 100.0;
2104                 seq->facf1 *= seq->blend_opacity / 100.0;
2105
2106                 early_out = sh.early_out(seq, seq->facf0, seq->facf1);
2107
2108                 switch (early_out) {
2109                 case -1:
2110                 case 2:
2111                         do_build_seq_recursively(seq, cfra);
2112                         if (se->ibuf) {
2113                                 se->ibuf_comp = se->ibuf;
2114                                 IMB_refImBuf(se->ibuf_comp);
2115                         } else {
2116                                 se->ibuf_comp = IMB_allocImBuf(
2117                                         (short)seqrectx, (short)seqrecty, 
2118                                         32, IB_rect, 0);
2119                         }
2120                         break;
2121                 case 1:
2122                         if (i == 0) {
2123                                 se->ibuf_comp = IMB_allocImBuf(
2124                                         (short)seqrectx, (short)seqrecty, 
2125                                         32, IB_rect, 0);
2126                                 IMB_cache_limiter_insert(se->ibuf_comp);
2127                                 IMB_cache_limiter_ref(se->ibuf_comp);
2128                                 IMB_cache_limiter_touch(se->ibuf_comp);
2129                         }
2130                         break;
2131                 case 0:
2132                         do_build_seq_recursively(seq, cfra);
2133                         if (!se->ibuf) {
2134                                 se->ibuf = IMB_allocImBuf(
2135                                         (short)seqrectx, (short)seqrecty, 
2136                                         32, IB_rect, 0);
2137                         }
2138                         if (i == 0) {
2139                                 se->ibuf_comp = se->ibuf;
2140                                 IMB_refImBuf(se->ibuf_comp);
2141                         }
2142                         break;
2143                 }
2144         
2145                 if (se->ibuf_comp) {
2146                         break;
2147                 }
2148         }
2149
2150         i++;
2151
2152         for (; i < count; i++) {
2153                 Sequence * seq = seq_arr[i];
2154                 struct SeqEffectHandle sh = get_sequence_blend(seq);
2155                 TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
2156                 TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
2157         
2158                 int early_out = sh.early_out(seq, seq->facf0, seq->facf1);
2159                 switch (early_out) {
2160                 case 0: {
2161                         int x= se2->ibuf->x;
2162                         int y= se2->ibuf->y;
2163                         int swap_input = FALSE;
2164
2165                         if (se1->ibuf_comp->rect_float ||
2166                             se2->ibuf->rect_float) {
2167                                 se2->ibuf_comp = IMB_allocImBuf(
2168                                         (short)seqrectx, (short)seqrecty, 
2169                                         32, IB_rectfloat, 0);
2170                         } else {
2171                                 se2->ibuf_comp = IMB_allocImBuf(
2172                                         (short)seqrectx, (short)seqrecty, 
2173                                         32, IB_rect, 0);
2174                         }
2175
2176
2177                         if (!se1->ibuf_comp->rect_float && 
2178                             se2->ibuf_comp->rect_float) {
2179                                 IMB_float_from_rect(se1->ibuf_comp);
2180                         }
2181                         if (!se2->ibuf->rect_float && 
2182                             se2->ibuf_comp->rect_float) {
2183                                 IMB_float_from_rect(se2->ibuf);
2184                         }
2185
2186                         if (!se1->ibuf_comp->rect && 
2187                             !se2->ibuf_comp->rect_float) {
2188                                 IMB_rect_from_float(se1->ibuf_comp);
2189                         }
2190                         if (!se2->ibuf->rect && 
2191                             !se2->ibuf_comp->rect_float) {
2192                                 IMB_rect_from_float(se2->ibuf);
2193                         }
2194
2195                         /* bad hack, to fix crazy input ordering of 
2196                            those two effects */
2197
2198                         if (seq->blend_mode == SEQ_ALPHAOVER ||
2199                             seq->blend_mode == SEQ_ALPHAUNDER ||
2200                             seq->blend_mode == SEQ_OVERDROP) {
2201                                 swap_input = TRUE;
2202                         }
2203
2204                         if (swap_input) {
2205                                 sh.execute(seq, cfra, 
2206                                            seq->facf0, seq->facf1, x, y, 
2207                                            se2->ibuf, se1->ibuf_comp, 0,
2208                                            se2->ibuf_comp);
2209                         } else {
2210                                 sh.execute(seq, cfra, 
2211                                            seq->facf0, seq->facf1, x, y, 
2212                                            se1->ibuf_comp, se2->ibuf, 0,
2213                                            se2->ibuf_comp);
2214                         }
2215                         
2216                         IMB_cache_limiter_insert(se2->ibuf_comp);
2217                         IMB_cache_limiter_ref(se2->ibuf_comp);
2218                         IMB_cache_limiter_touch(se2->ibuf_comp);
2219
2220                         IMB_cache_limiter_unref(se1->ibuf_comp);
2221                         IMB_cache_limiter_unref(se2->ibuf);
2222
2223                         break;
2224                 }
2225                 case 1: {
2226                         se2->ibuf_comp = se1->ibuf;
2227                         IMB_refImBuf(se2->ibuf_comp);
2228
2229                         break;
2230                 }
2231                 }
2232                 se = se2;
2233         }
2234
2235         return se;
2236 }
2237
2238 /*
2239  * returned ImBuf is refed!
2240  * you have to unref after usage!
2241  */
2242
2243 static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown)
2244 {
2245         Editing *ed;
2246         int count;
2247         ListBase *seqbasep;
2248         TStripElem *se;
2249
2250         ed= G.scene->ed;
2251         if(ed==0) return 0;
2252
2253         count = BLI_countlist(&ed->metastack);
2254         if((chanshown < 0) && (count > 0)) {
2255                 count = MAX2(count + chanshown, 0);
2256                 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2257         } else {
2258                 seqbasep= ed->seqbasep;
2259         }
2260
2261         seqrectx= rectx;        /* bad bad global! */
2262         seqrecty= recty;
2263
2264         se = do_build_seq_array_recursively(seqbasep, cfra, chanshown);
2265
2266         if(!se) { 
2267                 return 0;
2268         }
2269
2270         return se->ibuf_comp;
2271 }
2272
2273 ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra,
2274                             Sequence * seq)
2275 {
2276         TStripElem* se;
2277
2278         seqrectx= rectx;        /* bad bad global! */
2279         seqrecty= recty;
2280
2281         se = do_build_seq_recursively(seq, cfra);
2282
2283         if(!se) { 
2284                 return 0;
2285         }
2286
2287         if (se->ibuf) {
2288                 IMB_cache_limiter_unref(se->ibuf);
2289         }
2290
2291         return se->ibuf;
2292 }
2293
2294 ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
2295 {
2296         ImBuf* i = give_ibuf_seq_impl(rectx, recty, cfra, chanshown);
2297
2298         if (i) {
2299                 IMB_cache_limiter_unref(i);
2300         }
2301         return i;
2302 }
2303
2304 /* threading api */
2305
2306 static ListBase running_threads;
2307 static ListBase prefetch_wait;
2308 static ListBase prefetch_done;
2309
2310 static pthread_mutex_t queue_lock          = PTHREAD_MUTEX_INITIALIZER;
2311 static pthread_mutex_t wakeup_lock         = PTHREAD_MUTEX_INITIALIZER;
2312 static pthread_cond_t  wakeup_cond         = PTHREAD_COND_INITIALIZER;
2313
2314 static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2315 static pthread_cond_t  prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2316
2317 static pthread_mutex_t frame_done_lock     = PTHREAD_MUTEX_INITIALIZER;
2318 static pthread_cond_t  frame_done_cond     = PTHREAD_COND_INITIALIZER;
2319
2320 static volatile int seq_thread_shutdown = FALSE;
2321 static volatile int seq_last_given_monoton_cfra = 0;
2322 static int monoton_cfra = 0;
2323
2324 typedef struct PrefetchThread {
2325         struct PrefetchThread *next, *prev;
2326         struct PrefetchQueueElem *current;
2327         pthread_t pthread;
2328         int running;
2329 } PrefetchThread;
2330
2331 typedef struct PrefetchQueueElem {
2332         struct PrefetchQueueElem *next, *prev;
2333         
2334         int rectx;
2335         int recty;
2336         int cfra;
2337         int chanshown;
2338
2339         int monoton_cfra;
2340
2341         struct ImBuf * ibuf;
2342 } PrefetchQueueElem;
2343
2344 static void * seq_prefetch_thread(void * This_)
2345 {
2346         PrefetchThread * This = This_;
2347
2348         while (!seq_thread_shutdown) {
2349                 PrefetchQueueElem * e;
2350                 int s_last;
2351
2352                 pthread_mutex_lock(&queue_lock);
2353                 e = prefetch_wait.first;
2354                 if (e) {
2355                         BLI_remlink(&prefetch_wait, e);
2356                 }
2357                 s_last = seq_last_given_monoton_cfra;
2358
2359                 This->current = e;
2360
2361                 pthread_mutex_unlock(&queue_lock);
2362
2363                 if (!e) {
2364                         pthread_mutex_lock(&prefetch_ready_lock);
2365
2366                         This->running = FALSE;
2367
2368                         pthread_cond_signal(&prefetch_ready_cond);
2369                         pthread_mutex_unlock(&prefetch_ready_lock);
2370
2371                         pthread_mutex_lock(&wakeup_lock);
2372                         if (!seq_thread_shutdown) {
2373                                 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2374                         }
2375                         pthread_mutex_unlock(&wakeup_lock);
2376                         continue;
2377                 }
2378
2379                 This->running = TRUE;
2380                 
2381                 if (e->cfra >= s_last) { 
2382                         e->ibuf = give_ibuf_seq_impl(
2383                                 e->rectx, e->recty, e->cfra, e->chanshown);
2384                 }
2385
2386                 pthread_mutex_lock(&queue_lock);
2387
2388                 BLI_addtail(&prefetch_done, e);
2389
2390                 for (e = prefetch_wait.first; e; e = e->next) {
2391                         if (s_last > e->monoton_cfra) {
2392                                 BLI_remlink(&prefetch_wait, e);
2393                                 MEM_freeN(e);
2394                         }
2395                 }
2396
2397                 for (e = prefetch_done.first; e; e = e->next) {
2398                         if (s_last > e->monoton_cfra) {
2399                                 if (e->ibuf) {
2400                                         IMB_cache_limiter_unref(e->ibuf);
2401                                 }
2402                                 BLI_remlink(&prefetch_done, e);
2403                                 MEM_freeN(e);
2404                         }
2405                 }
2406
2407                 pthread_mutex_unlock(&queue_lock);
2408
2409                 pthread_mutex_lock(&frame_done_lock);
2410                 pthread_cond_signal(&frame_done_cond);
2411                 pthread_mutex_unlock(&frame_done_lock);
2412         }
2413         return 0;
2414 }
2415
2416 void seq_start_threads()
2417 {
2418         int i;
2419
2420         running_threads.first = running_threads.last = NULL;
2421         prefetch_wait.first = prefetch_wait.last = NULL;
2422         prefetch_done.first = prefetch_done.last = NULL;
2423
2424         seq_thread_shutdown = FALSE;
2425         seq_last_given_monoton_cfra = monoton_cfra = 0;
2426
2427         /* since global structures are modified during the processing
2428            of one frame, only one render thread is currently possible... 
2429
2430            (but we code, in the hope, that we can remove this restriction
2431            soon...)
2432         */
2433
2434         fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2435
2436         for (i = 0; i < 1; i++) {
2437                 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), 
2438                                                 "prefetch_thread");
2439                 t->running = TRUE;
2440                 BLI_addtail(&running_threads, t);
2441
2442                 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2443         }
2444
2445         /* init malloc mutex */
2446         BLI_init_threads(0, 0, 0);
2447 }
2448
2449 void seq_stop_threads()
2450 {
2451         PrefetchThread *tslot;
2452         PrefetchQueueElem * e;
2453
2454         fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2455
2456         if (seq_thread_shutdown) {
2457                 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2458                 return;
2459         }
2460         
2461         pthread_mutex_lock(&wakeup_lock);
2462
2463         seq_thread_shutdown = TRUE;
2464
2465         pthread_cond_broadcast(&wakeup_cond);
2466         pthread_mutex_unlock(&wakeup_lock);
2467
2468         for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2469                 pthread_join(tslot->pthread, NULL);
2470         }
2471
2472
2473         for (e = prefetch_wait.first; e; e = e->next) {
2474                 BLI_remlink(&prefetch_wait, e);
2475                 MEM_freeN(e);
2476         }
2477
2478         for (e = prefetch_done.first; e; e = e->next) {
2479                 if (e->ibuf) {
2480                         IMB_cache_limiter_unref(e->ibuf);
2481                 }
2482                 BLI_remlink(&prefetch_done, e);
2483                 MEM_freeN(e);
2484         }
2485
2486         BLI_freelistN(&running_threads);
2487
2488         /* deinit malloc mutex */
2489         BLI_end_threads(0);
2490 }
2491
2492 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown)
2493 {
2494         PrefetchQueueElem * e;
2495         if (seq_thread_shutdown) {
2496                 return;
2497         }
2498
2499         e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2500         e->rectx = rectx;
2501         e->recty = recty;
2502         e->cfra = cfra;
2503         e->chanshown = chanshown;
2504         e->monoton_cfra = monoton_cfra++;
2505
2506         pthread_mutex_lock(&queue_lock);
2507         BLI_addtail(&prefetch_wait, e);
2508         pthread_mutex_unlock(&queue_lock);
2509         
2510         pthread_mutex_lock(&wakeup_lock);
2511         pthread_cond_signal(&wakeup_cond);
2512         pthread_mutex_unlock(&wakeup_lock);
2513 }
2514
2515 void seq_wait_for_prefetch_ready()
2516 {
2517         PrefetchThread *tslot;
2518
2519         if (seq_thread_shutdown) {
2520                 return;
2521         }
2522
2523         fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
2524
2525         pthread_mutex_lock(&prefetch_ready_lock);
2526
2527         for(;;) {
2528                 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2529                         if (tslot->running) {
2530                                 break;
2531                         }
2532                 }
2533                 if (!tslot) {
2534                         break;
2535                 }
2536                 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
2537         }
2538
2539         pthread_mutex_unlock(&prefetch_ready_lock);
2540
2541         fprintf(stderr, "SEQ-THREAD: prefetch done\n");
2542 }
2543
2544 ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, int chanshown)
2545 {
2546         PrefetchQueueElem * e = 0;
2547         int found_something = FALSE;
2548
2549         if (seq_thread_shutdown) {
2550                 return give_ibuf_seq(rectx, recty, cfra, chanshown);
2551         }
2552
2553         while (!e) {
2554                 int success = FALSE;
2555                 pthread_mutex_lock(&queue_lock);
2556
2557                 for (e = prefetch_done.first; e; e = e->next) {
2558                         if (cfra == e->cfra &&
2559                             chanshown == e->chanshown &&
2560                             rectx == e->rectx && 
2561                             recty == e->recty) {
2562                                 success = TRUE;
2563                                 found_something = TRUE;
2564                                 break;
2565                         }
2566                 }
2567
2568                 if (!e) {
2569                         for (e = prefetch_wait.first; e; e = e->next) {
2570                                 if (cfra == e->cfra &&
2571                                     chanshown == e->chanshown &&
2572                                     rectx == e->rectx && 
2573                                     recty == e->recty) {
2574                                         found_something = TRUE;
2575                                         break;
2576                                 }
2577                         }
2578                 }
2579
2580                 if (!e) {
2581                         PrefetchThread *tslot;
2582
2583                         for(tslot = running_threads.first; 
2584                             tslot; tslot= tslot->next) {
2585                                 if (tslot->current &&
2586                                     cfra == tslot->current->cfra &&
2587                                     chanshown == tslot->current->chanshown &&
2588                                     rectx == tslot->current->rectx && 
2589                                     recty == tslot->current->recty) {
2590                                         found_something = TRUE;
2591                                         break;
2592                                 }
2593                         }
2594                 }
2595
2596                 /* e->ibuf is unrefed by render thread on next round. */
2597
2598                 if (e) {
2599                         seq_last_given_monoton_cfra = e->monoton_cfra;
2600                 }
2601
2602                 pthread_mutex_unlock(&queue_lock);
2603
2604                 if (!success) {
2605                         e = NULL;
2606
2607                         if (!found_something) {
2608                                 fprintf(stderr, 
2609                                         "SEQ-THREAD: Requested frame "
2610                                         "not in queue ???\n");
2611                                 break;
2612                         }
2613                         pthread_mutex_lock(&frame_done_lock);
2614                         pthread_cond_wait(&frame_done_cond, &frame_done_lock);
2615                         pthread_mutex_unlock(&frame_done_lock);
2616                 }
2617         }
2618         
2619         return e ? e->ibuf : 0;
2620 }
2621
2622 /* Functions to free imbuf and anim data on changes */
2623
2624 static void free_imbuf_strip_elem(TStripElem *se)
2625 {
2626         if(se->ibuf) {
2627                 IMB_freeImBuf(se->ibuf);
2628         }
2629         if(se->ibuf_comp) {
2630                 IMB_freeImBuf(se->ibuf_comp);
2631         }
2632         se->ibuf_comp = 0;
2633         se->ibuf= 0;
2634         se->ok= STRIPELEM_OK;
2635         se->se1= se->se2= se->se3= 0;
2636 }
2637
2638 static void free_anim_seq(Sequence *seq)
2639 {
2640         if(seq->anim) {
2641                 IMB_free_anim(seq->anim);
2642                 seq->anim = 0;
2643         }
2644 }
2645
2646 void free_imbuf_seq_except(int cfra)
2647 {
2648         Editing *ed= G.scene->ed;
2649         Sequence *seq;
2650         TStripElem *se;
2651         int a;
2652
2653         if(ed==0) return;
2654
2655         WHILE_SEQ(&ed->seqbase) {
2656                 if(seq->strip) {
2657                         TStripElem * curelem = give_tstripelem(seq, cfra);
2658
2659                         for(a = 0, se = seq->strip->tstripdata; 
2660                             a < seq->strip->len && se; a++, se++) {
2661                                 if(se != curelem) {
2662                                         free_imbuf_strip_elem(se);
2663                                 }
2664                         }
2665                         for(a = 0, se = seq->strip->tstripdata_startstill;
2666                             a < seq->strip->startstill && se; a++, se++) {
2667                                 if(se != curelem) {
2668                                         free_imbuf_strip_elem(se);
2669                                 }
2670                         }
2671                         for(a = 0, se = seq->strip->tstripdata_endstill;
2672                             a < seq->strip->endstill && se; a++, se++) {
2673                                 if(se != curelem) {
2674                                         free_imbuf_strip_elem(se);
2675                                 }
2676                         }
2677                         if(seq->strip->ibuf_startstill) {
2678                                 IMB_freeImBuf(seq->strip->ibuf_startstill);
2679                                 seq->strip->ibuf_startstill = 0;
2680                         }
2681
2682                         if(seq->strip->ibuf_endstill) {
2683                                 IMB_freeImBuf(seq->strip->ibuf_endstill);
2684                                 seq->strip->ibuf_endstill = 0;
2685                         }
2686
2687                         if(seq->type==SEQ_MOVIE)
2688                                 if(seq->startdisp > cfra || seq->enddisp < cfra)
2689                                         free_anim_seq(seq);
2690                 }
2691         }
2692         END_SEQ
2693 }
2694
2695 void free_imbuf_seq()
2696 {
2697         Editing *ed= G.scene->ed;
2698         Sequence *seq;
2699         TStripElem *se;
2700         int a;
2701
2702         if(ed==0) return;
2703
2704         WHILE_SEQ(&ed->seqbase) {
2705                 if(seq->strip) {
2706                         for(a = 0, se = seq->strip->tstripdata; 
2707                             a < seq->strip->len && se; a++, se++) {
2708                                 free_imbuf_strip_elem(se);
2709                         }
2710                         for(a = 0, se = seq->strip->tstripdata_startstill; 
2711                             a < seq->strip->startstill && se; a++, se++) {
2712                                 free_imbuf_strip_elem(se);
2713                         }
2714                         for(a = 0, se = seq->strip->tstripdata_endstill; 
2715                             a < seq->strip->endstill && se; a++, se++) {
2716                                 free_imbuf_strip_elem(se);
2717                         }
2718                         if(seq->strip->ibuf_startstill) {
2719                                 IMB_freeImBuf(seq->strip->ibuf_startstill);
2720                                 seq->strip->ibuf_startstill = 0;
2721                         }
2722
2723                         if(seq->strip->ibuf_endstill) {
2724                                 IMB_freeImBuf(seq->strip->ibuf_endstill);
2725                                 seq->strip->ibuf_endstill = 0;
2726                         }
2727
2728                         if(seq->type==SEQ_MOVIE)
2729                                 free_anim_seq(seq);
2730                         if(seq->type==SEQ_SPEED) {
2731                                 sequence_effect_speed_rebuild_map(seq, 1);
2732                         }
2733                 }
2734         }
2735         END_SEQ
2736 }
2737
2738 void free_imbuf_seq_with_ipo(struct Ipo *ipo)
2739 {
2740         /* force update of all sequences with this ipo, on ipo changes */
2741         Editing *ed= G.scene->ed;
2742         Sequence *seq;
2743
2744         if(ed==0) return;
2745
2746         WHILE_SEQ(&ed->seqbase) {
2747                 if(seq->ipo == ipo) {
2748                         update_changed_seq_and_deps(seq, 0, 1);
2749                         if(seq->type == SEQ_SPEED) {
2750                                 sequence_effect_speed_rebuild_map(seq, 1);
2751                         }
2752                 }
2753         }
2754         END_SEQ
2755 }
2756
2757 static int update_changed_seq_recurs(Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
2758 {
2759         Sequence *subseq;
2760         int a, free_imbuf = 0;
2761         TStripElem *se;
2762
2763         /* recurs downwards to see if this seq depends on the changed seq */
2764
2765         if(seq == NULL)
2766                 return 0;
2767
2768         if(seq == changed_seq)
2769                 free_imbuf = 1;
2770         
2771         for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
2772                 if(update_changed_seq_recurs(subseq, changed_seq, len_change, ibuf_change))
2773                         free_imbuf = TRUE;
2774         
2775         if(seq->seq1)
2776                 if(update_changed_seq_recurs(seq->seq1, changed_seq, len_change, ibuf_change))
2777                         free_imbuf = TRUE;
2778         if(seq->seq2 && (seq->seq2 != seq->seq1))
2779                 if(update_changed_seq_recurs(seq->seq2, changed_seq, len_change, ibuf_change))
2780                         free_imbuf = TRUE;
2781         if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
2782                 if(update_changed_seq_recurs(seq->seq3, changed_seq, len_change, ibuf_change))
2783                         free_imbuf = TRUE;
2784         
2785         if(free_imbuf) {
2786                 if(ibuf_change) {
2787                         se= seq->strip->tstripdata;
2788                         if (se) {
2789                                 for(a=0; a<seq->len; a++, se++)
2790                                         free_imbuf_strip_elem(se);
2791                         }
2792                 
2793                         if(seq->type == SEQ_MOVIE)
2794                                 free_anim_seq(seq);
2795                         if(seq->type == SEQ_SPEED) {
2796                                 sequence_effect_speed_rebuild_map(seq, 1);
2797                         }
2798                 }
2799
2800                 if(len_change)
2801                         calc_sequence(seq);
2802         }
2803         
2804         return free_imbuf;
2805 }
2806
2807 void update_changed_seq_and_deps(Sequence *changed_seq, int len_change, int ibuf_change)
2808 {
2809         Editing *ed= G.scene->ed;
2810         Sequence *seq;
2811
2812         if (!ed) return;
2813
2814         for (seq=ed->seqbase.first; seq; seq=seq->next)
2815                 update_changed_seq_recurs(seq, changed_seq, len_change, ibuf_change);
2816 }
2817
2818 /* bad levell call... */
2819 void do_render_seq(RenderResult *rr, int cfra)
2820 {
2821         ImBuf *ibuf;
2822
2823         G.f |= G_PLAYANIM;      /* waitcursor patch */
2824
2825         ibuf= give_ibuf_seq(rr->rectx, rr->recty, cfra, 0);
2826         
2827         if(ibuf) {
2828                 if(ibuf->rect_float) {
2829                         if (!rr->rectf)
2830                                 rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf");
2831                         
2832                         memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty);
2833                         
2834                         /* TSK! Since sequence render doesn't free the *rr render result, the old rect32
2835                            can hang around when sequence render has rendered a 32 bits one before */
2836                         if(rr->rect32) {
2837                                 MEM_freeN(rr->rect32);
2838                                 rr->rect32= NULL;
2839                         }
2840                 }
2841                 else if(ibuf->rect) {
2842                         if (!rr->rect32)
2843                                 rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
2844
2845                         memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty);
2846
2847                         /* if (ibuf->zbuf) { */
2848                         /*      if (R.rectz) freeN(R.rectz); */
2849                         /*      R.rectz = BLI_dupallocN(ibuf->zbuf); */
2850                         /* } */
2851                 }
2852                 
2853                 /* Let the cache limitor take care of this (schlaile) */
2854                 /* While render let's keep all memory available for render 
2855                    (ton)
2856                    At least if free memory is tight...
2857                    This can make a big difference in encoding speed
2858                    (it is around 4 times(!) faster, if we do not waste time
2859                    on freeing _all_ buffers every time on long timelines...)
2860                    (schlaile)
2861                 */
2862                 {
2863                         extern int mem_in_use;
2864                         extern int mmap_in_use;
2865
2866                         int max = MEM_CacheLimiter_get_maximum();
2867                         if (max != 0 && mem_in_use + mmap_in_use > max) {
2868                                 fprintf(stderr, "mem_in_use = %d, max = %d\n",
2869                                         mem_in_use + mmap_in_use, max);
2870                                 fprintf(stderr, "Cleaning up, please wait...\n"
2871                                         "If this happens very often,\n"
2872                                         "consider "
2873                                         "raising the memcache limit in the "
2874                                         "user preferences.\n");
2875                                 free_imbuf_seq();
2876                         }
2877                 }
2878         }
2879         else {
2880                 /* render result is delivered empty in most cases, nevertheless we handle all cases */
2881                 if (rr->rectf)
2882                         memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty);
2883                 else if (rr->rect32)
2884                         memset(rr->rect32, 0, 4*rr->rectx*rr->recty);
2885                 else
2886                         rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
2887         }
2888         
2889         G.f &= ~G_PLAYANIM;
2890
2891 }