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