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