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