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