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