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