fix for crash copying in the sequencer.
[blender.git] / source / blender / blenkernel / intern / sequencer.c
1 /**
2 * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): 
24  * - Blender Foundation, 2003-2009
25  * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <stddef.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <math.h>
34
35 #include "MEM_guardedalloc.h"
36 #include "MEM_CacheLimiterC-Api.h"
37
38 #include "DNA_sequence_types.h"
39 #include "DNA_scene_types.h"
40 #include "DNA_anim_types.h"
41 #include "DNA_object_types.h"
42
43 #include "BKE_animsys.h"
44 #include "BKE_global.h"
45 #include "BKE_image.h"
46 #include "BKE_main.h"
47 #include "BKE_sequencer.h"
48 #include "BKE_fcurve.h"
49 #include "BKE_scene.h"
50 #include "RNA_access.h"
51 #include "RE_pipeline.h"
52
53 #include "BLI_math.h"
54 #include "BLI_fileops.h"
55 #include "BLI_listbase.h"
56 #include "BLI_path_util.h"
57 #include "BLI_string.h"
58 #include <pthread.h>
59
60 #include "IMB_imbuf.h"
61 #include "IMB_imbuf_types.h"
62
63
64
65 #include "BKE_context.h"
66 #include "BKE_sound.h"
67 #include "AUD_C-API.h"
68
69 #ifdef WIN32
70 #define snprintf _snprintf
71 #endif
72
73 /* **** XXX ******** */
74 //static void waitcursor(int val) {}
75 //static int blender_test_break() {return 0;}
76
77 /* **** XXX ******** */
78 #define SELECT 1
79 ListBase seqbase_clipboard;
80 int seqbase_clipboard_frame;
81 SequencerDrawView sequencer_view3d_cb= NULL; /* NULL in background mode */
82
83
84 void printf_strip(Sequence *seq)
85 {
86         fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n",
87                         seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp);
88         fprintf(stderr, "\tseq_tx_set_final_left: %d %d\n\n", seq_tx_get_final_left(seq, 0), seq_tx_get_final_right(seq, 0));
89 }
90
91 int seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg)
92 {
93         Sequence *iseq;
94         for(iseq= seqbase->first; iseq; iseq= iseq->next) {
95                 if(seq_recursive_apply(iseq, apply_func, arg) == -1)
96                         return -1; /* bail out */
97         }
98         return 1;
99 }
100
101 int seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg)
102 {
103         int ret= apply_func(seq, arg);
104
105         if(ret == -1)
106                 return -1;  /* bail out */
107
108         if(ret && seq->seqbase.first)
109                 ret = seqbase_recursive_apply(&seq->seqbase, apply_func, arg);
110
111         return ret;
112 }
113
114 /* **********************************************************************
115    alloc / free functions
116    ********************************************************************** */
117
118 static void free_tstripdata(int len, TStripElem *se)
119 {
120         TStripElem *seo;
121         int a;
122
123         seo= se;
124         if (!se)
125                 return;
126
127         for(a=0; a<len; a++, se++) {
128                 if(se->ibuf) {
129                         IMB_freeImBuf(se->ibuf);
130                         se->ibuf = 0;
131                 }
132                 if(se->ibuf_comp) {
133                         IMB_freeImBuf(se->ibuf_comp);
134                         se->ibuf_comp = 0;
135                 }
136         }
137
138         MEM_freeN(seo);
139 }
140
141
142 void new_tstripdata(Sequence *seq)
143 {
144         if(seq->strip) {
145                 free_tstripdata(seq->strip->len, seq->strip->tstripdata);
146                 free_tstripdata(seq->strip->endstill, 
147                                 seq->strip->tstripdata_endstill);
148                 free_tstripdata(seq->strip->startstill, 
149                                 seq->strip->tstripdata_startstill);
150
151                 seq->strip->tstripdata= 0;
152                 seq->strip->tstripdata_endstill= 0;
153                 seq->strip->tstripdata_startstill= 0;
154
155                 if(seq->strip->ibuf_startstill) {
156                         IMB_freeImBuf(seq->strip->ibuf_startstill);
157                         seq->strip->ibuf_startstill = 0;
158                 }
159
160                 if(seq->strip->ibuf_endstill) {
161                         IMB_freeImBuf(seq->strip->ibuf_endstill);
162                         seq->strip->ibuf_endstill = 0;
163                 }
164
165                 seq->strip->len= seq->len;
166         }
167 }
168
169
170 /* free */
171
172 static void free_proxy_seq(Sequence *seq)
173 {
174         if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
175                 IMB_free_anim(seq->strip->proxy->anim);
176                 seq->strip->proxy->anim = 0;
177         }
178 }
179
180 void seq_free_strip(Strip *strip)
181 {
182         strip->us--;
183         if(strip->us>0) return;
184         if(strip->us<0) {
185                 printf("error: negative users in strip\n");
186                 return;
187         }
188
189         if (strip->stripdata) {
190                 MEM_freeN(strip->stripdata);
191         }
192
193         if (strip->proxy) {
194                 if (strip->proxy->anim) {
195                         IMB_free_anim(strip->proxy->anim);
196                 }
197
198                 MEM_freeN(strip->proxy);
199         }
200         if (strip->crop) {
201                 MEM_freeN(strip->crop);
202         }
203         if (strip->transform) {
204                 MEM_freeN(strip->transform);
205         }
206         if (strip->color_balance) {
207                 MEM_freeN(strip->color_balance);
208         }
209
210         free_tstripdata(strip->len, strip->tstripdata);
211         free_tstripdata(strip->endstill, strip->tstripdata_endstill);
212         free_tstripdata(strip->startstill, strip->tstripdata_startstill);
213
214         if(strip->ibuf_startstill) {
215                 IMB_freeImBuf(strip->ibuf_startstill);
216                 strip->ibuf_startstill = 0;
217         }
218
219         if(strip->ibuf_endstill) {
220                 IMB_freeImBuf(strip->ibuf_endstill);
221                 strip->ibuf_endstill = 0;
222         }
223
224         MEM_freeN(strip);
225 }
226
227 static void seq_free_animdata(Scene *scene, Sequence *seq);
228
229 void seq_free_sequence(Scene *scene, Sequence *seq)
230 {
231         if(seq->strip) seq_free_strip(seq->strip);
232
233         if(seq->anim) IMB_free_anim(seq->anim);
234
235         if (seq->type & SEQ_EFFECT) {
236                 struct SeqEffectHandle sh = get_sequence_effect(seq);
237
238                 sh.free(seq);
239         }
240
241         /* clipboard has no scene and will never have a sound handle or be active */
242         if(scene) {
243                 Editing *ed = scene->ed;
244
245                 if (ed->act_seq==seq)
246                         ed->act_seq= NULL;
247
248                 if(seq->scene_sound)
249                         sound_remove_scene_sound(scene, seq->scene_sound);
250
251                 seq_free_animdata(scene, seq);
252         }
253
254         MEM_freeN(seq);
255 }
256
257 Editing *seq_give_editing(Scene *scene, int alloc)
258 {
259         if (scene->ed == NULL && alloc) {
260                 Editing *ed;
261
262                 ed= scene->ed= MEM_callocN( sizeof(Editing), "addseq");
263                 ed->seqbasep= &ed->seqbase;
264         }
265         return scene->ed;
266 }
267
268 void seq_free_clipboard(void)
269 {
270         Sequence *seq, *nseq;
271
272         for(seq= seqbase_clipboard.first; seq; seq= nseq) {
273                 nseq= seq->next;
274                 seq_free_sequence(NULL, seq);
275         }
276         seqbase_clipboard.first= seqbase_clipboard.last= NULL;
277 }
278
279 void seq_free_editing(Scene *scene)
280 {
281         Editing *ed = scene->ed;
282         MetaStack *ms;
283         Sequence *seq;
284
285         if(ed==NULL)
286                 return;
287
288         SEQ_BEGIN(ed, seq) {
289                 seq_free_sequence(scene, seq);
290         }
291         SEQ_END
292
293         while((ms= ed->metastack.first)) {
294                 BLI_remlink(&ed->metastack, ms);
295                 MEM_freeN(ms);
296         }
297
298         MEM_freeN(ed);
299 }
300
301 /* ************************* itterator ************************** */
302 /* *************** (replaces old WHILE_SEQ) ********************* */
303 /* **************** use now SEQ_BEGIN() SEQ_END ***************** */
304
305 /* sequence strip iterator:
306  * - builds a full array, recursively into meta strips */
307
308 static void seq_count(ListBase *seqbase, int *tot)
309 {
310         Sequence *seq;
311
312         for(seq=seqbase->first; seq; seq=seq->next) {
313                 (*tot)++;
314
315                 if(seq->seqbase.first)
316                         seq_count(&seq->seqbase, tot);
317         }
318 }
319
320 static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
321 {
322         Sequence *seq;
323
324         for(seq=seqbase->first; seq; seq=seq->next) {
325                 seq->depth= depth;
326
327                 if(seq->seqbase.first)
328                         seq_build_array(&seq->seqbase, array, depth+1);
329
330                 **array= seq;
331                 (*array)++;
332         }
333 }
334
335 void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_pointer)
336 {
337         Sequence **array;
338
339         *seqarray= NULL;
340         *tot= 0;
341
342         if(ed == NULL)
343                 return;
344
345         if(use_pointer)
346                 seq_count(ed->seqbasep, tot);
347         else
348                 seq_count(&ed->seqbase, tot);
349
350         if(*tot == 0)
351                 return;
352
353         *seqarray= array= MEM_mallocN(sizeof(Sequence *)*(*tot), "SeqArray");
354         if(use_pointer)
355                 seq_build_array(ed->seqbasep, &array, 0);
356         else
357                 seq_build_array(&ed->seqbase, &array, 0);
358 }
359
360 void seq_begin(Editing *ed, SeqIterator *iter, int use_pointer)
361 {
362         memset(iter, 0, sizeof(*iter));
363         seq_array(ed, &iter->array, &iter->tot, use_pointer);
364
365         if(iter->tot) {
366                 iter->cur= 0;
367                 iter->seq= iter->array[iter->cur];
368                 iter->valid= 1;
369         }
370 }
371
372 void seq_next(SeqIterator *iter)
373 {
374         if(++iter->cur < iter->tot)
375                 iter->seq= iter->array[iter->cur];
376         else
377                 iter->valid= 0;
378 }
379
380 void seq_end(SeqIterator *iter)
381 {
382         if(iter->array)
383                 MEM_freeN(iter->array);
384
385         iter->valid= 0;
386 }
387
388 /*
389   **********************************************************************
390   * build_seqar
391   **********************************************************************
392   * Build a complete array of _all_ sequencies (including those
393   * in metastrips!)
394   **********************************************************************
395 */
396
397 static void do_seq_count(ListBase *seqbase, int *totseq)
398 {
399         Sequence *seq;
400
401         seq= seqbase->first;
402         while(seq) {
403                 (*totseq)++;
404                 if(seq->seqbase.first) do_seq_count(&seq->seqbase, totseq);
405                 seq= seq->next;
406         }
407 }
408
409 static void do_build_seqar(ListBase *seqbase, Sequence ***seqar, int depth)
410 {
411         Sequence *seq;
412
413         seq= seqbase->first;
414         while(seq) {
415                 seq->depth= depth;
416                 if(seq->seqbase.first) do_build_seqar(&seq->seqbase, seqar, depth+1);
417                 **seqar= seq;
418                 (*seqar)++;
419                 seq= seq->next;
420         }
421 }
422
423 void build_seqar(ListBase *seqbase, Sequence  ***seqar, int *totseq)
424 {
425         Sequence **tseqar;
426
427         *totseq= 0;
428         do_seq_count(seqbase, totseq);
429
430         if(*totseq==0) {
431                 *seqar= 0;
432                 return;
433         }
434         *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
435         tseqar= *seqar;
436
437         do_build_seqar(seqbase, seqar, 0);
438         *seqar= tseqar;
439 }
440
441 static void do_seq_count_cb(ListBase *seqbase, int *totseq,
442                                 int (*test_func)(Sequence * seq))
443 {
444         Sequence *seq;
445
446         seq= seqbase->first;
447         while(seq) {
448                 int test = test_func(seq);
449                 if (test & BUILD_SEQAR_COUNT_CURRENT) {
450                         (*totseq)++;
451                 }
452                 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
453                         do_seq_count_cb(&seq->seqbase, totseq, test_func);
454                 }
455                 seq= seq->next;
456         }
457 }
458
459 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
460                                   int (*test_func)(Sequence * seq))
461 {
462         Sequence *seq;
463
464         seq= seqbase->first;
465         while(seq) {
466                 int test = test_func(seq);
467                 seq->depth= depth;
468
469                 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
470                         do_build_seqar_cb(&seq->seqbase, seqar, depth+1, 
471                                           test_func);
472                 }
473                 if (test & BUILD_SEQAR_COUNT_CURRENT) {
474                         **seqar= seq;
475                         (*seqar)++;
476                 }
477                 seq= seq->next;
478         }
479 }
480
481 void build_seqar_cb(ListBase *seqbase, Sequence  ***seqar, int *totseq,
482                         int (*test_func)(Sequence * seq))
483 {
484         Sequence **tseqar;
485
486         *totseq= 0;
487         do_seq_count_cb(seqbase, totseq, test_func);
488
489         if(*totseq==0) {
490                 *seqar= 0;
491                 return;
492         }
493         *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
494         tseqar= *seqar;
495
496         do_build_seqar_cb(seqbase, seqar, 0, test_func);
497         *seqar= tseqar;
498 }
499
500
501 void calc_sequence_disp(Scene *scene, Sequence *seq)
502 {
503         if(seq->startofs && seq->startstill) seq->startstill= 0;
504         if(seq->endofs && seq->endstill) seq->endstill= 0;
505         
506         seq->startdisp= seq->start + seq->startofs - seq->startstill;
507         seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
508         
509         seq->handsize= 10.0;    /* 10 frames */
510         if( seq->enddisp-seq->startdisp < 10 ) {
511                 seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
512         }
513         else if(seq->enddisp-seq->startdisp > 250) {
514                 seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
515         }
516
517         seq_update_sound(scene, seq);
518 }
519
520 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_simple(se1->ibuf);
1026         }
1027         if (!se2->ibuf->rect_float && se->ibuf->rect_float) {
1028                 IMB_float_from_rect_simple(se2->ibuf);
1029         }
1030         if (!se3->ibuf->rect_float && se->ibuf->rect_float) {
1031                 IMB_float_from_rect_simple(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                         /* tweak to give more subtle results
1513                          * values above 1.0 are scaled */
1514                         if(cb.lift[c] > 1.0f)
1515                                 cb.lift[c] = pow(cb.lift[c] - 1.0f, 2.0f) + 1.0f;
1516
1517                         cb.lift[c] = 2.0f - cb.lift[c];
1518                 }
1519         }
1520
1521         if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
1522                 for (c = 0; c < 3; c++) {
1523                         if (cb.gain[c] != 0.0) {
1524                                 cb.gain[c] = 1.0/cb.gain[c];
1525                         } else {
1526                                 cb.gain[c] = 1000000; /* should be enough :) */
1527                         }
1528                 }
1529         }
1530
1531         if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
1532                 for (c = 0; c < 3; c++) {
1533                         if (cb.gamma[c] != 0.0) {
1534                                 cb.gamma[c] = 1.0/cb.gamma[c];
1535                         } else {
1536                                 cb.gamma[c] = 1000000; /* should be enough :) */
1537                         }
1538                 }
1539         }
1540
1541         return cb;
1542 }
1543
1544 /* note: lift is actually 2-lift */
1545 MINLINE float color_balance_fl(float in, const float lift, const float gain, const float gamma, const float mul)
1546 {
1547         float x= (((in - 1.0f) * lift) + 1.0f) * gain;
1548
1549         /* prevent NaN */
1550         if (x < 0.f) x = 0.f;
1551
1552         return powf(x, gamma) * mul;
1553 }
1554
1555 static void make_cb_table_byte(float lift, float gain, float gamma,
1556                                    unsigned char * table, float mul)
1557 {
1558         int y;
1559
1560         for (y = 0; y < 256; y++) {
1561                 float v= color_balance_fl((float)y * (1.0 / 255.0f), lift, gain, gamma, mul);
1562                 CLAMP(v, 0.0f, 1.0f);
1563                 table[y] = v * 255;
1564         }
1565 }
1566
1567 static void make_cb_table_float(float lift, float gain, float gamma,
1568                                 float * table, float mul)
1569 {
1570         int y;
1571
1572         for (y = 0; y < 256; y++) {
1573                 float v= color_balance_fl((float)y * (1.0 / 255.0f), lift, gain, gamma, mul);
1574                 table[y] = v;
1575         }
1576 }
1577
1578 static void color_balance_byte_byte(Sequence * seq, TStripElem* se, float mul)
1579 {
1580         unsigned char cb_tab[3][256];
1581         int c;
1582         unsigned char * p = (unsigned char*) se->ibuf->rect;
1583         unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1584
1585         StripColorBalance cb = calc_cb(seq->strip->color_balance);
1586
1587         for (c = 0; c < 3; c++) {
1588                 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1589                                    cb_tab[c], mul);
1590         }
1591
1592         while (p < e) {
1593                 p[0] = cb_tab[0][p[0]];
1594                 p[1] = cb_tab[1][p[1]];
1595                 p[2] = cb_tab[2][p[2]];
1596                 
1597                 p += 4;
1598         }
1599 }
1600
1601 static void color_balance_byte_float(Sequence * seq, TStripElem* se, float mul)
1602 {
1603         float cb_tab[4][256];
1604         int c,i;
1605         unsigned char * p = (unsigned char*) se->ibuf->rect;
1606         unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1607         float * o;
1608         StripColorBalance cb;
1609
1610         imb_addrectfloatImBuf(se->ibuf);
1611
1612         o = se->ibuf->rect_float;
1613
1614         cb = calc_cb(seq->strip->color_balance);
1615
1616         for (c = 0; c < 3; c++) {
1617                 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
1618                                         cb_tab[c], mul);
1619         }
1620
1621         for (i = 0; i < 256; i++) {
1622                 cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
1623         }
1624
1625         while (p < e) {
1626                 o[0] = cb_tab[0][p[0]];
1627                 o[1] = cb_tab[1][p[1]];
1628                 o[2] = cb_tab[2][p[2]];
1629                 o[3] = cb_tab[3][p[3]];
1630
1631                 p += 4; o += 4;
1632         }
1633 }
1634
1635 static void color_balance_float_float(Sequence * seq, TStripElem* se, float mul)
1636 {
1637         float * p = se->ibuf->rect_float;
1638         float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y;
1639         StripColorBalance cb = calc_cb(seq->strip->color_balance);
1640
1641         while (p < e) {
1642                 int c;
1643                 for (c = 0; c < 3; c++) {
1644                         p[c]= color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
1645                 }
1646                 p += 4;
1647         }
1648 }
1649
1650 static void color_balance(Sequence * seq, TStripElem* se, float mul)
1651 {
1652         if (se->ibuf->rect_float) {
1653                 color_balance_float_float(seq, se, mul);
1654         } else if(seq->flag & SEQ_MAKE_FLOAT) {
1655                 color_balance_byte_float(seq, se, mul);
1656         } else {
1657                 color_balance_byte_byte(seq, se, mul);
1658         }
1659 }
1660
1661 /*
1662   input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
1663
1664   Do all the things you can't really do afterwards using sequence effects
1665   (read: before rescaling to render resolution has been done)
1666
1667   Order is important!
1668
1669   - Deinterlace
1670   - Crop and transform in image source coordinate space
1671   - Flip X + Flip Y (could be done afterwards, backward compatibility)
1672   - Promote image to float data (affects pipeline operations afterwards)
1673   - Color balance (is most efficient in the byte -> float 
1674         (future: half -> float should also work fine!)
1675         case, if done on load, since we can use lookup tables)
1676   - Premultiply
1677
1678 */
1679
1680 static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se, int cfra, int seqrectx, int seqrecty)
1681 {
1682         float mul;
1683
1684         if ((seq->flag & SEQ_FILTERY) || 
1685                 (seq->flag & SEQ_USE_CROP) ||
1686                 (seq->flag & SEQ_USE_TRANSFORM) ||
1687                 (seq->flag & SEQ_FLIPX) ||
1688                 (seq->flag & SEQ_FLIPY) ||
1689                 (seq->flag & SEQ_USE_COLOR_BALANCE) ||
1690                 (seq->flag & SEQ_MAKE_PREMUL) ||
1691                 (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
1692                 return TRUE;
1693         }
1694
1695         mul = seq->mul;
1696
1697         if(seq->blend_mode == SEQ_BLEND_REPLACE &&
1698            !(seq->type & SEQ_EFFECT)) {
1699                 mul *= seq->blend_opacity / 100.0;
1700         }
1701
1702         if (mul != 1.0) {
1703                 return TRUE;
1704         }
1705                 
1706         return FALSE;
1707 }
1708
1709 static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int seqrectx, int seqrecty)
1710 {
1711         float mul;
1712
1713         seq->strip->orx= se->ibuf->x;
1714         seq->strip->ory= se->ibuf->y;
1715
1716         if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
1717                 IMB_filtery(se->ibuf);
1718         }
1719
1720         if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
1721                 StripCrop c;
1722                 StripTransform t;
1723                 int sx,sy,dx,dy;
1724
1725                 memset(&c, 0, sizeof(StripCrop));
1726                 memset(&t, 0, sizeof(StripTransform));
1727
1728                 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1729                         c = *seq->strip->crop;
1730                 }
1731                 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1732                         t = *seq->strip->transform;
1733                 }
1734
1735                 sx = se->ibuf->x - c.left - c.right;
1736                 sy = se->ibuf->y - c.top - c.bottom;
1737                 dx = sx;
1738                 dy = sy;
1739
1740                 if (seq->flag & SEQ_USE_TRANSFORM) {
1741                         dx = scene->r.xsch;
1742                         dy = scene->r.ysch;
1743                 }
1744
1745                 if (c.top + c.bottom >= se->ibuf->y ||
1746                         c.left + c.right >= se->ibuf->x ||
1747                         t.xofs >= dx || t.yofs >= dy) {
1748                         make_black_ibuf(se->ibuf);
1749                 } else {
1750                         ImBuf * i;
1751
1752                         if (se->ibuf->rect_float) {
1753                                 i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0);
1754                         } else {
1755                                 i = IMB_allocImBuf(dx, dy,32, IB_rect, 0);
1756                         }
1757
1758                         IMB_rectcpy(i, se->ibuf, 
1759                                         t.xofs, t.yofs, 
1760                                         c.left, c.bottom, 
1761                                         sx, sy);
1762
1763                         IMB_freeImBuf(se->ibuf);
1764
1765                         se->ibuf = i;
1766                 }
1767         } 
1768
1769         if(seq->flag & SEQ_FLIPX) {
1770                 IMB_flipx(se->ibuf);
1771         }
1772
1773         if(seq->sat != 1.0f) {
1774                 /* inline for now, could become an imbuf function */
1775                 int i;
1776                 char *rct= (char *)se->ibuf->rect;
1777                 float *rctf= se->ibuf->rect_float;
1778                 const float sat= seq->sat;
1779                 float hsv[3];
1780
1781                 if(rct) {
1782                         float rgb[3];
1783                         for (i = se->ibuf->x * se->ibuf->y; i > 0; i--, rct+=4) {
1784                                 rgb_byte_to_float(rct, rgb);
1785                                 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
1786                                 hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb+1, rgb+2);
1787                                 rgb_float_to_byte(rgb, rct);
1788                         }
1789                 }
1790
1791                 if(rctf) {
1792                         for (i = se->ibuf->x * se->ibuf->y; i > 0; i--, rctf+=4) {
1793                                 rgb_to_hsv(rctf[0], rctf[1], rctf[2], hsv, hsv+1, hsv+2);
1794                                 hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rctf, rctf+1, rctf+2);
1795                         }
1796                 }
1797         }
1798
1799         mul = seq->mul;
1800
1801         if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1802                 mul *= seq->blend_opacity / 100.0;
1803         }
1804
1805         if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1806                 color_balance(seq, se, mul);
1807                 mul = 1.0;
1808         }
1809
1810         if(seq->flag & SEQ_MAKE_FLOAT) {
1811                 if (!se->ibuf->rect_float)
1812                         IMB_float_from_rect_simple(se->ibuf);
1813
1814                 if (se->ibuf->rect) {
1815                         imb_freerectImBuf(se->ibuf);
1816                 }
1817         }
1818
1819         if(mul != 1.0) {
1820                 multibuf(se->ibuf, mul);
1821         }
1822
1823         if(seq->flag & SEQ_MAKE_PREMUL) {
1824                 if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
1825                         IMB_premultiply_alpha(se->ibuf);
1826                 }
1827         }
1828
1829
1830         if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
1831                 if(scene->r.mode & R_OSA) {
1832                         IMB_scaleImBuf(se->ibuf, 
1833                                            (short)seqrectx, (short)seqrecty);
1834                 } else {
1835                         IMB_scalefastImBuf(se->ibuf, 
1836                                            (short)seqrectx, (short)seqrecty);
1837                 }
1838         }
1839 }
1840
1841 /* test if image too small or discarded from cache: reload */
1842
1843 static void test_and_auto_discard_ibuf(TStripElem * se, 
1844                                        int seqrectx, int seqrecty)
1845 {
1846         if (se->ibuf) {
1847                 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty 
1848                    || !(se->ibuf->rect || se->ibuf->rect_float)) {
1849                         IMB_freeImBuf(se->ibuf);
1850
1851                         se->ibuf= 0;
1852                         se->ok= STRIPELEM_OK;
1853                 }
1854         }
1855         if (se->ibuf_comp) {
1856                 if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty 
1857                    || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) {
1858                         IMB_freeImBuf(se->ibuf_comp);
1859
1860                         se->ibuf_comp = 0;
1861                 }
1862         }
1863 }
1864
1865 static void test_and_auto_discard_ibuf_stills(Strip * strip)
1866 {
1867         if (strip->ibuf_startstill) {
1868                 if (!strip->ibuf_startstill->rect &&
1869                         !strip->ibuf_startstill->rect_float) {
1870                         IMB_freeImBuf(strip->ibuf_startstill);
1871                         strip->ibuf_startstill = 0;
1872                 }
1873         }
1874         if (strip->ibuf_endstill) {
1875                 if (!strip->ibuf_endstill->rect &&
1876                         !strip->ibuf_endstill->rect_float) {
1877                         IMB_freeImBuf(strip->ibuf_endstill);
1878                         strip->ibuf_endstill = 0;
1879                 }
1880         }
1881 }
1882
1883 static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
1884 {
1885         if (!se->ibuf) {
1886                 if (se->nr == 0 && seq->strip->ibuf_startstill) {
1887                         IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1888
1889                         se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
1890                 }
1891                 if (se->nr == seq->len - 1 
1892                         && (seq->len != 1)
1893                         && seq->strip->ibuf_endstill) {
1894                         IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1895
1896                         se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
1897                 }
1898         }
1899 }
1900
1901 static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
1902 {
1903         if (se->ibuf) {
1904                 if (se->nr == 0) {
1905                         seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
1906
1907                         IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
1908                         IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1909                 }
1910                 if (se->nr == seq->len - 1 && seq->len != 1) {
1911                         seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
1912
1913                         IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
1914                         IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1915                 }
1916         }
1917 }
1918
1919 static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown)
1920 {
1921         Sequence* seq_arr[MAXSEQ+1];
1922         int i;
1923         TStripElem* se = 0;
1924
1925         evaluate_seq_frame_gen(seq_arr, seqbasep, cfra);
1926
1927         for (i = 0; i < MAXSEQ; i++) {
1928                 if (!video_seq_is_rendered(seq_arr[i])) {
1929                         continue;
1930                 }
1931                 se = give_tstripelem(seq_arr[i], cfra);
1932                 if (se) {
1933                         if (se->ibuf) {
1934                                 IMB_freeImBuf(se->ibuf);
1935
1936                                 se->ibuf= 0;
1937                                 se->ok= STRIPELEM_OK;
1938                         }
1939
1940                         if (se->ibuf_comp) {
1941                                 IMB_freeImBuf(se->ibuf_comp);
1942
1943                                 se->ibuf_comp = 0;
1944                         }
1945                 }
1946         }
1947         
1948 }
1949
1950 static void check_limiter_refcount(const char * func, TStripElem *se)
1951 {
1952         if (se && se->ibuf) {
1953                 int refcount = IMB_cache_limiter_get_refcount(se->ibuf);
1954                 if (refcount != 1) {
1955                         /* can happen on complex pipelines */
1956                         if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1957                                 return;
1958                         }
1959  
1960                         fprintf(stderr, 
1961                                 "sequencer: (ibuf) %s: "
1962                                 "suspicious memcache "
1963                                 "limiter refcount: %d\n", func, refcount);
1964                 }
1965         }
1966 }
1967  
1968 static void check_limiter_refcount_comp(const char * func, TStripElem *se)
1969 {
1970         if (se && se->ibuf_comp) {
1971                 int refcount = IMB_cache_limiter_get_refcount(se->ibuf_comp);
1972                 if (refcount != 1) {
1973                         /* can happen on complex pipelines */
1974                         if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1975                                 return;
1976                         }
1977                         fprintf(stderr, 
1978                                 "sequencer: (ibuf comp) %s: "
1979                                 "suspicious memcache "
1980                                 "limiter refcount: %d\n", func, refcount);
1981                 }
1982         }
1983 }
1984
1985 static TStripElem* do_build_seq_array_recursively(
1986         Scene *scene,
1987         ListBase *seqbasep, int cfra, int chanshown, int render_size,
1988         int seqrectx, int seqrecty);
1989
1990 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1991                                   int build_proxy_run, int render_size, int seqrectx, int seqrecty)
1992 {
1993         char name[FILE_MAXDIR+FILE_MAXFILE];
1994         int use_limiter = TRUE;
1995
1996         test_and_auto_discard_ibuf(se, seqrectx, seqrecty);
1997         test_and_auto_discard_ibuf_stills(seq->strip);
1998
1999         if(seq->type == SEQ_META) {
2000                 TStripElem * meta_se = 0;
2001                 int use_preprocess = FALSE;
2002                 use_limiter = FALSE;
2003
2004                 if (!build_proxy_run && se->ibuf == 0) {
2005                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2006                         if (se->ibuf) {
2007                                 use_limiter = TRUE;
2008                                 use_preprocess = TRUE;
2009                         }
2010                 }
2011
2012                 if(!se->ibuf && seq->seqbase.first) {
2013                         meta_se = do_build_seq_array_recursively(scene,
2014                                 &seq->seqbase, seq->start + se->nr, 0,
2015                                 render_size, seqrectx, seqrecty);
2016
2017                         check_limiter_refcount("do_build_seq_ibuf: for META", meta_se);
2018                 }
2019
2020                 se->ok = STRIPELEM_OK;
2021
2022                 if(!se->ibuf && meta_se) {
2023                         se->ibuf = meta_se->ibuf_comp;
2024                         if(se->ibuf &&
2025                            (!input_have_to_preprocess(scene, seq, se, cfra,
2026                                                       seqrectx, seqrecty) ||
2027                                 build_proxy_run)) {
2028                                 IMB_refImBuf(se->ibuf);
2029                                 if (build_proxy_run) {
2030                                         IMB_cache_limiter_unref(se->ibuf);
2031                                 }
2032                         } else if (se->ibuf) {
2033                                 struct ImBuf * i = IMB_dupImBuf(se->ibuf);
2034
2035                                 IMB_cache_limiter_unref(se->ibuf);
2036
2037                                 se->ibuf = i;
2038
2039                                 use_limiter = TRUE;
2040                                 use_preprocess = TRUE;
2041                         }
2042                 } else if (se->ibuf) {
2043                         use_limiter = TRUE;
2044                 }
2045                 if (meta_se) {
2046                         free_metastrip_imbufs(
2047                                 &seq->seqbase, seq->start + se->nr, 0);
2048                 }
2049
2050                 if (use_preprocess) {
2051                         input_preprocess(scene, seq, se, cfra, seqrectx,
2052                                          seqrecty);
2053                 }
2054         } else if(seq->type & SEQ_EFFECT) {
2055                 int use_preprocess = FALSE;
2056                 /* should the effect be recalculated? */
2057                 
2058                 if (!build_proxy_run && se->ibuf == 0) {
2059                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2060                         if (se->ibuf) {
2061                                 use_preprocess = TRUE;
2062                         }
2063                 }
2064
2065                 if(se->ibuf == 0) {
2066                         /* if any inputs are rectfloat, output is float too */
2067                         if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
2068                            (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float) ||
2069                            (se->se3 && se->se3->ibuf && se->se3->ibuf->rect_float))
2070                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2071                         else
2072                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2073                         
2074                         do_effect(scene, cfra, seq, se, render_size);
2075                         if (input_have_to_preprocess(scene, seq, se, cfra,
2076                                                      seqrectx, seqrecty) &&
2077                                 !build_proxy_run) {
2078                                 if ((se->se1 && (se->ibuf == se->se1->ibuf)) ||
2079                                         (se->se2 && (se->ibuf == se->se2->ibuf))) {
2080                                         struct ImBuf * i
2081                                                 = IMB_dupImBuf(se->ibuf);
2082
2083                                         IMB_freeImBuf(se->ibuf);
2084
2085                                         se->ibuf = i;
2086                                 }
2087                                 use_preprocess = TRUE;
2088                         }
2089                 }
2090                 if (use_preprocess) {
2091                         input_preprocess(scene, seq, se, cfra, seqrectx,
2092                                          seqrecty);
2093                 }
2094         } else if(seq->type == SEQ_IMAGE) {
2095                 if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
2096                         StripElem * s_elem = give_stripelem(seq, cfra);
2097                         BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
2098                         BLI_path_abs(name, G.sce);
2099                         if (!build_proxy_run) {
2100                                 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2101                         }
2102                         copy_from_ibuf_still(seq, se);
2103
2104                         if (se->ibuf==NULL && (se->ibuf= IMB_loadiffname(name, IB_rect))) {
2105                                 /* we don't need both (speed reasons)! */
2106                                 if (se->ibuf->rect_float && se->ibuf->rect)
2107                                         imb_freerectImBuf(se->ibuf);
2108
2109                                 /* all sequencer color is done in SRGB space, linear gives odd crossfades */
2110                                 if(se->ibuf->profile == IB_PROFILE_LINEAR_RGB)
2111                                         IMB_convert_profile(se->ibuf, IB_PROFILE_NONE);
2112
2113                                 copy_to_ibuf_still(seq, se);
2114                         }
2115                         
2116                         if(se->ibuf == 0) {
2117                                 se->ok = STRIPELEM_FAILED;
2118                         } else if (!build_proxy_run) {
2119                                 input_preprocess(scene, seq, se, cfra,
2120                                                  seqrectx, seqrecty);
2121                         }
2122                 }
2123         } else if(seq->type == SEQ_MOVIE) {
2124                 if(se->ok == STRIPELEM_OK && se->ibuf==0) {
2125                         if(!build_proxy_run) {
2126                                 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2127                         }
2128                         copy_from_ibuf_still(seq, se);
2129
2130                         if (se->ibuf == 0) {
2131                                 if(seq->anim==0) {
2132                                         BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
2133                                         BLI_path_abs(name, G.sce);
2134                                         
2135                                         seq->anim = openanim(
2136                                                 name, IB_rect | 
2137                                                 ((seq->flag & SEQ_FILTERY) 
2138                                                  ? IB_animdeinterlace : 0));
2139                                 }
2140                                 if(seq->anim) {
2141                                         IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
2142                                         se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
2143                                         /* we don't need both (speed reasons)! */
2144                                         if (se->ibuf 
2145                                                 && se->ibuf->rect_float 
2146                                                 && se->ibuf->rect) {
2147                                                 imb_freerectImBuf(se->ibuf);
2148                                         }
2149
2150                                 }
2151                                 copy_to_ibuf_still(seq, se);
2152                         }
2153                         
2154                         if(se->ibuf == 0) {
2155                                 se->ok = STRIPELEM_FAILED;
2156                         } else if (!build_proxy_run) {
2157                                 input_preprocess(scene, seq, se, cfra,
2158                                                  seqrectx, seqrecty);
2159                         }
2160                 }
2161         } else if(seq->type == SEQ_SCENE) {     // scene can be NULL after deletions
2162                 Scene *sce= seq->scene;// *oldsce= scene;
2163                 int have_seq= FALSE;
2164                 int sce_valid= FALSE;
2165
2166                 if(sce) {
2167                         have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first;
2168                         sce_valid= (sce->camera || have_seq);
2169                 }
2170
2171                 if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
2172                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2173                         if (se->ibuf) {
2174                                 input_preprocess(scene, seq, se, cfra,
2175                                                  seqrectx, seqrecty);
2176                         }
2177                 }
2178
2179                 if (se->ibuf == NULL && sce_valid) {
2180                         copy_from_ibuf_still(seq, se);
2181                         if (se->ibuf) {
2182                                 input_preprocess(scene, seq, se, cfra,
2183                                                  seqrectx, seqrecty);
2184                         }
2185                 }
2186                 
2187                 if (!sce_valid) {
2188                         se->ok = STRIPELEM_FAILED;
2189                 }
2190                 else if (se->ibuf==NULL && sce_valid) {
2191                         int frame= seq->sfra + se->nr + seq->anim_startofs;
2192                         int oldcfra = seq->scene->r.cfra;
2193                         Object *oldcamera= seq->scene->camera;
2194                         ListBase oldmarkers;
2195
2196                         /* Hack! This function can be called from do_render_seq(), in that case
2197                            the seq->scene can already have a Render initialized with same name,
2198                            so we have to use a default name. (compositor uses scene name to
2199                            find render).
2200                            However, when called from within the UI (image preview in sequencer)
2201                            we do want to use scene Render, that way the render result is defined
2202                            for display in render/imagewindow
2203
2204                            Hmm, don't see, why we can't do that all the time,
2205                            and since G.rendering is uhm, gone... (Peter)
2206                         */
2207
2208                         int rendering = G.rendering;
2209                         int doseq;
2210                         int doseq_gl= G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : (scene->r.seq_flag & R_SEQ_GL_PREV);
2211
2212                         /* prevent eternal loop */
2213                         doseq= scene->r.scemode & R_DOSEQ;
2214                         scene->r.scemode &= ~R_DOSEQ;
2215
2216                         seq->scene->r.cfra= frame;
2217                         if(seq->scene_camera)   seq->scene->camera= seq->scene_camera;
2218                         else                                    scene_camera_switch_update(seq->scene);
2219
2220 #ifdef DURIAN_CAMERA_SWITCH
2221                         /* stooping to new low's in hackyness :( */
2222                         oldmarkers= seq->scene->markers;
2223                         seq->scene->markers.first= seq->scene->markers.last= NULL;
2224 #endif
2225
2226                         if(sequencer_view3d_cb && doseq_gl && (seq->scene == scene || have_seq==0) && seq->scene->camera) {
2227                                 /* opengl offscreen render */
2228                                 scene_update_for_newframe(seq->scene, seq->scene->lay);
2229                                 se->ibuf= sequencer_view3d_cb(seq->scene, seqrectx, seqrecty, scene->r.seq_prev_type);
2230                         }
2231                         else {
2232                                 Render *re;
2233                                 RenderResult rres;
2234
2235                                 if(rendering)
2236                                         re= RE_NewRender(" do_build_seq_ibuf");
2237                                 else
2238                                         re= RE_NewRender(sce->id.name);
2239
2240                                 RE_BlenderFrame(re, sce, NULL, sce->lay, frame);
2241
2242                                 RE_AcquireResultImage(re, &rres);
2243
2244                                 if(rres.rectf) {
2245                                         se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
2246                                         memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
2247                                         if(rres.rectz) {
2248                                                 addzbuffloatImBuf(se->ibuf);
2249                                                 memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
2250                                         }
2251                                 } else if (rres.rect32) {
2252                                         se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
2253                                         memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
2254                                 }
2255
2256                                 RE_ReleaseResultImage(re);
2257
2258                                 // BIF_end_render_callbacks();
2259                         }
2260                         
2261                         /* restore */
2262                         scene->r.scemode |= doseq;
2263
2264                         seq->scene->r.cfra = oldcfra;
2265                         seq->scene->camera= oldcamera;
2266
2267 #ifdef DURIAN_CAMERA_SWITCH
2268                         /* stooping to new low's in hackyness :( */
2269                         seq->scene->markers= oldmarkers;
2270 #endif
2271
2272                         copy_to_ibuf_still(seq, se);
2273
2274                         if (!build_proxy_run) {
2275                                 if(se->ibuf == NULL) {
2276                                         se->ok = STRIPELEM_FAILED;
2277                                 } else {
2278                                         input_preprocess(scene, seq, se, cfra,
2279                                                          seqrectx, seqrecty);
2280                                 }
2281                         }
2282
2283                 }
2284         }
2285         if (!build_proxy_run) {
2286                 if (se->ibuf && use_limiter) {
2287                         IMB_cache_limiter_insert(se->ibuf);
2288                         IMB_cache_limiter_ref(se->ibuf);
2289                         IMB_cache_limiter_touch(se->ibuf);
2290                 }
2291         }
2292 }
2293
2294 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size, int seqrectx, int seqrecty);
2295
2296 static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size, int seqrectx, int seqrecty)
2297 {
2298         float fac, facf;
2299         struct SeqEffectHandle sh = get_sequence_effect(seq);
2300         int early_out;
2301         FCurve *fcu= NULL;
2302
2303         se->se1 = 0;
2304         se->se2 = 0;
2305         se->se3 = 0;
2306
2307         if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
2308                 sh.get_default_fac(seq, cfra, &fac, &facf);
2309                 if( scene->r.mode & R_FIELDS ); else facf= fac;
2310         } else {
2311                 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, 
2312                                           "effect_fader", 0);
2313                 if (fcu) {
2314                         fac = facf = evaluate_fcurve(fcu, cfra);
2315                         if( scene->r.mode & R_FIELDS ) {
2316                                 facf = evaluate_fcurve(fcu, cfra + 0.5);
2317                         }
2318                 } else {
2319                         fac = facf = seq->effect_fader;
2320                 }
2321         }
2322
2323         early_out = sh.early_out(seq, fac, facf);
2324         switch (early_out) {
2325         case -1:
2326                 /* no input needed */
2327                 break;
2328         case 0:
2329                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size, seqrectx, seqrecty);
2330                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size, seqrectx, seqrecty);
2331                 if (seq->seq3) {
2332                         se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size, seqrectx, seqrecty);
2333                 }
2334                 break;
2335         case 1:
2336                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size, seqrectx, seqrecty);
2337                 break;
2338         case 2:
2339                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size, seqrectx, seqrecty);
2340                 break;
2341         }
2342
2343
2344         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size, seqrectx, seqrecty);
2345
2346         /* children are not needed anymore ... */
2347
2348         if (se->se1 && se->se1->ibuf) {
2349                 IMB_cache_limiter_unref(se->se1->ibuf);
2350         }
2351         if (se->se2 && se->se2->ibuf) {
2352                 IMB_cache_limiter_unref(se->se2->ibuf);
2353         }
2354         if (se->se3 && se->se3->ibuf) {
2355                 IMB_cache_limiter_unref(se->se3->ibuf);
2356         }
2357         check_limiter_refcount("do_effect_seq_recursively", se);
2358 }
2359
2360 static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty)
2361 {
2362         TStripElem *se;
2363
2364         se = give_tstripelem(seq, cfra);
2365
2366         if(se) {
2367                 if (seq->type & SEQ_EFFECT) {
2368                         do_effect_seq_recursively(scene, seq, se, cfra, render_size, seqrectx, seqrecty);
2369                 } else {
2370                         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size, seqrectx, seqrecty);
2371                 }
2372         }
2373         return se;
2374 }
2375
2376 /* FIXME:
2377    
2378 If cfra was float throughout blender (especially in the render
2379 pipeline) one could even _render_ with subframe precision
2380 instead of faking using the blend code below...
2381
2382 */
2383
2384 static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty)
2385 {
2386         SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
2387         int nr = cfra - seq->start;
2388         float f_cfra;
2389         int cfra_left;
2390         int cfra_right;
2391         TStripElem * se = 0;
2392         TStripElem * se1 = 0;
2393         TStripElem * se2 = 0;
2394         
2395         sequence_effect_speed_rebuild_map(scene, seq, 0);
2396         
2397         f_cfra = seq->start + s->frameMap[nr];
2398         
2399         cfra_left = (int) floor(f_cfra);
2400         cfra_right = (int) ceil(f_cfra);
2401
2402         se = give_tstripelem(seq, cfra);
2403
2404         if (!se) {
2405                 return se;
2406         }
2407
2408         if (cfra_left == cfra_right || 
2409                 (s->flags & SEQ_SPEED_BLEND) == 0) {
2410                 test_and_auto_discard_ibuf(se, seqrectx, seqrecty);
2411
2412                 if (se->ibuf == NULL) {
2413                         se1 = do_build_seq_recursively(scene, seq->seq1, cfra_left, render_size, seqrectx, seqrecty);
2414
2415                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2416                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2417                         else
2418                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2419
2420                         if (se1 == 0 || se1->ibuf == 0) {
2421                                 make_black_ibuf(se->ibuf);
2422                         } else {
2423                                 if (se->ibuf != se1->ibuf) {
2424                                         if (se->ibuf) {
2425                                                 IMB_freeImBuf(se->ibuf);
2426                                         }
2427
2428                                         se->ibuf = se1->ibuf;
2429                                         IMB_refImBuf(se->ibuf);
2430                                 }
2431                         }
2432                 }
2433         } else {
2434                 struct SeqEffectHandle sh;
2435
2436                 if(se->ibuf) {
2437                         if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty 
2438                            || !(se->ibuf->rect || se->ibuf->rect_float)) {
2439                                 IMB_freeImBuf(se->ibuf);
2440                                 se->ibuf= 0;
2441                         }
2442                 }
2443
2444                 if (se->ibuf == NULL) {
2445                         se1 = do_build_seq_recursively(scene, seq->seq1, cfra_left, render_size, seqrectx, seqrecty);
2446                         se2 = do_build_seq_recursively(scene, seq->seq1, cfra_right, render_size, seqrectx, seqrecty);
2447
2448                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2449                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2450                         else
2451                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2452                         
2453                         if (!se1 || !se2) {
2454                                 make_black_ibuf(se->ibuf);
2455                         } else {
2456                                 sh = get_sequence_effect(seq);
2457
2458                                 sh.execute(scene, seq, cfra, 
2459                                            f_cfra - (float) cfra_left, 
2460                                            f_cfra - (float) cfra_left, 
2461                                            se->ibuf->x, se->ibuf->y, 
2462                                            render_size,
2463                                            se1->ibuf, se2->ibuf, 0, se->ibuf);
2464                         }
2465                 }
2466
2467         }
2468
2469         /* caller expects this to be referenced, so do it! */
2470         if (se->ibuf) {
2471                 IMB_cache_limiter_insert(se->ibuf);
2472                 IMB_cache_limiter_ref(se->ibuf);
2473                 IMB_cache_limiter_touch(se->ibuf);
2474         }
2475
2476         /* children are no longer needed */
2477         if (se1 && se1->ibuf)
2478                 IMB_cache_limiter_unref(se1->ibuf);
2479         if (se2 && se2->ibuf)
2480                 IMB_cache_limiter_unref(se2->ibuf);
2481
2482         check_limiter_refcount("do_handle_speed_effect", se);
2483
2484         return se;
2485 }
2486
2487 /* 
2488  * build all ibufs recursively
2489  * 
2490  * if successfull, the returned TStripElem contains the (referenced!) imbuf
2491  * that means: you _must_ call 
2492  *
2493  * IMB_cache_limiter_unref(rval);
2494  * 
2495  * if rval != 0
2496  * 
2497  */
2498
2499 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty)
2500 {
2501         TStripElem *se;
2502
2503         /* BAD HACK! Seperate handling for speed effects needed, since
2504            a) you can't just fetch a different cfra within an effect strip
2505            b) we have to blend two frames, and CFRA is not float...
2506         */
2507         if (seq->type == SEQ_SPEED) {
2508                 se = do_handle_speed_effect(scene, seq, cfra, render_size, seqrectx, seqrecty);
2509         } else {
2510                 se = do_build_seq_recursively_impl(scene, seq, cfra, render_size, seqrectx, seqrecty);
2511         }
2512
2513         check_limiter_refcount("do_build_seq_recursively", se);
2514
2515         return se;
2516 }
2517
2518 static int seq_must_swap_input_in_blend_mode(Sequence * seq)
2519 {
2520         int swap_input = FALSE;
2521
2522         /* bad hack, to fix crazy input ordering of 
2523            those two effects */
2524
2525         if (seq->blend_mode == SEQ_ALPHAOVER ||
2526                 seq->blend_mode == SEQ_ALPHAUNDER ||
2527                 seq->blend_mode == SEQ_OVERDROP) {
2528                 swap_input = TRUE;
2529         }
2530         
2531         return swap_input;
2532 }
2533
2534 static int seq_get_early_out_for_blend_mode(Sequence * seq)
2535 {
2536         struct SeqEffectHandle sh = get_sequence_blend(seq);
2537         float facf = seq->blend_opacity / 100.0;
2538         int early_out = sh.early_out(seq, facf, facf);
2539         
2540         if (early_out < 1) {
2541                 return early_out;
2542         }
2543
2544         if (seq_must_swap_input_in_blend_mode(seq)) {
2545                 if (early_out == 2) {
2546                         return 1;
2547                 } else if (early_out == 1) {
2548                         return 2;
2549                 }
2550         }
2551         return early_out;
2552 }
2553
2554 static TStripElem* do_build_seq_array_recursively(
2555         Scene *scene, ListBase *seqbasep, int cfra, int chanshown, 
2556         int render_size, int seqrectx, int seqrecty)
2557 {
2558         Sequence* seq_arr[MAXSEQ+1];
2559         int count;
2560         int i;
2561         TStripElem* se = 0;
2562
2563         count = get_shown_sequences(seqbasep, cfra, chanshown, 
2564                                         (Sequence **)&seq_arr);
2565
2566         if (!count) {
2567                 return 0;
2568         }
2569
2570         se = give_tstripelem(seq_arr[count - 1], cfra);
2571
2572         if (!se) {
2573                 return 0;
2574         }
2575
2576 #if 0 /* commentind since this breaks keyframing, since it resets the value on draw */
2577         if(scene->r.cfra != cfra) {
2578                 // XXX for prefetch and overlay offset!..., very bad!!!
2579                 AnimData *adt= BKE_animdata_from_id(&scene->id);
2580                 BKE_animsys_evaluate_animdata(&scene->id, adt, cfra, ADT_RECALC_ANIM);
2581         }
2582 #endif
2583
2584         test_and_auto_discard_ibuf(se, seqrectx, seqrecty);
2585
2586         if (se->ibuf_comp != 0) {
2587                 IMB_cache_limiter_insert(se->ibuf_comp);
2588                 IMB_cache_limiter_ref(se->ibuf_comp);
2589                 IMB_cache_limiter_touch(se->ibuf_comp);
2590                 return se;
2591         }
2592
2593         
2594         if(count == 1) {
2595                 se = do_build_seq_recursively(scene, seq_arr[0],
2596                                               cfra, render_size,
2597                                               seqrectx, seqrecty);
2598                 if (se->ibuf) {
2599                         se->ibuf_comp = se->ibuf;
2600                         IMB_refImBuf(se->ibuf_comp);
2601                 }
2602                 return se;
2603         }
2604
2605
2606         for (i = count - 1; i >= 0; i--) {
2607                 int early_out;
2608                 Sequence * seq = seq_arr[i];
2609
2610                 se = give_tstripelem(seq, cfra);
2611
2612                 test_and_auto_discard_ibuf(se, seqrectx, seqrecty);
2613
2614                 if (se->ibuf_comp != 0) {
2615                         break;
2616                 }
2617                 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2618                         do_build_seq_recursively(
2619                                 scene, seq, cfra, render_size,
2620                                 seqrectx, seqrecty);
2621
2622                         if (se->ibuf) {
2623                                 se->ibuf_comp = se->ibuf;
2624                                 IMB_refImBuf(se->ibuf);
2625                         } else {
2626                                 se->ibuf_comp = IMB_allocImBuf(
2627                                         (short)seqrectx, (short)seqrecty, 
2628                                         32, IB_rect, 0);
2629                                 IMB_cache_limiter_insert(se->ibuf_comp);
2630                                 IMB_cache_limiter_ref(se->ibuf_comp);
2631                                 IMB_cache_limiter_touch(se->ibuf_comp);
2632                         }
2633                         break;
2634                 }
2635
2636                 early_out = seq_get_early_out_for_blend_mode(seq);
2637
2638                 switch (early_out) {
2639                 case -1:
2640                 case 2:
2641                         do_build_seq_recursively(
2642                                 scene, seq, cfra, render_size,
2643                                 seqrectx, seqrecty);
2644
2645                         if (se->ibuf) {
2646                                 se->ibuf_comp = se->ibuf;
2647                                 IMB_refImBuf(se->ibuf_comp);
2648                         } else {
2649                                 se->ibuf_comp = IMB_allocImBuf(
2650                                         (short)seqrectx, (short)seqrecty, 
2651                                         32, IB_rect, 0);
2652                                 IMB_cache_limiter_insert(se->ibuf_comp);
2653                                 IMB_cache_limiter_ref(se->ibuf_comp);
2654                                 IMB_cache_limiter_touch(se->ibuf_comp);
2655                         }
2656                         break;
2657                 case 1:
2658                         if (i == 0) {
2659                                 se->ibuf_comp = IMB_allocImBuf(
2660                                         (short)seqrectx, (short)seqrecty, 
2661                                         32, IB_rect, 0);
2662                                 IMB_cache_limiter_insert(se->ibuf_comp);
2663                                 IMB_cache_limiter_ref(se->ibuf_comp);
2664                                 IMB_cache_limiter_touch(se->ibuf_comp);
2665                         }
2666                         break;
2667                 case 0:
2668                         do_build_seq_recursively(
2669                                 scene, seq, cfra, render_size,
2670                                 seqrectx, seqrecty);
2671
2672                         if (!se->ibuf) {
2673                                 se->ibuf = IMB_allocImBuf(
2674                                         (short)seqrectx, (short)seqrecty, 
2675                                         32, IB_rect, 0);
2676                                 IMB_cache_limiter_insert(se->ibuf);
2677                                 IMB_cache_limiter_ref(se->ibuf);
2678                                 IMB_cache_limiter_touch(se->ibuf);
2679                         }
2680                         if (i == 0) {
2681                                 se->ibuf_comp = se->ibuf;
2682                                 IMB_refImBuf(se->ibuf_comp);
2683                         }
2684                         break;
2685                 }
2686         
2687                 if (se->ibuf_comp) {
2688                         break;
2689                 }
2690         }
2691
2692         i++;
2693
2694         for (; i < count; i++) {
2695                 Sequence * seq = seq_arr[i];
2696                 struct SeqEffectHandle sh = get_sequence_blend(seq);
2697                 TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
2698                 TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
2699
2700                 float facf = seq->blend_opacity / 100.0;
2701                 int swap_input = seq_must_swap_input_in_blend_mode(seq);
2702                 int early_out = seq_get_early_out_for_blend_mode(seq);
2703
2704                 switch (early_out) {
2705                 case 0: {
2706                         int x= se2->ibuf->x;
2707                         int y= se2->ibuf->y;
2708
2709                         if(se1->ibuf_comp == NULL)
2710                                 continue;
2711
2712                         if (se1->ibuf_comp->rect_float ||
2713                                 se2->ibuf->rect_float) {
2714                                 se2->ibuf_comp = IMB_allocImBuf(
2715                                         (short)seqrectx, (short)seqrecty, 
2716                                         32, IB_rectfloat, 0);
2717                         } else {
2718                                 se2->ibuf_comp = IMB_allocImBuf(
2719                                         (short)seqrectx, (short)seqrecty, 
2720                                         32, IB_rect, 0);
2721                         }
2722
2723
2724                         if (!se1->ibuf_comp->rect_float && 
2725                                 se2->ibuf_comp->rect_float) {
2726                                 IMB_float_from_rect_simple(se1->ibuf_comp);
2727                         }
2728                         if (!se2->ibuf->rect_float && 
2729                                 se2->ibuf_comp->rect_float) {
2730                                 IMB_float_from_rect_simple(se2->ibuf);
2731                         }
2732
2733                         if (!se1->ibuf_comp->rect && 
2734                                 !se2->ibuf_comp->rect_float) {
2735                                 IMB_rect_from_float(se1->ibuf_comp);
2736                         }
2737                         if (!se2->ibuf->rect && 
2738                                 !se2->ibuf_comp->rect_float) {
2739                                 IMB_rect_from_float(se2->ibuf);
2740                         }
2741                         
2742                         if (swap_input) {
2743                                 sh.execute(scene, seq, cfra, 
2744                                            facf, facf, x, y, render_size,
2745                                            se2->ibuf, se1->ibuf_comp, 0,
2746                                            se2->ibuf_comp);
2747                         } else {
2748                                 sh.execute(scene, seq, cfra, 
2749                                            facf, facf, x, y, render_size,
2750                                            se1->ibuf_comp, se2->ibuf, 0,
2751                                            se2->ibuf_comp);
2752                         }
2753                         
2754                         IMB_cache_limiter_insert(se2->ibuf_comp);
2755                         IMB_cache_limiter_ref(se2->ibuf_comp);
2756                         IMB_cache_limiter_touch(se2->ibuf_comp);
2757
2758                         IMB_cache_limiter_unref(se1->ibuf_comp);
2759                         IMB_cache_limiter_unref(se2->ibuf);
2760
2761                         break;
2762                 }
2763                 case 1: {
2764                         se2->ibuf_comp = se1->ibuf_comp;
2765                         if(se2->ibuf_comp)
2766                                 IMB_refImBuf(se2->ibuf_comp);
2767
2768                         break;
2769                 }
2770                 }
2771                 se = se2;
2772         }
2773
2774         return se;
2775 }
2776
2777 /*
2778  * returned ImBuf is refed!
2779  * you have to unref after usage!
2780  */
2781
2782 static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2783 {
2784         Editing *ed= seq_give_editing(scene, FALSE);
2785         int count;
2786         ListBase *seqbasep;
2787         TStripElem *se;
2788
2789         
2790         if(ed==NULL) return NULL;
2791
2792         count = BLI_countlist(&ed->metastack);
2793         if((chanshown < 0) && (count > 0)) {
2794                 count = MAX2(count + chanshown, 0);
2795                 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2796         } else {
2797                 seqbasep= ed->seqbasep;
2798         }
2799
2800         se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size, rectx, recty);
2801
2802         if(!se) { 
2803                 return 0;
2804         }
2805
2806         check_limiter_refcount_comp("give_ibuf_seq_impl", se);
2807
2808         return se->ibuf_comp;
2809 }
2810
2811 ImBuf *give_ibuf_seqbase(struct Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size, ListBase *seqbasep)
2812 {
2813         TStripElem *se;
2814
2815         se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size, rectx, recty);
2816
2817         if(!se) { 
2818                 return 0;
2819         }
2820
2821         check_limiter_refcount_comp("give_ibuf_seqbase", se);
2822
2823         if (se->ibuf_comp) {
2824                 IMB_cache_limiter_unref(se->ibuf_comp);
2825         }
2826
2827         return se->ibuf_comp;
2828 }
2829
2830
2831 ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
2832 {
2833         TStripElem* se;
2834
2835         se = do_build_seq_recursively(scene, seq, cfra, render_size, rectx, recty);
2836
2837         if(!se) { 
2838                 return 0;
2839         }
2840
2841         check_limiter_refcount("give_ibuf_seq_direct", se);
2842
2843         if (se->ibuf) {
2844                 IMB_cache_limiter_unref(se->ibuf);
2845         }
2846
2847         return se->ibuf;
2848 }
2849
2850 ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2851 {
2852         ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size);
2853
2854         if (i) {
2855                 IMB_cache_limiter_unref(i);
2856         }
2857         return i;
2858 }
2859
2860 #if 0
2861 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2862 static int seq_can_blend(Sequence *seq)
2863 {
2864         if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2865                 return 1;
2866         } else {
2867                 return 0;
2868         }
2869 }
2870 #endif
2871
2872 /* *********************** threading api ******************* */
2873
2874 static ListBase running_threads;
2875 static ListBase prefetch_wait;
2876 static ListBase prefetch_done;
2877
2878 static pthread_mutex_t queue_lock          = PTHREAD_MUTEX_INITIALIZER;
2879 static pthread_mutex_t wakeup_lock         = PTHREAD_MUTEX_INITIALIZER;
2880 static pthread_cond_t  wakeup_cond         = PTHREAD_COND_INITIALIZER;
2881
2882 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2883 //static pthread_cond_t  prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2884
2885 static pthread_mutex_t frame_done_lock     = PTHREAD_MUTEX_INITIALIZER;
2886 static pthread_cond_t  frame_done_cond     = PTHREAD_COND_INITIALIZER;
2887
2888 static volatile int seq_thread_shutdown = TRUE; 
2889 static volatile int seq_last_given_monoton_cfra = 0;
2890 static int monoton_cfra = 0;
2891
2892 typedef struct PrefetchThread {
2893         struct PrefetchThread *next, *prev;
2894         
2895         Scene *scene;
2896         struct PrefetchQueueElem *current;
2897         pthread_t pthread;
2898         int running;
2899         
2900 } PrefetchThread;
2901
2902 typedef struct PrefetchQueueElem {
2903         struct PrefetchQueueElem *next, *prev;
2904         
2905         int rectx;
2906         int recty;
2907         int cfra;
2908         int chanshown;
2909         int render_size;
2910
2911         int monoton_cfra;
2912
2913         struct ImBuf * ibuf;
2914 } PrefetchQueueElem;
2915
2916 #if 0
2917 static void *seq_prefetch_thread(void * This_)
2918 {
2919         PrefetchThread * This = This_;
2920
2921         while (!seq_thread_shutdown) {
2922                 PrefetchQueueElem *e;
2923                 int s_last;
2924
2925                 pthread_mutex_lock(&queue_lock);
2926                 e = prefetch_wait.first;
2927                 if (e) {
2928                         BLI_remlink(&prefetch_wait, e);
2929                 }
2930                 s_last = seq_last_given_monoton_cfra;
2931
2932                 This->current = e;
2933
2934                 pthread_mutex_unlock(&queue_lock);
2935
2936                 if (!e) {
2937                         pthread_mutex_lock(&prefetch_ready_lock);
2938
2939                         This->running = FALSE;
2940
2941                         pthread_cond_signal(&prefetch_ready_cond);
2942                         pthread_mutex_unlock(&prefetch_ready_lock);
2943
2944                         pthread_mutex_lock(&wakeup_lock);
2945                         if (!seq_thread_shutdown) {
2946                                 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2947                         }
2948                         pthread_mutex_unlock(&wakeup_lock);
2949                         continue;
2950                 }
2951
2952                 This->running = TRUE;
2953                 
2954                 if (e->cfra >= s_last) { 
2955                         e->ibuf = give_ibuf_seq_impl(This->scene, 
2956                                 e->rectx, e->recty, e->cfra, e->chanshown,
2957                                 e->render_size);
2958                 }
2959
2960                 pthread_mutex_lock(&queue_lock);
2961
2962                 BLI_addtail(&prefetch_done, e);
2963
2964                 for (e = prefetch_wait.first; e; e = e->next) {
2965                         if (s_last > e->monoton_cfra) {
2966                                 BLI_remlink(&prefetch_wait, e);
2967                                 MEM_freeN(e);
2968                         }
2969                 }
2970
2971                 for (e = prefetch_done.first; e; e = e->next) {
2972                         if (s_last > e->monoton_cfra) {
2973                                 if (e->ibuf) {
2974                                         IMB_cache_limiter_unref(e->ibuf);
2975                                 }
2976                                 BLI_remlink(&prefetch_done, e);
2977                                 MEM_freeN(e);
2978                         }
2979                 }
2980
2981                 pthread_mutex_unlock(&queue_lock);
2982
2983                 pthread_mutex_lock(&frame_done_lock);
2984                 pthread_cond_signal(&frame_done_cond);
2985                 pthread_mutex_unlock(&frame_done_lock);
2986         }
2987         return 0;
2988 }
2989
2990 static void seq_start_threads(Scene *scene)
2991 {
2992         int i;
2993
2994         running_threads.first = running_threads.last = NULL;
2995         prefetch_wait.first = prefetch_wait.last = NULL;
2996         prefetch_done.first = prefetch_done.last = NULL;
2997
2998         seq_thread_shutdown = FALSE;
2999         seq_last_given_monoton_cfra = monoton_cfra = 0;
3000
3001         /* since global structures are modified during the processing
3002            of one frame, only one render thread is currently possible... 
3003
3004            (but we code, in the hope, that we can remove this restriction
3005            soon...)
3006         */
3007
3008         fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
3009
3010         for (i = 0; i < 1; i++) {
3011                 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
3012                 t->scene= scene;
3013                 t->running = TRUE;
3014                 BLI_addtail(&running_threads, t);
3015
3016                 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
3017         }
3018
3019         /* init malloc mutex */
3020         BLI_init_threads(0, 0, 0);
3021 }
3022
3023 static void seq_stop_threads()
3024 {
3025         PrefetchThread *tslot;
3026         PrefetchQueueElem *e;
3027
3028         fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
3029
3030         if (seq_thread_shutdown) {
3031                 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
3032                 return;
3033         }
3034         
3035         pthread_mutex_lock(&wakeup_lock);
3036
3037         seq_thread_shutdown = TRUE;
3038
3039                 pthread_cond_broadcast(&wakeup_cond);
3040                 pthread_mutex_unlock(&wakeup_lock);
3041
3042         for(tslot = running_threads.first; tslot; tslot= tslot->next) {
3043                 pthread_join(tslot->pthread, NULL);
3044         }
3045
3046
3047         for (e = prefetch_wait.first; e; e = e->next) {
3048                 BLI_remlink(&prefetch_wait, e);
3049                 MEM_freeN(e);
3050         }
3051
3052         for (e = prefetch_done.first; e; e = e->next) {
3053                 if (e->ibuf) {
3054                         IMB_cache_limiter_unref(e->ibuf);
3055                 }
3056                 BLI_remlink(&prefetch_done, e);
3057                 MEM_freeN(e);
3058         }
3059
3060         BLI_freelistN(&running_threads);
3061
3062         /* deinit malloc mutex */
3063         BLI_end_threads(0);
3064 }
3065 #endif
3066
3067 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
3068                                 int render_size)
3069 {
3070         PrefetchQueueElem *e;
3071         if (seq_thread_shutdown) {
3072                 return;
3073         }
3074
3075         e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
3076         e->rectx = rectx;
3077         e->recty = recty;
3078         e->cfra = cfra;
3079         e->chanshown = chanshown;
3080         e->render_size = render_size;
3081         e->monoton_cfra = monoton_cfra++;
3082
3083         pthread_mutex_lock(&queue_lock);
3084         BLI_addtail(&prefetch_wait, e);
3085         pthread_mutex_unlock(&queue_lock);
3086         
3087         pthread_mutex_lock(&wakeup_lock);
3088         pthread_cond_signal(&wakeup_cond);
3089         pthread_mutex_unlock(&wakeup_lock);
3090 }
3091
3092 #if 0
3093 static void seq_wait_for_prefetch_ready()
3094 {
3095         PrefetchThread *tslot;
3096
3097         if (seq_thread_shutdown) {
3098                 return;
3099         }
3100
3101         fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
3102
3103         pthread_mutex_lock(&prefetch_ready_lock);
3104
3105         for(;;) {
3106                 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
3107                         if (tslot->running) {
3108                                 break;
3109                         }
3110                 }
3111                 if (!tslot) {
3112                         break;
3113                 }
3114                 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
3115         }
3116
3117         pthread_mutex_unlock(&prefetch_ready_lock);
3118
3119         fprintf(stderr, "SEQ-THREAD: prefetch done\n");
3120 }
3121 #endif
3122
3123 ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
3124 {
3125         PrefetchQueueElem *e = NULL;
3126         int found_something = FALSE;
3127
3128         if (seq_thread_shutdown) {
3129                 return give_ibuf_seq(scene, rectx, recty, cfra, chanshown, render_size);
3130         }
3131
3132         while (!e) {
3133                 int success = FALSE;
3134                 pthread_mutex_lock(&queue_lock);
3135
3136                 for (e = prefetch_done.first; e; e = e->next) {
3137                         if (cfra == e->cfra &&
3138                                 chanshown == e->chanshown &&
3139                                 rectx == e->rectx && 
3140                                 recty == e->recty &&
3141                                 render_size == e->render_size) {
3142                                 success = TRUE;
3143                                 found_something = TRUE;
3144                                 break;
3145                         }
3146                 }
3147
3148                 if (!e) {
3149                         for (e = prefetch_wait.first; e; e = e->next) {
3150                                 if (cfra == e->cfra &&
3151                                         chanshown == e->chanshown &&
3152                                         rectx == e->rectx && 
3153                                         recty == e->recty &&
3154                                         render_size == e->render_size) {
3155                                         found_something = TRUE;
3156                                         break;
3157                                 }
3158                         }
3159                 }
3160
3161                 if (!e) {
3162                         PrefetchThread *tslot;
3163
3164                         for(tslot = running_threads.first; 
3165                                 tslot; tslot= tslot->next) {
3166                                 if (tslot->current &&
3167                                         cfra == tslot->current->cfra &&
3168                                         chanshown == tslot->current->chanshown &&
3169                                         rectx == tslot->current->rectx && 
3170                                         recty == tslot->current->recty &&
3171                                         render_size== tslot->current->render_size){
3172                                         found_something = TRUE;
3173                                         break;
3174                                 }
3175                         }
3176                 }
3177
3178                 /* e->ibuf is unrefed by render thread on next round. */
3179
3180                 if (e) {
3181                         seq_last_given_monoton_cfra = e->monoton_cfra;
3182                 }
3183
3184                 pthread_mutex_unlock(&queue_lock);
3185
3186                 if (!success) {
3187                         e = NULL;
3188
3189                         if (!found_something) {
3190                                 fprintf(stderr, 
3191                                         "SEQ-THREAD: Requested frame "
3192                                         "not in queue ???\n");
3193                                 break;
3194                         }
3195                         pthread_mutex_lock(&frame_done_lock);
3196                         pthread_cond_wait(&frame_done_cond, &frame_done_lock);
3197                         pthread_mutex_unlock(&frame_done_lock);
3198                 }
3199         }
3200         
3201