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