* Fixing various compiler warnings under scons+mingw. Mostly unused variables and...
[blender.git] / source / blender / blenkernel / intern / sequence.c
1 /**
2 * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): 
24  * - Blender Foundation, 2003-2009
25  * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
33
34 #include "MEM_guardedalloc.h"
35 #include "MEM_CacheLimiterC-Api.h"
36
37 #include "DNA_listBase.h"
38 #include "DNA_sequence_types.h"
39 #include "DNA_scene_types.h"
40
41 #include "BKE_global.h"
42 #include "BKE_image.h"
43 #include "BKE_main.h"
44 #include "BKE_sequence.h"
45 #include "BKE_utildefines.h"
46
47 #include "BLI_blenlib.h"
48
49 #include "IMB_imbuf.h"
50 #include "IMB_imbuf_types.h"
51
52 #include "BLI_threads.h"
53 #include <pthread.h>
54
55 #include "BKE_context.h"
56 #include "BKE_sound.h"
57 #include "AUD_C-API.h"
58
59 #ifdef WIN32
60 #define snprintf _snprintf
61 #endif
62
63 /* **** XXX ******** */
64 static int seqrectx= 0; /* bad bad global! */
65 static int seqrecty= 0;
66 //static void waitcursor(int val) {}
67 //static int blender_test_break() {return 0;}
68
69 /* **** XXX ******** */
70
71
72 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 separate 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 #if 0
1234 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1235                               int build_proxy_run, int render_size);
1236
1237 static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int render_size)
1238 {
1239         char name[PROXY_MAXFILE];
1240         int quality;
1241         TStripElem * se;
1242         int ok;
1243         int rectx, recty;
1244         struct ImBuf * ibuf;
1245
1246         if (!(seq->flag & SEQ_USE_PROXY)) {
1247                 return;
1248         }
1249
1250         /* rendering at 100% ? No real sense in proxy-ing, right? */
1251         if (render_size == 100) {
1252                 return;
1253         }
1254
1255         /* that's why it is called custom... */
1256         if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1257                 return;
1258     }
1259
1260         if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1261                 return;
1262         }
1263
1264         se = give_tstripelem(seq, cfra);
1265         if (!se) {
1266                 return;
1267         }
1268
1269         if(se->ibuf) {
1270                 IMB_freeImBuf(se->ibuf);
1271                 se->ibuf = 0;
1272         }
1273         
1274         do_build_seq_ibuf(scene, seq, se, cfra, TRUE, render_size);
1275
1276         if (!se->ibuf) {
1277                 return;
1278         }
1279
1280         rectx= (render_size*scene->r.xsch)/100;
1281         recty= (render_size*scene->r.ysch)/100;
1282
1283         ibuf = se->ibuf;
1284
1285         if (ibuf->x != rectx || ibuf->y != recty) {
1286                 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1287         }
1288
1289         /* quality is fixed, otherwise one has to generate separate
1290            directories for every quality...
1291
1292            depth = 32 is intentionally left in, otherwise ALPHA channels
1293            won't work... */
1294         quality = seq->strip->proxy->quality;
1295         ibuf->ftype= JPG | quality;
1296
1297         BLI_make_existing_file(name);
1298         
1299         ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
1300         if (ok == 0) {
1301                 perror(name);
1302         }
1303
1304         IMB_freeImBuf(ibuf);
1305         se->ibuf = 0;
1306 }
1307
1308 static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
1309 {
1310         int cfra;
1311         float rsize = seq->strip->proxy->size;
1312
1313         waitcursor(1);
1314
1315         G.afbreek = 0;
1316
1317         /* flag management tries to account for strobe and 
1318            other "non-linearities", that might come in the future...
1319            better way would be to "touch" the files, so that _really_
1320            no one is rebuild twice.
1321          */
1322
1323         for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
1324                 TStripElem * tse = give_tstripelem(seq, cfra);
1325
1326                 tse->flag &= ~STRIPELEM_PREVIEW_DONE;
1327         }
1328
1329         
1330
1331         /* a _lot_ faster for movie files, if we read frames in
1332            sequential order */
1333         if (seq->flag & SEQ_REVERSE_FRAMES) {
1334                 for (cfra = seq->enddisp-seq->endstill-1; 
1335                      cfra >= seq->startdisp + seq->startstill; cfra--) {
1336                         TStripElem * tse = give_tstripelem(seq, cfra);
1337
1338                         if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1339 //XXX                           set_timecursor(cfra);
1340                                 seq_proxy_build_frame(scene, seq, cfra, rsize);
1341                                 tse->flag |= STRIPELEM_PREVIEW_DONE;
1342                         }
1343                         if (blender_test_break()) {
1344                                 break;
1345                         }
1346                 }
1347         } else {
1348                 for (cfra = seq->startdisp + seq->startstill; 
1349                      cfra < seq->enddisp - seq->endstill; cfra++) {
1350                         TStripElem * tse = give_tstripelem(seq, cfra);
1351
1352                         if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1353 //XXX                           set_timecursor(cfra);
1354                                 seq_proxy_build_frame(scene, seq, cfra, rsize);
1355                                 tse->flag |= STRIPELEM_PREVIEW_DONE;
1356                         }
1357                         if (blender_test_break()) {
1358                                 break;
1359                         }
1360                 }
1361         }
1362         waitcursor(0);
1363 }
1364 #endif
1365
1366
1367 /* **********************************************************************
1368    color balance 
1369    ********************************************************************** */
1370
1371 static StripColorBalance calc_cb(StripColorBalance * cb_)
1372 {
1373         StripColorBalance cb = *cb_;
1374         int c;
1375
1376         if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
1377                 for (c = 0; c < 3; c++) {
1378                         cb.lift[c] = 1.0 - cb.lift[c];
1379                 }
1380         } else {
1381                 for (c = 0; c < 3; c++) {
1382                         cb.lift[c] = -(1.0 - cb.lift[c]);
1383                 }
1384         }
1385         if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
1386                 for (c = 0; c < 3; c++) {
1387                         if (cb.gain[c] != 0.0) {
1388                                 cb.gain[c] = 1.0/cb.gain[c];
1389                         } else {
1390                                 cb.gain[c] = 1000000; /* should be enough :) */
1391                         }
1392                 }
1393         }
1394
1395         if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
1396                 for (c = 0; c < 3; c++) {
1397                         if (cb.gamma[c] != 0.0) {
1398                                 cb.gamma[c] = 1.0/cb.gamma[c];
1399                         } else {
1400                                 cb.gamma[c] = 1000000; /* should be enough :) */
1401                         }
1402                 }
1403         }
1404
1405         return cb;
1406 }
1407
1408 static void make_cb_table_byte(float lift, float gain, float gamma,
1409                                unsigned char * table, float mul)
1410 {
1411         int y;
1412
1413         for (y = 0; y < 256; y++) {
1414                 float v = 1.0 * y / 255;
1415                 v *= gain;
1416                 v += lift; 
1417                 v = pow(v, gamma);
1418                 v *= mul;
1419                 if ( v > 1.0) {
1420                         v = 1.0;
1421                 } else if (v < 0.0) {
1422                         v = 0.0;
1423                 }
1424                 table[y] = v * 255;
1425         }
1426
1427 }
1428
1429 static void make_cb_table_float(float lift, float gain, float gamma,
1430                                 float * table, float mul)
1431 {
1432         int y;
1433
1434         for (y = 0; y < 256; y++) {
1435                 float v = (float) y * 1.0 / 255.0;
1436                 v *= gain;
1437                 v += lift;
1438                 v = pow(v, gamma);
1439                 v *= mul;
1440                 table[y] = v;
1441         }
1442 }
1443
1444 static void color_balance_byte_byte(Sequence * seq, TStripElem* se, float mul)
1445 {
1446         unsigned char cb_tab[3][256];
1447         int c;
1448         unsigned char * p = (unsigned char*) se->ibuf->rect;
1449         unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1450
1451         StripColorBalance cb = calc_cb(seq->strip->color_balance);
1452
1453         for (c = 0; c < 3; c++) {
1454                 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1455                                    cb_tab[c], mul);
1456         }
1457
1458         while (p < e) {
1459                 p[0] = cb_tab[0][p[0]];
1460                 p[1] = cb_tab[1][p[1]];
1461                 p[2] = cb_tab[2][p[2]];
1462                 
1463                 p += 4;
1464         }
1465 }
1466
1467 static void color_balance_byte_float(Sequence * seq, TStripElem* se, float mul)
1468 {
1469         float cb_tab[4][256];
1470         int c,i;
1471         unsigned char * p = (unsigned char*) se->ibuf->rect;
1472         unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1473         float * o;
1474         StripColorBalance cb;
1475
1476         imb_addrectfloatImBuf(se->ibuf);
1477
1478         o = se->ibuf->rect_float;
1479
1480         cb = calc_cb(seq->strip->color_balance);
1481
1482         for (c = 0; c < 3; c++) {
1483                 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
1484                                     cb_tab[c], mul);
1485         }
1486
1487         for (i = 0; i < 256; i++) {
1488                 cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
1489         }
1490
1491         while (p < e) {
1492                 o[0] = cb_tab[0][p[0]];
1493                 o[1] = cb_tab[1][p[1]];
1494                 o[2] = cb_tab[2][p[2]];
1495                 o[3] = cb_tab[3][p[3]];
1496
1497                 p += 4; o += 4;
1498         }
1499 }
1500
1501 static void color_balance_float_float(Sequence * seq, TStripElem* se, float mul)
1502 {
1503         float * p = se->ibuf->rect_float;
1504         float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y;
1505         StripColorBalance cb = calc_cb(seq->strip->color_balance);
1506
1507         while (p < e) {
1508                 int c;
1509                 for (c = 0; c < 3; c++) {
1510                         p[c] = pow(p[c] * cb.gain[c] + cb.lift[c], 
1511                                    cb.gamma[c]) * mul;
1512                 }
1513                 p += 4;
1514         }
1515 }
1516
1517 static void color_balance(Sequence * seq, TStripElem* se, float mul)
1518 {
1519         if (se->ibuf->rect_float) {
1520                 color_balance_float_float(seq, se, mul);
1521         } else if(seq->flag & SEQ_MAKE_FLOAT) {
1522                 color_balance_byte_float(seq, se, mul);
1523         } else {
1524                 color_balance_byte_byte(seq, se, mul);
1525         }
1526 }
1527
1528 /*
1529   input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
1530
1531   Do all the things you can't really do afterwards using sequence effects
1532   (read: before rescaling to render resolution has been done)
1533
1534   Order is important!
1535
1536   - Deinterlace
1537   - Crop and transform in image source coordinate space
1538   - Flip X + Flip Y (could be done afterwards, backward compatibility)
1539   - Promote image to float data (affects pipeline operations afterwards)
1540   - Color balance (is most efficient in the byte -> float 
1541     (future: half -> float should also work fine!)
1542     case, if done on load, since we can use lookup tables)
1543   - Premultiply
1544
1545 */
1546
1547 static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se, int cfra)
1548 {
1549         float mul;
1550
1551         if ((seq->flag & SEQ_FILTERY) || 
1552             (seq->flag & SEQ_USE_CROP) ||
1553             (seq->flag & SEQ_USE_TRANSFORM) ||
1554             (seq->flag & SEQ_FLIPX) ||
1555             (seq->flag & SEQ_FLIPY) ||
1556             (seq->flag & SEQ_USE_COLOR_BALANCE) ||
1557             (seq->flag & SEQ_MAKE_PREMUL) ||
1558             (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
1559                 return TRUE;
1560         }
1561
1562         mul = seq->mul;
1563
1564         if(seq->blend_mode == SEQ_BLEND_REPLACE &&
1565            !(seq->type & SEQ_EFFECT)) {
1566 #if 0 // XXX old animation system
1567                 if (seq->ipo && seq->ipo->curve.first) {
1568                         do_seq_ipo(scene, seq, cfra);
1569                         mul *= seq->facf0;
1570                 }
1571 #endif // XXX old animation system
1572                 mul *= seq->blend_opacity / 100.0;
1573         }
1574
1575         if (mul != 1.0) {
1576                 return TRUE;
1577         }
1578                 
1579         return FALSE;
1580 }
1581
1582 static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cfra)
1583 {
1584         float mul;
1585
1586         seq->strip->orx= se->ibuf->x;
1587         seq->strip->ory= se->ibuf->y;
1588
1589         if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
1590                 IMB_filtery(se->ibuf);
1591         }
1592
1593         if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
1594                 StripCrop c;
1595                 StripTransform t;
1596                 int sx,sy,dx,dy;
1597
1598                 memset(&c, 0, sizeof(StripCrop));
1599                 memset(&t, 0, sizeof(StripTransform));
1600
1601                 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1602                         c = *seq->strip->crop;
1603                 }
1604                 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1605                         t = *seq->strip->transform;
1606                 }
1607
1608                 sx = se->ibuf->x - c.left - c.right;
1609                 sy = se->ibuf->y - c.top - c.bottom;
1610                 dx = sx;
1611                 dy = sy;
1612
1613                 if (seq->flag & SEQ_USE_TRANSFORM) {
1614                         dx = scene->r.xsch;
1615                         dy = scene->r.ysch;
1616                 }
1617
1618                 if (c.top + c.bottom >= se->ibuf->y ||
1619                     c.left + c.right >= se->ibuf->x ||
1620                     t.xofs >= dx || t.yofs >= dy) {
1621                         make_black_ibuf(se->ibuf);
1622                 } else {
1623                         ImBuf * i;
1624
1625                         if (se->ibuf->rect_float) {
1626                                 i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0);
1627                         } else {
1628                                 i = IMB_allocImBuf(dx, dy,32, IB_rect, 0);
1629                         }
1630
1631                         IMB_rectcpy(i, se->ibuf, 
1632                                     t.xofs, t.yofs, 
1633                                     c.left, c.bottom, 
1634                                     sx, sy);
1635
1636                         IMB_freeImBuf(se->ibuf);
1637
1638                         se->ibuf = i;
1639                 }
1640         } 
1641
1642         if(seq->flag & SEQ_FLIPX) {
1643                 IMB_flipx(se->ibuf);
1644         }
1645         if(seq->flag & SEQ_FLIPY) {
1646                 IMB_flipy(se->ibuf);
1647         }
1648
1649         if(seq->mul == 0.0) {
1650                 seq->mul = 1.0;
1651         }
1652
1653         mul = seq->mul;
1654
1655         if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1656 #if 0 // XXX old animation system
1657                 if (seq->ipo && seq->ipo->curve.first) {
1658                         do_seq_ipo(scene, seq, cfra);
1659                         mul *= seq->facf0;
1660                 }
1661 #endif // XXX old animation system
1662                 mul *= seq->blend_opacity / 100.0;
1663         }
1664
1665         if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1666                 color_balance(seq, se, mul);
1667                 mul = 1.0;
1668         }
1669
1670         if(seq->flag & SEQ_MAKE_FLOAT) {
1671                 if (!se->ibuf->rect_float) {
1672                         IMB_float_from_rect(se->ibuf);
1673                 }
1674                 if (se->ibuf->rect) {
1675                         imb_freerectImBuf(se->ibuf);
1676                 }
1677         }
1678
1679         if(mul != 1.0) {
1680                 multibuf(se->ibuf, mul);
1681         }
1682
1683         if(seq->flag & SEQ_MAKE_PREMUL) {
1684                 if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
1685                         converttopremul(se->ibuf);
1686                 }
1687         }
1688
1689
1690         if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
1691                 if(scene->r.mode & R_OSA) {
1692                         IMB_scaleImBuf(se->ibuf, 
1693                                        (short)seqrectx, (short)seqrecty);
1694                 } else {
1695                         IMB_scalefastImBuf(se->ibuf, 
1696                                            (short)seqrectx, (short)seqrecty);
1697                 }
1698         }
1699 }
1700
1701 /* test if image too small or discarded from cache: reload */
1702
1703 static void test_and_auto_discard_ibuf(TStripElem * se)
1704 {
1705         if (se->ibuf) {
1706                 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty 
1707                    || !(se->ibuf->rect || se->ibuf->rect_float)) {
1708                         IMB_freeImBuf(se->ibuf);
1709
1710                         se->ibuf= 0;
1711                         se->ok= STRIPELEM_OK;
1712                 }
1713         }
1714         if (se->ibuf_comp) {
1715                 if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty 
1716                    || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) {
1717                         IMB_freeImBuf(se->ibuf_comp);
1718
1719                         se->ibuf_comp = 0;
1720                 }
1721         }
1722 }
1723
1724 static void test_and_auto_discard_ibuf_stills(Strip * strip)
1725 {
1726         if (strip->ibuf_startstill) {
1727                 if (!strip->ibuf_startstill->rect &&
1728                     !strip->ibuf_startstill->rect_float) {
1729                         IMB_freeImBuf(strip->ibuf_startstill);
1730                         strip->ibuf_startstill = 0;
1731                 }
1732         }
1733         if (strip->ibuf_endstill) {
1734                 if (!strip->ibuf_endstill->rect &&
1735                     !strip->ibuf_endstill->rect_float) {
1736                         IMB_freeImBuf(strip->ibuf_endstill);
1737                         strip->ibuf_endstill = 0;
1738                 }
1739         }
1740 }
1741
1742 static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
1743 {
1744         if (!se->ibuf) {
1745                 if (se->nr == 0 && seq->strip->ibuf_startstill) {
1746                         IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1747
1748                         se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
1749                 }
1750                 if (se->nr == seq->len - 1 
1751                     && (seq->len != 1)
1752                     && seq->strip->ibuf_endstill) {
1753                         IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1754
1755                         se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
1756                 }
1757         }
1758 }
1759
1760 static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
1761 {
1762         if (se->ibuf) {
1763                 if (se->nr == 0) {
1764                         seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
1765
1766                         IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
1767                         IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1768                 }
1769                 if (se->nr == seq->len - 1 && seq->len != 1) {
1770                         seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
1771
1772                         IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
1773                         IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1774                 }
1775         }
1776 }
1777
1778 static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown)
1779 {
1780         Sequence* seq_arr[MAXSEQ+1];
1781         int i;
1782         TStripElem* se = 0;
1783
1784         evaluate_seq_frame_gen(seq_arr, seqbasep, cfra);
1785
1786         for (i = 0; i < MAXSEQ; i++) {
1787                 if (!video_seq_is_rendered(seq_arr[i])) {
1788                         continue;
1789                 }
1790                 se = give_tstripelem(seq_arr[i], cfra);
1791                 if (se) {
1792                         if (se->ibuf) {
1793                                 IMB_freeImBuf(se->ibuf);
1794
1795                                 se->ibuf= 0;
1796                                 se->ok= STRIPELEM_OK;
1797                         }
1798
1799                         if (se->ibuf_comp) {
1800                                 IMB_freeImBuf(se->ibuf_comp);
1801
1802                                 se->ibuf_comp = 0;
1803                         }
1804                 }
1805         }
1806         
1807 }
1808
1809 static void check_limiter_refcount(const char * func, TStripElem *se)
1810 {
1811         if (se && se->ibuf) {
1812                 int refcount = IMB_cache_limiter_get_refcount(se->ibuf);
1813                 if (refcount != 1) {
1814                         /* can happen on complex pipelines */
1815                         if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1816                                 return;
1817                         }
1818  
1819                         fprintf(stderr, 
1820                                 "sequencer: (ibuf) %s: "
1821                                 "suspicious memcache "
1822                                 "limiter refcount: %d\n", func, refcount);
1823                 }
1824         }
1825 }
1826  
1827 static void check_limiter_refcount_comp(const char * func, TStripElem *se)
1828 {
1829         if (se && se->ibuf_comp) {
1830                 int refcount = IMB_cache_limiter_get_refcount(se->ibuf_comp);
1831                 if (refcount != 1) {
1832                         /* can happen on complex pipelines */
1833                         if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1834                                 return;
1835                         }
1836                         fprintf(stderr, 
1837                                 "sequencer: (ibuf comp) %s: "
1838                                 "suspicious memcache "
1839                                 "limiter refcount: %d\n", func, refcount);
1840                 }
1841         }
1842 }
1843
1844 static TStripElem* do_build_seq_array_recursively(Scene *scene,
1845                                 ListBase *seqbasep, int cfra, int chanshown, int render_size);
1846
1847 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1848                               int build_proxy_run, int render_size)
1849 {
1850         char name[FILE_MAXDIR+FILE_MAXFILE];
1851         int use_limiter = TRUE;
1852
1853         test_and_auto_discard_ibuf(se);
1854         test_and_auto_discard_ibuf_stills(seq->strip);
1855
1856         if(seq->type == SEQ_META) {
1857                 TStripElem * meta_se = 0;
1858                 int use_preprocess = FALSE;
1859                 use_limiter = FALSE;
1860
1861                 if (!build_proxy_run && se->ibuf == 0) {
1862                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1863                         if (se->ibuf) {
1864                                 use_limiter = TRUE;
1865                                 use_preprocess = TRUE;
1866                         }
1867                 }
1868
1869                 if(!se->ibuf && seq->seqbase.first) {
1870                         meta_se = do_build_seq_array_recursively(scene,
1871                                 &seq->seqbase, seq->start + se->nr, 0,
1872                                 render_size);
1873
1874                         check_limiter_refcount("do_build_seq_ibuf: for META", meta_se);
1875                 }
1876
1877                 se->ok = STRIPELEM_OK;
1878
1879                 if(!se->ibuf && meta_se) {
1880                         se->ibuf = meta_se->ibuf_comp;
1881                         if(se->ibuf &&
1882                            (!input_have_to_preprocess(scene, seq, se, cfra) ||
1883                             build_proxy_run)) {
1884                                 IMB_refImBuf(se->ibuf);
1885                                 if (build_proxy_run) {
1886                                         IMB_cache_limiter_unref(se->ibuf);
1887                                 }
1888                         } else if (se->ibuf) {
1889                                 struct ImBuf * i = IMB_dupImBuf(se->ibuf);
1890
1891                                 IMB_cache_limiter_unref(se->ibuf);
1892
1893                                 se->ibuf = i;
1894
1895                                 use_limiter = TRUE;
1896                                 use_preprocess = TRUE;
1897                         }
1898                 } else if (se->ibuf) {
1899                         use_limiter = TRUE;
1900                 }
1901                 if (meta_se) {
1902                         free_metastrip_imbufs(
1903                                 &seq->seqbase, seq->start + se->nr, 0);
1904                 }
1905
1906                 if (use_preprocess) {
1907                         input_preprocess(scene, seq, se, cfra);
1908                 }
1909         } else if(seq->type & SEQ_EFFECT) {
1910                 int use_preprocess = FALSE;
1911                 /* should the effect be recalculated? */
1912                 
1913                 if (!build_proxy_run && se->ibuf == 0) {
1914                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1915                         if (se->ibuf) {
1916                                 use_preprocess = TRUE;
1917                         }
1918                 }
1919
1920                 if(se->ibuf == 0) {
1921                         /* if any inputs are rectfloat, output is float too */
1922                         if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
1923                            (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float) ||
1924                            (se->se3 && se->se3->ibuf && se->se3->ibuf->rect_float))
1925                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
1926                         else
1927                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
1928                         
1929                         do_effect(scene, cfra, seq, se);
1930                         if (input_have_to_preprocess(scene, seq, se, cfra) &&
1931                             !build_proxy_run) {
1932                                 if ((se->se1 && (se->ibuf == se->se1->ibuf)) ||
1933                                     (se->se2 && (se->ibuf == se->se2->ibuf))) {
1934                                         struct ImBuf * i
1935                                                 = IMB_dupImBuf(se->ibuf);
1936
1937                                         IMB_freeImBuf(se->ibuf);
1938
1939                                         se->ibuf = i;
1940                                 }
1941                                 use_preprocess = TRUE;
1942                         }
1943                 }
1944                 if (use_preprocess) {
1945                         input_preprocess(scene, seq, se, cfra);
1946                 }
1947         } else if(seq->type == SEQ_IMAGE) {
1948                 if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
1949                         StripElem * s_elem = give_stripelem(seq, cfra);
1950                         BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
1951                         BLI_convertstringcode(name, G.sce);
1952                         BLI_convertstringframe(name, scene->r.cfra);
1953                         if (!build_proxy_run) {
1954                                 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1955                         }
1956                         copy_from_ibuf_still(seq, se);
1957
1958                         if (!se->ibuf) {
1959                                 se->ibuf= IMB_loadiffname(
1960                                         name, IB_rect);
1961                                 /* we don't need both (speed reasons)! */
1962                                 if (se->ibuf &&
1963                                         se->ibuf->rect_float && se->ibuf->rect) {
1964                                         imb_freerectImBuf(se->ibuf);
1965                                 }
1966
1967                                 copy_to_ibuf_still(seq, se);
1968                         }
1969                         
1970                         if(se->ibuf == 0) {
1971                                 se->ok = STRIPELEM_FAILED;
1972                         } else if (!build_proxy_run) {
1973                                 input_preprocess(scene, seq, se, cfra);
1974                         }
1975                 }
1976         } else if(seq->type == SEQ_MOVIE) {
1977                 if(se->ok == STRIPELEM_OK && se->ibuf==0) {
1978                         if(!build_proxy_run) {
1979                                 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1980                         }
1981                         copy_from_ibuf_still(seq, se);
1982
1983                         if (se->ibuf == 0) {
1984                                 if(seq->anim==0) {
1985                                         BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
1986                                         BLI_convertstringcode(name, G.sce);
1987                                         BLI_convertstringframe(name, scene->r.cfra);
1988                                         
1989                                         seq->anim = openanim(
1990                                                 name, IB_rect | 
1991                                                 ((seq->flag & SEQ_FILTERY) 
1992                                                  ? IB_animdeinterlace : 0));
1993                                 }
1994                                 if(seq->anim) {
1995                                         IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
1996                                         se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
1997                                         /* we don't need both (speed reasons)! */
1998                                         if (se->ibuf 
1999                                             && se->ibuf->rect_float 
2000                                             && se->ibuf->rect) {
2001                                                 imb_freerectImBuf(se->ibuf);
2002                                         }
2003
2004                                 }
2005                                 copy_to_ibuf_still(seq, se);
2006                         }
2007                         
2008                         if(se->ibuf == 0) {
2009                                 se->ok = STRIPELEM_FAILED;
2010                         } else if (!build_proxy_run) {
2011                                 input_preprocess(scene, seq, se, cfra);
2012                         }
2013                 }
2014         } else if(seq->type == SEQ_SCENE) {     // scene can be NULL after deletions
2015 #if 0
2016                 /* XXX move entirely to render? */
2017                 int oldcfra = CFRA;
2018                 Sequence * oldseq = get_last_seq();
2019                 Scene *sce= seq->scene, *oldsce= scene;
2020                 Render *re;
2021                 RenderResult rres;
2022                 int doseq, rendering= G.rendering;
2023                 char scenename[64];
2024                 int have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first;
2025                 int sce_valid =sce && (sce->camera || have_seq);
2026                         
2027                 if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
2028                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2029                         if (se->ibuf) {
2030                                 input_preprocess(scene, seq, se, cfra);
2031                         }
2032                 }
2033
2034                 if (se->ibuf == NULL && sce_valid) {
2035                         copy_from_ibuf_still(seq, se);
2036                         if (se->ibuf) {
2037                                 input_preprocess(scene, seq, se, cfra);
2038                         }
2039                 }
2040                 
2041                 if (!sce_valid) {
2042                         se->ok = STRIPELEM_FAILED;
2043                 } else if (se->ibuf==NULL && sce_valid) {
2044                         /* no need to display a waitcursor on sequencer
2045                            scene strips */
2046                         if (!have_seq)
2047                                 waitcursor(1);
2048                         
2049                         /* Hack! This function can be called from do_render_seq(), in that case
2050                            the seq->scene can already have a Render initialized with same name, 
2051                            so we have to use a default name. (compositor uses scene name to
2052                            find render).
2053                            However, when called from within the UI (image preview in sequencer)
2054                            we do want to use scene Render, that way the render result is defined
2055                            for display in render/imagewindow */
2056                         if(rendering) {
2057                                 BLI_strncpy(scenename, sce->id.name+2, 64);
2058                                 strcpy(sce->id.name+2, " do_build_seq_ibuf");
2059                         }
2060                         re= RE_NewRender(sce->id.name);
2061                         
2062                         /* prevent eternal loop */
2063                         doseq= scene->r.scemode & R_DOSEQ;
2064                         scene->r.scemode &= ~R_DOSEQ;
2065                         
2066                         BIF_init_render_callbacks(re, 0);       /* 0= no display callbacks */
2067                         
2068                         /* XXX hrms, set_scene still needed? work on that... */
2069                         if(sce!=oldsce) set_scene_bg(sce);
2070                         RE_BlenderFrame(re, sce,
2071                                         seq->sfra+se->nr+seq->anim_startofs);
2072                         if(sce!=oldsce) set_scene_bg(oldsce);
2073                         
2074                         /* UGLY WARNING, it is set to zero in  RE_BlenderFrame */
2075                         G.rendering= rendering;
2076                         if(rendering)
2077                                 BLI_strncpy(sce->id.name+2, scenename, 64);
2078                         
2079                         RE_AcquireResultImage(re, &rres);
2080                         
2081                         if(rres.rectf) {
2082                                 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
2083                                 memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
2084                                 if(rres.rectz) {
2085                                         addzbuffloatImBuf(se->ibuf);
2086                                         memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
2087                                 }
2088                         } else if (rres.rect32) {
2089                                 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
2090                                 memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
2091                         }
2092
2093                         RE_ReleaseResultImage(re);
2094                         
2095                         BIF_end_render_callbacks();
2096                         
2097                         /* restore */
2098                         scene->r.scemode |= doseq;
2099
2100                         // XXX
2101 #if 0
2102                         if((G.f & G_PLAYANIM)==0 /* bad, is set on do_render_seq */
2103                            && !have_seq
2104                            && !build_proxy_run) 
2105 #endif
2106                         
2107                         CFRA = oldcfra;
2108                         set_last_seq(oldseq);
2109
2110                         copy_to_ibuf_still(seq, se);
2111
2112                         if (!build_proxy_run) {
2113                                 if(se->ibuf == NULL) {
2114                                         se->ok = STRIPELEM_FAILED;
2115                                 } else {
2116                                         input_preprocess(scene, seq, se, cfra);
2117                                 }
2118                         }
2119
2120                 }
2121 #endif
2122         }
2123         if (!build_proxy_run) {
2124                 if (se->ibuf && use_limiter) {
2125                         IMB_cache_limiter_insert(se->ibuf);
2126                         IMB_cache_limiter_ref(se->ibuf);
2127                         IMB_cache_limiter_touch(se->ibuf);
2128                 }
2129         }
2130 }
2131
2132 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size);
2133
2134 static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size)
2135 {
2136         float fac, facf;
2137         struct SeqEffectHandle sh = get_sequence_effect(seq);
2138         int early_out;
2139
2140         se->se1 = 0;
2141         se->se2 = 0;
2142         se->se3 = 0;
2143
2144 #if 0 // XXX old animation system
2145         if(seq->ipo && seq->ipo->curve.first) {
2146                 do_seq_ipo(scene, seq, cfra);
2147                 fac= seq->facf0;
2148                 facf= seq->facf1;
2149         } else 
2150 #endif // XXX old animation system
2151         {
2152                 sh.get_default_fac(seq, cfra, &fac, &facf);
2153         } 
2154
2155         if( scene->r.mode & R_FIELDS ); else facf= fac;
2156         
2157         early_out = sh.early_out(seq, fac, facf);
2158         switch (early_out) {
2159         case -1:
2160                 /* no input needed */
2161                 break;
2162         case 0:
2163                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2164                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2165                 if (seq->seq3) {
2166                         se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size);
2167                 }
2168                 break;
2169         case 1:
2170                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2171                 break;
2172         case 2:
2173                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2174                 break;
2175         }
2176
2177
2178         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2179
2180         /* children are not needed anymore ... */
2181
2182         if (se->se1 && se->se1->ibuf) {
2183                 IMB_cache_limiter_unref(se->se1->ibuf);
2184         }
2185         if (se->se2 && se->se2->ibuf) {
2186                 IMB_cache_limiter_unref(se->se2->ibuf);
2187         }
2188         if (se->se3 && se->se3->ibuf) {
2189                 IMB_cache_limiter_unref(se->se3->ibuf);
2190         }
2191         check_limiter_refcount("do_effect_seq_recursively", se);
2192 }
2193
2194 static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size)
2195 {
2196         TStripElem *se;
2197
2198         se = give_tstripelem(seq, cfra);
2199
2200         if(se) {
2201                 if (seq->type & SEQ_EFFECT) {
2202                         do_effect_seq_recursively(scene, seq, se, cfra, render_size);
2203                 } else {
2204                         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2205                 }
2206         }
2207         return se;
2208 }
2209
2210 /* FIXME:
2211    
2212 If cfra was float throughout blender (especially in the render
2213 pipeline) one could even _render_ with subframe precision
2214 instead of faking using the blend code below...
2215
2216 */
2217
2218 static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size)
2219 {
2220         SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
2221         int nr = cfra - seq->start;
2222         float f_cfra;
2223         int cfra_left;
2224         int cfra_right;
2225         TStripElem * se = 0;
2226         TStripElem * se1 = 0;
2227         TStripElem * se2 = 0;
2228         
2229         sequence_effect_speed_rebuild_map(seq, 0);
2230         
2231         f_cfra = seq->start + s->frameMap[nr];
2232         
2233         cfra_left = (int) floor(f_cfra);
2234         cfra_right = (int) ceil(f_cfra);
2235
2236         se = give_tstripelem(seq, cfra);
2237
2238         if (!se) {
2239                 return se;
2240         }
2241
2242         if (cfra_left == cfra_right || 
2243             (s->flags & SEQ_SPEED_BLEND) == 0) {
2244                 test_and_auto_discard_ibuf(se);
2245
2246                 if (se->ibuf == NULL) {
2247                         se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2248
2249                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2250                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2251                         else
2252                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2253
2254                         if (se1 == 0 || se1->ibuf == 0) {
2255                                 make_black_ibuf(se->ibuf);
2256                         } else {
2257                                 if (se->ibuf != se1->ibuf) {
2258                                         if (se->ibuf) {
2259                                                 IMB_freeImBuf(se->ibuf);
2260                                         }
2261
2262                                         se->ibuf = se1->ibuf;
2263                                         IMB_refImBuf(se->ibuf);
2264                                 }
2265                         }
2266                 }
2267         } else {
2268                 struct SeqEffectHandle sh;
2269
2270                 if(se->ibuf) {
2271                         if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty 
2272                            || !(se->ibuf->rect || se->ibuf->rect_float)) {
2273                                 IMB_freeImBuf(se->ibuf);
2274                                 se->ibuf= 0;
2275                         }
2276                 }
2277
2278                 if (se->ibuf == NULL) {
2279                         se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2280                         se2 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_right, render_size);
2281
2282                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2283                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2284                         else
2285                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2286                         
2287                         if (!se1 || !se2) {
2288                                 make_black_ibuf(se->ibuf);
2289                         } else {
2290                                 sh = get_sequence_effect(seq);
2291
2292                                 sh.execute(seq, cfra, 
2293                                            f_cfra - (float) cfra_left, 
2294                                            f_cfra - (float) cfra_left, 
2295                                            se->ibuf->x, se->ibuf->y, 
2296                                            se1->ibuf, se2->ibuf, 0, se->ibuf);
2297                         }
2298                 }
2299
2300         }
2301
2302         /* caller expects this to be referenced, so do it! */
2303         if (se->ibuf) {
2304                 IMB_cache_limiter_insert(se->ibuf);
2305                 IMB_cache_limiter_ref(se->ibuf);
2306                 IMB_cache_limiter_touch(se->ibuf);
2307         }
2308
2309         /* children are no longer needed */
2310         if (se1 && se1->ibuf)
2311                 IMB_cache_limiter_unref(se1->ibuf);
2312         if (se2 && se2->ibuf)
2313                 IMB_cache_limiter_unref(se2->ibuf);
2314
2315         check_limiter_refcount("do_handle_speed_effect", se);
2316
2317         return se;
2318 }
2319
2320 /* 
2321  * build all ibufs recursively
2322  * 
2323  * if successfull, the returned TStripElem contains the (referenced!) imbuf
2324  * that means: you _must_ call 
2325  *
2326  * IMB_cache_limiter_unref(rval);
2327  * 
2328  * if rval != 0
2329  * 
2330  */
2331
2332 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size)
2333 {
2334         TStripElem *se;
2335         if (seq->type == SEQ_SPEED) {
2336                 se = do_handle_speed_effect(scene, seq, cfra, render_size);
2337         } else {
2338                 se = do_build_seq_recursively_impl(scene, seq, cfra, render_size);
2339         }
2340
2341         check_limiter_refcount("do_build_seq_recursively", se);
2342
2343         return se;
2344 }
2345
2346 static TStripElem* do_build_seq_array_recursively(Scene *scene,
2347         ListBase *seqbasep, int cfra, int chanshown, int render_size)
2348 {
2349         Sequence* seq_arr[MAXSEQ+1];
2350         int count;
2351         int i;
2352         TStripElem* se = 0;
2353
2354         count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
2355
2356         if (!count) {
2357                 return 0;
2358         }
2359
2360         se = give_tstripelem(seq_arr[count - 1], cfra);
2361
2362         if (!se) {
2363                 return 0;
2364         }
2365
2366         test_and_auto_discard_ibuf(se);
2367
2368         if (se->ibuf_comp != 0) {
2369                 IMB_cache_limiter_insert(se->ibuf_comp);
2370                 IMB_cache_limiter_ref(se->ibuf_comp);
2371                 IMB_cache_limiter_touch(se->ibuf_comp);
2372                 return se;
2373         }
2374
2375         
2376         if(count == 1) {
2377                 se = do_build_seq_recursively(scene, seq_arr[0], cfra, render_size);
2378                 if (se->ibuf) {
2379                         se->ibuf_comp = se->ibuf;
2380                         IMB_refImBuf(se->ibuf_comp);
2381                 }
2382                 return se;
2383         }
2384
2385
2386         for (i = count - 1; i >= 0; i--) {
2387                 int early_out;
2388                 Sequence * seq = seq_arr[i];
2389                 struct SeqEffectHandle sh;
2390
2391                 se = give_tstripelem(seq, cfra);
2392
2393                 test_and_auto_discard_ibuf(se);
2394
2395                 if (se->ibuf_comp != 0) {
2396                         break;
2397                 }
2398                 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2399                         do_build_seq_recursively(scene, seq, cfra, render_size);
2400                         if (se->ibuf) {
2401                                 se->ibuf_comp = se->ibuf;
2402                                 IMB_refImBuf(se->ibuf);
2403                         } else {
2404                                 se->ibuf_comp = IMB_allocImBuf(
2405                                         (short)seqrectx, (short)seqrecty, 
2406                                         32, IB_rect, 0);
2407                                 IMB_cache_limiter_insert(se->ibuf_comp);
2408                                 IMB_cache_limiter_ref(se->ibuf_comp);
2409                                 IMB_cache_limiter_touch(se->ibuf_comp);
2410                         }
2411                         break;
2412                 }
2413
2414                 sh = get_sequence_blend(seq);
2415
2416                 seq->facf0 = seq->facf1 = 1.0;
2417
2418 #if 0 // XXX old animation system
2419                 if(seq->ipo && seq->ipo->curve.first) {
2420                         do_seq_ipo(scene, seq, cfra);
2421                 } 
2422 #endif
2423
2424                 if( scene->r.mode & R_FIELDS ); else seq->facf0 = seq->facf1;
2425
2426                 seq->facf0 *= seq->blend_opacity / 100.0;
2427                 seq->facf1 *= seq->blend_opacity / 100.0;
2428
2429                 early_out = sh.early_out(seq, seq->facf0, seq->facf1);
2430
2431                 switch (early_out) {
2432                 case -1:
2433                 case 2:
2434                         do_build_seq_recursively(scene, seq, cfra, render_size);
2435                         if (se->ibuf) {
2436                                 se->ibuf_comp = se->ibuf;
2437                                 IMB_refImBuf(se->ibuf_comp);
2438                         } else {
2439                                 se->ibuf_comp = IMB_allocImBuf(
2440                                         (short)seqrectx, (short)seqrecty, 
2441                                         32, IB_rect, 0);
2442                                 IMB_cache_limiter_insert(se->ibuf_comp);
2443                                 IMB_cache_limiter_ref(se->ibuf_comp);
2444                                 IMB_cache_limiter_touch(se->ibuf_comp);
2445                         }
2446                         break;
2447                 case 1:
2448                         if (i == 0) {
2449                                 se->ibuf_comp = IMB_allocImBuf(
2450                                         (short)seqrectx, (short)seqrecty, 
2451                                         32, IB_rect, 0);
2452                                 IMB_cache_limiter_insert(se->ibuf_comp);
2453                                 IMB_cache_limiter_ref(se->ibuf_comp);
2454                                 IMB_cache_limiter_touch(se->ibuf_comp);
2455                         }
2456                         break;
2457                 case 0:
2458                         do_build_seq_recursively(scene, seq, cfra, render_size);
2459                         if (!se->ibuf) {
2460                                 se->ibuf = IMB_allocImBuf(
2461                                         (short)seqrectx, (short)seqrecty, 
2462                                         32, IB_rect, 0);
2463                                 IMB_cache_limiter_insert(se->ibuf);
2464                                 IMB_cache_limiter_ref(se->ibuf);
2465                                 IMB_cache_limiter_touch(se->ibuf);
2466                         }
2467                         if (i == 0) {
2468                                 se->ibuf_comp = se->ibuf;
2469                                 IMB_refImBuf(se->ibuf_comp);
2470                         }
2471                         break;
2472                 }
2473         
2474                 if (se->ibuf_comp) {
2475                         break;
2476                 }
2477         }
2478
2479         i++;
2480
2481         for (; i < count; i++) {
2482                 Sequence * seq = seq_arr[i];
2483                 struct SeqEffectHandle sh = get_sequence_blend(seq);
2484                 TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
2485                 TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
2486         
2487                 int early_out = sh.early_out(seq, seq->facf0, seq->facf1);
2488                 switch (early_out) {
2489                 case 0: {
2490                         int x= se2->ibuf->x;
2491                         int y= se2->ibuf->y;
2492                         int swap_input = FALSE;
2493
2494                         if (se1->ibuf_comp->rect_float ||
2495                             se2->ibuf->rect_float) {
2496                                 se2->ibuf_comp = IMB_allocImBuf(
2497                                         (short)seqrectx, (short)seqrecty, 
2498                                         32, IB_rectfloat, 0);
2499                         } else {
2500                                 se2->ibuf_comp = IMB_allocImBuf(
2501                                         (short)seqrectx, (short)seqrecty, 
2502                                         32, IB_rect, 0);
2503                         }
2504
2505
2506                         if (!se1->ibuf_comp->rect_float && 
2507                             se2->ibuf_comp->rect_float) {
2508                                 IMB_float_from_rect(se1->ibuf_comp);
2509                         }
2510                         if (!se2->ibuf->rect_float && 
2511                             se2->ibuf_comp->rect_float) {
2512                                 IMB_float_from_rect(se2->ibuf);
2513                         }
2514
2515                         if (!se1->ibuf_comp->rect && 
2516                             !se2->ibuf_comp->rect_float) {
2517                                 IMB_rect_from_float(se1->ibuf_comp);
2518                         }
2519                         if (!se2->ibuf->rect && 
2520                             !se2->ibuf_comp->rect_float) {
2521                                 IMB_rect_from_float(se2->ibuf);
2522                         }
2523                         
2524                         /* bad hack, to fix crazy input ordering of 
2525                            those two effects */
2526
2527                         if (seq->blend_mode == SEQ_ALPHAOVER ||
2528                             seq->blend_mode == SEQ_ALPHAUNDER ||
2529                             seq->blend_mode == SEQ_OVERDROP) {
2530                                 swap_input = TRUE;
2531                         }
2532
2533                         if (swap_input) {
2534                                 sh.execute(seq, cfra, 
2535                                            seq->facf0, seq->facf1, x, y, 
2536                                            se2->ibuf, se1->ibuf_comp, 0,
2537                                            se2->ibuf_comp);
2538                         } else {
2539                                 sh.execute(seq, cfra, 
2540                                            seq->facf0, seq->facf1, x, y, 
2541                                            se1->ibuf_comp, se2->ibuf, 0,
2542                                            se2->ibuf_comp);
2543                         }
2544                         
2545                         IMB_cache_limiter_insert(se2->ibuf_comp);
2546                         IMB_cache_limiter_ref(se2->ibuf_comp);
2547                         IMB_cache_limiter_touch(se2->ibuf_comp);
2548
2549                         IMB_cache_limiter_unref(se1->ibuf_comp);
2550                         IMB_cache_limiter_unref(se2->ibuf);
2551
2552                         break;
2553                 }
2554                 case 1: {
2555                         se2->ibuf_comp = se1->ibuf;
2556                         IMB_refImBuf(se2->ibuf_comp);
2557
2558                         break;
2559                 }
2560                 }
2561                 se = se2;
2562         }
2563
2564         return se;
2565 }
2566
2567 /*
2568  * returned ImBuf is refed!
2569  * you have to unref after usage!
2570  */
2571
2572 static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2573 {
2574         Editing *ed= seq_give_editing(scene, FALSE);
2575         int count;
2576         ListBase *seqbasep;
2577         TStripElem *se;
2578
2579         
2580         if(ed==NULL) return NULL;
2581
2582         count = BLI_countlist(&ed->metastack);
2583         if((chanshown < 0) && (count > 0)) {
2584                 count = MAX2(count + chanshown, 0);
2585                 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2586         } else {
2587                 seqbasep= ed->seqbasep;
2588         }
2589
2590         seqrectx= rectx;        /* bad bad global! */
2591         seqrecty= recty;
2592
2593         se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size);
2594
2595         if(!se) { 
2596                 return 0;
2597         }
2598
2599         check_limiter_refcount_comp("give_ibuf_seq_impl", se);
2600
2601         return se->ibuf_comp;
2602 }
2603
2604 ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
2605 {
2606         TStripElem* se;
2607
2608         seqrectx= rectx;        /* bad bad global! */
2609         seqrecty= recty;
2610
2611         se = do_build_seq_recursively(scene, seq, cfra, render_size);
2612
2613         if(!se) { 
2614                 return 0;
2615         }
2616
2617         check_limiter_refcount("give_ibuf_seq_direct", se);
2618
2619         if (se->ibuf) {
2620                 IMB_cache_limiter_unref(se->ibuf);
2621         }
2622
2623         return se->ibuf;
2624 }
2625
2626 ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2627 {
2628         ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size);
2629
2630         if (i) {
2631                 IMB_cache_limiter_unref(i);
2632         }
2633         return i;
2634 }
2635
2636 #if 0
2637 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2638 static int seq_can_blend(Sequence *seq)
2639 {
2640         if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2641                 return 1;
2642         } else {
2643                 return 0;
2644         }
2645 }
2646 #endif
2647
2648 /* *********************** threading api ******************* */
2649
2650 static ListBase running_threads;
2651 static ListBase prefetch_wait;
2652 static ListBase prefetch_done;
2653
2654 static pthread_mutex_t queue_lock          = PTHREAD_MUTEX_INITIALIZER;
2655 static pthread_mutex_t wakeup_lock         = PTHREAD_MUTEX_INITIALIZER;
2656 static pthread_cond_t  wakeup_cond         = PTHREAD_COND_INITIALIZER;
2657
2658 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2659 //static pthread_cond_t  prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2660
2661 static pthread_mutex_t frame_done_lock     = PTHREAD_MUTEX_INITIALIZER;
2662 static pthread_cond_t  frame_done_cond     = PTHREAD_COND_INITIALIZER;
2663
2664 static volatile int seq_thread_shutdown = FALSE;
2665 static volatile int seq_last_given_monoton_cfra = 0;
2666 static int monoton_cfra = 0;
2667
2668 typedef struct PrefetchThread {
2669         struct PrefetchThread *next, *prev;
2670         
2671         Scene *scene;
2672         struct PrefetchQueueElem *current;
2673         pthread_t pthread;
2674         int running;
2675         
2676 } PrefetchThread;
2677
2678 typedef struct PrefetchQueueElem {
2679         struct PrefetchQueueElem *next, *prev;
2680         
2681         int rectx;
2682         int recty;
2683         int cfra;
2684         int chanshown;
2685         int render_size;
2686
2687         int monoton_cfra;
2688
2689         struct ImBuf * ibuf;
2690 } PrefetchQueueElem;
2691
2692 #if 0
2693 static void *seq_prefetch_thread(void * This_)
2694 {
2695         PrefetchThread * This = This_;
2696
2697         while (!seq_thread_shutdown) {
2698                 PrefetchQueueElem *e;
2699                 int s_last;
2700
2701                 pthread_mutex_lock(&queue_lock);
2702                 e = prefetch_wait.first;
2703                 if (e) {
2704                         BLI_remlink(&prefetch_wait, e);
2705                 }
2706                 s_last = seq_last_given_monoton_cfra;
2707
2708                 This->current = e;
2709
2710                 pthread_mutex_unlock(&queue_lock);
2711
2712                 if (!e) {
2713                         pthread_mutex_lock(&prefetch_ready_lock);
2714
2715                         This->running = FALSE;
2716
2717                         pthread_cond_signal(&prefetch_ready_cond);
2718                         pthread_mutex_unlock(&prefetch_ready_lock);
2719
2720                         pthread_mutex_lock(&wakeup_lock);
2721                         if (!seq_thread_shutdown) {
2722                                 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2723                         }
2724                         pthread_mutex_unlock(&wakeup_lock);
2725                         continue;
2726                 }
2727
2728                 This->running = TRUE;
2729                 
2730                 if (e->cfra >= s_last) { 
2731                         e->ibuf = give_ibuf_seq_impl(This->scene, 
2732                                 e->rectx, e->recty, e->cfra, e->chanshown,
2733                                 e->render_size);
2734                 }
2735
2736                 pthread_mutex_lock(&queue_lock);
2737
2738                 BLI_addtail(&prefetch_done, e);
2739
2740                 for (e = prefetch_wait.first; e; e = e->next) {
2741                         if (s_last > e->monoton_cfra) {
2742                                 BLI_remlink(&prefetch_wait, e);
2743                                 MEM_freeN(e);
2744                         }
2745                 }
2746
2747                 for (e = prefetch_done.first; e; e = e->next) {
2748                         if (s_last > e->monoton_cfra) {
2749                                 if (e->ibuf) {
2750                                         IMB_cache_limiter_unref(e->ibuf);
2751                                 }
2752                                 BLI_remlink(&prefetch_done, e);
2753                                 MEM_freeN(e);
2754                         }
2755                 }
2756
2757                 pthread_mutex_unlock(&queue_lock);
2758
2759                 pthread_mutex_lock(&frame_done_lock);
2760                 pthread_cond_signal(&frame_done_cond);
2761                 pthread_mutex_unlock(&frame_done_lock);
2762         }
2763         return 0;
2764 }
2765
2766 static void seq_start_threads(Scene *scene)
2767 {
2768         int i;
2769
2770         running_threads.first = running_threads.last = NULL;
2771         prefetch_wait.first = prefetch_wait.last = NULL;
2772         prefetch_done.first = prefetch_done.last = NULL;
2773
2774         seq_thread_shutdown = FALSE;
2775         seq_last_given_monoton_cfra = monoton_cfra = 0;
2776
2777         /* since global structures are modified during the processing
2778            of one frame, only one render thread is currently possible... 
2779
2780            (but we code, in the hope, that we can remove this restriction
2781            soon...)
2782         */
2783
2784         fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2785
2786         for (i = 0; i < 1; i++) {
2787                 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
2788                 t->scene= scene;
2789                 t->running = TRUE;
2790                 BLI_addtail(&running_threads, t);
2791
2792                 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2793         }
2794
2795         /* init malloc mutex */
2796         BLI_init_threads(0, 0, 0);
2797 }
2798
2799 static void seq_stop_threads()
2800 {
2801         PrefetchThread *tslot;
2802         PrefetchQueueElem *e;
2803
2804         fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2805
2806         if (seq_thread_shutdown) {
2807                 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2808                 return;
2809         }
2810         
2811         pthread_mutex_lock(&wakeup_lock);
2812
2813         seq_thread_shutdown = TRUE;
2814
2815         pthread_cond_broadcast(&wakeup_cond);
2816         pthread_mutex_unlock(&wakeup_lock);
2817
2818         for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2819                 pthread_join(tslot->pthread, NULL);
2820         }
2821
2822
2823         for (e = prefetch_wait.first; e; e = e->next) {
2824                 BLI_remlink(&prefetch_wait, e);
2825                 MEM_freeN(e);
2826         }
2827
2828         for (e = prefetch_done.first; e; e = e->next) {
2829                 if (e->ibuf) {
2830                         IMB_cache_limiter_unref(e->ibuf);
2831                 }
2832                 BLI_remlink(&prefetch_done, e);
2833                 MEM_freeN(e);
2834         }
2835
2836         BLI_freelistN(&running_threads);
2837
2838         /* deinit malloc mutex */
2839         BLI_end_threads(0);
2840 }
2841 #endif
2842
2843 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
2844                                 int render_size)
2845 {
2846         PrefetchQueueElem *e;
2847         if (seq_thread_shutdown) {
2848                 return;
2849         }
2850
2851         e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2852         e->rectx = rectx;
2853         e->recty = recty;
2854         e->cfra = cfra;
2855         e->chanshown = chanshown;
2856         e->render_size = render_size;
2857         e->monoton_cfra = monoton_cfra++;
2858
2859         pthread_mutex_lock(&queue_lock);
2860         BLI_addtail(&prefetch_wait, e);
2861         pthread_mutex_unlock(&queue_lock);
2862         
2863         pthread_mutex_lock(&wakeup_lock);
2864         pthread_cond_signal(&wakeup_cond);
2865         pthread_mutex_unlock(&wakeup_lock);
2866 }
2867
2868 #if 0
2869 static void seq_wait_for_prefetch_ready()
2870 {
2871         PrefetchThread *tslot;
2872
2873         if (seq_thread_shutdown) {
2874                 return;
2875         }
2876
2877         fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
2878
2879         pthread_mutex_lock(&prefetch_ready_lock);
2880
2881         for(;;) {
2882                 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2883                         if (tslot->running) {
2884                                 break;
2885                         }
2886                 }
2887                 if (!tslot) {
2888                         break;
2889                 }
2890                 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
2891         }
2892
2893         pthread_mutex_unlock(&prefetch_ready_lock);
2894
2895         fprintf(stderr, "SEQ-THREAD: prefetch done\n");
2896 }
2897 #endif
2898
2899 ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2900 {
2901         PrefetchQueueElem *e = NULL;
2902         int found_something = FALSE;
2903
2904         if (seq_thread_shutdown) {
2905                 return give_ibuf_seq(scene, rectx, recty, cfra, chanshown, render_size);
2906         }
2907
2908         while (!e) {
2909                 int success = FALSE;
2910                 pthread_mutex_lock(&queue_lock);
2911
2912                 for (e = prefetch_done.first; e; e = e->next) {
2913                         if (cfra == e->cfra &&
2914                             chanshown == e->chanshown &&
2915                             rectx == e->rectx && 
2916                             recty == e->recty &&
2917                             render_size == e->render_size) {
2918                                 success = TRUE;
2919                                 found_something = TRUE;
2920                                 break;
2921                         }
2922                 }
2923
2924                 if (!e) {
2925                         for (e = prefetch_wait.first; e; e = e->next) {
2926                                 if (cfra == e->cfra &&
2927                                     chanshown == e->chanshown &&
2928                                     rectx == e->rectx && 
2929                                     recty == e->recty &&
2930                                     render_size == e->render_size) {
2931                                         found_something = TRUE;
2932                                         break;
2933                                 }
2934                         }
2935                 }
2936
2937                 if (!e) {
2938                         PrefetchThread *tslot;
2939
2940                         for(tslot = running_threads.first; 
2941                             tslot; tslot= tslot->next) {
2942                                 if (tslot->current &&
2943                                     cfra == tslot->current->cfra &&
2944                                     chanshown == tslot->current->chanshown &&
2945                                     rectx == tslot->current->rectx && 
2946                                     recty == tslot->current->recty &&
2947                                     render_size== tslot->current->render_size){
2948                                         found_something = TRUE;
2949                                         break;
2950                                 }
2951                         }
2952                 }
2953
2954                 /* e->ibuf is unrefed by render thread on next round. */
2955
2956                 if (e) {
2957                         seq_last_given_monoton_cfra = e->monoton_cfra;
2958                 }
2959
2960                 pthread_mutex_unlock(&queue_lock);
2961
2962                 if (!success) {
2963                         e = NULL;
2964
2965                         if (!found_something) {
2966                                 fprintf(stderr, 
2967                                         "SEQ-THREAD: Requested frame "
2968                                         "not in queue ???\n");
2969                                 break;
2970                         }
2971                         pthread_mutex_lock(&frame_done_lock);
2972                         pthread_cond_wait(&frame_done_cond, &frame_done_lock);
2973                         pthread_mutex_unlock(&frame_done_lock);
2974                 }
2975         }
2976         
2977         return e ? e->ibuf : 0;
2978 }
2979
2980 /* Functions to free imbuf and anim data on changes */
2981
2982 static void free_imbuf_strip_elem(TStripElem *se)
2983 {
2984         if(se->ibuf) {
2985                 IMB_freeImBuf(se->ibuf);
2986         }
2987         if(se->ibuf_comp) {
2988                 IMB_freeImBuf(se->ibuf_comp);
2989         }
2990         se->ibuf_comp = 0;
2991         se->ibuf= 0;
2992         se->ok= STRIPELEM_OK;
2993         se->se1= se->se2= se->se3= 0;
2994 }
2995
2996 static void free_anim_seq(Sequence *seq)
2997 {
2998         if(seq->anim) {
2999                 IMB_free_anim(seq->anim);
3000                 seq->anim = 0;
3001         }
3002 }
3003
3004 #if 0
3005 static void free_imbuf_seq_except(Scene *scene, int cfra)
3006 {
3007         Editing *ed= seq_give_editing(scene, FALSE);
3008         Sequence *seq;
3009         TStripElem *se;
3010         int a;
3011
3012         if(ed==NULL) return;
3013
3014         SEQ_BEGIN(ed, seq) {
3015                 if(seq->strip) {
3016                         TStripElem * curelem = give_tstripelem(seq, cfra);
3017
3018                         for(a = 0, se = seq->strip->tstripdata; 
3019                             a < seq->strip->len && se; a++, se++) {
3020                                 if(se != curelem) {
3021                                         free_imbuf_strip_elem(se);
3022                                 }
3023                         }
3024                         for(a = 0, se = seq->strip->tstripdata_startstill;
3025                             a < seq->strip->startstill && se; a++, se++) {
3026                                 if(se != curelem) {
3027                                         free_imbuf_strip_elem(se);
3028                                 }
3029                         }
3030                         for(a = 0, se = seq->strip->tstripdata_endstill;
3031                             a < seq->strip->endstill && se; a++, se++) {
3032                                 if(se != curelem) {
3033                                         free_imbuf_strip_elem(se);
3034                                 }
3035                         }
3036                         if(seq->strip->ibuf_startstill) {
3037                                 IMB_freeImBuf(seq->strip->ibuf_startstill);
3038                                 seq->strip->ibuf_startstill = 0;
3039                         }
3040
3041                         if(seq->strip->ibuf_endstill) {
3042                                 IMB_freeImBuf(seq->strip->ibuf_endstill);
3043                                 seq->strip->ibuf_endstill = 0;
3044                         }
3045
3046                         if(seq->type==SEQ_MOVIE)
3047                                 if(seq->startdisp > cfra || seq->enddisp < cfra)
3048                                         free_anim_seq(seq);
3049                         free_proxy_seq(seq);
3050                 }
3051         }
3052         SEQ_END
3053 }
3054 #endif
3055
3056 void free_imbuf_seq(ListBase * seqbase, int check_mem_usage)
3057 {
3058         Sequence *seq;
3059         TStripElem *se;
3060         int a;
3061
3062         if (check_mem_usage) {
3063                 /* Let the cache limitor take care of this (schlaile) */
3064                 /* While render let's keep all memory available for render 
3065                    (ton)
3066                    At least if free memory is tight...
3067                    This can make a big difference in encoding speed
3068                    (it is around 4 times(!) faster, if we do not waste time
3069                    on freeing _all_ buffers every time on long timelines...)
3070                    (schlaile)
3071                 */
3072         
3073                 uintptr_t mem_in_use;
3074                 uintptr_t mmap_in_use;
3075                 uintptr_t max;
3076         
3077                 mem_in_use= MEM_get_memory_in_use();
3078                 mmap_in_use= MEM_get_mapped_memory_in_use();
3079                 max = MEM_CacheLimiter_get_maximum();
3080         
3081                 if (max == 0 || mem_in_use + mmap_in_use <= max) {
3082                         return;
3083                 }
3084         }
3085
3086         
3087         for(seq= seqbase->first; seq; seq= seq->next) {
3088                 if(seq->strip) {
3089                         for(a = 0, se = seq->strip->tstripdata; 
3090                             a < seq->strip->len && se; a++, se++) {
3091                                 free_imbuf_strip_elem(se);
3092                         }
3093                         for(a = 0, se = seq->strip->tstripdata_startstill; 
3094                             a < seq->strip->startstill && se; a++, se++) {
3095                                 free_imbuf_strip_elem(se);
3096                         }
3097                         for(a = 0, se = seq->strip->tstripdata_endstill; 
3098                             a < seq->strip->endstill && se; a++, se++) {
3099                                 free_imbuf_strip_elem(se);
3100                         }
3101                         if(seq->strip->ibuf_startstill) {
3102                                 IMB_freeImBuf(seq->strip->ibuf_startstill);
3103                                 seq->strip->ibuf_startstill = 0;
3104                         }
3105
3106                         if(seq->strip->ibuf_endstill) {
3107                                 IMB_freeImBuf(seq->strip->ibuf_endstill);
3108                                 seq->strip->ibuf_endstill = 0;
3109                         }
3110
3111                         if(seq->type==SEQ_MOVIE)
3112                                 free_anim_seq(seq);
3113                         if(seq->type==SEQ_SPEED) {
3114                                 sequence_effect_speed_rebuild_map(seq, 1);
3115                         }
3116                 }
3117                 if(seq->type==SEQ_META) {
3118                         free_imbuf_seq(&seq->seqbase, FALSE);
3119                 }
3120                 if(seq->type==SEQ_SCENE) {
3121                         /* FIXME: recurs downwards, 
3122                            but do recurs protection somehow! */
3123                 }
3124         }
3125         
3126 }
3127
3128 static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
3129 {
3130         Sequence *subseq;
3131         int a, free_imbuf = 0;
3132         TStripElem *se;
3133         
3134         /* recurs downwards to see if this seq depends on the changed seq */
3135         
3136         if(seq == NULL)
3137                 return 0;
3138         
3139         if(seq == changed_seq)
3140                 free_imbuf = 1;
3141         
3142         for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
3143                 if(update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change))
3144                         free_imbuf = TRUE;
3145         
3146         if(seq->seq1)
3147                 if(update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change))
3148                         free_imbuf = TRUE;
3149         if(seq->seq2 && (seq->seq2 != seq->seq1))
3150                 if(update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change))
3151                         free_imbuf = TRUE;
3152         if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
3153                 if(update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change))
3154                         free_imbuf = TRUE;
3155         
3156         if(free_imbuf) {
3157                 if(ibuf_change) {
3158                         se= seq->strip->tstripdata;
3159                         if (se) {
3160                                 for(a=0; a<seq->len; a++, se++)
3161                                         free_imbuf_strip_elem(se);
3162                         }
3163                         
3164                         if(seq->type == SEQ_MOVIE)
3165                                 free_anim_seq(seq);
3166                         if(seq->type == SEQ_SPEED) {
3167                                 sequence_effect_speed_rebuild_map(seq, 1);
3168                         }
3169                 }
3170                 
3171                 if(len_change)
3172                         calc_sequence(seq);
3173         }
3174         
3175         return free_imbuf;
3176 }
3177
3178 void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
3179 {
3180         Editing *ed= seq_give_editing(scene, FALSE);
3181         Sequence *seq;
3182         
3183         if (ed==NULL) return;
3184         
3185         for (seq=ed->seqbase.first; seq; seq=seq->next)
3186                 update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change);
3187 }
3188
3189 #if 0 // XXX from 2.4x, needs updating
3190 void free_imbuf_seq()
3191 {
3192         Scene * sce = G.main->scene.first;
3193         while(sce) {
3194                 free_imbuf_seq_editing(sce->ed);
3195                 sce= sce->id.next;
3196         }
3197 }
3198 #endif 
3199
3200 #if 0 // XXX old animation system
3201 static void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo)
3202 {
3203         /* force update of all sequences with this ipo, on ipo changes */
3204         Editing *ed= seq_give_editing(scene, FALSE);
3205         Sequence *seq;
3206
3207         if(ed==NULL) return;
3208
3209         SEQ_BEGIN(ed, seq) {
3210                 if(seq->ipo == ipo) {