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