use static functions where possible for some local functions.
[blender.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_GetResultImage(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                         BIF_end_render_callbacks();
2085                         
2086                         /* restore */
2087                         scene->r.scemode |= doseq;
2088
2089                         // XXX
2090 #if 0
2091                         if((G.f & G_PLAYANIM)==0 /* bad, is set on do_render_seq */
2092                            && !have_seq
2093                            && !build_proxy_run) 
2094 #endif
2095                         
2096                         CFRA = oldcfra;
2097                         set_last_seq(oldseq);
2098
2099                         copy_to_ibuf_still(seq, se);
2100
2101                         if (!build_proxy_run) {
2102                                 if(se->ibuf == NULL) {
2103                                         se->ok = STRIPELEM_FAILED;
2104                                 } else {
2105                                         input_preprocess(scene, seq, se, cfra);
2106                                 }
2107                         }
2108
2109                 }
2110 #endif
2111         }
2112         if (!build_proxy_run) {
2113                 if (se->ibuf && use_limiter) {
2114                         IMB_cache_limiter_insert(se->ibuf);
2115                         IMB_cache_limiter_ref(se->ibuf);
2116                         IMB_cache_limiter_touch(se->ibuf);
2117                 }
2118         }
2119 }
2120
2121 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size);
2122
2123 static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size)
2124 {
2125         float fac, facf;
2126         struct SeqEffectHandle sh = get_sequence_effect(seq);
2127         int early_out;
2128
2129         se->se1 = 0;
2130         se->se2 = 0;
2131         se->se3 = 0;
2132
2133 #if 0 // XXX old animation system
2134         if(seq->ipo && seq->ipo->curve.first) {
2135                 do_seq_ipo(scene, seq, cfra);
2136                 fac= seq->facf0;
2137                 facf= seq->facf1;
2138         } else 
2139 #endif // XXX old animation system
2140         {
2141                 sh.get_default_fac(seq, cfra, &fac, &facf);
2142         } 
2143
2144         if( scene->r.mode & R_FIELDS ); else facf= fac;
2145         
2146         early_out = sh.early_out(seq, fac, facf);
2147         switch (early_out) {
2148         case -1:
2149                 /* no input needed */
2150                 break;
2151         case 0:
2152                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2153                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2154                 if (seq->seq3) {
2155                         se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size);
2156                 }
2157                 break;
2158         case 1:
2159                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2160                 break;
2161         case 2:
2162                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2163                 break;
2164         }
2165
2166
2167         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2168
2169         /* children are not needed anymore ... */
2170
2171         if (se->se1 && se->se1->ibuf) {
2172                 IMB_cache_limiter_unref(se->se1->ibuf);
2173         }
2174         if (se->se2 && se->se2->ibuf) {
2175                 IMB_cache_limiter_unref(se->se2->ibuf);
2176         }
2177         if (se->se3 && se->se3->ibuf) {
2178                 IMB_cache_limiter_unref(se->se3->ibuf);
2179         }
2180         check_limiter_refcount("do_effect_seq_recursively", se);
2181 }
2182
2183 static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size)
2184 {
2185         TStripElem *se;
2186
2187         se = give_tstripelem(seq, cfra);
2188
2189         if(se) {
2190                 if (seq->type & SEQ_EFFECT) {
2191                         do_effect_seq_recursively(scene, seq, se, cfra, render_size);
2192                 } else {
2193                         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2194                 }
2195         }
2196         return se;
2197 }
2198
2199 /* FIXME:
2200    
2201 If cfra was float throughout blender (especially in the render
2202 pipeline) one could even _render_ with subframe precision
2203 instead of faking using the blend code below...
2204
2205 */
2206
2207 static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size)
2208 {
2209         SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
2210         int nr = cfra - seq->start;
2211         float f_cfra;
2212         int cfra_left;
2213         int cfra_right;
2214         TStripElem * se = 0;
2215         TStripElem * se1 = 0;
2216         TStripElem * se2 = 0;
2217         
2218         sequence_effect_speed_rebuild_map(seq, 0);
2219         
2220         f_cfra = seq->start + s->frameMap[nr];
2221         
2222         cfra_left = (int) floor(f_cfra);
2223         cfra_right = (int) ceil(f_cfra);
2224
2225         se = give_tstripelem(seq, cfra);
2226
2227         if (!se) {
2228                 return se;
2229         }
2230
2231         if (cfra_left == cfra_right || 
2232             (s->flags & SEQ_SPEED_BLEND) == 0) {
2233                 test_and_auto_discard_ibuf(se);
2234
2235                 if (se->ibuf == NULL) {
2236                         se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2237
2238                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2239                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2240                         else
2241                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2242
2243                         if (se1 == 0 || se1->ibuf == 0) {
2244                                 make_black_ibuf(se->ibuf);
2245                         } else {
2246                                 if (se->ibuf != se1->ibuf) {
2247                                         if (se->ibuf) {
2248                                                 IMB_freeImBuf(se->ibuf);
2249                                         }
2250
2251                                         se->ibuf = se1->ibuf;
2252                                         IMB_refImBuf(se->ibuf);
2253                                 }
2254                         }
2255                 }
2256         } else {
2257                 struct SeqEffectHandle sh;
2258
2259                 if(se->ibuf) {
2260                         if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty 
2261                            || !(se->ibuf->rect || se->ibuf->rect_float)) {
2262                                 IMB_freeImBuf(se->ibuf);
2263                                 se->ibuf= 0;
2264                         }
2265                 }
2266
2267                 if (se->ibuf == NULL) {
2268                         se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2269                         se2 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_right, render_size);
2270
2271                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2272                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2273                         else
2274                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2275                         
2276                         if (!se1 || !se2) {
2277                                 make_black_ibuf(se->ibuf);
2278                         } else {
2279                                 sh = get_sequence_effect(seq);
2280
2281                                 sh.execute(seq, cfra, 
2282                                            f_cfra - (float) cfra_left, 
2283                                            f_cfra - (float) cfra_left, 
2284                                            se->ibuf->x, se->ibuf->y, 
2285                                            se1->ibuf, se2->ibuf, 0, se->ibuf);
2286                         }
2287                 }
2288
2289         }
2290
2291         /* caller expects this to be referenced, so do it! */
2292         if (se->ibuf) {
2293                 IMB_cache_limiter_insert(se->ibuf);
2294                 IMB_cache_limiter_ref(se->ibuf);
2295                 IMB_cache_limiter_touch(se->ibuf);
2296         }
2297
2298         /* children are no longer needed */
2299         if (se1 && se1->ibuf)
2300                 IMB_cache_limiter_unref(se1->ibuf);
2301         if (se2 && se2->ibuf)
2302                 IMB_cache_limiter_unref(se2->ibuf);
2303
2304         check_limiter_refcount("do_handle_speed_effect", se);
2305
2306         return se;
2307 }
2308
2309 /* 
2310  * build all ibufs recursively
2311  * 
2312  * if successfull, the returned TStripElem contains the (referenced!) imbuf
2313  * that means: you _must_ call 
2314  *
2315  * IMB_cache_limiter_unref(rval);
2316  * 
2317  * if rval != 0
2318  * 
2319  */
2320
2321 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size)
2322 {
2323         TStripElem *se;
2324         if (seq->type == SEQ_SPEED) {
2325                 se = do_handle_speed_effect(scene, seq, cfra, render_size);
2326         } else {
2327                 se = do_build_seq_recursively_impl(scene, seq, cfra, render_size);
2328         }
2329
2330         check_limiter_refcount("do_build_seq_recursively", se);
2331
2332         return se;
2333 }
2334
2335 static TStripElem* do_build_seq_array_recursively(Scene *scene,
2336         ListBase *seqbasep, int cfra, int chanshown, int render_size)
2337 {
2338         Sequence* seq_arr[MAXSEQ+1];
2339         int count;
2340         int i;
2341         TStripElem* se = 0;
2342
2343         count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
2344
2345         if (!count) {
2346                 return 0;
2347         }
2348
2349         se = give_tstripelem(seq_arr[count - 1], cfra);
2350
2351         if (!se) {
2352                 return 0;
2353         }
2354
2355         test_and_auto_discard_ibuf(se);
2356
2357         if (se->ibuf_comp != 0) {
2358                 IMB_cache_limiter_insert(se->ibuf_comp);
2359                 IMB_cache_limiter_ref(se->ibuf_comp);
2360                 IMB_cache_limiter_touch(se->ibuf_comp);
2361                 return se;
2362         }
2363
2364         
2365         if(count == 1) {
2366                 se = do_build_seq_recursively(scene, seq_arr[0], cfra, render_size);
2367                 if (se->ibuf) {
2368                         se->ibuf_comp = se->ibuf;
2369                         IMB_refImBuf(se->ibuf_comp);
2370                 }
2371                 return se;
2372         }
2373
2374
2375         for (i = count - 1; i >= 0; i--) {
2376                 int early_out;
2377                 Sequence * seq = seq_arr[i];
2378                 struct SeqEffectHandle sh;
2379
2380                 se = give_tstripelem(seq, cfra);
2381
2382                 test_and_auto_discard_ibuf(se);
2383
2384                 if (se->ibuf_comp != 0) {
2385                         break;
2386                 }
2387                 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2388                         do_build_seq_recursively(scene, seq, cfra, render_size);
2389                         if (se->ibuf) {
2390                                 se->ibuf_comp = se->ibuf;
2391                                 IMB_refImBuf(se->ibuf);
2392                         } else {
2393                                 se->ibuf_comp = IMB_allocImBuf(
2394                                         (short)seqrectx, (short)seqrecty, 
2395                                         32, IB_rect, 0);
2396                                 IMB_cache_limiter_insert(se->ibuf_comp);
2397                                 IMB_cache_limiter_ref(se->ibuf_comp);
2398                                 IMB_cache_limiter_touch(se->ibuf_comp);
2399                         }
2400                         break;
2401                 }
2402
2403                 sh = get_sequence_blend(seq);
2404
2405                 seq->facf0 = seq->facf1 = 1.0;
2406
2407 #if 0 // XXX old animation system
2408                 if(seq->ipo && seq->ipo->curve.first) {
2409                         do_seq_ipo(scene, seq, cfra);
2410                 } 
2411 #endif
2412
2413                 if( scene->r.mode & R_FIELDS ); else seq->facf0 = seq->facf1;
2414
2415                 seq->facf0 *= seq->blend_opacity / 100.0;
2416                 seq->facf1 *= seq->blend_opacity / 100.0;
2417
2418                 early_out = sh.early_out(seq, seq->facf0, seq->facf1);
2419
2420                 switch (early_out) {
2421                 case -1:
2422                 case 2:
2423                         do_build_seq_recursively(scene, seq, cfra, render_size);
2424                         if (se->ibuf) {
2425                                 se->ibuf_comp = se->ibuf;
2426                                 IMB_refImBuf(se->ibuf_comp);
2427                         } else {
2428                                 se->ibuf_comp = IMB_allocImBuf(
2429                                         (short)seqrectx, (short)seqrecty, 
2430                                         32, IB_rect, 0);
2431                                 IMB_cache_limiter_insert(se->ibuf_comp);
2432                                 IMB_cache_limiter_ref(se->ibuf_comp);
2433                                 IMB_cache_limiter_touch(se->ibuf_comp);
2434                         }
2435                         break;
2436                 case 1:
2437                         if (i == 0) {
2438                                 se->ibuf_comp = IMB_allocImBuf(
2439                                         (short)seqrectx, (short)seqrecty, 
2440                                         32, IB_rect, 0);
2441                                 IMB_cache_limiter_insert(se->ibuf_comp);
2442                                 IMB_cache_limiter_ref(se->ibuf_comp);
2443                                 IMB_cache_limiter_touch(se->ibuf_comp);
2444                         }
2445                         break;
2446                 case 0:
2447                         do_build_seq_recursively(scene, seq, cfra, render_size);
2448                         if (!se->ibuf) {
2449                                 se->ibuf = IMB_allocImBuf(
2450                                         (short)seqrectx, (short)seqrecty, 
2451                                         32, IB_rect, 0);
2452                                 IMB_cache_limiter_insert(se->ibuf);
2453                                 IMB_cache_limiter_ref(se->ibuf);
2454                                 IMB_cache_limiter_touch(se->ibuf);
2455                         }
2456                         if (i == 0) {
2457                                 se->ibuf_comp = se->ibuf;
2458                                 IMB_refImBuf(se->ibuf_comp);
2459                         }
2460                         break;
2461                 }
2462         
2463                 if (se->ibuf_comp) {
2464                         break;
2465                 }
2466         }
2467
2468         i++;
2469
2470         for (; i < count; i++) {
2471                 Sequence * seq = seq_arr[i];
2472                 struct SeqEffectHandle sh = get_sequence_blend(seq);
2473                 TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
2474                 TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
2475         
2476                 int early_out = sh.early_out(seq, seq->facf0, seq->facf1);
2477                 switch (early_out) {
2478                 case 0: {
2479                         int x= se2->ibuf->x;
2480                         int y= se2->ibuf->y;
2481                         int swap_input = FALSE;
2482
2483                         if (se1->ibuf_comp->rect_float ||
2484                             se2->ibuf->rect_float) {
2485                                 se2->ibuf_comp = IMB_allocImBuf(
2486                                         (short)seqrectx, (short)seqrecty, 
2487                                         32, IB_rectfloat, 0);
2488                         } else {
2489                                 se2->ibuf_comp = IMB_allocImBuf(
2490                                         (short)seqrectx, (short)seqrecty, 
2491                                         32, IB_rect, 0);
2492                         }
2493
2494
2495                         if (!se1->ibuf_comp->rect_float && 
2496                             se2->ibuf_comp->rect_float) {
2497                                 IMB_float_from_rect(se1->ibuf_comp);
2498                         }
2499                         if (!se2->ibuf->rect_float && 
2500                             se2->ibuf_comp->rect_float) {
2501                                 IMB_float_from_rect(se2->ibuf);
2502                         }
2503
2504                         if (!se1->ibuf_comp->rect && 
2505                             !se2->ibuf_comp->rect_float) {
2506                                 IMB_rect_from_float(se1->ibuf_comp);
2507                         }
2508                         if (!se2->ibuf->rect && 
2509                             !se2->ibuf_comp->rect_float) {
2510                                 IMB_rect_from_float(se2->ibuf);
2511                         }
2512                         
2513                         /* bad hack, to fix crazy input ordering of 
2514                            those two effects */
2515
2516                         if (seq->blend_mode == SEQ_ALPHAOVER ||
2517                             seq->blend_mode == SEQ_ALPHAUNDER ||
2518                             seq->blend_mode == SEQ_OVERDROP) {
2519                                 swap_input = TRUE;
2520                         }
2521
2522                         if (swap_input) {
2523                                 sh.execute(seq, cfra, 
2524                                            seq->facf0, seq->facf1, x, y, 
2525                                            se2->ibuf, se1->ibuf_comp, 0,
2526                                            se2->ibuf_comp);
2527                         } else {
2528                                 sh.execute(seq, cfra, 
2529                                            seq->facf0, seq->facf1, x, y, 
2530                                            se1->ibuf_comp, se2->ibuf, 0,
2531                                            se2->ibuf_comp);
2532                         }
2533                         
2534                         IMB_cache_limiter_insert(se2->ibuf_comp);
2535                         IMB_cache_limiter_ref(se2->ibuf_comp);
2536                         IMB_cache_limiter_touch(se2->ibuf_comp);
2537
2538                         IMB_cache_limiter_unref(se1->ibuf_comp);
2539                         IMB_cache_limiter_unref(se2->ibuf);
2540
2541                         break;
2542                 }
2543                 case 1: {
2544                         se2->ibuf_comp = se1->ibuf;
2545                         IMB_refImBuf(se2->ibuf_comp);
2546
2547                         break;
2548                 }
2549                 }
2550                 se = se2;
2551         }
2552
2553         return se;
2554 }
2555
2556 /*
2557  * returned ImBuf is refed!
2558  * you have to unref after usage!
2559  */
2560
2561 static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2562 {
2563         Editing *ed= seq_give_editing(scene, FALSE);
2564         int count;
2565         ListBase *seqbasep;
2566         TStripElem *se;
2567
2568         
2569         if(ed==NULL) return NULL;
2570
2571         count = BLI_countlist(&ed->metastack);
2572         if((chanshown < 0) && (count > 0)) {
2573                 count = MAX2(count + chanshown, 0);
2574                 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2575         } else {
2576                 seqbasep= ed->seqbasep;
2577         }
2578
2579         seqrectx= rectx;        /* bad bad global! */
2580         seqrecty= recty;
2581
2582         se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size);
2583
2584         if(!se) { 
2585                 return 0;
2586         }
2587
2588         check_limiter_refcount_comp("give_ibuf_seq_impl", se);
2589
2590         return se->ibuf_comp;
2591 }
2592
2593 ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
2594 {
2595         TStripElem* se;
2596
2597         seqrectx= rectx;        /* bad bad global! */
2598         seqrecty= recty;
2599
2600         se = do_build_seq_recursively(scene, seq, cfra, render_size);
2601
2602         if(!se) { 
2603                 return 0;
2604         }
2605
2606         check_limiter_refcount("give_ibuf_seq_direct", se);
2607
2608         if (se->ibuf) {
2609                 IMB_cache_limiter_unref(se->ibuf);
2610         }
2611
2612         return se->ibuf;
2613 }
2614
2615 ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2616 {
2617         ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size);
2618
2619         if (i) {
2620                 IMB_cache_limiter_unref(i);
2621         }
2622         return i;
2623 }
2624
2625 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2626 static int seq_can_blend(Sequence *seq)
2627 {
2628         if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2629                 return 1;
2630         } else {
2631                 return 0;
2632         }
2633 }
2634
2635 /* *********************** threading api ******************* */
2636
2637 static ListBase running_threads;
2638 static ListBase prefetch_wait;
2639 static ListBase prefetch_done;
2640
2641 static pthread_mutex_t queue_lock          = PTHREAD_MUTEX_INITIALIZER;
2642 static pthread_mutex_t wakeup_lock         = PTHREAD_MUTEX_INITIALIZER;
2643 static pthread_cond_t  wakeup_cond         = PTHREAD_COND_INITIALIZER;
2644
2645 static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2646 static pthread_cond_t  prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2647
2648 static pthread_mutex_t frame_done_lock     = PTHREAD_MUTEX_INITIALIZER;
2649 static pthread_cond_t  frame_done_cond     = PTHREAD_COND_INITIALIZER;
2650
2651 static volatile int seq_thread_shutdown = FALSE;
2652 static volatile int seq_last_given_monoton_cfra = 0;
2653 static int monoton_cfra = 0;
2654
2655 typedef struct PrefetchThread {
2656         struct PrefetchThread *next, *prev;
2657         
2658         Scene *scene;
2659         struct PrefetchQueueElem *current;
2660         pthread_t pthread;
2661         int running;
2662         
2663 } PrefetchThread;
2664
2665 typedef struct PrefetchQueueElem {
2666         struct PrefetchQueueElem *next, *prev;
2667         
2668         int rectx;
2669         int recty;
2670         int cfra;
2671         int chanshown;
2672         int render_size;
2673
2674         int monoton_cfra;
2675
2676         struct ImBuf * ibuf;
2677 } PrefetchQueueElem;
2678
2679 static void *seq_prefetch_thread(void * This_)
2680 {
2681         PrefetchThread * This = This_;
2682
2683         while (!seq_thread_shutdown) {
2684                 PrefetchQueueElem *e;
2685                 int s_last;
2686
2687                 pthread_mutex_lock(&queue_lock);
2688                 e = prefetch_wait.first;
2689                 if (e) {
2690                         BLI_remlink(&prefetch_wait, e);
2691                 }
2692                 s_last = seq_last_given_monoton_cfra;
2693
2694                 This->current = e;
2695
2696                 pthread_mutex_unlock(&queue_lock);
2697
2698                 if (!e) {
2699                         pthread_mutex_lock(&prefetch_ready_lock);
2700
2701                         This->running = FALSE;
2702
2703                         pthread_cond_signal(&prefetch_ready_cond);
2704                         pthread_mutex_unlock(&prefetch_ready_lock);
2705
2706                         pthread_mutex_lock(&wakeup_lock);
2707                         if (!seq_thread_shutdown) {
2708                                 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2709                         }
2710                         pthread_mutex_unlock(&wakeup_lock);
2711                         continue;
2712                 }
2713
2714                 This->running = TRUE;
2715                 
2716                 if (e->cfra >= s_last) { 
2717                         e->ibuf = give_ibuf_seq_impl(This->scene, 
2718                                 e->rectx, e->recty, e->cfra, e->chanshown,
2719                                 e->render_size);
2720                 }
2721
2722                 pthread_mutex_lock(&queue_lock);
2723
2724                 BLI_addtail(&prefetch_done, e);
2725
2726                 for (e = prefetch_wait.first; e; e = e->next) {
2727                         if (s_last > e->monoton_cfra) {
2728                                 BLI_remlink(&prefetch_wait, e);
2729                                 MEM_freeN(e);
2730                         }
2731                 }
2732
2733                 for (e = prefetch_done.first; e; e = e->next) {
2734                         if (s_last > e->monoton_cfra) {
2735                                 if (e->ibuf) {
2736                                         IMB_cache_limiter_unref(e->ibuf);
2737                                 }
2738                                 BLI_remlink(&prefetch_done, e);
2739                                 MEM_freeN(e);
2740                         }
2741                 }
2742
2743                 pthread_mutex_unlock(&queue_lock);
2744
2745                 pthread_mutex_lock(&frame_done_lock);
2746                 pthread_cond_signal(&frame_done_cond);
2747                 pthread_mutex_unlock(&frame_done_lock);
2748         }
2749         return 0;
2750 }
2751
2752 static void seq_start_threads(Scene *scene)
2753 {
2754         int i;
2755
2756         running_threads.first = running_threads.last = NULL;
2757         prefetch_wait.first = prefetch_wait.last = NULL;
2758         prefetch_done.first = prefetch_done.last = NULL;
2759
2760         seq_thread_shutdown = FALSE;
2761         seq_last_given_monoton_cfra = monoton_cfra = 0;
2762
2763         /* since global structures are modified during the processing
2764            of one frame, only one render thread is currently possible... 
2765
2766            (but we code, in the hope, that we can remove this restriction
2767            soon...)
2768         */
2769
2770         fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2771
2772         for (i = 0; i < 1; i++) {
2773                 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
2774                 t->scene= scene;
2775                 t->running = TRUE;
2776                 BLI_addtail(&running_threads, t);
2777
2778                 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2779         }
2780
2781         /* init malloc mutex */
2782         BLI_init_threads(0, 0, 0);
2783 }
2784
2785 static void seq_stop_threads()
2786 {
2787         PrefetchThread *tslot;
2788         PrefetchQueueElem *e;
2789
2790         fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2791
2792         if (seq_thread_shutdown) {
2793                 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2794                 return;
2795         }
2796         
2797         pthread_mutex_lock(&wakeup_lock);
2798
2799         seq_thread_shutdown = TRUE;
2800
2801         pthread_cond_broadcast(&wakeup_cond);
2802         pthread_mutex_unlock(&wakeup_lock);
2803
2804         for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2805                 pthread_join(tslot->pthread, NULL);
2806         }
2807
2808
2809         for (e = prefetch_wait.first; e; e = e->next) {
2810                 BLI_remlink(&prefetch_wait, e);
2811                 MEM_freeN(e);
2812         }
2813
2814         for (e = prefetch_done.first; e; e = e->next) {
2815                 if (e->ibuf) {
2816                         IMB_cache_limiter_unref(e->ibuf);
2817                 }
2818                 BLI_remlink(&prefetch_done, e);
2819                 MEM_freeN(e);
2820         }
2821
2822         BLI_freelistN(&running_threads);
2823
2824         /* deinit malloc mutex */
2825         BLI_end_threads(0);
2826 }
2827
2828 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
2829                                 int render_size)
2830 {
2831         PrefetchQueueElem *e;
2832         if (seq_thread_shutdown) {
2833                 return;
2834         }
2835
2836         e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2837         e->rectx = rectx;
2838         e->recty = recty;
2839         e->cfra = cfra;
2840         e->chanshown = chanshown;
2841         e->render_size = render_size;
2842         e->monoton_cfra = monoton_cfra++;
2843
2844         pthread_mutex_lock(&queue_lock);
2845         BLI_addtail(&prefetch_wait, e);
2846         pthread_mutex_unlock(&queue_lock);
2847         
2848         pthread_mutex_lock(&wakeup_lock);
2849         pthread_cond_signal(&wakeup_cond);
2850         pthread_mutex_unlock(&wakeup_lock);
2851 }
2852
2853 static void seq_wait_for_prefetch_ready()
2854 {
2855         PrefetchThread *tslot;
2856
2857         if (seq_thread_shutdown) {
2858                 return;
2859         }
2860
2861         fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
2862
2863         pthread_mutex_lock(&prefetch_ready_lock);
2864
2865         for(;;) {
2866                 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2867                         if (tslot->running) {
2868                                 break;
2869                         }
2870                 }
2871                 if (!tslot) {
2872                         break;
2873                 }
2874                 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
2875         }
2876
2877         pthread_mutex_unlock(&prefetch_ready_lock);
2878
2879         fprintf(stderr, "SEQ-THREAD: prefetch done\n");
2880 }
2881
2882 ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2883 {
2884         PrefetchQueueElem *e = NULL;
2885         int found_something = FALSE;
2886
2887         if (seq_thread_shutdown) {
2888                 return give_ibuf_seq(scene, rectx, recty, cfra, chanshown, render_size);
2889         }
2890
2891         while (!e) {
2892                 int success = FALSE;
2893                 pthread_mutex_lock(&queue_lock);
2894
2895                 for (e = prefetch_done.first; e; e = e->next) {
2896                         if (cfra == e->cfra &&
2897                             chanshown == e->chanshown &&
2898                             rectx == e->rectx && 
2899                             recty == e->recty &&
2900                             render_size == e->render_size) {
2901                                 success = TRUE;
2902                                 found_something = TRUE;
2903                                 break;
2904                         }
2905                 }
2906
2907                 if (!e) {
2908                         for (e = prefetch_wait.first; e; e = e->next) {
2909                                 if (cfra == e->cfra &&
2910                                     chanshown == e->chanshown &&
2911                                     rectx == e->rectx && 
2912                                     recty == e->recty &&
2913                                     render_size == e->render_size) {
2914                                         found_something = TRUE;
2915                                         break;
2916                                 }
2917                         }
2918                 }
2919
2920                 if (!e) {
2921                         PrefetchThread *tslot;
2922
2923                         for(tslot = running_threads.first; 
2924                             tslot; tslot= tslot->next) {
2925                                 if (tslot->current &&
2926                                     cfra == tslot->current->cfra &&
2927                                     chanshown == tslot->current->chanshown &&
2928                                     rectx == tslot->current->rectx && 
2929                                     recty == tslot->current->recty &&
2930                                     render_size== tslot->current->render_size){
2931                                         found_something = TRUE;
2932                                         break;
2933                                 }
2934                         }
2935                 }
2936
2937                 /* e->ibuf is unrefed by render thread on next round. */
2938
2939                 if (e) {
2940                         seq_last_given_monoton_cfra = e->monoton_cfra;
2941                 }
2942
2943                 pthread_mutex_unlock(&queue_lock);
2944
2945                 if (!success) {
2946                         e = NULL;
2947
2948                         if (!found_something) {
2949                                 fprintf(stderr, 
2950                                         "SEQ-THREAD: Requested frame "
2951                                         "not in queue ???\n");
2952                                 break;
2953                         }
2954                         pthread_mutex_lock(&frame_done_lock);
2955                         pthread_cond_wait(&frame_done_cond, &frame_done_lock);
2956                         pthread_mutex_unlock(&frame_done_lock);
2957                 }
2958         }
2959         
2960         return e ? e->ibuf : 0;
2961 }
2962
2963 /* Functions to free imbuf and anim data on changes */
2964
2965 static void free_imbuf_strip_elem(TStripElem *se)
2966 {
2967         if(se->ibuf) {
2968                 IMB_freeImBuf(se->ibuf);
2969         }
2970         if(se->ibuf_comp) {
2971                 IMB_freeImBuf(se->ibuf_comp);
2972         }
2973         se->ibuf_comp = 0;
2974         se->ibuf= 0;
2975         se->ok= STRIPELEM_OK;
2976         se->se1= se->se2= se->se3= 0;
2977 }
2978
2979 static void free_anim_seq(Sequence *seq)
2980 {
2981         if(seq->anim) {
2982                 IMB_free_anim(seq->anim);
2983                 seq->anim = 0;
2984         }
2985 }
2986
2987 static void free_imbuf_seq_except(Scene *scene, int cfra)
2988 {
2989         Editing *ed= seq_give_editing(scene, FALSE);
2990         Sequence *seq;
2991         TStripElem *se;
2992         int a;
2993
2994         if(ed==NULL) return;
2995
2996         SEQ_BEGIN(ed, seq) {
2997                 if(seq->strip) {
2998                         TStripElem * curelem = give_tstripelem(seq, cfra);
2999
3000                         for(a = 0, se = seq->strip->tstripdata; 
3001                             a < seq->strip->len && se; a++, se++) {
3002                                 if(se != curelem) {
3003                                         free_imbuf_strip_elem(se);
3004                                 }
3005                         }
3006                         for(a = 0, se = seq->strip->tstripdata_startstill;
3007                             a < seq->strip->startstill && se; a++, se++) {
3008                                 if(se != curelem) {
3009                                         free_imbuf_strip_elem(se);
3010                                 }
3011                         }
3012                         for(a = 0, se = seq->strip->tstripdata_endstill;
3013                             a < seq->strip->endstill && se; a++, se++) {
3014                                 if(se != curelem) {
3015                                         free_imbuf_strip_elem(se);
3016                                 }
3017                         }
3018                         if(seq->strip->ibuf_startstill) {
3019                                 IMB_freeImBuf(seq->strip->ibuf_startstill);
3020                                 seq->strip->ibuf_startstill = 0;
3021                         }
3022
3023                         if(seq->strip->ibuf_endstill) {
3024                                 IMB_freeImBuf(seq->strip->ibuf_endstill);
3025                                 seq->strip->ibuf_endstill = 0;
3026                         }
3027
3028                         if(seq->type==SEQ_MOVIE)
3029                                 if(seq->startdisp > cfra || seq->enddisp < cfra)
3030                                         free_anim_seq(seq);
3031                         free_proxy_seq(seq);
3032                 }
3033         }
3034         SEQ_END
3035 }
3036
3037 void free_imbuf_seq(ListBase * seqbase, int check_mem_usage)
3038 {
3039         Sequence *seq;
3040         TStripElem *se;
3041         int a;
3042
3043         if (check_mem_usage) {
3044                 /* Let the cache limitor take care of this (schlaile) */
3045                 /* While render let's keep all memory available for render 
3046                    (ton)
3047                    At least if free memory is tight...
3048                    This can make a big difference in encoding speed
3049                    (it is around 4 times(!) faster, if we do not waste time
3050                    on freeing _all_ buffers every time on long timelines...)
3051                    (schlaile)
3052                 */
3053         
3054                 uintptr_t mem_in_use;
3055                 uintptr_t mmap_in_use;
3056                 uintptr_t max;
3057         
3058                 mem_in_use= MEM_get_memory_in_use();
3059                 mmap_in_use= MEM_get_mapped_memory_in_use();
3060                 max = MEM_CacheLimiter_get_maximum();
3061         
3062                 if (max == 0 || mem_in_use + mmap_in_use <= max) {
3063                         return;
3064                 }
3065         }
3066
3067         
3068         for(seq= seqbase->first; seq; seq= seq->next) {
3069                 if(seq->strip) {
3070                         for(a = 0, se = seq->strip->tstripdata; 
3071                             a < seq->strip->len && se; a++, se++) {
3072                                 free_imbuf_strip_elem(se);
3073                         }
3074                         for(a = 0, se = seq->strip->tstripdata_startstill; 
3075                             a < seq->strip->startstill && se; a++, se++) {
3076                                 free_imbuf_strip_elem(se);
3077                         }
3078                         for(a = 0, se = seq->strip->tstripdata_endstill; 
3079                             a < seq->strip->endstill && se; a++, se++) {
3080                                 free_imbuf_strip_elem(se);
3081                         }
3082                         if(seq->strip->ibuf_startstill) {
3083                                 IMB_freeImBuf(seq->strip->ibuf_startstill);
3084                                 seq->strip->ibuf_startstill = 0;
3085                         }
3086
3087                         if(seq->strip->ibuf_endstill) {
3088                                 IMB_freeImBuf(seq->strip->ibuf_endstill);
3089                                 seq->strip->ibuf_endstill = 0;
3090                         }
3091
3092                         if(seq->type==SEQ_MOVIE)
3093                                 free_anim_seq(seq);
3094                         if(seq->type==SEQ_SPEED) {
3095                                 sequence_effect_speed_rebuild_map(seq, 1);
3096                         }
3097                 }
3098                 if(seq->type==SEQ_META) {
3099                         free_imbuf_seq(&seq->seqbase, FALSE);
3100                 }
3101                 if(seq->type==SEQ_SCENE) {
3102                         /* FIXME: recurs downwards, 
3103                            but do recurs protection somehow! */
3104                 }
3105         }
3106         
3107 }
3108
3109 static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
3110 {
3111         Sequence *subseq;
3112         int a, free_imbuf = 0;
3113         TStripElem *se;
3114         
3115         /* recurs downwards to see if this seq depends on the changed seq */
3116         
3117         if(seq == NULL)
3118                 return 0;
3119         
3120         if(seq == changed_seq)
3121                 free_imbuf = 1;
3122         
3123         for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
3124                 if(update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change))
3125                         free_imbuf = TRUE;
3126         
3127         if(seq->seq1)
3128                 if(update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change))
3129                         free_imbuf = TRUE;
3130         if(seq->seq2 && (seq->seq2 != seq->seq1))
3131                 if(update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change))
3132                         free_imbuf = TRUE;
3133         if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
3134                 if(update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change))
3135                         free_imbuf = TRUE;
3136         
3137         if(free_imbuf) {
3138                 if(ibuf_change) {
3139                         se= seq->strip->tstripdata;
3140                         if (se) {
3141                                 for(a=0; a<seq->len; a++, se++)
3142                                         free_imbuf_strip_elem(se);
3143                         }
3144                         
3145                         if(seq->type == SEQ_MOVIE)
3146                                 free_anim_seq(seq);
3147                         if(seq->type == SEQ_SPEED) {
3148                                 sequence_effect_speed_rebuild_map(seq, 1);
3149                         }
3150                 }
3151                 
3152                 if(len_change)
3153                         calc_sequence(seq);
3154         }
3155         
3156         return free_imbuf;
3157 }
3158
3159 void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
3160 {
3161         Editing *ed= seq_give_editing(scene, FALSE);
3162         Sequence *seq;
3163         
3164         if (ed==NULL) return;
3165         
3166         for (seq=ed->seqbase.first; seq; seq=seq->next)
3167                 update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change);
3168 }
3169
3170 #if 0 // XXX from 2.4x, needs updating
3171 void free_imbuf_seq()
3172 {
3173         Scene * sce = G.main->scene.first;
3174         while(sce) {
3175                 free_imbuf_seq_editing(sce->ed);
3176                 sce= sce->id.next;
3177         }
3178 }
3179 #endif 
3180
3181 static void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo)
3182 {
3183         /* force update of all sequences with this ipo, on ipo changes */
3184         Editing *ed= seq_give_editing(scene, FALSE);
3185         Sequence *seq;
3186
3187         if(ed==NULL) return;
3188
3189         SEQ_BEGIN(ed, seq) {
3190                 if(seq->ipo == ipo) {
3191                         update_changed_seq_and_deps(scene, seq, 0, 1);
3192                         if(seq->type == SEQ_SPEED) {
3193                                 sequence_effect_speed_rebuild_map(seq, 1);
3194                         }
3195                         free_proxy_seq(seq);
3196                 }
3197         }
3198         SEQ_END
3199 }
3200
3201 /* seq funcs's for transforming internally
3202  notice the difference between start/end and left/right.
3203
3204  left and right are the bounds at which the sequence is rendered,
3205 start and end are from the start and fixed length of the sequence.
3206 */
3207 int seq_tx_get_start(Sequence *seq) {
3208         return seq->start;