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