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