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