== Sequencer ==
[blender.git] / source / blender / blenkernel / intern / sequencer.c
1 /**
2 * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): 
24  * - Blender Foundation, 2003-2009
25  * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <stddef.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <math.h>
34
35 #include "MEM_guardedalloc.h"
36 #include "MEM_CacheLimiterC-Api.h"
37
38 #include "DNA_sequence_types.h"
39 #include "DNA_scene_types.h"
40 #include "DNA_anim_types.h"
41 #include "DNA_object_types.h"
42
43 #include "BKE_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             || (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE)) {
1236                 strcpy(dir, seq->strip->proxy->dir);
1237         } else {
1238                 if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
1239                         snprintf(dir, FILE_MAXDIR, "%s/BL_proxy", 
1240                                  seq->strip->dir);
1241                 } else {
1242                         return FALSE;
1243                 }
1244         }
1245
1246         if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1247                 BLI_join_dirfile(name, dir, seq->strip->proxy->file);
1248                 BLI_path_abs(name, G.sce);
1249
1250                 return TRUE;
1251         }
1252
1253         /* generate a separate proxy directory for each preview size */
1254
1255         if (seq->type == SEQ_IMAGE) {
1256                 StripElem * se = give_stripelem(seq, cfra);
1257                 snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy",
1258                          dir, render_size, se->name);
1259                 frameno = 1;
1260         } else if (seq->type == SEQ_MOVIE) {
1261                 TStripElem * tse = give_tstripelem(seq, cfra);
1262
1263                 frameno = tse->nr + seq->anim_startofs;
1264
1265                 snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir,
1266                          seq->strip->stripdata->name,
1267                          render_size);
1268         } else {
1269                 TStripElem * tse = give_tstripelem(seq, cfra);
1270
1271                 frameno = tse->nr + seq->anim_startofs;
1272
1273                 snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
1274                          render_size);
1275         }
1276
1277         BLI_path_abs(name, G.sce);
1278         BLI_path_frame(name, frameno, 0);
1279
1280
1281         strcat(name, ".jpg");
1282
1283         return TRUE;
1284 }
1285
1286 static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra, int render_size)
1287 {
1288         char name[PROXY_MAXFILE];
1289
1290         if (!(seq->flag & SEQ_USE_PROXY)) {
1291                 return 0;
1292         }
1293
1294         /* rendering at 100% ? No real sense in proxy-ing, right? */
1295         if (render_size == 100) {
1296                 return 0;
1297         }
1298
1299         if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1300                 TStripElem * tse = give_tstripelem(seq, cfra);
1301                 int frameno = tse->nr + seq->anim_startofs;
1302                 if (!seq->strip->proxy->anim) {
1303                         if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1304                                 return 0;
1305                         }
1306  
1307                         seq->strip->proxy->anim = openanim(name, IB_rect);
1308                 }
1309                 if (!seq->strip->proxy->anim) {
1310                         return 0;
1311                 }
1312  
1313                 return IMB_anim_absolute(seq->strip->proxy->anim, frameno);
1314         }
1315  
1316         if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1317                 return 0;
1318         }
1319
1320         if (BLI_exists(name)) {
1321                 return IMB_loadiffname(name, IB_rect);
1322         } else {
1323                 return 0;
1324         }
1325 }
1326
1327 #if 0
1328 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1329                                   int build_proxy_run, int render_size);
1330
1331 static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int render_size)
1332 {
1333         char name[PROXY_MAXFILE];
1334         int quality;
1335         TStripElem * se;
1336         int ok;
1337         int rectx, recty;
1338         struct ImBuf * ibuf;
1339
1340         if (!(seq->flag & SEQ_USE_PROXY)) {
1341                 return;
1342         }
1343
1344         /* rendering at 100% ? No real sense in proxy-ing, right? */
1345         if (render_size == 100) {
1346                 return;
1347         }
1348
1349         /* that's why it is called custom... */
1350         if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1351                 return;
1352         }
1353
1354         if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1355                 return;
1356         }
1357
1358         se = give_tstripelem(seq, cfra);
1359         if (!se) {
1360                 return;
1361         }
1362
1363         if(se->ibuf) {
1364                 IMB_freeImBuf(se->ibuf);
1365                 se->ibuf = 0;
1366         }
1367         
1368         do_build_seq_ibuf(scene, seq, se, cfra, TRUE, render_size);
1369
1370         if (!se->ibuf) {
1371                 return;
1372         }
1373
1374         rectx= (render_size*scene->r.xsch)/100;
1375         recty= (render_size*scene->r.ysch)/100;
1376
1377         ibuf = se->ibuf;
1378
1379         if (ibuf->x != rectx || ibuf->y != recty) {
1380                 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1381         }
1382
1383         /* quality is fixed, otherwise one has to generate separate
1384            directories for every quality...
1385
1386            depth = 32 is intentionally left in, otherwise ALPHA channels
1387            won't work... */
1388         quality = seq->strip->proxy->quality;
1389         ibuf->ftype= JPG | quality;
1390
1391         BLI_make_existing_file(name);
1392         
1393         ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
1394         if (ok == 0) {
1395                 perror(name);
1396         }
1397
1398         IMB_freeImBuf(ibuf);
1399         se->ibuf = 0;
1400 }
1401
1402 static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
1403 {
1404         int cfra;
1405         float rsize = seq->strip->proxy->size;
1406
1407         waitcursor(1);
1408
1409         G.afbreek = 0;
1410
1411         /* flag management tries to account for strobe and 
1412            other "non-linearities", that might come in the future...
1413            better way would be to "touch" the files, so that _really_
1414            no one is rebuild twice.
1415          */
1416
1417         for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
1418                 TStripElem * tse = give_tstripelem(seq, cfra);
1419
1420                 tse->flag &= ~STRIPELEM_PREVIEW_DONE;
1421         }
1422
1423         
1424
1425         /* a _lot_ faster for movie files, if we read frames in
1426            sequential order */
1427         if (seq->flag & SEQ_REVERSE_FRAMES) {
1428                 for (cfra = seq->enddisp-seq->endstill-1; 
1429                          cfra >= seq->startdisp + seq->startstill; cfra--) {
1430                         TStripElem * tse = give_tstripelem(seq, cfra);
1431
1432                         if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1433 //XXX                           set_timecursor(cfra);
1434                                 seq_proxy_build_frame(scene, seq, cfra, rsize);
1435                                 tse->flag |= STRIPELEM_PREVIEW_DONE;
1436                         }
1437                         if (blender_test_break()) {
1438                                 break;
1439                         }
1440                 }
1441         } else {
1442                 for (cfra = seq->startdisp + seq->startstill; 
1443                          cfra < seq->enddisp - seq->endstill; cfra++) {
1444                         TStripElem * tse = give_tstripelem(seq, cfra);
1445
1446                         if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1447 //XXX                           set_timecursor(cfra);
1448                                 seq_proxy_build_frame(scene, seq, cfra, rsize);
1449                                 tse->flag |= STRIPELEM_PREVIEW_DONE;
1450                         }
1451                         if (blender_test_break()) {
1452                                 break;
1453                         }
1454                 }
1455         }
1456         waitcursor(0);
1457 }
1458 #endif
1459
1460
1461 /* **********************************************************************
1462    color balance 
1463    ********************************************************************** */
1464
1465 static StripColorBalance calc_cb(StripColorBalance * cb_)
1466 {
1467         StripColorBalance cb = *cb_;
1468         int c;
1469
1470         if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
1471                 for (c = 0; c < 3; c++) {
1472                         cb.lift[c] = 1.0 - cb.lift[c];
1473                 }
1474         } else {
1475                 for (c = 0; c < 3; c++) {
1476                         cb.lift[c] = -(1.0 - cb.lift[c]);
1477                 }
1478         }
1479         if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
1480                 for (c = 0; c < 3; c++) {
1481                         if (cb.gain[c] != 0.0) {
1482                                 cb.gain[c] = 1.0/cb.gain[c];
1483                         } else {
1484                                 cb.gain[c] = 1000000; /* should be enough :) */
1485                         }
1486                 }
1487         }
1488
1489         if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
1490                 for (c = 0; c < 3; c++) {
1491                         if (cb.gamma[c] != 0.0) {
1492                                 cb.gamma[c] = 1.0/cb.gamma[c];
1493                         } else {
1494                                 cb.gamma[c] = 1000000; /* should be enough :) */
1495                         }
1496                 }
1497         }
1498
1499         return cb;
1500 }
1501
1502 static void make_cb_table_byte(float lift, float gain, float gamma,
1503                                    unsigned char * table, float mul)
1504 {
1505         int y;
1506
1507         for (y = 0; y < 256; y++) {
1508                         float v = 1.0 * y / 255;
1509                 v *= gain;
1510                 v += lift; 
1511                 v = pow(v, gamma);
1512                 v *= mul;
1513                 if ( v > 1.0) {
1514                         v = 1.0;
1515                 } else if (v < 0.0) {
1516                         v = 0.0;
1517                 }
1518                 table[y] = v * 255;
1519         }
1520
1521 }
1522
1523 static void make_cb_table_float(float lift, float gain, float gamma,
1524                                 float * table, float mul)
1525 {
1526         int y;
1527
1528         for (y = 0; y < 256; y++) {
1529                         float v = (float) y * 1.0 / 255.0;
1530                 v *= gain;
1531                 v += lift;
1532                 v = pow(v, gamma);
1533                 v *= mul;
1534                 table[y] = v;
1535         }
1536 }
1537
1538 static void color_balance_byte_byte(Sequence * seq, TStripElem* se, float mul)
1539 {
1540         unsigned char cb_tab[3][256];
1541         int c;
1542         unsigned char * p = (unsigned char*) se->ibuf->rect;
1543         unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1544
1545         StripColorBalance cb = calc_cb(seq->strip->color_balance);
1546
1547         for (c = 0; c < 3; c++) {
1548                 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1549                                    cb_tab[c], mul);
1550         }
1551
1552         while (p < e) {
1553                 p[0] = cb_tab[0][p[0]];
1554                 p[1] = cb_tab[1][p[1]];
1555                 p[2] = cb_tab[2][p[2]];
1556                 
1557                 p += 4;
1558         }
1559 }
1560
1561 static void color_balance_byte_float(Sequence * seq, TStripElem* se, float mul)
1562 {
1563         float cb_tab[4][256];
1564         int c,i;
1565         unsigned char * p = (unsigned char*) se->ibuf->rect;
1566         unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1567         float * o;
1568         StripColorBalance cb;
1569
1570         imb_addrectfloatImBuf(se->ibuf);
1571
1572         o = se->ibuf->rect_float;
1573
1574         cb = calc_cb(seq->strip->color_balance);
1575
1576         for (c = 0; c < 3; c++) {
1577                 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
1578                                         cb_tab[c], mul);
1579         }
1580
1581         for (i = 0; i < 256; i++) {
1582                 cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
1583         }
1584
1585         while (p < e) {
1586                 o[0] = cb_tab[0][p[0]];
1587                 o[1] = cb_tab[1][p[1]];
1588                 o[2] = cb_tab[2][p[2]];
1589                 o[3] = cb_tab[3][p[3]];
1590
1591                 p += 4; o += 4;
1592         }
1593 }
1594
1595 static void color_balance_float_float(Sequence * seq, TStripElem* se, float mul)
1596 {
1597         float * p = se->ibuf->rect_float;
1598         float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y;
1599         StripColorBalance cb = calc_cb(seq->strip->color_balance);
1600
1601         while (p < e) {
1602                 int c;
1603                 for (c = 0; c < 3; c++) {
1604                         p[c] = pow(p[c] * cb.gain[c] + cb.lift[c], 
1605                                    cb.gamma[c]) * mul;
1606                 }
1607                 p += 4;
1608         }
1609 }
1610
1611 static void color_balance(Sequence * seq, TStripElem* se, float mul)
1612 {
1613         if (se->ibuf->rect_float) {
1614                 color_balance_float_float(seq, se, mul);
1615         } else if(seq->flag & SEQ_MAKE_FLOAT) {
1616                 color_balance_byte_float(seq, se, mul);
1617         } else {
1618                 color_balance_byte_byte(seq, se, mul);
1619         }
1620 }
1621
1622 /*
1623   input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
1624
1625   Do all the things you can't really do afterwards using sequence effects
1626   (read: before rescaling to render resolution has been done)
1627
1628   Order is important!
1629
1630   - Deinterlace
1631   - Crop and transform in image source coordinate space
1632   - Flip X + Flip Y (could be done afterwards, backward compatibility)
1633   - Promote image to float data (affects pipeline operations afterwards)
1634   - Color balance (is most efficient in the byte -> float 
1635         (future: half -> float should also work fine!)
1636         case, if done on load, since we can use lookup tables)
1637   - Premultiply
1638
1639 */
1640
1641 static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se, int cfra)
1642 {
1643         float mul;
1644
1645         if ((seq->flag & SEQ_FILTERY) || 
1646                 (seq->flag & SEQ_USE_CROP) ||
1647                 (seq->flag & SEQ_USE_TRANSFORM) ||
1648                 (seq->flag & SEQ_FLIPX) ||
1649                 (seq->flag & SEQ_FLIPY) ||
1650                 (seq->flag & SEQ_USE_COLOR_BALANCE) ||
1651                 (seq->flag & SEQ_MAKE_PREMUL) ||
1652                 (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
1653                 return TRUE;
1654         }
1655
1656         mul = seq->mul;
1657
1658         if(seq->blend_mode == SEQ_BLEND_REPLACE &&
1659            !(seq->type & SEQ_EFFECT)) {
1660                 mul *= seq->blend_opacity / 100.0;
1661         }
1662
1663         if (mul != 1.0) {
1664                 return TRUE;
1665         }
1666                 
1667         return FALSE;
1668 }
1669
1670 static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cfra)
1671 {
1672         float mul;
1673
1674         seq->strip->orx= se->ibuf->x;
1675         seq->strip->ory= se->ibuf->y;
1676
1677         if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
1678                 IMB_filtery(se->ibuf);
1679         }
1680
1681         if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
1682                 StripCrop c;
1683                 StripTransform t;
1684                 int sx,sy,dx,dy;
1685
1686                 memset(&c, 0, sizeof(StripCrop));
1687                 memset(&t, 0, sizeof(StripTransform));
1688
1689                 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1690                         c = *seq->strip->crop;
1691                 }
1692                 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1693                         t = *seq->strip->transform;
1694                 }
1695
1696                 sx = se->ibuf->x - c.left - c.right;
1697                 sy = se->ibuf->y - c.top - c.bottom;
1698                 dx = sx;
1699                 dy = sy;
1700
1701                 if (seq->flag & SEQ_USE_TRANSFORM) {
1702                         dx = scene->r.xsch;
1703                         dy = scene->r.ysch;
1704                 }
1705
1706                 if (c.top + c.bottom >= se->ibuf->y ||
1707                         c.left + c.right >= se->ibuf->x ||
1708                         t.xofs >= dx || t.yofs >= dy) {
1709                         make_black_ibuf(se->ibuf);
1710                 } else {
1711                         ImBuf * i;
1712
1713                         if (se->ibuf->rect_float) {
1714                                 i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0);
1715                         } else {
1716                                 i = IMB_allocImBuf(dx, dy,32, IB_rect, 0);
1717                         }
1718
1719                         IMB_rectcpy(i, se->ibuf, 
1720                                         t.xofs, t.yofs, 
1721                                         c.left, c.bottom, 
1722                                         sx, sy);
1723
1724                         IMB_freeImBuf(se->ibuf);
1725
1726                         se->ibuf = i;
1727                 }
1728         } 
1729
1730         if(seq->flag & SEQ_FLIPX) {
1731                 IMB_flipx(se->ibuf);
1732         }
1733         if(seq->flag & SEQ_FLIPY) {
1734                 IMB_flipy(se->ibuf);
1735         }
1736
1737         if(seq->mul == 0.0) {
1738                 seq->mul = 1.0;
1739         }
1740
1741         mul = seq->mul;
1742
1743         if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1744                 mul *= seq->blend_opacity / 100.0;
1745         }
1746
1747         if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1748                 color_balance(seq, se, mul);
1749                 mul = 1.0;
1750         }
1751
1752         if(seq->flag & SEQ_MAKE_FLOAT) {
1753                 if (!se->ibuf->rect_float) {
1754                         int profile = IB_PROFILE_NONE;
1755                         
1756                         /* no color management:
1757                          * don't disturb the existing profiles */
1758                         SWAP(int, se->ibuf->profile, profile);
1759
1760                         IMB_float_from_rect(se->ibuf);
1761                         
1762                         SWAP(int, se->ibuf->profile, profile);
1763                 }
1764                 if (se->ibuf->rect) {
1765                         imb_freerectImBuf(se->ibuf);
1766                 }
1767         }
1768
1769         if(mul != 1.0) {
1770                 multibuf(se->ibuf, mul);
1771         }
1772
1773         if(seq->flag & SEQ_MAKE_PREMUL) {
1774                 if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
1775                         converttopremul(se->ibuf);
1776                 }
1777         }
1778
1779
1780         if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
1781                 if(scene->r.mode & R_OSA) {
1782                         IMB_scaleImBuf(se->ibuf, 
1783                                            (short)seqrectx, (short)seqrecty);
1784                 } else {
1785                         IMB_scalefastImBuf(se->ibuf, 
1786                                            (short)seqrectx, (short)seqrecty);
1787                 }
1788         }
1789 }
1790
1791 /* test if image too small or discarded from cache: reload */
1792
1793 static void test_and_auto_discard_ibuf(TStripElem * se)
1794 {
1795         if (se->ibuf) {
1796                 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty 
1797                    || !(se->ibuf->rect || se->ibuf->rect_float)) {
1798                         IMB_freeImBuf(se->ibuf);
1799
1800                         se->ibuf= 0;
1801                         se->ok= STRIPELEM_OK;
1802                 }
1803         }
1804         if (se->ibuf_comp) {
1805                 if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty 
1806                    || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) {
1807                         IMB_freeImBuf(se->ibuf_comp);
1808
1809                         se->ibuf_comp = 0;
1810                 }
1811         }
1812 }
1813
1814 static void test_and_auto_discard_ibuf_stills(Strip * strip)
1815 {
1816         if (strip->ibuf_startstill) {
1817                 if (!strip->ibuf_startstill->rect &&
1818                         !strip->ibuf_startstill->rect_float) {
1819                         IMB_freeImBuf(strip->ibuf_startstill);
1820                         strip->ibuf_startstill = 0;
1821                 }
1822         }
1823         if (strip->ibuf_endstill) {
1824                 if (!strip->ibuf_endstill->rect &&
1825                         !strip->ibuf_endstill->rect_float) {
1826                         IMB_freeImBuf(strip->ibuf_endstill);
1827                         strip->ibuf_endstill = 0;
1828                 }
1829         }
1830 }
1831
1832 static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
1833 {
1834         if (!se->ibuf) {
1835                 if (se->nr == 0 && seq->strip->ibuf_startstill) {
1836                         IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1837
1838                         se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
1839                 }
1840                 if (se->nr == seq->len - 1 
1841                         && (seq->len != 1)
1842                         && seq->strip->ibuf_endstill) {
1843                         IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1844
1845                         se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
1846                 }
1847         }
1848 }
1849
1850 static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
1851 {
1852         if (se->ibuf) {
1853                 if (se->nr == 0) {
1854                         seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
1855
1856                         IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
1857                         IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1858                 }
1859                 if (se->nr == seq->len - 1 && seq->len != 1) {
1860                         seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
1861
1862                         IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
1863                         IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1864                 }
1865         }
1866 }
1867
1868 static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown)
1869 {
1870         Sequence* seq_arr[MAXSEQ+1];
1871         int i;
1872         TStripElem* se = 0;
1873
1874         evaluate_seq_frame_gen(seq_arr, seqbasep, cfra);
1875
1876         for (i = 0; i < MAXSEQ; i++) {
1877                 if (!video_seq_is_rendered(seq_arr[i])) {
1878                         continue;
1879                 }
1880                 se = give_tstripelem(seq_arr[i], cfra);
1881                 if (se) {
1882                         if (se->ibuf) {
1883                                 IMB_freeImBuf(se->ibuf);
1884
1885                                 se->ibuf= 0;
1886                                 se->ok= STRIPELEM_OK;
1887                         }
1888
1889                         if (se->ibuf_comp) {
1890                                 IMB_freeImBuf(se->ibuf_comp);
1891
1892                                 se->ibuf_comp = 0;
1893                         }
1894                 }
1895         }
1896         
1897 }
1898
1899 static void check_limiter_refcount(const char * func, TStripElem *se)
1900 {
1901         if (se && se->ibuf) {
1902                 int refcount = IMB_cache_limiter_get_refcount(se->ibuf);
1903                 if (refcount != 1) {
1904                         /* can happen on complex pipelines */
1905                         if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1906                                 return;
1907                         }
1908  
1909                         fprintf(stderr, 
1910                                 "sequencer: (ibuf) %s: "
1911                                 "suspicious memcache "
1912                                 "limiter refcount: %d\n", func, refcount);
1913                 }
1914         }
1915 }
1916  
1917 static void check_limiter_refcount_comp(const char * func, TStripElem *se)
1918 {
1919         if (se && se->ibuf_comp) {
1920                 int refcount = IMB_cache_limiter_get_refcount(se->ibuf_comp);
1921                 if (refcount != 1) {
1922                         /* can happen on complex pipelines */
1923                         if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1924                                 return;
1925                         }
1926                         fprintf(stderr, 
1927                                 "sequencer: (ibuf comp) %s: "
1928                                 "suspicious memcache "
1929                                 "limiter refcount: %d\n", func, refcount);
1930                 }
1931         }
1932 }
1933
1934 static TStripElem* do_build_seq_array_recursively(Scene *scene,
1935                                 ListBase *seqbasep, int cfra, int chanshown, int render_size);
1936
1937 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1938                                   int build_proxy_run, int render_size)
1939 {
1940         char name[FILE_MAXDIR+FILE_MAXFILE];
1941         int use_limiter = TRUE;
1942
1943         test_and_auto_discard_ibuf(se);
1944         test_and_auto_discard_ibuf_stills(seq->strip);
1945
1946         if(seq->type == SEQ_META) {
1947                 TStripElem * meta_se = 0;
1948                 int use_preprocess = FALSE;
1949                 use_limiter = FALSE;
1950
1951                 if (!build_proxy_run && se->ibuf == 0) {
1952                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1953                         if (se->ibuf) {
1954                                 use_limiter = TRUE;
1955                                 use_preprocess = TRUE;
1956                         }
1957                 }
1958
1959                 if(!se->ibuf && seq->seqbase.first) {
1960                         meta_se = do_build_seq_array_recursively(scene,
1961                                 &seq->seqbase, seq->start + se->nr, 0,
1962                                 render_size);
1963
1964                         check_limiter_refcount("do_build_seq_ibuf: for META", meta_se);
1965                 }
1966
1967                 se->ok = STRIPELEM_OK;
1968
1969                 if(!se->ibuf && meta_se) {
1970                         se->ibuf = meta_se->ibuf_comp;
1971                         if(se->ibuf &&
1972                            (!input_have_to_preprocess(scene, seq, se, cfra) ||
1973                                 build_proxy_run)) {
1974                                 IMB_refImBuf(se->ibuf);
1975                                 if (build_proxy_run) {
1976                                         IMB_cache_limiter_unref(se->ibuf);
1977                                 }
1978                         } else if (se->ibuf) {
1979                                 struct ImBuf * i = IMB_dupImBuf(se->ibuf);
1980
1981                                 IMB_cache_limiter_unref(se->ibuf);
1982
1983                                 se->ibuf = i;
1984
1985                                 use_limiter = TRUE;
1986                                 use_preprocess = TRUE;
1987                         }
1988                 } else if (se->ibuf) {
1989                         use_limiter = TRUE;
1990                 }
1991                 if (meta_se) {
1992                         free_metastrip_imbufs(
1993                                 &seq->seqbase, seq->start + se->nr, 0);
1994                 }
1995
1996                 if (use_preprocess) {
1997                         input_preprocess(scene, seq, se, cfra);
1998                 }
1999         } else if(seq->type & SEQ_EFFECT) {
2000                 int use_preprocess = FALSE;
2001                 /* should the effect be recalculated? */
2002                 
2003                 if (!build_proxy_run && se->ibuf == 0) {
2004                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2005                         if (se->ibuf) {
2006                                 use_preprocess = TRUE;
2007                         }
2008                 }
2009
2010                 if(se->ibuf == 0) {
2011                         /* if any inputs are rectfloat, output is float too */
2012                         if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
2013                            (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float) ||
2014                            (se->se3 && se->se3->ibuf && se->se3->ibuf->rect_float))
2015                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2016                         else
2017                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2018                         
2019                         do_effect(scene, cfra, seq, se);
2020                         if (input_have_to_preprocess(scene, seq, se, cfra) &&
2021                                 !build_proxy_run) {
2022                                 if ((se->se1 && (se->ibuf == se->se1->ibuf)) ||
2023                                         (se->se2 && (se->ibuf == se->se2->ibuf))) {
2024                                         struct ImBuf * i
2025                                                 = IMB_dupImBuf(se->ibuf);
2026
2027                                         IMB_freeImBuf(se->ibuf);
2028
2029                                         se->ibuf = i;
2030                                 }
2031                                 use_preprocess = TRUE;
2032                         }
2033                 }
2034                 if (use_preprocess) {
2035                         input_preprocess(scene, seq, se, cfra);
2036                 }
2037         } else if(seq->type == SEQ_IMAGE) {
2038                 if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
2039                         StripElem * s_elem = give_stripelem(seq, cfra);
2040                         BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
2041                         BLI_path_abs(name, G.sce);
2042                         if (!build_proxy_run) {
2043                                 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2044                         }
2045                         copy_from_ibuf_still(seq, se);
2046
2047                         if (!se->ibuf) {
2048                                 se->ibuf= IMB_loadiffname(
2049                                         name, IB_rect);
2050                                 /* we don't need both (speed reasons)! */
2051                                 if (se->ibuf &&
2052                                         se->ibuf->rect_float && se->ibuf->rect) {
2053                                         imb_freerectImBuf(se->ibuf);
2054                                 }
2055
2056                                 copy_to_ibuf_still(seq, se);
2057                         }
2058                         
2059                         if(se->ibuf == 0) {
2060                                 se->ok = STRIPELEM_FAILED;
2061                         } else if (!build_proxy_run) {
2062                                 input_preprocess(scene, seq, se, cfra);
2063                         }
2064                 }
2065         } else if(seq->type == SEQ_MOVIE) {
2066                 if(se->ok == STRIPELEM_OK && se->ibuf==0) {
2067                         if(!build_proxy_run) {
2068                                 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2069                         }
2070                         copy_from_ibuf_still(seq, se);
2071
2072                         if (se->ibuf == 0) {
2073                                 if(seq->anim==0) {
2074                                         BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
2075                                         BLI_path_abs(name, G.sce);
2076                                         
2077                                         seq->anim = openanim(
2078                                                 name, IB_rect | 
2079                                                 ((seq->flag & SEQ_FILTERY) 
2080                                                  ? IB_animdeinterlace : 0));
2081                                 }
2082                                 if(seq->anim) {
2083                                         IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
2084                                         se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
2085                                         /* we don't need both (speed reasons)! */
2086                                         if (se->ibuf 
2087                                                 && se->ibuf->rect_float 
2088                                                 && se->ibuf->rect) {
2089                                                 imb_freerectImBuf(se->ibuf);
2090                                         }
2091
2092                                 }
2093                                 copy_to_ibuf_still(seq, se);
2094                         }
2095                         
2096                         if(se->ibuf == 0) {
2097                                 se->ok = STRIPELEM_FAILED;
2098                         } else if (!build_proxy_run) {
2099                                 input_preprocess(scene, seq, se, cfra);
2100                         }
2101                 }
2102         } else if(seq->type == SEQ_SCENE) {     // scene can be NULL after deletions
2103                 Scene *sce= seq->scene;// *oldsce= scene;
2104                 int have_seq= FALSE;
2105                 int sce_valid= FALSE;
2106
2107                 if(sce) {
2108                         have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first;
2109                         sce_valid= (sce->camera || have_seq);
2110                 }
2111
2112                 if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
2113                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2114                         if (se->ibuf) {
2115                                 input_preprocess(scene, seq, se, cfra);
2116                         }
2117                 }
2118
2119                 if (se->ibuf == NULL && sce_valid) {
2120                         copy_from_ibuf_still(seq, se);
2121                         if (se->ibuf) {
2122                                 input_preprocess(scene, seq, se, cfra);
2123                         }
2124                 }
2125                 
2126                 if (!sce_valid) {
2127                         se->ok = STRIPELEM_FAILED;
2128                 }
2129                 else if (se->ibuf==NULL && sce_valid) {
2130                         int frame= seq->sfra + se->nr + seq->anim_startofs;
2131                         int oldcfra = seq->scene->r.cfra;
2132                         Object *oldcamera= seq->scene->camera;
2133                         ListBase oldmarkers;
2134
2135                         /* Hack! This function can be called from do_render_seq(), in that case
2136                            the seq->scene can already have a Render initialized with same name,
2137                            so we have to use a default name. (compositor uses scene name to
2138                            find render).
2139                            However, when called from within the UI (image preview in sequencer)
2140                            we do want to use scene Render, that way the render result is defined
2141                            for display in render/imagewindow
2142
2143                            Hmm, don't see, why we can't do that all the time,
2144                            and since G.rendering is uhm, gone... (Peter)
2145                         */
2146
2147                         int rendering = 1;
2148                         int doseq;
2149                         int doseq_gl= G.rendering ? (scene->r.seq_flag & R_SEQ_GL_REND) : (scene->r.seq_flag & R_SEQ_GL_PREV);
2150
2151                         /* prevent eternal loop */
2152                         doseq= scene->r.scemode & R_DOSEQ;
2153                         scene->r.scemode &= ~R_DOSEQ;
2154
2155                         seq->scene->r.cfra= frame;
2156                         if(seq->scene_camera)   seq->scene->camera= seq->scene_camera;
2157                         else                                    scene_camera_switch_update(seq->scene);
2158
2159 #ifdef DURIAN_CAMERA_SWITCH
2160                         /* stooping to new low's in hackyness :( */
2161                         oldmarkers= seq->scene->markers;
2162                         seq->scene->markers.first= seq->scene->markers.last= NULL;
2163 #endif
2164
2165                         if(sequencer_view3d_cb && doseq_gl && (seq->scene == scene || have_seq==0)) {
2166                                 /* opengl offscreen render */
2167                                 scene_update_for_newframe(seq->scene, seq->scene->lay);
2168                                 se->ibuf= sequencer_view3d_cb(seq->scene, seqrectx, seqrecty, scene->r.seq_prev_type);
2169                         }
2170                         else {
2171                                 Render *re;
2172                                 RenderResult rres;
2173
2174                                 if(rendering)
2175                                         re= RE_NewRender(" do_build_seq_ibuf");
2176                                 else
2177                                         re= RE_NewRender(sce->id.name);
2178
2179                                 RE_BlenderFrame(re, sce, NULL, sce->lay, frame);
2180
2181                                 RE_AcquireResultImage(re, &rres);
2182
2183                                 if(rres.rectf) {
2184                                         se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
2185                                         memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
2186                                         if(rres.rectz) {
2187                                                 addzbuffloatImBuf(se->ibuf);
2188                                                 memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
2189                                         }
2190                                 } else if (rres.rect32) {
2191                                         se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
2192                                         memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
2193                                 }
2194
2195                                 RE_ReleaseResultImage(re);
2196
2197                                 // BIF_end_render_callbacks();
2198                         }
2199                         
2200                         /* restore */
2201                         scene->r.scemode |= doseq;
2202
2203                         seq->scene->r.cfra = oldcfra;
2204                         seq->scene->camera= oldcamera;
2205
2206 #ifdef DURIAN_CAMERA_SWITCH
2207                         /* stooping to new low's in hackyness :( */
2208                         seq->scene->markers= oldmarkers;
2209 #endif
2210
2211                         copy_to_ibuf_still(seq, se);
2212
2213                         if (!build_proxy_run) {
2214                                 if(se->ibuf == NULL) {
2215                                         se->ok = STRIPELEM_FAILED;
2216                                 } else {
2217                                         input_preprocess(scene, seq, se, cfra);
2218                                 }
2219                         }
2220
2221                 }
2222         }
2223         if (!build_proxy_run) {
2224                 if (se->ibuf && use_limiter) {
2225                         IMB_cache_limiter_insert(se->ibuf);
2226                         IMB_cache_limiter_ref(se->ibuf);
2227                         IMB_cache_limiter_touch(se->ibuf);
2228                 }
2229         }
2230 }
2231
2232 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size);
2233
2234 static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size)
2235 {
2236         float fac, facf;
2237         struct SeqEffectHandle sh = get_sequence_effect(seq);
2238         int early_out;
2239         FCurve *fcu= NULL;
2240
2241         se->se1 = 0;
2242         se->se2 = 0;
2243         se->se3 = 0;
2244
2245         if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
2246                 sh.get_default_fac(seq, cfra, &fac, &facf);
2247                 if( scene->r.mode & R_FIELDS ); else facf= fac;
2248         } else {
2249                 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, 
2250                                           "effect_fader", 0);
2251                 if (fcu) {
2252                         fac = facf = evaluate_fcurve(fcu, cfra);
2253                         if( scene->r.mode & R_FIELDS ) {
2254                                 facf = evaluate_fcurve(fcu, cfra + 0.5);
2255                         }
2256                 } else {
2257                         fac = facf = seq->effect_fader;
2258                 }
2259         }
2260
2261         early_out = sh.early_out(seq, fac, facf);
2262         switch (early_out) {
2263         case -1:
2264                 /* no input needed */
2265                 break;
2266         case 0:
2267                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2268                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2269                 if (seq->seq3) {
2270                         se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size);
2271                 }
2272                 break;
2273         case 1:
2274                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2275                 break;
2276         case 2:
2277                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2278                 break;
2279         }
2280
2281
2282         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2283
2284         /* children are not needed anymore ... */
2285
2286         if (se->se1 && se->se1->ibuf) {
2287                 IMB_cache_limiter_unref(se->se1->ibuf);
2288         }
2289         if (se->se2 && se->se2->ibuf) {
2290                 IMB_cache_limiter_unref(se->se2->ibuf);
2291         }
2292         if (se->se3 && se->se3->ibuf) {
2293                 IMB_cache_limiter_unref(se->se3->ibuf);
2294         }
2295         check_limiter_refcount("do_effect_seq_recursively", se);
2296 }
2297
2298 static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size)
2299 {
2300         TStripElem *se;
2301
2302         se = give_tstripelem(seq, cfra);
2303
2304         if(se) {
2305                 if (seq->type & SEQ_EFFECT) {
2306                         do_effect_seq_recursively(scene, seq, se, cfra, render_size);
2307                 } else {
2308                         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2309                 }
2310         }
2311         return se;
2312 }
2313
2314 /* FIXME:
2315    
2316 If cfra was float throughout blender (especially in the render
2317 pipeline) one could even _render_ with subframe precision
2318 instead of faking using the blend code below...
2319
2320 */
2321
2322 static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size)
2323 {
2324         SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
2325         int nr = cfra - seq->start;
2326         float f_cfra;
2327         int cfra_left;
2328         int cfra_right;
2329         TStripElem * se = 0;
2330         TStripElem * se1 = 0;
2331         TStripElem * se2 = 0;
2332         
2333         sequence_effect_speed_rebuild_map(scene, seq, 0);
2334         
2335         f_cfra = seq->start + s->frameMap[nr];
2336         
2337         cfra_left = (int) floor(f_cfra);
2338         cfra_right = (int) ceil(f_cfra);
2339
2340         se = give_tstripelem(seq, cfra);
2341
2342         if (!se) {
2343                 return se;
2344         }
2345
2346         if (cfra_left == cfra_right || 
2347                 (s->flags & SEQ_SPEED_BLEND) == 0) {
2348                 test_and_auto_discard_ibuf(se);
2349
2350                 if (se->ibuf == NULL) {
2351                         se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2352
2353                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2354                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2355                         else
2356                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2357
2358                         if (se1 == 0 || se1->ibuf == 0) {
2359                                 make_black_ibuf(se->ibuf);
2360                         } else {
2361                                 if (se->ibuf != se1->ibuf) {
2362                                         if (se->ibuf) {
2363                                                 IMB_freeImBuf(se->ibuf);
2364                                         }
2365
2366                                         se->ibuf = se1->ibuf;
2367                                         IMB_refImBuf(se->ibuf);
2368                                 }
2369                         }
2370                 }
2371         } else {
2372                 struct SeqEffectHandle sh;
2373
2374                 if(se->ibuf) {
2375                         if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty 
2376                            || !(se->ibuf->rect || se->ibuf->rect_float)) {
2377                                 IMB_freeImBuf(se->ibuf);
2378                                 se->ibuf= 0;
2379                         }
2380                 }
2381
2382                 if (se->ibuf == NULL) {
2383                         se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2384                         se2 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_right, render_size);
2385
2386                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2387                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2388                         else
2389                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2390                         
2391                         if (!se1 || !se2) {
2392                                 make_black_ibuf(se->ibuf);
2393                         } else {
2394                                 sh = get_sequence_effect(seq);
2395
2396                                 sh.execute(scene, seq, cfra, 
2397                                            f_cfra - (float) cfra_left, 
2398                                            f_cfra - (float) cfra_left, 
2399                                            se->ibuf->x, se->ibuf->y, 
2400                                            se1->ibuf, se2->ibuf, 0, se->ibuf);
2401                         }
2402                 }
2403
2404         }
2405
2406         /* caller expects this to be referenced, so do it! */
2407         if (se->ibuf) {
2408                 IMB_cache_limiter_insert(se->ibuf);
2409                 IMB_cache_limiter_ref(se->ibuf);
2410                 IMB_cache_limiter_touch(se->ibuf);
2411         }
2412
2413         /* children are no longer needed */
2414         if (se1 && se1->ibuf)
2415                 IMB_cache_limiter_unref(se1->ibuf);
2416         if (se2 && se2->ibuf)
2417                 IMB_cache_limiter_unref(se2->ibuf);
2418
2419         check_limiter_refcount("do_handle_speed_effect", se);
2420
2421         return se;
2422 }
2423
2424 /* 
2425  * build all ibufs recursively
2426  * 
2427  * if successfull, the returned TStripElem contains the (referenced!) imbuf
2428  * that means: you _must_ call 
2429  *
2430  * IMB_cache_limiter_unref(rval);
2431  * 
2432  * if rval != 0
2433  * 
2434  */
2435
2436 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size)
2437 {
2438         TStripElem *se;
2439         if (seq->type == SEQ_SPEED) {
2440                 se = do_handle_speed_effect(scene, seq, cfra, render_size);
2441         } else {
2442                 se = do_build_seq_recursively_impl(scene, seq, cfra, render_size);
2443         }
2444
2445         check_limiter_refcount("do_build_seq_recursively", se);
2446
2447         return se;
2448 }
2449
2450 static int seq_must_swap_input_in_blend_mode(Sequence * seq)
2451 {
2452         int swap_input = FALSE;
2453
2454         /* bad hack, to fix crazy input ordering of 
2455            those two effects */
2456
2457         if (seq->blend_mode == SEQ_ALPHAOVER ||
2458                 seq->blend_mode == SEQ_ALPHAUNDER ||
2459                 seq->blend_mode == SEQ_OVERDROP) {
2460                 swap_input = TRUE;
2461         }
2462         
2463         return swap_input;
2464 }
2465
2466 static int seq_get_early_out_for_blend_mode(Sequence * seq)
2467 {
2468         struct SeqEffectHandle sh = get_sequence_blend(seq);
2469         float facf = seq->blend_opacity / 100.0;
2470         int early_out = sh.early_out(seq, facf, facf);
2471         
2472         if (early_out < 1) {
2473                 return early_out;
2474         }
2475
2476         if (seq_must_swap_input_in_blend_mode(seq)) {
2477                 if (early_out == 2) {
2478                         return 1;
2479                 } else if (early_out == 1) {
2480                         return 2;
2481                 }
2482         }
2483         return early_out;
2484 }
2485
2486 static TStripElem* do_build_seq_array_recursively(Scene *scene,
2487         ListBase *seqbasep, int cfra, int chanshown, int render_size)
2488 {
2489         Sequence* seq_arr[MAXSEQ+1];
2490         int count;
2491         int i;
2492         TStripElem* se = 0;
2493
2494         count = get_shown_sequences(seqbasep, cfra, chanshown, 
2495                                         (Sequence **)&seq_arr);
2496
2497         if (!count) {
2498                 return 0;
2499         }
2500
2501         se = give_tstripelem(seq_arr[count - 1], cfra);
2502
2503         if (!se) {
2504                 return 0;
2505         }
2506
2507         test_and_auto_discard_ibuf(se);
2508
2509         if (se->ibuf_comp != 0) {
2510                 IMB_cache_limiter_insert(se->ibuf_comp);
2511                 IMB_cache_limiter_ref(se->ibuf_comp);
2512                 IMB_cache_limiter_touch(se->ibuf_comp);
2513                 return se;
2514         }
2515
2516         
2517         if(count == 1) {
2518                 se = do_build_seq_recursively(scene, seq_arr[0],
2519                                                   cfra, render_size);
2520                 if (se->ibuf) {
2521                         se->ibuf_comp = se->ibuf;
2522                         IMB_refImBuf(se->ibuf_comp);
2523                 }
2524                 return se;
2525         }
2526
2527
2528         for (i = count - 1; i >= 0; i--) {
2529                 int early_out;
2530                 Sequence * seq = seq_arr[i];
2531
2532                 se = give_tstripelem(seq, cfra);
2533
2534                 test_and_auto_discard_ibuf(se);
2535
2536                 if (se->ibuf_comp != 0) {
2537                         break;
2538                 }
2539                 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2540                         do_build_seq_recursively(
2541                                 scene, seq, cfra, render_size);
2542
2543                         if (se->ibuf) {
2544                                 se->ibuf_comp = se->ibuf;
2545                                 IMB_refImBuf(se->ibuf);
2546                         } else {
2547                                 se->ibuf_comp = IMB_allocImBuf(
2548                                         (short)seqrectx, (short)seqrecty, 
2549                                         32, IB_rect, 0);
2550                                 IMB_cache_limiter_insert(se->ibuf_comp);
2551                                 IMB_cache_limiter_ref(se->ibuf_comp);
2552                                 IMB_cache_limiter_touch(se->ibuf_comp);
2553                         }
2554                         break;
2555                 }
2556
2557                 early_out = seq_get_early_out_for_blend_mode(seq);
2558
2559                 switch (early_out) {
2560                 case -1:
2561                 case 2:
2562                         do_build_seq_recursively(
2563                                 scene, seq, cfra, render_size);
2564
2565                         if (se->ibuf) {
2566                                 se->ibuf_comp = se->ibuf;
2567                                 IMB_refImBuf(se->ibuf_comp);
2568                         } else {
2569                                 se->ibuf_comp = IMB_allocImBuf(
2570                                         (short)seqrectx, (short)seqrecty, 
2571                                         32, IB_rect, 0);
2572                                 IMB_cache_limiter_insert(se->ibuf_comp);
2573                                 IMB_cache_limiter_ref(se->ibuf_comp);
2574                                 IMB_cache_limiter_touch(se->ibuf_comp);
2575                         }
2576                         break;
2577                 case 1:
2578                         if (i == 0) {
2579                                 se->ibuf_comp = IMB_allocImBuf(
2580                                         (short)seqrectx, (short)seqrecty, 
2581                                         32, IB_rect, 0);
2582                                 IMB_cache_limiter_insert(se->ibuf_comp);
2583                                 IMB_cache_limiter_ref(se->ibuf_comp);
2584                                 IMB_cache_limiter_touch(se->ibuf_comp);
2585                         }
2586                         break;
2587                 case 0:
2588                         do_build_seq_recursively(
2589                                 scene, seq, cfra, render_size);
2590
2591                         if (!se->ibuf) {
2592                                 se->ibuf = IMB_allocImBuf(
2593                                         (short)seqrectx, (short)seqrecty, 
2594                                         32, IB_rect, 0);
2595                                 IMB_cache_limiter_insert(se->ibuf);
2596                                 IMB_cache_limiter_ref(se->ibuf);
2597                                 IMB_cache_limiter_touch(se->ibuf);
2598                         }
2599                         if (i == 0) {
2600                                 se->ibuf_comp = se->ibuf;
2601                                 IMB_refImBuf(se->ibuf_comp);
2602                         }
2603                         break;
2604                 }
2605         
2606                 if (se->ibuf_comp) {
2607                         break;
2608                 }
2609         }
2610
2611         i++;
2612
2613         for (; i < count; i++) {
2614                 Sequence * seq = seq_arr[i];
2615                 struct SeqEffectHandle sh = get_sequence_blend(seq);
2616                 TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
2617                 TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
2618
2619                 float facf = seq->blend_opacity / 100.0;
2620                 int swap_input = seq_must_swap_input_in_blend_mode(seq);
2621                 int early_out = seq_get_early_out_for_blend_mode(seq);
2622
2623                 switch (early_out) {
2624                 case 0: {
2625                         int x= se2->ibuf->x;
2626                         int y= se2->ibuf->y;
2627
2628                         if(se1->ibuf_comp == NULL)
2629                                 continue;
2630
2631                         if (se1->ibuf_comp->rect_float ||
2632                                 se2->ibuf->rect_float) {
2633                                 se2->ibuf_comp = IMB_allocImBuf(
2634                                         (short)seqrectx, (short)seqrecty, 
2635                                         32, IB_rectfloat, 0);
2636                         } else {
2637                                 se2->ibuf_comp = IMB_allocImBuf(
2638                                         (short)seqrectx, (short)seqrecty, 
2639                                         32, IB_rect, 0);
2640                         }
2641
2642
2643                         if (!se1->ibuf_comp->rect_float && 
2644                                 se2->ibuf_comp->rect_float) {
2645                                 IMB_float_from_rect(se1->ibuf_comp);
2646                         }
2647                         if (!se2->ibuf->rect_float && 
2648                                 se2->ibuf_comp->rect_float) {
2649                                 IMB_float_from_rect(se2->ibuf);
2650                         }
2651
2652                         if (!se1->ibuf_comp->rect && 
2653                                 !se2->ibuf_comp->rect_float) {
2654                                 IMB_rect_from_float(se1->ibuf_comp);
2655                         }
2656                         if (!se2->ibuf->rect && 
2657                                 !se2->ibuf_comp->rect_float) {
2658                                 IMB_rect_from_float(se2->ibuf);
2659                         }
2660                         
2661                         if (swap_input) {
2662                                 sh.execute(scene, seq, cfra, 
2663                                            facf, facf, x, y, 
2664                                            se2->ibuf, se1->ibuf_comp, 0,
2665                                            se2->ibuf_comp);
2666                         } else {
2667                                 sh.execute(scene, seq, cfra, 
2668                                            facf, facf, x, y, 
2669                                            se1->ibuf_comp, se2->ibuf, 0,
2670                                            se2->ibuf_comp);
2671                         }
2672                         
2673                         IMB_cache_limiter_insert(se2->ibuf_comp);
2674                         IMB_cache_limiter_ref(se2->ibuf_comp);
2675                         IMB_cache_limiter_touch(se2->ibuf_comp);
2676
2677                         IMB_cache_limiter_unref(se1->ibuf_comp);
2678                         IMB_cache_limiter_unref(se2->ibuf);
2679
2680                         break;
2681                 }
2682                 case 1: {
2683                         se2->ibuf_comp = se1->ibuf_comp;
2684                         if(se2->ibuf_comp)
2685                                 IMB_refImBuf(se2->ibuf_comp);
2686
2687                         break;
2688                 }
2689                 }
2690                 se = se2;
2691         }
2692
2693         return se;
2694 }
2695
2696 /*
2697  * returned ImBuf is refed!
2698  * you have to unref after usage!
2699  */
2700
2701 static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2702 {
2703         Editing *ed= seq_give_editing(scene, FALSE);
2704         int count;
2705         ListBase *seqbasep;
2706         TStripElem *se;
2707
2708         
2709         if(ed==NULL) return NULL;
2710
2711         count = BLI_countlist(&ed->metastack);
2712         if((chanshown < 0) && (count > 0)) {
2713                 count = MAX2(count + chanshown, 0);
2714                 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2715         } else {
2716                 seqbasep= ed->seqbasep;
2717         }
2718
2719         seqrectx= rectx;        /* bad bad global! */
2720         seqrecty= recty;
2721
2722         se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size);
2723
2724         if(!se) { 
2725                 return 0;
2726         }
2727
2728         check_limiter_refcount_comp("give_ibuf_seq_impl", se);
2729
2730         return se->ibuf_comp;
2731 }
2732
2733 ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
2734 {
2735         TStripElem* se;
2736
2737         seqrectx= rectx;        /* bad bad global! */
2738         seqrecty= recty;
2739
2740         se = do_build_seq_recursively(scene, seq, cfra, render_size);
2741
2742         if(!se) { 
2743                 return 0;
2744         }
2745
2746         check_limiter_refcount("give_ibuf_seq_direct", se);
2747
2748         if (se->ibuf) {
2749                 IMB_cache_limiter_unref(se->ibuf);
2750         }
2751
2752         return se->ibuf;
2753 }
2754
2755 ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2756 {
2757         ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size);
2758
2759         if (i) {
2760                 IMB_cache_limiter_unref(i);
2761         }
2762         return i;
2763 }
2764
2765 #if 0
2766 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2767 static int seq_can_blend(Sequence *seq)
2768 {
2769         if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2770                 return 1;
2771         } else {
2772                 return 0;
2773         }
2774 }
2775 #endif
2776
2777 /* *********************** threading api ******************* */
2778
2779 static ListBase running_threads;
2780 static ListBase prefetch_wait;
2781 static ListBase prefetch_done;
2782
2783 static pthread_mutex_t queue_lock          = PTHREAD_MUTEX_INITIALIZER;
2784 static pthread_mutex_t wakeup_lock         = PTHREAD_MUTEX_INITIALIZER;
2785 static pthread_cond_t  wakeup_cond         = PTHREAD_COND_INITIALIZER;
2786
2787 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2788 //static pthread_cond_t  prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2789
2790 static pthread_mutex_t frame_done_lock     = PTHREAD_MUTEX_INITIALIZER;
2791 static pthread_cond_t  frame_done_cond     = PTHREAD_COND_INITIALIZER;
2792
2793 static volatile int seq_thread_shutdown = FALSE;
2794 static volatile int seq_last_given_monoton_cfra = 0;
2795 static int monoton_cfra = 0;
2796
2797 typedef struct PrefetchThread {
2798         struct PrefetchThread *next, *prev;
2799         
2800         Scene *scene;
2801         struct PrefetchQueueElem *current;
2802         pthread_t pthread;
2803         int running;
2804         
2805 } PrefetchThread;
2806
2807 typedef struct PrefetchQueueElem {
2808         struct PrefetchQueueElem *next, *prev;
2809         
2810         int rectx;
2811         int recty;
2812         int cfra;
2813         int chanshown;
2814         int render_size;
2815
2816         int monoton_cfra;
2817
2818         struct ImBuf * ibuf;
2819 } PrefetchQueueElem;
2820
2821 #if 0
2822 static void *seq_prefetch_thread(void * This_)
2823 {
2824         PrefetchThread * This = This_;
2825
2826         while (!seq_thread_shutdown) {
2827                 PrefetchQueueElem *e;
2828                 int s_last;
2829
2830                 pthread_mutex_lock(&queue_lock);
2831                 e = prefetch_wait.first;
2832                 if (e) {
2833                         BLI_remlink(&prefetch_wait, e);
2834                 }
2835                 s_last = seq_last_given_monoton_cfra;
2836
2837                 This->current = e;
2838
2839                 pthread_mutex_unlock(&queue_lock);
2840
2841                 if (!e) {
2842                         pthread_mutex_lock(&prefetch_ready_lock);
2843
2844                         This->running = FALSE;
2845
2846                         pthread_cond_signal(&prefetch_ready_cond);
2847                         pthread_mutex_unlock(&prefetch_ready_lock);
2848
2849                         pthread_mutex_lock(&wakeup_lock);
2850                         if (!seq_thread_shutdown) {
2851                                 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2852                         }
2853                         pthread_mutex_unlock(&wakeup_lock);
2854                         continue;
2855                 }
2856
2857                 This->running = TRUE;
2858                 
2859                 if (e->cfra >= s_last) { 
2860                         e->ibuf = give_ibuf_seq_impl(This->scene, 
2861                                 e->rectx, e->recty, e->cfra, e->chanshown,
2862                                 e->render_size);
2863                 }
2864
2865                 pthread_mutex_lock(&queue_lock);
2866
2867                 BLI_addtail(&prefetch_done, e);
2868
2869                 for (e = prefetch_wait.first; e; e = e->next) {
2870                         if (s_last > e->monoton_cfra) {
2871                                 BLI_remlink(&prefetch_wait, e);
2872                                 MEM_freeN(e);
2873                         }
2874                 }
2875
2876                 for (e = prefetch_done.first; e; e = e->next) {
2877                         if (s_last > e->monoton_cfra) {
2878                                 if (e->ibuf) {
2879                                         IMB_cache_limiter_unref(e->ibuf);
2880                                 }
2881                                 BLI_remlink(&prefetch_done, e);
2882                                 MEM_freeN(e);
2883                         }
2884                 }
2885
2886                 pthread_mutex_unlock(&queue_lock);
2887
2888                 pthread_mutex_lock(&frame_done_lock);
2889                 pthread_cond_signal(&frame_done_cond);
2890                 pthread_mutex_unlock(&frame_done_lock);
2891         }
2892         return 0;
2893 }
2894
2895 static void seq_start_threads(Scene *scene)
2896 {
2897         int i;
2898
2899         running_threads.first = running_threads.last = NULL;
2900         prefetch_wait.first = prefetch_wait.last = NULL;
2901         prefetch_done.first = prefetch_done.last = NULL;
2902
2903         seq_thread_shutdown = FALSE;
2904         seq_last_given_monoton_cfra = monoton_cfra = 0;
2905
2906         /* since global structures are modified during the processing
2907            of one frame, only one render thread is currently possible... 
2908
2909            (but we code, in the hope, that we can remove this restriction
2910            soon...)
2911         */
2912
2913         fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2914
2915         for (i = 0; i < 1; i++) {
2916                 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
2917                 t->scene= scene;
2918                 t->running = TRUE;
2919                 BLI_addtail(&running_threads, t);
2920
2921                 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2922         }
2923
2924         /* init malloc mutex */
2925         BLI_init_threads(0, 0, 0);
2926 }
2927
2928 static void seq_stop_threads()
2929 {
2930         PrefetchThread *tslot;
2931         PrefetchQueueElem *e;
2932
2933         fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2934
2935         if (seq_thread_shutdown) {
2936                 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2937                 return;
2938         }
2939         
2940         pthread_mutex_lock(&wakeup_lock);
2941
2942         seq_thread_shutdown = TRUE;
2943
2944                 pthread_cond_broadcast(&wakeup_cond);
2945                 pthread_mutex_unlock(&wakeup_lock);
2946
2947         for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2948                 pthread_join(tslot->pthread, NULL);
2949         }
2950
2951
2952         for (e = prefetch_wait.first; e; e = e->next) {
2953                 BLI_remlink(&prefetch_wait, e);
2954                 MEM_freeN(e);
2955         }
2956
2957         for (e = prefetch_done.first; e; e = e->next) {
2958                 if (e->ibuf) {
2959                         IMB_cache_limiter_unref(e->ibuf);
2960                 }
2961                 BLI_remlink(&prefetch_done, e);
2962                 MEM_freeN(e);
2963         }
2964
2965         BLI_freelistN(&running_threads);
2966
2967         /* deinit malloc mutex */
2968         BLI_end_threads(0);
2969 }
2970 #endif
2971
2972 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
2973                                 int render_size)
2974 {
2975         PrefetchQueueElem *e;
2976         if (seq_thread_shutdown) {
2977                 return;
2978         }
2979
2980         e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2981         e->rectx = rectx;
2982         e->recty = recty;
2983         e->cfra = cfra;
2984         e->chanshown = chanshown;
2985         e->render_size = render_size;
2986         e->monoton_cfra = monoton_cfra++;
2987
2988         pthread_mutex_lock(&queue_lock);
2989         BLI_addtail(&prefetch_wait, e);
2990         pthread_mutex_unlock(&queue_lock);
2991         
2992         pthread_mutex_lock(&wakeup_lock);
2993         pthread_cond_signal(&wakeup_cond);
2994         pthread_mutex_unlock(&wakeup_lock);
2995 }
2996
2997 #if 0
2998 static void seq_wait_for_prefetch_ready()
2999 {
3000         PrefetchThread *tslot;
3001
3002         if (seq_thread_shutdown) {
3003                 return;
3004         }
3005
3006         fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
3007
3008         pthread_mutex_lock(&prefetch_ready_lock);
3009
3010         for(;;) {
3011                 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
3012                         if (tslot->running) {
3013                                 break;
3014                         }
3015                 }
3016                 if (!tslot) {
3017                         break;
3018                 }
3019                 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
3020         }
3021
3022         pthread_mutex_unlock(&prefetch_ready_lock);
3023
3024         fprintf(stderr, "SEQ-THREAD: prefetch done\n");
3025 }
3026 #endif
3027
3028 ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
3029 {
3030         PrefetchQueueElem *e = NULL;
3031         int found_something = FALSE;
3032
3033         if (seq_thread_shutdown) {
3034                 return give_ibuf_seq(scene, rectx, recty, cfra, chanshown, render_size);
3035         }
3036
3037         while (!e) {
3038                 int success = FALSE;
3039                 pthread_mutex_lock(&queue_lock);
3040
3041                 for (e = prefetch_done.first; e; e = e->next) {
3042                         if (cfra == e->cfra &&
3043                                 chanshown == e->chanshown &&
3044                                 rectx == e->rectx && 
3045                                 recty == e->recty &&
3046                                 render_size == e->render_size) {
3047                                 success = TRUE;
3048                                 found_something = TRUE;
3049                                 break;
3050                         }
3051                 }
3052
3053                 if (!e) {
3054                         for (e = prefetch_wait.first; e; e = e->next) {
3055                                 if (cfra == e->cfra &&
3056                                         chanshown == e->chanshown &&
3057                                         rectx == e->rectx && 
3058                                         recty == e->recty &&
3059                                         render_size == e->render_size) {
3060                                         found_something = TRUE;
3061                                         break;
3062                                 }
3063                         }
3064                 }
3065
3066                 if (!e) {
3067                         PrefetchThread *tslot;
3068
3069                         for(tslot = running_threads.first; 
3070                                 tslot; tslot= tslot->next) {
3071                                 if (tslot->current &&
3072                                         cfra == tslot->current->cfra &&
3073                                         chanshown == tslot->current->chanshown &&
3074                                         rectx == tslot->current->rectx && 
3075                                         recty == tslot->current->recty &&
3076                                         render_size== tslot->current->render_size){
3077                                         found_something = TRUE;
3078                                         break;
3079                                 }
3080                         }
3081                 }
3082
3083                 /* e->ibuf is unrefed by render thread on next round. */
3084
3085                 if (e) {
3086                         seq_last_given_monoton_cfra = e->monoton_cfra;
3087                 }
3088
3089                 pthread_mutex_unlock(&queue_lock);
3090
3091                 if (!success) {
3092                         e = NULL;
3093
3094                         if (!found_something) {
3095                                 fprintf(stderr, 
3096                                         "SEQ-THREAD: Requested frame "
3097                                         "not in queue ???\n");
3098                                 break;
3099                         }
3100                         pthread_mutex_lock(&frame_done_lock);
3101                         pthread_cond_wait(&frame_done_cond, &frame_done_lock);
3102                         pthread_mutex_unlock(&frame_done_lock);
3103                 }
3104         }
3105         
3106         return e ? e->ibuf : 0;
3107 }
3108
3109 /* Functions to free imbuf and anim data on changes */
3110
3111 static void free_imbuf_strip_elem(TStripElem *se)
3112 {
3113         if(se->ibuf) {
3114                 IMB_freeImBuf(se->ibuf);
3115         }
3116         if(se->ibuf_comp) {
3117                 IMB_freeImBuf(se->ibuf_comp);
3118         }
3119         se->ibuf_comp = 0;
3120         se->ibuf= 0;
3121         se->ok= STRIPELEM_OK;
3122         se->se1= se->se2= se->se3= 0;
3123 }
3124
3125 static void free_anim_seq(Sequence *seq)
3126 {
3127         if(seq->anim) {
3128                 IMB_free_anim(seq->anim);
3129                 seq->anim = 0;
3130         }
3131 }
3132
3133 #if 0
3134 static void free_imbuf_seq_except(Scene *scene, int cfra)
3135 {
3136         Editing *ed= seq_give_editing(scene, FALSE);
3137         Sequence *seq;
3138         TStripElem *se;
3139         int a;
3140
3141         if(ed==NULL) return;
3142
3143         SEQ_BEGIN(ed, seq) {
3144                 if(seq->strip) {
3145                         TStripElem * curelem = give_tstripelem(seq, cfra);
3146
3147                         for(a = 0, se = seq->strip->tstripdata; 
3148                                 a < seq->strip->len && se; a++, se++) {
3149                                 if(se != curelem) {
3150                                         free_imbuf_strip_elem(se);
3151                                 }
3152                         }
3153                         for(a = 0, se = seq->strip->tstripdata_startstill;
3154                                 a < seq->strip->startstill && se; a++, se++) {
3155                                 if(se != curelem) {
3156                                         free_imbuf_strip_elem(se);
3157                                 }
3158                         }
3159                         for(a = 0, se = seq->strip->tstripdata_endstill;
3160                                 a < seq->strip->endstill && se; a++, se++) {
3161                                 if(se != curelem) {
3162                                         free_imbuf_strip_elem(se);
3163                                 }
3164                         }
3165                         if(seq->strip->ibuf_startstill) {
3166                                 IMB_freeImBuf(seq->strip->ibuf_startstill);
3167                                 seq->strip->ibuf_startstill = 0;
3168                         }
3169
3170                         if(seq->strip->ibuf_endstill) {
3171                                 IMB_freeImBuf(seq->strip->ibuf_endstill);
3172                                 seq->strip->ibuf_endstill = 0;
3173                         }
3174
3175                         if(seq->type==SEQ_MOVIE)
3176                                 if(seq->startdisp > cfra || seq->enddisp < cfra)
3177                                         free_anim_seq(seq);
3178                         free_proxy_seq(seq);
3179                 }
3180         }
3181         SEQ_END
3182 }
3183 #endif
3184
3185 void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage)
3186 {
3187         Sequence *seq;
3188         TStripElem *se;
3189         int a;
3190
3191         if (check_mem_usage) {
3192                 /* Let the cache limitor take care of this (schlaile) */
3193                 /* While render let's keep all memory available for render 
3194                    (ton)
3195                    At least if free memory is tight...
3196                    This can make a big difference in encoding speed
3197                    (it is around 4 times(!) faster, if we do not waste time
3198                    on freeing _all_ buffers every time on long timelines...)
3199                    (schlaile)
3200                 */
3201         
3202                 uintptr_t mem_in_use;
3203                 uintptr_t mmap_in_use;
3204                 uintptr_t max;
3205         
3206                 mem_in_use= MEM_get_memory_in_use();
3207                 mmap_in_use= MEM_get_mapped_memory_in_use();
3208      &nb