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