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