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