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