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