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