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