1ab4e75ee06a89cd9b9f035480fc220c9bb0ca2d
[blender.git] / source / blender / blenkernel / intern / sequencer.c
1 /**
2 * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): 
24  * - Blender Foundation, 2003-2009
25  * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <stddef.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <math.h>
34
35 #include "MEM_guardedalloc.h"
36 #include "MEM_CacheLimiterC-Api.h"
37
38 #include "DNA_sequence_types.h"
39 #include "DNA_scene_types.h"
40 #include "DNA_anim_types.h"
41 #include "DNA_object_types.h"
42
43 #include "BKE_animsys.h"
44 #include "BKE_global.h"
45 #include "BKE_image.h"
46 #include "BKE_main.h"
47 #include "BKE_sequencer.h"
48 #include "BKE_fcurve.h"
49 #include "BKE_scene.h"
50 #include "RNA_access.h"
51 #include "RE_pipeline.h"
52
53 #include "BLI_math.h"
54 #include "BLI_fileops.h"
55 #include "BLI_listbase.h"
56 #include "BLI_path_util.h"
57 #include "BLI_string.h"
58 #include <pthread.h>
59
60 #include "IMB_imbuf.h"
61 #include "IMB_imbuf_types.h"
62
63
64
65 #include "BKE_context.h"
66 #include "BKE_sound.h"
67 #include "AUD_C-API.h"
68
69 #ifdef WIN32
70 #define snprintf _snprintf
71 #endif
72
73 /* **** XXX ******** */
74 //static void waitcursor(int val) {}
75 //static int blender_test_break() {return 0;}
76
77 /* **** XXX ******** */
78 #define SELECT 1
79 ListBase seqbase_clipboard;
80 int seqbase_clipboard_frame;
81 SequencerDrawView sequencer_view3d_cb= NULL; /* NULL in background mode */
82
83
84 void printf_strip(Sequence *seq)
85 {
86         fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n",
87                         seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp);
88         fprintf(stderr, "\tseq_tx_set_final_left: %d %d\n\n", seq_tx_get_final_left(seq, 0), seq_tx_get_final_right(seq, 0));
89 }
90
91 int seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg)
92 {
93         Sequence *iseq;
94         for(iseq= seqbase->first; iseq; iseq= iseq->next) {
95                 if(seq_recursive_apply(iseq, apply_func, arg) == -1)
96                         return -1; /* bail out */
97         }
98         return 1;
99 }
100
101 int seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg)
102 {
103         int ret= apply_func(seq, arg);
104
105         if(ret == -1)
106                 return -1;  /* bail out */
107
108         if(ret && seq->seqbase.first)
109                 ret = seqbase_recursive_apply(&seq->seqbase, apply_func, arg);
110
111         return ret;
112 }
113
114 /* **********************************************************************
115    alloc / free functions
116    ********************************************************************** */
117
118 static void free_tstripdata(int len, TStripElem *se)
119 {
120         TStripElem *seo;
121         int a;
122
123         seo= se;
124         if (!se)
125                 return;
126
127         for(a=0; a<len; a++, se++) {
128                 if(se->ibuf) {
129                         IMB_freeImBuf(se->ibuf);
130                         se->ibuf = 0;
131                 }
132                 if(se->ibuf_comp) {
133                         IMB_freeImBuf(se->ibuf_comp);
134                         se->ibuf_comp = 0;
135                 }
136         }
137
138         MEM_freeN(seo);
139 }
140
141
142 void new_tstripdata(Sequence *seq)
143 {
144         if(seq->strip) {
145                 free_tstripdata(seq->strip->len, seq->strip->tstripdata);
146                 free_tstripdata(seq->strip->endstill, 
147                                 seq->strip->tstripdata_endstill);
148                 free_tstripdata(seq->strip->startstill, 
149                                 seq->strip->tstripdata_startstill);
150
151                 seq->strip->tstripdata= 0;
152                 seq->strip->tstripdata_endstill= 0;
153                 seq->strip->tstripdata_startstill= 0;
154
155                 if(seq->strip->ibuf_startstill) {
156                         IMB_freeImBuf(seq->strip->ibuf_startstill);
157                         seq->strip->ibuf_startstill = 0;
158                 }
159
160                 if(seq->strip->ibuf_endstill) {
161                         IMB_freeImBuf(seq->strip->ibuf_endstill);
162                         seq->strip->ibuf_endstill = 0;
163                 }
164
165                 seq->strip->len= seq->len;
166         }
167 }
168
169
170 /* free */
171
172 static void free_proxy_seq(Sequence *seq)
173 {
174         if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
175                 IMB_free_anim(seq->strip->proxy->anim);
176                 seq->strip->proxy->anim = 0;
177         }
178 }
179
180 void seq_free_strip(Strip *strip)
181 {
182         strip->us--;
183         if(strip->us>0) return;
184         if(strip->us<0) {
185                 printf("error: negative users in strip\n");
186                 return;
187         }
188
189         if (strip->stripdata) {
190                 MEM_freeN(strip->stripdata);
191         }
192
193         if (strip->proxy) {
194                 if (strip->proxy->anim) {
195                         IMB_free_anim(strip->proxy->anim);
196                 }
197
198                 MEM_freeN(strip->proxy);
199         }
200         if (strip->crop) {
201                 MEM_freeN(strip->crop);
202         }
203         if (strip->transform) {
204                 MEM_freeN(strip->transform);
205         }
206         if (strip->color_balance) {
207                 MEM_freeN(strip->color_balance);
208         }
209
210         free_tstripdata(strip->len, strip->tstripdata);
211         free_tstripdata(strip->endstill, strip->tstripdata_endstill);
212         free_tstripdata(strip->startstill, strip->tstripdata_startstill);
213
214         if(strip->ibuf_startstill) {
215                 IMB_freeImBuf(strip->ibuf_startstill);
216                 strip->ibuf_startstill = 0;
217         }
218
219         if(strip->ibuf_endstill) {
220                 IMB_freeImBuf(strip->ibuf_endstill);
221                 strip->ibuf_endstill = 0;
222         }
223
224         MEM_freeN(strip);
225 }
226
227 static void seq_free_animdata(Scene *scene, Sequence *seq);
228
229 void seq_free_sequence(Scene *scene, Sequence *seq)
230 {
231         if(seq->strip) seq_free_strip(seq->strip);
232
233         if(seq->anim) IMB_free_anim(seq->anim);
234
235         if (seq->type & SEQ_EFFECT) {
236                 struct SeqEffectHandle sh = get_sequence_effect(seq);
237
238                 sh.free(seq);
239         }
240
241         /* clipboard has no scene and will never have a sound handle or be active */
242         if(scene) {
243                 Editing *ed = scene->ed;
244
245                 if (ed->act_seq==seq)
246                         ed->act_seq= NULL;
247
248                 if(seq->scene_sound)
249                         sound_remove_scene_sound(scene, seq->scene_sound);
250         }
251
252         seq_free_animdata(scene, seq);
253
254         MEM_freeN(seq);
255 }
256
257 Editing *seq_give_editing(Scene *scene, int alloc)
258 {
259         if (scene->ed == NULL && alloc) {
260                 Editing *ed;
261
262                 ed= scene->ed= MEM_callocN( sizeof(Editing), "addseq");
263                 ed->seqbasep= &ed->seqbase;
264         }
265         return scene->ed;
266 }
267
268 void seq_free_clipboard(void)
269 {
270         Sequence *seq, *nseq;
271
272         for(seq= seqbase_clipboard.first; seq; seq= nseq) {
273                 nseq= seq->next;
274                 seq_free_sequence(NULL, seq);
275         }
276         seqbase_clipboard.first= seqbase_clipboard.last= NULL;
277 }
278
279 void seq_free_editing(Scene *scene)
280 {
281         Editing *ed = scene->ed;
282         MetaStack *ms;
283         Sequence *seq;
284
285         if(ed==NULL)
286                 return;
287
288         SEQ_BEGIN(ed, seq) {
289                 seq_free_sequence(scene, seq);
290         }
291         SEQ_END
292
293         while((ms= ed->metastack.first)) {
294                 BLI_remlink(&ed->metastack, ms);
295                 MEM_freeN(ms);
296         }
297
298         MEM_freeN(ed);
299 }
300
301 /* ************************* itterator ************************** */
302 /* *************** (replaces old WHILE_SEQ) ********************* */
303 /* **************** use now SEQ_BEGIN() SEQ_END ***************** */
304
305 /* sequence strip iterator:
306  * - builds a full array, recursively into meta strips */
307
308 static void seq_count(ListBase *seqbase, int *tot)
309 {
310         Sequence *seq;
311
312         for(seq=seqbase->first; seq; seq=seq->next) {
313                 (*tot)++;
314
315                 if(seq->seqbase.first)
316                         seq_count(&seq->seqbase, tot);
317         }
318 }
319
320 static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
321 {
322         Sequence *seq;
323
324         for(seq=seqbase->first; seq; seq=seq->next) {
325                 seq->depth= depth;
326
327                 if(seq->seqbase.first)
328                         seq_build_array(&seq->seqbase, array, depth+1);
329
330                 **array= seq;
331                 (*array)++;
332         }
333 }
334
335 void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_pointer)
336 {
337         Sequence **array;
338
339         *seqarray= NULL;
340         *tot= 0;
341
342         if(ed == NULL)
343                 return;
344
345         if(use_pointer)
346                 seq_count(ed->seqbasep, tot);
347         else
348                 seq_count(&ed->seqbase, tot);
349
350         if(*tot == 0)
351                 return;
352
353         *seqarray= array= MEM_mallocN(sizeof(Sequence *)*(*tot), "SeqArray");
354         if(use_pointer)
355                 seq_build_array(ed->seqbasep, &array, 0);
356         else
357                 seq_build_array(&ed->seqbase, &array, 0);
358 }
359
360 void seq_begin(Editing *ed, SeqIterator *iter, int use_pointer)
361 {
362         memset(iter, 0, sizeof(*iter));
363         seq_array(ed, &iter->array, &iter->tot, use_pointer);
364
365         if(iter->tot) {
366                 iter->cur= 0;
367                 iter->seq= iter->array[iter->cur];
368                 iter->valid= 1;
369         }
370 }
371
372 void seq_next(SeqIterator *iter)
373 {
374         if(++iter->cur < iter->tot)
375                 iter->seq= iter->array[iter->cur];
376         else
377                 iter->valid= 0;
378 }
379
380 void seq_end(SeqIterator *iter)
381 {
382         if(iter->array)
383                 MEM_freeN(iter->array);
384
385         iter->valid= 0;
386 }
387
388 /*
389   **********************************************************************
390   * build_seqar
391   **********************************************************************
392   * Build a complete array of _all_ sequencies (including those
393   * in metastrips!)
394   **********************************************************************
395 */
396
397 static void do_seq_count(ListBase *seqbase, int *totseq)
398 {
399         Sequence *seq;
400
401         seq= seqbase->first;
402         while(seq) {
403                 (*totseq)++;
404                 if(seq->seqbase.first) do_seq_count(&seq->seqbase, totseq);
405                 seq= seq->next;
406         }
407 }
408
409 static void do_build_seqar(ListBase *seqbase, Sequence ***seqar, int depth)
410 {
411         Sequence *seq;
412
413         seq= seqbase->first;
414         while(seq) {
415                 seq->depth= depth;
416                 if(seq->seqbase.first) do_build_seqar(&seq->seqbase, seqar, depth+1);
417                 **seqar= seq;
418                 (*seqar)++;
419                 seq= seq->next;
420         }
421 }
422
423 void build_seqar(ListBase *seqbase, Sequence  ***seqar, int *totseq)
424 {
425         Sequence **tseqar;
426
427         *totseq= 0;
428         do_seq_count(seqbase, totseq);
429
430         if(*totseq==0) {
431                 *seqar= 0;
432                 return;
433         }
434         *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
435         tseqar= *seqar;
436
437         do_build_seqar(seqbase, seqar, 0);
438         *seqar= tseqar;
439 }
440
441 static void do_seq_count_cb(ListBase *seqbase, int *totseq,
442                                 int (*test_func)(Sequence * seq))
443 {
444         Sequence *seq;
445
446         seq= seqbase->first;
447         while(seq) {
448                 int test = test_func(seq);
449                 if (test & BUILD_SEQAR_COUNT_CURRENT) {
450                         (*totseq)++;
451                 }
452                 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
453                         do_seq_count_cb(&seq->seqbase, totseq, test_func);
454                 }
455                 seq= seq->next;
456         }
457 }
458
459 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
460                                   int (*test_func)(Sequence * seq))
461 {
462         Sequence *seq;
463
464         seq= seqbase->first;
465         while(seq) {
466                 int test = test_func(seq);
467                 seq->depth= depth;
468
469                 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
470                         do_build_seqar_cb(&seq->seqbase, seqar, depth+1, 
471                                           test_func);
472                 }
473                 if (test & BUILD_SEQAR_COUNT_CURRENT) {
474                         **seqar= seq;
475                         (*seqar)++;
476                 }
477                 seq= seq->next;
478         }
479 }
480
481 void build_seqar_cb(ListBase *seqbase, Sequence  ***seqar, int *totseq,
482                         int (*test_func)(Sequence * seq))
483 {
484         Sequence **tseqar;
485
486         *totseq= 0;
487         do_seq_count_cb(seqbase, totseq, test_func);
488
489         if(*totseq==0) {
490                 *seqar= 0;
491                 return;
492         }
493         *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
494         tseqar= *seqar;
495
496         do_build_seqar_cb(seqbase, seqar, 0, test_func);
497         *seqar= tseqar;
498 }
499
500
501 void calc_sequence_disp(Scene *scene, Sequence *seq)
502 {
503         if(seq->startofs && seq->startstill) seq->startstill= 0;
504         if(seq->endofs && seq->endstill) seq->endstill= 0;
505         
506         seq->startdisp= seq->start + seq->startofs - seq->startstill;
507         seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
508         
509         seq->handsize= 10.0;    /* 10 frames */
510         if( seq->enddisp-seq->startdisp < 10 ) {
511                 seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
512         }
513         else if(seq->enddisp-seq->startdisp > 250) {
514                 seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
515         }
516
517         seq_update_sound(scene, seq);
518 }
519
520 void calc_sequence(Scene *scene, Sequence *seq)
521 {
522         Sequence *seqm;
523         int min, max;
524
525         /* check all metas recursively */
526         seqm= seq->seqbase.first;
527         while(seqm) {
528                 if(seqm->seqbase.first) calc_sequence(scene, seqm);
529                 seqm= seqm->next;
530         }
531
532         /* effects and meta: automatic start and end */
533
534         if(seq->type & SEQ_EFFECT) {
535                 /* pointers */
536                 if(seq->seq2==0) seq->seq2= seq->seq1;
537                 if(seq->seq3==0) seq->seq3= seq->seq1;
538
539                 /* effecten go from seq1 -> seq2: test */
540
541                 /* we take the largest start and smallest end */
542
543                 // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
544                 // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
545
546                 if (seq->seq1) {
547                         seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
548                         seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
549                         seq->len= seq->enddisp - seq->startdisp;
550                 } else {
551                         calc_sequence_disp(scene, seq);
552                 }
553
554                 if(seq->strip && seq->len!=seq->strip->len) {
555                         new_tstripdata(seq);
556                 }
557
558         }
559         else {
560                 if(seq->type==SEQ_META) {
561                         seqm= seq->seqbase.first;
562                         if(seqm) {
563                                 min=  MAXFRAME * 2;
564                                 max= -MAXFRAME * 2;
565                                 while(seqm) {
566                                         if(seqm->startdisp < min) min= seqm->startdisp;
567                                         if(seqm->enddisp > max) max= seqm->enddisp;
568                                         seqm= seqm->next;
569                                 }
570                                 seq->start= min + seq->anim_startofs;
571                                 seq->len = max-min;
572                                 seq->len -= seq->anim_startofs;
573                                 seq->len -= seq->anim_endofs;
574
575                                 if(seq->strip && seq->len!=seq->strip->len) {
576                                         new_tstripdata(seq);
577                                 }
578                         }
579                 }
580                 calc_sequence_disp(scene, seq);
581         }
582 }
583
584 /* note: caller should run calc_sequence(scene, seq) after */
585 void reload_sequence_new_file(Scene *scene, Sequence * seq, int lock_range)
586 {
587         char str[FILE_MAXDIR+FILE_MAXFILE];
588         int prev_startdisp, prev_enddisp;
589         /* note: dont rename the strip, will break animation curves */
590
591         if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
592                   seq->type == SEQ_SOUND ||
593                   seq->type == SEQ_SCENE || seq->type == SEQ_META)) {
594                 return;
595         }
596
597         if(lock_range) {
598                 /* keep so we dont have to move the actual start and end points (only the data) */
599                 calc_sequence_disp(scene, seq);
600                 prev_startdisp= seq->startdisp;
601                 prev_enddisp= seq->enddisp;
602         }
603
604
605         new_tstripdata(seq);
606
607         if (seq->type != SEQ_SCENE && seq->type != SEQ_META &&
608                 seq->type != SEQ_IMAGE) {
609                 BLI_join_dirfile(str, seq->strip->dir, seq->strip->stripdata->name);
610                 BLI_path_abs(str, G.sce);
611         }
612
613         if (seq->type == SEQ_IMAGE) {
614                 /* Hack? */
615                 size_t olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem);
616
617                 seq->len = olen;
618                 seq->len -= seq->anim_startofs;
619                 seq->len -= seq->anim_endofs;
620                 if (seq->len < 0) {
621                         seq->len = 0;
622                 }
623                 seq->strip->len = seq->len;
624         } else if (seq->type == SEQ_MOVIE) {
625                 if(seq->anim) IMB_free_anim(seq->anim);
626                 seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0));
627
628                 if (!seq->anim) {
629                         return;
630                 }
631         
632                 seq->len = IMB_anim_get_duration(seq->anim);
633                 
634                 seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
635
636                 seq->len -= seq->anim_startofs;
637                 seq->len -= seq->anim_endofs;
638                 if (seq->len < 0) {
639                         seq->len = 0;
640                 }
641                 seq->strip->len = seq->len;
642         } else if (seq->type == SEQ_SOUND) {
643                 seq->len = ceil(AUD_getInfo(seq->sound->playback_handle).length * FPS);
644                 seq->len -= seq->anim_startofs;
645                 seq->len -= seq->anim_endofs;
646                 if (seq->len < 0) {
647                         seq->len = 0;
648                 }
649                 seq->strip->len = seq->len;
650         } else if (seq->type == SEQ_SCENE) {
651                 /* 'seq->scenenr' should be replaced with something more reliable */
652                 Scene * sce = G.main->scene.first;
653                 int nr = 1;
654                 
655                 while(sce) {
656                         if(nr == seq->scenenr) {
657                                 break;
658                         }
659                         nr++;
660                         sce= sce->id.next;
661                 }
662
663                 if (sce) {
664                         seq->scene = sce;
665                 } else {
666                         sce = seq->scene;
667                 }
668                 
669                 seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
670                 seq->len -= seq->anim_startofs;
671                 seq->len -= seq->anim_endofs;
672                 if (seq->len < 0) {
673                         seq->len = 0;
674                 }
675                 seq->strip->len = seq->len;
676         }
677
678         free_proxy_seq(seq);
679
680         if(lock_range) {
681                 seq_tx_set_final_left(seq, prev_startdisp);
682                 seq_tx_set_final_right(seq, prev_enddisp);
683                 seq_single_fix(seq);
684         }
685         
686         calc_sequence(scene, seq);
687 }
688
689 void sort_seq(Scene *scene)
690 {
691         /* all strips together per kind, and in order of y location ("machine") */
692         ListBase seqbase, effbase;
693         Editing *ed= seq_give_editing(scene, FALSE);
694         Sequence *seq, *seqt;
695
696         
697         if(ed==NULL) return;
698
699         seqbase.first= seqbase.last= 0;
700         effbase.first= effbase.last= 0;
701
702         while( (seq= ed->seqbasep->first) ) {
703                 BLI_remlink(ed->seqbasep, seq);
704
705                 if(seq->type & SEQ_EFFECT) {
706                         seqt= effbase.first;
707                         while(seqt) {
708                                 if(seqt->machine>=seq->machine) {
709                                         BLI_insertlinkbefore(&effbase, seqt, seq);
710                                         break;
711                                 }
712                                 seqt= seqt->next;
713                         }
714                         if(seqt==0) BLI_addtail(&effbase, seq);
715                 }
716                 else {
717                         seqt= seqbase.first;
718                         while(seqt) {
719                                 if(seqt->machine>=seq->machine) {
720                                         BLI_insertlinkbefore(&seqbase, seqt, seq);
721                                         break;
722                                 }
723                                 seqt= seqt->next;
724                         }
725                         if(seqt==0) BLI_addtail(&seqbase, seq);
726                 }
727         }
728
729         addlisttolist(&seqbase, &effbase);
730         *(ed->seqbasep)= seqbase;
731 }
732
733
734 static int clear_scene_in_allseqs_cb(Sequence *seq, void *arg_pt)
735 {
736         if(seq->scene==(Scene *)arg_pt)
737                 seq->scene= NULL;
738         return 1;
739 }
740
741 void clear_scene_in_allseqs(Scene *scene)
742 {
743         Scene *scene_iter;
744
745         /* when a scene is deleted: test all seqs */
746         for(scene_iter= G.main->scene.first; scene_iter; scene_iter= scene_iter->id.next) {
747                 if(scene_iter != scene && scene_iter->ed) {
748                         seqbase_recursive_apply(&scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene);
749                 }
750         }
751 }
752
753 typedef struct SeqUniqueInfo {
754         Sequence *seq;
755         char name_src[32];
756         char name_dest[32];
757         int count;
758         int match;
759 } SeqUniqueInfo;
760
761 /*
762 static void seqbase_unique_name(ListBase *seqbasep, Sequence *seq)
763 {
764          BLI_uniquename(seqbasep, seq, "Sequence", '.', offsetof(Sequence, name), SEQ_NAME_MAXSTR);
765 }*/
766
767 static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
768 {
769         Sequence *seq;
770         for(seq=seqbasep->first; seq; seq= seq->next) {
771                 if (sui->seq != seq && strcmp(sui->name_dest, seq->name+2)==0) {
772                         sprintf(sui->name_dest, "%.18s.%03d",  sui->name_src, sui->count++);
773                         sui->match= 1; /* be sure to re-scan */
774                 }
775         }
776 }
777
778 static int seqbase_unique_name_recursive_cb(Sequence *seq, void *arg_pt)
779 {
780         if(seq->seqbase.first)
781                 seqbase_unique_name(&seq->seqbase, (SeqUniqueInfo *)arg_pt);
782         return 1;
783 }
784
785 void seqbase_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq)
786 {
787         SeqUniqueInfo sui;
788         char *dot;
789         sui.seq= seq;
790         strcpy(sui.name_src, seq->name+2);
791         strcpy(sui.name_dest, seq->name+2);
792
793         /* Strip off the suffix */
794         if ((dot=strrchr(sui.name_src, '.')))
795                 *dot= '\0';
796
797         sui.count= 1;
798         sui.match= 1; /* assume the worst to start the loop */
799
800         while(sui.match) {
801                 sui.match= 0;
802                 seqbase_unique_name(seqbasep, &sui);
803                 seqbase_recursive_apply(seqbasep, seqbase_unique_name_recursive_cb, &sui);
804         }
805
806         strcpy(seq->name+2, sui.name_dest);
807 }
808
809 static char *give_seqname_by_type(int type)
810 {
811         switch(type) {
812         case SEQ_META:       return "Meta";
813         case SEQ_IMAGE:      return "Image";
814         case SEQ_SCENE:      return "Scene";
815         case SEQ_MOVIE:      return "Movie";
816         case SEQ_SOUND:      return "Audio";
817         case SEQ_CROSS:      return "Cross";
818         case SEQ_GAMCROSS:   return "Gamma Cross";
819         case SEQ_ADD:        return "Add";
820         case SEQ_SUB:        return "Sub";
821         case SEQ_MUL:        return "Mul";
822         case SEQ_ALPHAOVER:  return "Alpha Over";
823         case SEQ_ALPHAUNDER: return "Alpha Under";
824         case SEQ_OVERDROP:   return "Over Drop";
825         case SEQ_WIPE:       return "Wipe";
826         case SEQ_GLOW:       return "Glow";
827         case SEQ_TRANSFORM:  return "Transform";
828         case SEQ_COLOR:      return "Color";
829         case SEQ_MULTICAM:   return "Multicam";
830         case SEQ_SPEED:      return "Speed";
831         default:
832                 return 0;
833         }
834 }
835
836 char *give_seqname(Sequence *seq)
837 {
838         char * name = give_seqname_by_type(seq->type);
839
840         if (!name) {
841                 if(seq->type<SEQ_EFFECT) {
842                         return seq->strip->dir;
843                 } else if(seq->type==SEQ_PLUGIN) {
844                         if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
845                            seq->plugin && seq->plugin->doit) {
846                                 return seq->plugin->pname;
847                         } else {
848                                 return "Plugin";
849                         }
850                 } else {
851                         return "Effect";
852                 }
853         }
854         return name;
855 }
856
857 /* ***************** DO THE SEQUENCE ***************** */
858
859 static void make_black_ibuf(ImBuf *ibuf)
860 {
861         unsigned int *rect;
862         float *rect_float;
863         int tot;
864
865         if(ibuf==0 || (ibuf->rect==0 && ibuf->rect_float==0)) return;
866
867         tot= ibuf->x*ibuf->y;
868
869         rect= ibuf->rect;
870         rect_float = ibuf->rect_float;
871
872         if (rect) {
873                 memset(rect,       0, tot * sizeof(char) * 4);
874         }
875
876         if (rect_float) {
877                 memset(rect_float, 0, tot * sizeof(float) * 4);
878         }
879 }
880
881 static void multibuf(ImBuf *ibuf, float fmul)
882 {
883         char *rt;
884         float *rt_float;
885
886         int a, mul, icol;
887
888         mul= (int)(256.0*fmul);
889         rt= (char *)ibuf->rect;
890         rt_float = ibuf->rect_float;
891
892         if (rt) {
893                 a= ibuf->x*ibuf->y;
894                 while(a--) {
895
896                         icol= (mul*rt[0])>>8;
897                         if(icol>254) rt[0]= 255; else rt[0]= icol;
898                         icol= (mul*rt[1])>>8;
899                         if(icol>254) rt[1]= 255; else rt[1]= icol;
900                         icol= (mul*rt[2])>>8;
901                         if(icol>254) rt[2]= 255; else rt[2]= icol;
902                         icol= (mul*rt[3])>>8;
903                         if(icol>254) rt[3]= 255; else rt[3]= icol;
904                         
905                         rt+= 4;
906                 }
907         }
908         if (rt_float) {
909                 a= ibuf->x*ibuf->y;
910                 while(a--) {
911                         rt_float[0] *= fmul;
912                         rt_float[1] *= fmul;
913                         rt_float[2] *= fmul;
914                         rt_float[3] *= fmul;
915                         
916                         rt_float += 4;
917                 }
918         }
919 }
920
921 static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se,
922                       int render_size)
923 {
924         TStripElem *se1, *se2, *se3;
925         float fac, facf;
926         int x, y;
927         int early_out;
928         struct SeqEffectHandle sh = get_sequence_effect(seq);
929         FCurve *fcu= NULL;
930
931         if (!sh.execute) { /* effect not supported in this version... */
932                 make_black_ibuf(se->ibuf);
933                 return;
934         }
935
936         if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
937                 sh.get_default_fac(seq, cfra, &fac, &facf);
938                 if( scene->r.mode & R_FIELDS ); else facf= fac;
939         } else {
940                 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, 
941                                           "effect_fader", 0);
942                 if (fcu) {
943                         fac = facf = evaluate_fcurve(fcu, cfra);
944                         if( scene->r.mode & R_FIELDS ) {
945                                 facf = evaluate_fcurve(fcu, cfra + 0.5);
946                         }
947                 } else {
948                         fac = facf = seq->effect_fader;
949                 }
950         }
951
952         early_out = sh.early_out(seq, fac, facf);
953
954         if (early_out == -1) { /* no input needed */
955                 sh.execute(scene, seq, cfra, fac, facf, 
956                            se->ibuf->x, se->ibuf->y, render_size,
957                            0, 0, 0, se->ibuf);
958                 return;
959         }
960
961         switch (early_out) {
962         case 0:
963                 if (se->se1==0 || se->se2==0 || se->se3==0) {
964                         make_black_ibuf(se->ibuf);
965                         return;
966                 }
967
968                 se1= se->se1;
969                 se2= se->se2;
970                 se3= se->se3;
971
972                 if (   (se1==0 || se2==0 || se3==0)
973                         || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) {
974                         make_black_ibuf(se->ibuf);
975                         return;
976                 }
977
978                 break;
979         case 1:
980                 if (se->se1 == 0) {
981                         make_black_ibuf(se->ibuf);
982                         return;
983                 }
984
985                 se1= se->se1;
986
987                 if (se1 == 0 || se1->ibuf == 0) {
988                         make_black_ibuf(se->ibuf);
989                         return;
990                 }
991
992                 if (se->ibuf != se1->ibuf) {
993                         IMB_freeImBuf(se->ibuf);
994                         se->ibuf = se1->ibuf;
995                         IMB_refImBuf(se->ibuf);
996                 }
997                 return;
998         case 2:
999                 if (se->se2 == 0) {
1000                         make_black_ibuf(se->ibuf);
1001                         return;
1002                 }
1003
1004                 se2= se->se2;
1005
1006                 if (se2 == 0 || se2->ibuf == 0) {
1007                         make_black_ibuf(se->ibuf);
1008                         return;
1009                 }
1010                 if (se->ibuf != se2->ibuf) {
1011                         IMB_freeImBuf(se->ibuf);
1012                         se->ibuf = se2->ibuf;
1013                         IMB_refImBuf(se->ibuf);
1014                 }
1015                 return;
1016         default:
1017                 make_black_ibuf(se->ibuf);
1018                 return;
1019         }
1020
1021         x= se2->ibuf->x;
1022         y= se2->ibuf->y;
1023
1024         if (!se1->ibuf->rect_float && se->ibuf->rect_float) {
1025                 IMB_float_from_rect_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         if(seq->flag & SEQ_FLIPY) {
1773                 IMB_flipy(se->ibuf);
1774         }
1775
1776         if(seq->mul == 0.0) {
1777                 seq->mul = 1.0;
1778         }
1779
1780         mul = seq->mul;
1781
1782         if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1783                 mul *= seq->blend_opacity / 100.0;
1784         }
1785
1786         if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1787                 color_balance(seq, se, mul);
1788                 mul = 1.0;
1789         }
1790
1791         if(seq->flag & SEQ_MAKE_FLOAT) {
1792                 if (!se->ibuf->rect_float)
1793                         IMB_float_from_rect_simple(se->ibuf);
1794
1795                 if (se->ibuf->rect) {
1796                         imb_freerectImBuf(se->ibuf);
1797                 }
1798         }
1799
1800         if(mul != 1.0) {
1801                 multibuf(se->ibuf, mul);
1802         }
1803
1804         if(seq->flag & SEQ_MAKE_PREMUL) {
1805                 if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
1806                         IMB_premultiply_alpha(se->ibuf);
1807                 }
1808         }
1809
1810
1811         if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
1812                 if(scene->r.mode & R_OSA) {
1813                         IMB_scaleImBuf(se->ibuf, 
1814                                            (short)seqrectx, (short)seqrecty);
1815                 } else {
1816                         IMB_scalefastImBuf(se->ibuf, 
1817                                            (short)seqrectx, (short)seqrecty);
1818                 }
1819         }
1820 }
1821
1822 /* test if image too small or discarded from cache: reload */
1823
1824 static void test_and_auto_discard_ibuf(TStripElem * se, 
1825                                        int seqrectx, int seqrecty)
1826 {
1827         if (se->ibuf) {
1828                 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty 
1829                    || !(se->ibuf->rect || se->ibuf->rect_float)) {
1830                         IMB_freeImBuf(se->ibuf);
1831
1832                         se->ibuf= 0;
1833                         se->ok= STRIPELEM_OK;
1834                 }
1835         }
1836         if (se->ibuf_comp) {
1837                 if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty 
1838                    || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) {
1839                         IMB_freeImBuf(se->ibuf_comp);
1840
1841                         se->ibuf_comp = 0;
1842                 }
1843         }
1844 }
1845
1846 static void test_and_auto_discard_ibuf_stills(Strip * strip)
1847 {
1848         if (strip->ibuf_startstill) {
1849                 if (!strip->ibuf_startstill->rect &&
1850                         !strip->ibuf_startstill->rect_float) {
1851                         IMB_freeImBuf(strip->ibuf_startstill);
1852                         strip->ibuf_startstill = 0;
1853                 }
1854         }
1855         if (strip->ibuf_endstill) {
1856                 if (!strip->ibuf_endstill->rect &&
1857                         !strip->ibuf_endstill->rect_float) {
1858                         IMB_freeImBuf(strip->ibuf_endstill);
1859                         strip->ibuf_endstill = 0;
1860                 }
1861         }
1862 }
1863
1864 static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
1865 {
1866         if (!se->ibuf) {
1867                 if (se->nr == 0 && seq->strip->ibuf_startstill) {
1868                         IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1869
1870                         se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
1871                 }
1872                 if (se->nr == seq->len - 1 
1873                         && (seq->len != 1)
1874                         && seq->strip->ibuf_endstill) {
1875                         IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1876
1877                         se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
1878                 }
1879         }
1880 }
1881
1882 static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
1883 {
1884         if (se->ibuf) {
1885                 if (se->nr == 0) {
1886                         seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
1887
1888                         IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
1889                         IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1890                 }
1891                 if (se->nr == seq->len - 1 && seq->len != 1) {
1892                         seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
1893
1894                         IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
1895                         IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1896                 }
1897         }
1898 }
1899
1900 static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown)
1901 {
1902         Sequence* seq_arr[MAXSEQ+1];
1903         int i;
1904         TStripElem* se = 0;
1905
1906         evaluate_seq_frame_gen(seq_arr, seqbasep, cfra);
1907
1908         for (i = 0; i < MAXSEQ; i++) {
1909                 if (!video_seq_is_rendered(seq_arr[i])) {
1910                         continue;
1911                 }
1912                 se = give_tstripelem(seq_arr[i], cfra);
1913                 if (se) {
1914                         if (se->ibuf) {
1915                                 IMB_freeImBuf(se->ibuf);
1916
1917                                 se->ibuf= 0;
1918                                 se->ok= STRIPELEM_OK;
1919                         }
1920
1921                         if (se->ibuf_comp) {
1922                                 IMB_freeImBuf(se->ibuf_comp);
1923
1924                                 se->ibuf_comp = 0;
1925                         }
1926                 }
1927         }
1928         
1929 }
1930
1931 static void check_limiter_refcount(const char * func, TStripElem *se)
1932 {
1933         if (se && se->ibuf) {
1934                 int refcount = IMB_cache_limiter_get_refcount(se->ibuf);
1935                 if (refcount != 1) {
1936                         /* can happen on complex pipelines */
1937                         if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1938                                 return;
1939                         }
1940  
1941                         fprintf(stderr, 
1942                                 "sequencer: (ibuf) %s: "
1943                                 "suspicious memcache "
1944                                 "limiter refcount: %d\n", func, refcount);
1945                 }
1946         }
1947 }
1948  
1949 static void check_limiter_refcount_comp(const char * func, TStripElem *se)
1950 {
1951         if (se && se->ibuf_comp) {
1952                 int refcount = IMB_cache_limiter_get_refcount(se->ibuf_comp);
1953                 if (refcount != 1) {
1954                         /* can happen on complex pipelines */
1955                         if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1956                                 return;
1957                         }
1958                         fprintf(stderr, 
1959                                 "sequencer: (ibuf comp) %s: "
1960                                 "suspicious memcache "
1961                                 "limiter refcount: %d\n", func, refcount);
1962                 }
1963         }
1964 }
1965
1966 static TStripElem* do_build_seq_array_recursively(
1967         Scene *scene,
1968         ListBase *seqbasep, int cfra, int chanshown, int render_size,
1969         int seqrectx, int seqrecty);
1970
1971 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1972                                   int build_proxy_run, int render_size, int seqrectx, int seqrecty)
1973 {
1974         char name[FILE_MAXDIR+FILE_MAXFILE];
1975         int use_limiter = TRUE;
1976
1977         test_and_auto_discard_ibuf(se, seqrectx, seqrecty);
1978         test_and_auto_discard_ibuf_stills(seq->strip);
1979
1980         if(seq->type == SEQ_META) {
1981                 TStripElem * meta_se = 0;
1982                 int use_preprocess = FALSE;
1983                 use_limiter = FALSE;
1984
1985                 if (!build_proxy_run && se->ibuf == 0) {
1986                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1987                         if (se->ibuf) {
1988                                 use_limiter = TRUE;
1989                                 use_preprocess = TRUE;
1990                         }
1991                 }
1992
1993                 if(!se->ibuf && seq->seqbase.first) {
1994                         meta_se = do_build_seq_array_recursively(scene,
1995                                 &seq->seqbase, seq->start + se->nr, 0,
1996                                 render_size, seqrectx, seqrecty);
1997
1998                         check_limiter_refcount("do_build_seq_ibuf: for META", meta_se);
1999                 }
2000
2001                 se->ok = STRIPELEM_OK;
2002
2003                 if(!se->ibuf && meta_se) {
2004                         se->ibuf = meta_se->ibuf_comp;
2005                         if(se->ibuf &&
2006                            (!input_have_to_preprocess(scene, seq, se, cfra,
2007                                                       seqrectx, seqrecty) ||
2008                                 build_proxy_run)) {
2009                                 IMB_refImBuf(se->ibuf);
2010                                 if (build_proxy_run) {
2011                                         IMB_cache_limiter_unref(se->ibuf);
2012                                 }
2013                         } else if (se->ibuf) {
2014                                 struct ImBuf * i = IMB_dupImBuf(se->ibuf);
2015
2016                                 IMB_cache_limiter_unref(se->ibuf);
2017
2018                                 se->ibuf = i;
2019
2020                                 use_limiter = TRUE;
2021                                 use_preprocess = TRUE;
2022                         }
2023                 } else if (se->ibuf) {
2024                         use_limiter = TRUE;
2025                 }
2026                 if (meta_se) {
2027                         free_metastrip_imbufs(
2028                                 &seq->seqbase, seq->start + se->nr, 0);
2029                 }
2030
2031                 if (use_preprocess) {
2032                         input_preprocess(scene, seq, se, cfra, seqrectx,
2033                                          seqrecty);
2034                 }
2035         } else if(seq->type & SEQ_EFFECT) {
2036                 int use_preprocess = FALSE;
2037                 /* should the effect be recalculated? */
2038                 
2039                 if (!build_proxy_run && se->ibuf == 0) {
2040                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2041                         if (se->ibuf) {
2042                                 use_preprocess = TRUE;
2043                         }
2044                 }
2045
2046                 if(se->ibuf == 0) {
2047                         /* if any inputs are rectfloat, output is float too */
2048                         if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
2049                            (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float) ||
2050                            (se->se3 && se->se3->ibuf && se->se3->ibuf->rect_float))
2051                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2052                         else
2053                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2054                         
2055                         do_effect(scene, cfra, seq, se, render_size);
2056                         if (input_have_to_preprocess(scene, seq, se, cfra,
2057                                                      seqrectx, seqrecty) &&
2058                                 !build_proxy_run) {
2059                                 if ((se->se1 && (se->ibuf == se->se1->ibuf)) ||
2060                                         (se->se2 && (se->ibuf == se->se2->ibuf))) {
2061                                         struct ImBuf * i
2062                                                 = IMB_dupImBuf(se->ibuf);
2063
2064                                         IMB_freeImBuf(se->ibuf);
2065
2066                                         se->ibuf = i;
2067                                 }
2068                                 use_preprocess = TRUE;
2069                         }
2070                 }
2071                 if (use_preprocess) {
2072                         input_preprocess(scene, seq, se, cfra, seqrectx,
2073                                          seqrecty);
2074                 }
2075         } else if(seq->type == SEQ_IMAGE) {
2076                 if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
2077                         StripElem * s_elem = give_stripelem(seq, cfra);
2078                         BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
2079                         BLI_path_abs(name, G.sce);
2080                         if (!build_proxy_run) {
2081                                 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2082                         }
2083                         copy_from_ibuf_still(seq, se);
2084
2085                         if (se->ibuf==NULL && (se->ibuf= IMB_loadiffname(name, IB_rect))) {
2086                                 /* we don't need both (speed reasons)! */
2087                                 if (se->ibuf->rect_float && se->ibuf->rect)
2088                                         imb_freerectImBuf(se->ibuf);
2089
2090                                 /* all sequencer color is done in SRGB space, linear gives odd crossfades */
2091                                 if(se->ibuf->profile == IB_PROFILE_LINEAR_RGB)
2092                                         IMB_convert_profile(se->ibuf, IB_PROFILE_NONE);
2093
2094                                 copy_to_ibuf_still(seq, se);
2095                         }
2096                         
2097                         if(se->ibuf == 0) {
2098                                 se->ok = STRIPELEM_FAILED;
2099                         } else if (!build_proxy_run) {
2100                                 input_preprocess(scene, seq, se, cfra,
2101                                                  seqrectx, seqrecty);
2102                         }
2103                 }
2104         } else if(seq->type == SEQ_MOVIE) {
2105                 if(se->ok == STRIPELEM_OK && se->ibuf==0) {
2106                         if(!build_proxy_run) {
2107                                 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2108                         }
2109                         copy_from_ibuf_still(seq, se);
2110
2111                         if (se->ibuf == 0) {
2112                                 if(seq->anim==0) {
2113                                         BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
2114                                         BLI_path_abs(name, G.sce);
2115                                         
2116                                         seq->anim = openanim(
2117                                                 name, IB_rect | 
2118                                                 ((seq->flag & SEQ_FILTERY) 
2119                                                  ? IB_animdeinterlace : 0));
2120                                 }
2121                                 if(seq->anim) {
2122                                         IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
2123                                         se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
2124                                         /* we don't need both (speed reasons)! */
2125                                         if (se->ibuf 
2126                                                 && se->ibuf->rect_float 
2127                                                 && se->ibuf->rect) {
2128                                                 imb_freerectImBuf(se->ibuf);
2129                                         }
2130
2131                                 }
2132                                 copy_to_ibuf_still(seq, se);
2133                         }
2134                         
2135                         if(se->ibuf == 0) {
2136                                 se->ok = STRIPELEM_FAILED;
2137                         } else if (!build_proxy_run) {
2138                                 input_preprocess(scene, seq, se, cfra,
2139                                                  seqrectx, seqrecty);
2140                         }
2141                 }
2142         } else if(seq->type == SEQ_SCENE) {     // scene can be NULL after deletions
2143                 Scene *sce= seq->scene;// *oldsce= scene;
2144                 int have_seq= FALSE;
2145                 int sce_valid= FALSE;
2146
2147                 if(sce) {
2148                         have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first;
2149                         sce_valid= (sce->camera || have_seq);
2150                 }
2151
2152                 if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
2153                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2154                         if (se->ibuf) {
2155                                 input_preprocess(scene, seq, se, cfra,
2156                                                  seqrectx, seqrecty);
2157                         }
2158                 }
2159
2160                 if (se->ibuf == NULL && sce_valid) {
2161                         copy_from_ibuf_still(seq, se);
2162                         if (se->ibuf) {
2163                                 input_preprocess(scene, seq, se, cfra,
2164                                                  seqrectx, seqrecty);
2165                         }
2166                 }
2167                 
2168                 if (!sce_valid) {
2169                         se->ok = STRIPELEM_FAILED;
2170                 }
2171                 else if (se->ibuf==NULL && sce_valid) {
2172                         int frame= seq->sfra + se->nr + seq->anim_startofs;
2173                         int oldcfra = seq->scene->r.cfra;
2174                         Object *oldcamera= seq->scene->camera;
2175                         ListBase oldmarkers;
2176
2177                         /* Hack! This function can be called from do_render_seq(), in that case
2178                            the seq->scene can already have a Render initialized with same name,
2179                            so we have to use a default name. (compositor uses scene name to
2180                            find render).
2181                            However, when called from within the UI (image preview in sequencer)
2182                            we do want to use scene Render, that way the render result is defined
2183                            for display in render/imagewindow
2184
2185                            Hmm, don't see, why we can't do that all the time,
2186                            and since G.rendering is uhm, gone... (Peter)
2187                         */
2188
2189                         int rendering = G.rendering;
2190                         int doseq;
2191                         int doseq_gl= G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : (scene->r.seq_flag & R_SEQ_GL_PREV);
2192
2193                         /* prevent eternal loop */
2194                         doseq= scene->r.scemode & R_DOSEQ;
2195                         scene->r.scemode &= ~R_DOSEQ;
2196
2197                         seq->scene->r.cfra= frame;
2198                         if(seq->scene_camera)   seq->scene->camera= seq->scene_camera;
2199                         else                                    scene_camera_switch_update(seq->scene);
2200
2201 #ifdef DURIAN_CAMERA_SWITCH
2202                         /* stooping to new low's in hackyness :( */
2203                         oldmarkers= seq->scene->markers;
2204                         seq->scene->markers.first= seq->scene->markers.last= NULL;
2205 #endif
2206
2207                         if(sequencer_view3d_cb && doseq_gl && (seq->scene == scene || have_seq==0) && seq->scene->camera) {
2208                                 /* opengl offscreen render */
2209                                 scene_update_for_newframe(seq->scene, seq->scene->lay);
2210                                 se->ibuf= sequencer_view3d_cb(seq->scene, seqrectx, seqrecty, scene->r.seq_prev_type);
2211                         }
2212                         else {
2213                                 Render *re;
2214                                 RenderResult rres;
2215
2216                                 if(rendering)
2217                                         re= RE_NewRender(" do_build_seq_ibuf");
2218                                 else
2219                                         re= RE_NewRender(sce->id.name);
2220
2221                                 RE_BlenderFrame(re, sce, NULL, sce->lay, frame);
2222
2223                                 RE_AcquireResultImage(re, &rres);
2224
2225                                 if(rres.rectf) {
2226                                         se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
2227                                         memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
2228                                         if(rres.rectz) {
2229                                                 addzbuffloatImBuf(se->ibuf);
2230                                                 memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
2231                                         }
2232                                 } else if (rres.rect32) {
2233                                         se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
2234                                         memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
2235                                 }
2236
2237                                 RE_ReleaseResultImage(re);
2238
2239                                 // BIF_end_render_callbacks();
2240                         }
2241                         
2242                         /* restore */
2243                         scene->r.scemode |= doseq;
2244
2245                         seq->scene->r.cfra = oldcfra;
2246                         seq->scene->camera= oldcamera;
2247
2248 #ifdef DURIAN_CAMERA_SWITCH
2249                         /* stooping to new low's in hackyness :( */
2250                         seq->scene->markers= oldmarkers;
2251 #endif
2252
2253                         copy_to_ibuf_still(seq, se);
2254
2255                         if (!build_proxy_run) {
2256                                 if(se->ibuf == NULL) {
2257                                         se->ok = STRIPELEM_FAILED;
2258                                 } else {
2259                                         input_preprocess(scene, seq, se, cfra,
2260                                                          seqrectx, seqrecty);
2261                                 }
2262                         }
2263
2264                 }
2265         }
2266         if (!build_proxy_run) {
2267                 if (se->ibuf && use_limiter) {
2268                         IMB_cache_limiter_insert(se->ibuf);
2269                         IMB_cache_limiter_ref(se->ibuf);
2270                         IMB_cache_limiter_touch(se->ibuf);
2271                 }
2272         }
2273 }
2274
2275 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size, int seqrectx, int seqrecty);
2276
2277 static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size, int seqrectx, int seqrecty)
2278 {
2279         float fac, facf;
2280         struct SeqEffectHandle sh = get_sequence_effect(seq);
2281         int early_out;
2282         FCurve *fcu= NULL;
2283
2284         se->se1 = 0;
2285         se->se2 = 0;
2286         se->se3 = 0;
2287
2288         if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
2289                 sh.get_default_fac(seq, cfra, &fac, &facf);
2290                 if( scene->r.mode & R_FIELDS ); else facf= fac;
2291         } else {
2292                 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, 
2293                                           "effect_fader", 0);
2294                 if (fcu) {
2295                         fac = facf = evaluate_fcurve(fcu, cfra);
2296                         if( scene->r.mode & R_FIELDS ) {
2297                                 facf = evaluate_fcurve(fcu, cfra + 0.5);
2298                         }
2299                 } else {
2300                         fac = facf = seq->effect_fader;
2301                 }
2302         }
2303
2304         early_out = sh.early_out(seq, fac, facf);
2305         switch (early_out) {
2306         case -1:
2307                 /* no input needed */
2308                 break;
2309         case 0:
2310                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size, seqrectx, seqrecty);
2311                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size, seqrectx, seqrecty);
2312                 if (seq->seq3) {
2313                         se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size, seqrectx, seqrecty);
2314                 }
2315                 break;
2316         case 1:
2317                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size, seqrectx, seqrecty);
2318                 break;
2319         case 2:
2320                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size, seqrectx, seqrecty);
2321                 break;
2322         }
2323
2324
2325         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size, seqrectx, seqrecty);
2326
2327         /* children are not needed anymore ... */
2328
2329         if (se->se1 && se->se1->ibuf) {
2330                 IMB_cache_limiter_unref(se->se1->ibuf);
2331         }
2332         if (se->se2 && se->se2->ibuf) {
2333                 IMB_cache_limiter_unref(se->se2->ibuf);
2334         }
2335         if (se->se3 && se->se3->ibuf) {
2336                 IMB_cache_limiter_unref(se->se3->ibuf);
2337         }
2338         check_limiter_refcount("do_effect_seq_recursively", se);
2339 }
2340
2341 static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty)
2342 {
2343         TStripElem *se;
2344
2345         se = give_tstripelem(seq, cfra);
2346
2347         if(se) {
2348                 if (seq->type & SEQ_EFFECT) {
2349                         do_effect_seq_recursively(scene, seq, se, cfra, render_size, seqrectx, seqrecty);
2350                 } else {
2351                         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size, seqrectx, seqrecty);
2352                 }
2353         }
2354         return se;
2355 }
2356
2357 /* FIXME:
2358    
2359 If cfra was float throughout blender (especially in the render
2360 pipeline) one could even _render_ with subframe precision
2361 instead of faking using the blend code below...
2362
2363 */
2364
2365 static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty)
2366 {
2367         SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
2368         int nr = cfra - seq->start;
2369         float f_cfra;
2370         int cfra_left;
2371         int cfra_right;
2372         TStripElem * se = 0;
2373         TStripElem * se1 = 0;
2374         TStripElem * se2 = 0;
2375         
2376         sequence_effect_speed_rebuild_map(scene, seq, 0);
2377         
2378         f_cfra = seq->start + s->frameMap[nr];
2379         
2380         cfra_left = (int) floor(f_cfra);
2381         cfra_right = (int) ceil(f_cfra);
2382
2383         se = give_tstripelem(seq, cfra);
2384
2385         if (!se) {
2386                 return se;
2387         }
2388
2389         if (cfra_left == cfra_right || 
2390                 (s->flags & SEQ_SPEED_BLEND) == 0) {
2391                 test_and_auto_discard_ibuf(se, seqrectx, seqrecty);
2392
2393                 if (se->ibuf == NULL) {
2394                         se1 = do_build_seq_recursively(scene, seq->seq1, cfra_left, render_size, seqrectx, seqrecty);
2395
2396                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2397                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2398                         else
2399                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2400
2401                         if (se1 == 0 || se1->ibuf == 0) {
2402                                 make_black_ibuf(se->ibuf);
2403                         } else {
2404                                 if (se->ibuf != se1->ibuf) {
2405                                         if (se->ibuf) {
2406                                                 IMB_freeImBuf(se->ibuf);
2407                                         }
2408
2409                                         se->ibuf = se1->ibuf;
2410                                         IMB_refImBuf(se->ibuf);
2411                                 }
2412                         }
2413                 }
2414         } else {
2415                 struct SeqEffectHandle sh;
2416
2417                 if(se->ibuf) {
2418                         if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty 
2419                            || !(se->ibuf->rect || se->ibuf->rect_float)) {
2420                                 IMB_freeImBuf(se->ibuf);
2421                                 se->ibuf= 0;
2422                         }
2423                 }
2424
2425                 if (se->ibuf == NULL) {
2426                         se1 = do_build_seq_recursively(scene, seq->seq1, cfra_left, render_size, seqrectx, seqrecty);
2427                         se2 = do_build_seq_recursively(scene, seq->seq1, cfra_right, render_size, seqrectx, seqrecty);
2428
2429                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2430                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2431                         else
2432                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2433                         
2434                         if (!se1 || !se2) {
2435                                 make_black_ibuf(se->ibuf);
2436                         } else {
2437                                 sh = get_sequence_effect(seq);
2438
2439                                 sh.execute(scene, seq, cfra, 
2440                                            f_cfra - (float) cfra_left, 
2441                                            f_cfra - (float) cfra_left, 
2442                                            se->ibuf->x, se->ibuf->y, 
2443                                            render_size,
2444                                            se1->ibuf, se2->ibuf, 0, se->ibuf);
2445                         }
2446                 }
2447
2448         }
2449
2450         /* caller expects this to be referenced, so do it! */
2451         if (se->ibuf) {
2452                 IMB_cache_limiter_insert(se->ibuf);
2453                 IMB_cache_limiter_ref(se->ibuf);
2454                 IMB_cache_limiter_touch(se->ibuf);
2455         }
2456
2457         /* children are no longer needed */
2458         if (se1 && se1->ibuf)
2459                 IMB_cache_limiter_unref(se1->ibuf);
2460         if (se2 && se2->ibuf)
2461                 IMB_cache_limiter_unref(se2->ibuf);
2462
2463         check_limiter_refcount("do_handle_speed_effect", se);
2464
2465         return se;
2466 }
2467
2468 /* 
2469  * build all ibufs recursively
2470  * 
2471  * if successfull, the returned TStripElem contains the (referenced!) imbuf
2472  * that means: you _must_ call 
2473  *
2474  * IMB_cache_limiter_unref(rval);
2475  * 
2476  * if rval != 0
2477  * 
2478  */
2479
2480 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty)
2481 {
2482         TStripElem *se;
2483
2484         /* BAD HACK! Seperate handling for speed effects needed, since
2485            a) you can't just fetch a different cfra within an effect strip
2486            b) we have to blend two frames, and CFRA is not float...
2487         */
2488         if (seq->type == SEQ_SPEED) {
2489                 se = do_handle_speed_effect(scene, seq, cfra, render_size, seqrectx, seqrecty);
2490         } else {
2491                 se = do_build_seq_recursively_impl(scene, seq, cfra, render_size, seqrectx, seqrecty);
2492         }
2493
2494         check_limiter_refcount("do_build_seq_recursively", se);
2495
2496         return se;
2497 }
2498
2499 static int seq_must_swap_input_in_blend_mode(Sequence * seq)
2500 {
2501         int swap_input = FALSE;
2502
2503         /* bad hack, to fix crazy input ordering of 
2504            those two effects */
2505
2506         if (seq->blend_mode == SEQ_ALPHAOVER ||
2507                 seq->blend_mode == SEQ_ALPHAUNDER ||
2508                 seq->blend_mode == SEQ_OVERDROP) {
2509                 swap_input = TRUE;
2510         }
2511         
2512         return swap_input;
2513 }
2514
2515 static int seq_get_early_out_for_blend_mode(Sequence * seq)
2516 {
2517         struct SeqEffectHandle sh = get_sequence_blend(seq);
2518         float facf = seq->blend_opacity / 100.0;
2519         int early_out = sh.early_out(seq, facf, facf);
2520         
2521         if (early_out < 1) {
2522                 return early_out;
2523         }
2524
2525         if (seq_must_swap_input_in_blend_mode(seq)) {
2526                 if (early_out == 2) {
2527                         return 1;
2528                 } else if (early_out == 1) {
2529                         return 2;
2530                 }
2531         }
2532         return early_out;
2533 }
2534
2535 static TStripElem* do_build_seq_array_recursively(
2536         Scene *scene, ListBase *seqbasep, int cfra, int chanshown, 
2537         int render_size, int seqrectx, int seqrecty)
2538 {
2539         Sequence* seq_arr[MAXSEQ+1];
2540         int count;
2541         int i;
2542         TStripElem* se = 0;
2543
2544         count = get_shown_sequences(seqbasep, cfra, chanshown, 
2545                                         (Sequence **)&seq_arr);
2546
2547         if (!count) {
2548                 return 0;
2549         }
2550
2551         se = give_tstripelem(seq_arr[count - 1], cfra);
2552
2553         if (!se) {
2554                 return 0;
2555         }
2556
2557 #if 0 /* commentind since this breaks keyframing, since it resets the value on draw */
2558         if(scene->r.cfra != cfra) {
2559                 // XXX for prefetch and overlay offset!..., very bad!!!
2560                 AnimData *adt= BKE_animdata_from_id(&scene->id);
2561                 BKE_animsys_evaluate_animdata(&scene->id, adt, cfra, ADT_RECALC_ANIM);
2562         }
2563 #endif
2564
2565         test_and_auto_discard_ibuf(se, seqrectx, seqrecty);
2566
2567         if (se->ibuf_comp != 0) {
2568                 IMB_cache_limiter_insert(se->ibuf_comp);
2569                 IMB_cache_limiter_ref(se->ibuf_comp);
2570                 IMB_cache_limiter_touch(se->ibuf_comp);
2571                 return se;
2572         }
2573
2574         
2575         if(count == 1) {
2576                 se = do_build_seq_recursively(scene, seq_arr[0],
2577                                               cfra, render_size,
2578                                               seqrectx, seqrecty);
2579                 if (se->ibuf) {
2580                         se->ibuf_comp = se->ibuf;
2581                         IMB_refImBuf(se->ibuf_comp);
2582                 }
2583                 return se;
2584         }
2585
2586
2587         for (i = count - 1; i >= 0; i--) {
2588                 int early_out;
2589                 Sequence * seq = seq_arr[i];
2590
2591                 se = give_tstripelem(seq, cfra);
2592
2593                 test_and_auto_discard_ibuf(se, seqrectx, seqrecty);
2594
2595                 if (se->ibuf_comp != 0) {
2596                         break;
2597                 }
2598                 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2599                         do_build_seq_recursively(
2600                                 scene, seq, cfra, render_size,
2601                                 seqrectx, seqrecty);
2602
2603                         if (se->ibuf) {
2604                                 se->ibuf_comp = se->ibuf;
2605                                 IMB_refImBuf(se->ibuf);
2606                         } else {
2607                                 se->ibuf_comp = IMB_allocImBuf(
2608                                         (short)seqrectx, (short)seqrecty, 
2609                                         32, IB_rect, 0);
2610                                 IMB_cache_limiter_insert(se->ibuf_comp);
2611                                 IMB_cache_limiter_ref(se->ibuf_comp);
2612                                 IMB_cache_limiter_touch(se->ibuf_comp);
2613                         }
2614                         break;
2615                 }
2616
2617                 early_out = seq_get_early_out_for_blend_mode(seq);
2618
2619                 switch (early_out) {
2620                 case -1:
2621                 case 2:
2622                         do_build_seq_recursively(
2623                                 scene, seq, cfra, render_size,
2624                                 seqrectx, seqrecty);
2625
2626                         if (se->ibuf) {
2627                                 se->ibuf_comp = se->ibuf;
2628                                 IMB_refImBuf(se->ibuf_comp);
2629                         } else {
2630                                 se->ibuf_comp = IMB_allocImBuf(
2631                                         (short)seqrectx, (short)seqrecty, 
2632                                         32, IB_rect, 0);
2633                                 IMB_cache_limiter_insert(se->ibuf_comp);
2634                                 IMB_cache_limiter_ref(se->ibuf_comp);
2635                                 IMB_cache_limiter_touch(se->ibuf_comp);
2636                         }
2637                         break;
2638                 case 1:
2639                         if (i == 0) {
2640                                 se->ibuf_comp = IMB_allocImBuf(
2641                                         (short)seqrectx, (short)seqrecty, 
2642                                         32, IB_rect, 0);
2643                                 IMB_cache_limiter_insert(se->ibuf_comp);
2644                                 IMB_cache_limiter_ref(se->ibuf_comp);
2645                                 IMB_cache_limiter_touch(se->ibuf_comp);
2646                         }
2647                         break;
2648                 case 0:
2649                         do_build_seq_recursively(
2650                                 scene, seq, cfra, render_size,
2651                                 seqrectx, seqrecty);
2652
2653                         if (!se->ibuf) {
2654                                 se->ibuf = IMB_allocImBuf(
2655                                         (short)seqrectx, (short)seqrecty, 
2656                                         32, IB_rect, 0);
2657                                 IMB_cache_limiter_insert(se->ibuf);
2658                                 IMB_cache_limiter_ref(se->ibuf);
2659                                 IMB_cache_limiter_touch(se->ibuf);
2660                         }
2661                         if (i == 0) {
2662                                 se->ibuf_comp = se->ibuf;
2663                                 IMB_refImBuf(se->ibuf_comp);
2664                         }
2665                         break;
2666                 }
2667         
2668                 if (se->ibuf_comp) {
2669                         break;
2670                 }
2671         }
2672
2673         i++;
2674
2675         for (; i < count; i++) {
2676                 Sequence * seq = seq_arr[i];
2677                 struct SeqEffectHandle sh = get_sequence_blend(seq);
2678                 TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
2679                 TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
2680
2681                 float facf = seq->blend_opacity / 100.0;
2682                 int swap_input = seq_must_swap_input_in_blend_mode(seq);
2683                 int early_out = seq_get_early_out_for_blend_mode(seq);
2684
2685                 switch (early_out) {
2686                 case 0: {
2687                         int x= se2->ibuf->x;
2688                         int y= se2->ibuf->y;
2689
2690                         if(se1->ibuf_comp == NULL)
2691                                 continue;
2692
2693                         if (se1->ibuf_comp->rect_float ||
2694                                 se2->ibuf->rect_float) {
2695                                 se2->ibuf_comp = IMB_allocImBuf(
2696                                         (short)seqrectx, (short)seqrecty, 
2697                                         32, IB_rectfloat, 0);
2698                         } else {
2699                                 se2->ibuf_comp = IMB_allocImBuf(
2700                                         (short)seqrectx, (short)seqrecty, 
2701                                         32, IB_rect, 0);
2702                         }
2703
2704
2705                         if (!se1->ibuf_comp->rect_float && 
2706                                 se2->ibuf_comp->rect_float) {
2707                                 IMB_float_from_rect_simple(se1->ibuf_comp);
2708                         }
2709                         if (!se2->ibuf->rect_float && 
2710                                 se2->ibuf_comp->rect_float) {
2711                                 IMB_float_from_rect_simple(se2->ibuf);
2712                         }
2713
2714                         if (!se1->ibuf_comp->rect && 
2715                                 !se2->ibuf_comp->rect_float) {
2716                                 IMB_rect_from_float(se1->ibuf_comp);
2717                         }
2718                         if (!se2->ibuf->rect && 
2719                                 !se2->ibuf_comp->rect_float) {
2720                                 IMB_rect_from_float(se2->ibuf);
2721                         }
2722                         
2723                         if (swap_input) {
2724                                 sh.execute(scene, seq, cfra, 
2725                                            facf, facf, x, y, render_size,
2726                                            se2->ibuf, se1->ibuf_comp, 0,
2727                                            se2->ibuf_comp);
2728                         } else {
2729                                 sh.execute(scene, seq, cfra, 
2730                                            facf, facf, x, y, render_size,
2731                                            se1->ibuf_comp, se2->ibuf, 0,
2732                                            se2->ibuf_comp);
2733                         }
2734                         
2735                         IMB_cache_limiter_insert(se2->ibuf_comp);
2736                         IMB_cache_limiter_ref(se2->ibuf_comp);
2737                         IMB_cache_limiter_touch(se2->ibuf_comp);
2738
2739                         IMB_cache_limiter_unref(se1->ibuf_comp);
2740                         IMB_cache_limiter_unref(se2->ibuf);
2741
2742                         break;
2743                 }
2744                 case 1: {
2745                         se2->ibuf_comp = se1->ibuf_comp;
2746                         if(se2->ibuf_comp)
2747                                 IMB_refImBuf(se2->ibuf_comp);
2748
2749                         break;
2750                 }
2751                 }
2752                 se = se2;
2753         }
2754
2755         return se;
2756 }
2757
2758 /*
2759  * returned ImBuf is refed!
2760  * you have to unref after usage!
2761  */
2762
2763 static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2764 {
2765         Editing *ed= seq_give_editing(scene, FALSE);
2766         int count;
2767         ListBase *seqbasep;
2768         TStripElem *se;
2769
2770         
2771         if(ed==NULL) return NULL;
2772
2773         count = BLI_countlist(&ed->metastack);
2774         if((chanshown < 0) && (count > 0)) {
2775                 count = MAX2(count + chanshown, 0);
2776                 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2777         } else {
2778                 seqbasep= ed->seqbasep;
2779         }
2780
2781         se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size, rectx, recty);
2782
2783         if(!se) { 
2784                 return 0;
2785         }
2786
2787         check_limiter_refcount_comp("give_ibuf_seq_impl", se);
2788
2789         return se->ibuf_comp;
2790 }
2791
2792 ImBuf *give_ibuf_seqbase(struct Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size, ListBase *seqbasep)
2793 {
2794         TStripElem *se;
2795
2796         se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size, rectx, recty);
2797
2798         if(!se) { 
2799                 return 0;
2800         }
2801
2802         check_limiter_refcount_comp("give_ibuf_seqbase", se);
2803
2804         if (se->ibuf_comp) {
2805                 IMB_cache_limiter_unref(se->ibuf_comp);
2806         }
2807
2808         return se->ibuf_comp;
2809 }
2810
2811
2812 ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
2813 {
2814         TStripElem* se;
2815
2816         se = do_build_seq_recursively(scene, seq, cfra, render_size, rectx, recty);
2817
2818         if(!se) { 
2819                 return 0;
2820         }
2821
2822         check_limiter_refcount("give_ibuf_seq_direct", se);
2823
2824         if (se->ibuf) {
2825                 IMB_cache_limiter_unref(se->ibuf);
2826         }
2827
2828         return se->ibuf;
2829 }
2830
2831 ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2832 {
2833         ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size);
2834
2835         if (i) {
2836                 IMB_cache_limiter_unref(i);
2837         }
2838         return i;
2839 }
2840
2841 #if 0
2842 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2843 static int seq_can_blend(Sequence *seq)
2844 {
2845         if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2846                 return 1;
2847         } else {
2848                 return 0;
2849         }
2850 }
2851 #endif
2852
2853 /* *********************** threading api ******************* */
2854
2855 static ListBase running_threads;
2856 static ListBase prefetch_wait;
2857 static ListBase prefetch_done;
2858
2859 static pthread_mutex_t queue_lock          = PTHREAD_MUTEX_INITIALIZER;
2860 static pthread_mutex_t wakeup_lock         = PTHREAD_MUTEX_INITIALIZER;
2861 static pthread_cond_t  wakeup_cond         = PTHREAD_COND_INITIALIZER;
2862
2863 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2864 //static pthread_cond_t  prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2865
2866 static pthread_mutex_t frame_done_lock     = PTHREAD_MUTEX_INITIALIZER;
2867 static pthread_cond_t  frame_done_cond     = PTHREAD_COND_INITIALIZER;
2868
2869 static volatile int seq_thread_shutdown = TRUE; 
2870 static volatile int seq_last_given_monoton_cfra = 0;
2871 static int monoton_cfra = 0;
2872
2873 typedef struct PrefetchThread {
2874         struct PrefetchThread *next, *prev;
2875         
2876         Scene *scene;
2877         struct PrefetchQueueElem *current;
2878         pthread_t pthread;
2879         int running;
2880         
2881 } PrefetchThread;
2882
2883 typedef struct PrefetchQueueElem {
2884         struct PrefetchQueueElem *next, *prev;
2885         
2886         int rectx;
2887         int recty;
2888         int cfra;
2889         int chanshown;
2890         int render_size;
2891
2892         int monoton_cfra;
2893
2894         struct ImBuf * ibuf;
2895 } PrefetchQueueElem;
2896
2897 #if 0
2898 static void *seq_prefetch_thread(void * This_)
2899 {
2900         PrefetchThread * This = This_;
2901
2902         while (!seq_thread_shutdown) {
2903                 PrefetchQueueElem *e;
2904                 int s_last;
2905
2906                 pthread_mutex_lock(&queue_lock);
2907                 e = prefetch_wait.first;
2908                 if (e) {
2909                         BLI_remlink(&prefetch_wait, e);
2910                 }
2911                 s_last = seq_last_given_monoton_cfra;
2912
2913                 This->current = e;
2914
2915                 pthread_mutex_unlock(&queue_lock);
2916
2917                 if (!e) {
2918                         pthread_mutex_lock(&prefetch_ready_lock);
2919
2920                         This->running = FALSE;
2921
2922                         pthread_cond_signal(&prefetch_ready_cond);
2923                         pthread_mutex_unlock(&prefetch_ready_lock);
2924
2925                         pthread_mutex_lock(&wakeup_lock);
2926                         if (!seq_thread_shutdown) {
2927                                 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2928                         }
2929                         pthread_mutex_unlock(&wakeup_lock);
2930                         continue;
2931                 }
2932
2933                 This->running = TRUE;
2934                 
2935                 if (e->cfra >= s_last) { 
2936                         e->ibuf = give_ibuf_seq_impl(This->scene, 
2937                                 e->rectx, e->recty, e->cfra, e->chanshown,
2938                                 e->render_size);
2939                 }
2940
2941                 pthread_mutex_lock(&queue_lock);
2942
2943                 BLI_addtail(&prefetch_done, e);
2944
2945                 for (e = prefetch_wait.first; e; e = e->next) {
2946                         if (s_last > e->monoton_cfra) {
2947                                 BLI_remlink(&prefetch_wait, e);
2948                                 MEM_freeN(e);
2949                         }
2950                 }
2951
2952                 for (e = prefetch_done.first; e; e = e->next) {
2953                         if (s_last > e->monoton_cfra) {
2954                                 if (e->ibuf) {
2955                                         IMB_cache_limiter_unref(e->ibuf);
2956                                 }
2957                                 BLI_remlink(&prefetch_done, e);
2958                                 MEM_freeN(e);
2959                         }
2960                 }
2961
2962                 pthread_mutex_unlock(&queue_lock);
2963
2964                 pthread_mutex_lock(&frame_done_lock);
2965                 pthread_cond_signal(&frame_done_cond);
2966                 pthread_mutex_unlock(&frame_done_lock);
2967         }
2968         return 0;
2969 }
2970
2971 static void seq_start_threads(Scene *scene)
2972 {
2973         int i;
2974
2975         running_threads.first = running_threads.last = NULL;
2976         prefetch_wait.first = prefetch_wait.last = NULL;
2977         prefetch_done.first = prefetch_done.last = NULL;
2978
2979         seq_thread_shutdown = FALSE;
2980         seq_last_given_monoton_cfra = monoton_cfra = 0;
2981
2982         /* since global structures are modified during the processing
2983            of one frame, only one render thread is currently possible... 
2984
2985            (but we code, in the hope, that we can remove this restriction
2986            soon...)
2987         */
2988
2989         fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2990
2991         for (i = 0; i < 1; i++) {
2992                 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
2993                 t->scene= scene;
2994                 t->running = TRUE;
2995                 BLI_addtail(&running_threads, t);
2996
2997                 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2998         }
2999
3000         /* init malloc mutex */
3001         BLI_init_threads(0, 0, 0);
3002 }
3003
3004 static void seq_stop_threads()
3005 {
3006         PrefetchThread *tslot;
3007         PrefetchQueueElem *e;
3008
3009         fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
3010
3011         if (seq_thread_shutdown) {
3012                 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
3013                 return;
3014         }
3015         
3016         pthread_mutex_lock(&wakeup_lock);
3017
3018         seq_thread_shutdown = TRUE;
3019
3020                 pthread_cond_broadcast(&wakeup_cond);
3021                 pthread_mutex_unlock(&wakeup_lock);
3022
3023         for(tslot = running_threads.first; tslot; tslot= tslot->next) {
3024                 pthread_join(tslot->pthread, NULL);
3025         }
3026
3027
3028         for (e = prefetch_wait.first; e; e = e->next) {
3029                 BLI_remlink(&prefetch_wait, e);
3030                 MEM_freeN(e);
3031         }
3032
3033         for (e = prefetch_done.first; e; e = e->next) {
3034                 if (e->ibuf) {
3035                         IMB_cache_limiter_unref(e->ibuf);
3036                 }
3037                 BLI_remlink(&prefetch_done, e);
3038                 MEM_freeN(e);
3039         }
3040
3041         BLI_freelistN(&running_threads);
3042
3043         /* deinit malloc mutex */
3044         BLI_end_threads(0);
3045 }
3046 #endif
3047
3048 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
3049                                 int render_size)
3050 {
3051         PrefetchQueueElem *e;
3052         if (seq_thread_shutdown) {
3053                 return;
3054         }
3055
3056         e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
3057         e->rectx = rectx;
3058         e->recty = recty;
3059         e->cfra = cfra;
3060         e->chanshown = chanshown;
3061         e->render_size = render_size;
3062         e->monoton_cfra = monoton_cfra++;
3063
3064         pthread_mutex_lock(&queue_lock);
3065         BLI_addtail(&prefetch_wait, e);
3066         pthread_mutex_unlock(&queue_lock);
3067         
3068         pthread_mutex_lock(&wakeup_lock);
3069         pthread_cond_signal(&wakeup_cond);
3070         pthread_mutex_unlock(&wakeup_lock);
3071 }
3072
3073 #if 0
3074 static void seq_wait_for_prefetch_ready()
3075 {
3076         PrefetchThread *tslot;
3077
3078         if (seq_thread_shutdown) {
3079                 return;
3080         }
3081
3082         fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
3083
3084         pthread_mutex_lock(&prefetch_ready_lock);
3085
3086         for(;;) {
3087                 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
3088                         if (tslot->running) {
3089                                 break;
3090                         }
3091                 }
3092                 if (!tslot) {
3093                         break;
3094                 }
3095                 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
3096         }
3097
3098         pthread_mutex_unlock(&prefetch_ready_lock);
3099
3100         fprintf(stderr, "SEQ-THREAD: prefetch done\n");
3101 }
3102 #endif
3103
3104 ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
3105 {
3106         PrefetchQueueElem *e = NULL;
3107         int found_something = FALSE;
3108
3109         if (seq_thread_shutdown) {
3110                 return give_ibuf_seq(scene, rectx, recty, cfra, chanshown, render_size);
3111         }
3112
3113         while (!e) {
3114                 int success = FALSE;
3115                 pthread_mutex_lock(&queue_lock);
3116
3117                 for (e = prefetch_done.first; e; e = e->next) {
3118                         if (cfra == e->cfra &&
3119                                 chanshown == e->chanshown &&
3120                                 rectx == e->rectx && 
3121                                 recty == e->recty &&
3122                                 render_size == e->render_size) {
3123                                 success = TRUE;
3124                                 found_something = TRUE;
3125                                 break;
3126                         }
3127                 }
3128
3129                 if (!e) {
3130                         for (e = prefetch_wait.first; e; e = e->next) {
3131                                 if (cfra == e->cfra &&
3132                                         chanshown == e->chanshown &&
3133                                         rectx == e->rectx && 
3134                                         recty == e->recty &&
3135                                         render_size == e->render_size) {
3136                                         found_something = TRUE;
3137                                         break;
3138                                 }
3139                         }
3140                 }
3141
3142                 if (!e) {
3143                         PrefetchThread *tslot;
3144
3145                         for(tslot = running_threads.first; 
3146                                 tslot; tslot= tslot->next) {
3147                                 if (tslot->current &&
3148                                         cfra == tslot->current->cfra &&
3149                                         chanshown == tslot->current->chanshown &&
3150                                         rectx == tslot->current->rectx && 
3151                                         recty == tslot->current->recty &&
3152                                         render_size== tslot->current->render_size){
3153                                         found_something = TRUE;
3154                                         break;
3155                                 }
3156                         }
3157                 }
3158
3159                 /* e->ibuf is unrefed by render thread on next round. */
3160
3161                 if (e) {
3162                         seq_last_given_monoton_cfra = e->monoton_cfra;
3163                 }
3164
3165                 pthread_mutex_unlock(&queue_lock);
3166
3167                 if (!success) {
3168                         e = NULL;
3169
3170                         if (!found_something) {
3171                                 fprintf(stderr, 
3172                                         "SEQ-THREAD: Requested frame "
3173                                         "not in queue ???\n");
3174                                 break;
3175                         }
3176                         pthread_mutex_lock(&frame_done_lock);
3177                         pthread_cond_wait(&frame_done_cond, &frame_done_lock);
3178                         pthread_mutex_unlock(&frame_done_lock);
3179                 }
3180         }
3181         
3182         return e ? e->ibuf : 0;
3183 }
3184
3185 /* Functions to free imbuf and anim data on changes */
3186
3187 static void free_imbuf_strip_elem(TStripElem *se)
3188 {
3189         if(se->ibuf) {
3190                 IMB_freeImBuf(se->ibuf);
3191         }
3192         if(se->ibuf_comp) {
3193                 IMB_freeImBuf(se->ibuf_comp);
3194         }
3195         se->ibuf_comp = 0;
3196         se->ibuf= 0;
3197         se->ok= STRIPELEM_OK;
3198         se->se1= se->se2= se->se3= 0;
3199 }
3200
3201 static void free_anim_seq(Sequence *seq)
3202 {
3203         if(seq->anim) {