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