Various warning fixes.
[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
2156                         /* prevent eternal loop */
2157                         doseq= scene->r.scemode & R_DOSEQ;
2158                         scene->r.scemode &= ~R_DOSEQ;
2159
2160                         seq->scene->r.cfra= frame;
2161                         if(seq->scene_camera)   seq->scene->camera= seq->scene_camera;
2162                         else                                    scene_camera_switch_update(seq->scene);
2163
2164 #ifdef DURIAN_CAMERA_SWITCH
2165                         /* stooping to new low's in hackyness :( */
2166                         oldmarkers= seq->scene->markers;
2167                         seq->scene->markers.first= seq->scene->markers.last= NULL;
2168 #endif
2169
2170                         if(sequencer_view3d_cb && (seq->flag & SEQ_USE_SCENE_OPENGL) && (seq->scene == scene || have_seq==0)) {
2171                                 /* opengl offscreen render */
2172                                 scene_update_for_newframe(seq->scene, seq->scene->lay);
2173                                 se->ibuf= sequencer_view3d_cb(seq->scene, seqrectx, seqrecty);
2174                         }
2175                         else {
2176                                 Render *re;
2177                                 RenderResult rres;
2178
2179                                 if(rendering)
2180                                         re= RE_NewRender(" do_build_seq_ibuf", RE_SLOT_DEFAULT);
2181                                 else
2182                                         re= RE_NewRender(sce->id.name, RE_SLOT_VIEW);
2183
2184                                 RE_BlenderFrame(re, sce, NULL, sce->lay, frame);
2185
2186                                 RE_AcquireResultImage(re, &rres);
2187
2188                                 if(rres.rectf) {
2189                                         se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
2190                                         memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
2191                                         if(rres.rectz) {
2192                                                 addzbuffloatImBuf(se->ibuf);
2193                                                 memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
2194                                         }
2195                                 } else if (rres.rect32) {
2196                                         se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
2197                                         memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
2198                                 }
2199
2200                                 RE_ReleaseResultImage(re);
2201
2202                                 // BIF_end_render_callbacks();
2203                         }
2204                         
2205                         /* restore */
2206                         scene->r.scemode |= doseq;
2207
2208                         seq->scene->r.cfra = oldcfra;
2209                         seq->scene->camera= oldcamera;
2210
2211 #ifdef DURIAN_CAMERA_SWITCH
2212                         /* stooping to new low's in hackyness :( */
2213                         seq->scene->markers= oldmarkers;
2214 #endif
2215
2216                         copy_to_ibuf_still(seq, se);
2217
2218                         if (!build_proxy_run) {
2219                                 if(se->ibuf == NULL) {
2220                                         se->ok = STRIPELEM_FAILED;
2221                                 } else {
2222                                         input_preprocess(scene, seq, se, cfra);
2223                                 }
2224                         }
2225
2226                 }
2227         }
2228         if (!build_proxy_run) {
2229                 if (se->ibuf && use_limiter) {
2230                         IMB_cache_limiter_insert(se->ibuf);
2231                         IMB_cache_limiter_ref(se->ibuf);
2232                         IMB_cache_limiter_touch(se->ibuf);
2233                 }
2234         }
2235 }
2236
2237 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size);
2238
2239 static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size)
2240 {
2241         float fac, facf;
2242         struct SeqEffectHandle sh = get_sequence_effect(seq);
2243         int early_out;
2244         FCurve *fcu= NULL;
2245
2246         se->se1 = 0;
2247         se->se2 = 0;
2248         se->se3 = 0;
2249
2250         if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
2251                 sh.get_default_fac(seq, cfra, &fac, &facf);
2252                 if( scene->r.mode & R_FIELDS ); else facf= fac;
2253         } else {
2254                 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, 
2255                                           "effect_fader", 0);
2256                 if (fcu) {
2257                         fac = facf = evaluate_fcurve(fcu, cfra);
2258                         if( scene->r.mode & R_FIELDS ) {
2259                                 facf = evaluate_fcurve(fcu, cfra + 0.5);
2260                         }
2261                 } else {
2262                         fac = facf = seq->effect_fader;
2263                 }
2264         }
2265
2266         early_out = sh.early_out(seq, fac, facf);
2267         switch (early_out) {
2268         case -1:
2269                 /* no input needed */
2270                 break;
2271         case 0:
2272                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2273                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2274                 if (seq->seq3) {
2275                         se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size);
2276                 }
2277                 break;
2278         case 1:
2279                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2280                 break;
2281         case 2:
2282                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2283                 break;
2284         }
2285
2286
2287         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2288
2289         /* children are not needed anymore ... */
2290
2291         if (se->se1 && se->se1->ibuf) {
2292                 IMB_cache_limiter_unref(se->se1->ibuf);
2293         }
2294         if (se->se2 && se->se2->ibuf) {
2295                 IMB_cache_limiter_unref(se->se2->ibuf);
2296         }
2297         if (se->se3 && se->se3->ibuf) {
2298                 IMB_cache_limiter_unref(se->se3->ibuf);
2299         }
2300         check_limiter_refcount("do_effect_seq_recursively", se);
2301 }
2302
2303 static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size)
2304 {
2305         TStripElem *se;
2306
2307         se = give_tstripelem(seq, cfra);
2308
2309         if(se) {
2310                 if (seq->type & SEQ_EFFECT) {
2311                         do_effect_seq_recursively(scene, seq, se, cfra, render_size);
2312                 } else {
2313                         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2314                 }
2315         }
2316         return se;
2317 }
2318
2319 /* FIXME:
2320    
2321 If cfra was float throughout blender (especially in the render
2322 pipeline) one could even _render_ with subframe precision
2323 instead of faking using the blend code below...
2324
2325 */
2326
2327 static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size)
2328 {
2329         SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
2330         int nr = cfra - seq->start;
2331         float f_cfra;
2332         int cfra_left;
2333         int cfra_right;
2334         TStripElem * se = 0;
2335         TStripElem * se1 = 0;
2336         TStripElem * se2 = 0;
2337         
2338         sequence_effect_speed_rebuild_map(scene, seq, 0);
2339         
2340         f_cfra = seq->start + s->frameMap[nr];
2341         
2342         cfra_left = (int) floor(f_cfra);
2343         cfra_right = (int) ceil(f_cfra);
2344
2345         se = give_tstripelem(seq, cfra);
2346
2347         if (!se) {
2348                 return se;
2349         }
2350
2351         if (cfra_left == cfra_right || 
2352             (s->flags & SEQ_SPEED_BLEND) == 0) {
2353                 test_and_auto_discard_ibuf(se);
2354
2355                 if (se->ibuf == NULL) {
2356                         se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2357
2358                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2359                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2360                         else
2361                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2362
2363                         if (se1 == 0 || se1->ibuf == 0) {
2364                                 make_black_ibuf(se->ibuf);
2365                         } else {
2366                                 if (se->ibuf != se1->ibuf) {
2367                                         if (se->ibuf) {
2368                                                 IMB_freeImBuf(se->ibuf);
2369                                         }
2370
2371                                         se->ibuf = se1->ibuf;
2372                                         IMB_refImBuf(se->ibuf);
2373                                 }
2374                         }
2375                 }
2376         } else {
2377                 struct SeqEffectHandle sh;
2378
2379                 if(se->ibuf) {
2380                         if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty 
2381                            || !(se->ibuf->rect || se->ibuf->rect_float)) {
2382                                 IMB_freeImBuf(se->ibuf);
2383                                 se->ibuf= 0;
2384                         }
2385                 }
2386
2387                 if (se->ibuf == NULL) {
2388                         se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2389                         se2 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_right, render_size);
2390
2391                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2392                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2393                         else
2394                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2395                         
2396                         if (!se1 || !se2) {
2397                                 make_black_ibuf(se->ibuf);
2398                         } else {
2399                                 sh = get_sequence_effect(seq);
2400
2401                                 sh.execute(scene, seq, cfra, 
2402                                            f_cfra - (float) cfra_left, 
2403                                            f_cfra - (float) cfra_left, 
2404                                            se->ibuf->x, se->ibuf->y, 
2405                                            se1->ibuf, se2->ibuf, 0, se->ibuf);
2406                         }
2407                 }
2408
2409         }
2410
2411         /* caller expects this to be referenced, so do it! */
2412         if (se->ibuf) {
2413                 IMB_cache_limiter_insert(se->ibuf);
2414                 IMB_cache_limiter_ref(se->ibuf);
2415                 IMB_cache_limiter_touch(se->ibuf);
2416         }
2417
2418         /* children are no longer needed */
2419         if (se1 && se1->ibuf)
2420                 IMB_cache_limiter_unref(se1->ibuf);
2421         if (se2 && se2->ibuf)
2422                 IMB_cache_limiter_unref(se2->ibuf);
2423
2424         check_limiter_refcount("do_handle_speed_effect", se);
2425
2426         return se;
2427 }
2428
2429 /* 
2430  * build all ibufs recursively
2431  * 
2432  * if successfull, the returned TStripElem contains the (referenced!) imbuf
2433  * that means: you _must_ call 
2434  *
2435  * IMB_cache_limiter_unref(rval);
2436  * 
2437  * if rval != 0
2438  * 
2439  */
2440
2441 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size)
2442 {
2443         TStripElem *se;
2444         if (seq->type == SEQ_SPEED) {
2445                 se = do_handle_speed_effect(scene, seq, cfra, render_size);
2446         } else {
2447                 se = do_build_seq_recursively_impl(scene, seq, cfra, render_size);
2448         }
2449
2450         check_limiter_refcount("do_build_seq_recursively", se);
2451
2452         return se;
2453 }
2454
2455 static int seq_must_swap_input_in_blend_mode(Sequence * seq)
2456 {
2457         int swap_input = FALSE;
2458
2459         /* bad hack, to fix crazy input ordering of 
2460            those two effects */
2461
2462         if (seq->blend_mode == SEQ_ALPHAOVER ||
2463             seq->blend_mode == SEQ_ALPHAUNDER ||
2464             seq->blend_mode == SEQ_OVERDROP) {
2465                 swap_input = TRUE;
2466         }
2467         
2468         return swap_input;
2469 }
2470
2471 static int seq_get_early_out_for_blend_mode(Sequence * seq)
2472 {
2473         struct SeqEffectHandle sh = get_sequence_blend(seq);
2474         float facf = seq->blend_opacity / 100.0;
2475         int early_out = sh.early_out(seq, facf, facf);
2476         
2477         if (early_out < 1) {
2478                 return early_out;
2479         }
2480
2481         if (seq_must_swap_input_in_blend_mode(seq)) {
2482                 if (early_out == 2) {
2483                         return 1;
2484                 } else if (early_out == 1) {
2485                         return 2;
2486                 }
2487         }
2488         return early_out;
2489 }
2490
2491 static TStripElem* do_build_seq_array_recursively(Scene *scene,
2492         ListBase *seqbasep, int cfra, int chanshown, int render_size)
2493 {
2494         Sequence* seq_arr[MAXSEQ+1];
2495         int count;
2496         int i;
2497         TStripElem* se = 0;
2498
2499         count = get_shown_sequences(seqbasep, cfra, chanshown, 
2500                                     (Sequence **)&seq_arr);
2501
2502         if (!count) {
2503                 return 0;
2504         }
2505
2506         se = give_tstripelem(seq_arr[count - 1], cfra);
2507
2508         if (!se) {
2509                 return 0;
2510         }
2511
2512         test_and_auto_discard_ibuf(se);
2513
2514         if (se->ibuf_comp != 0) {
2515                 IMB_cache_limiter_insert(se->ibuf_comp);
2516                 IMB_cache_limiter_ref(se->ibuf_comp);
2517                 IMB_cache_limiter_touch(se->ibuf_comp);
2518                 return se;
2519         }
2520
2521         
2522         if(count == 1) {
2523                 se = do_build_seq_recursively(scene, seq_arr[0],
2524                                               cfra, render_size);
2525                 if (se->ibuf) {
2526                         se->ibuf_comp = se->ibuf;
2527                         IMB_refImBuf(se->ibuf_comp);
2528                 }
2529                 return se;
2530         }
2531
2532
2533         for (i = count - 1; i >= 0; i--) {
2534                 int early_out;
2535                 Sequence * seq = seq_arr[i];
2536
2537                 se = give_tstripelem(seq, cfra);
2538
2539                 test_and_auto_discard_ibuf(se);
2540
2541                 if (se->ibuf_comp != 0) {
2542                         break;
2543                 }
2544                 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2545                         do_build_seq_recursively(
2546                                 scene, seq, cfra, render_size);
2547
2548                         if (se->ibuf) {
2549                                 se->ibuf_comp = se->ibuf;
2550                                 IMB_refImBuf(se->ibuf);
2551                         } else {
2552                                 se->ibuf_comp = IMB_allocImBuf(
2553                                         (short)seqrectx, (short)seqrecty, 
2554                                         32, IB_rect, 0);
2555                                 IMB_cache_limiter_insert(se->ibuf_comp);
2556                                 IMB_cache_limiter_ref(se->ibuf_comp);
2557                                 IMB_cache_limiter_touch(se->ibuf_comp);
2558                         }
2559                         break;
2560                 }
2561
2562                 early_out = seq_get_early_out_for_blend_mode(seq);
2563
2564                 switch (early_out) {
2565                 case -1:
2566                 case 2:
2567                         do_build_seq_recursively(
2568                                 scene, seq, cfra, render_size);
2569
2570                         if (se->ibuf) {
2571                                 se->ibuf_comp = se->ibuf;
2572                                 IMB_refImBuf(se->ibuf_comp);
2573                         } else {
2574                                 se->ibuf_comp = IMB_allocImBuf(
2575                                         (short)seqrectx, (short)seqrecty, 
2576                                         32, IB_rect, 0);
2577                                 IMB_cache_limiter_insert(se->ibuf_comp);
2578                                 IMB_cache_limiter_ref(se->ibuf_comp);
2579                                 IMB_cache_limiter_touch(se->ibuf_comp);
2580                         }
2581                         break;
2582                 case 1:
2583                         if (i == 0) {
2584                                 se->ibuf_comp = IMB_allocImBuf(
2585                                         (short)seqrectx, (short)seqrecty, 
2586                                         32, IB_rect, 0);
2587                                 IMB_cache_limiter_insert(se->ibuf_comp);
2588                                 IMB_cache_limiter_ref(se->ibuf_comp);
2589                                 IMB_cache_limiter_touch(se->ibuf_comp);
2590                         }
2591                         break;
2592                 case 0:
2593                         do_build_seq_recursively(
2594                                 scene, seq, cfra, render_size);
2595
2596                         if (!se->ibuf) {
2597                                 se->ibuf = IMB_allocImBuf(
2598                                         (short)seqrectx, (short)seqrecty, 
2599                                         32, IB_rect, 0);
2600                                 IMB_cache_limiter_insert(se->ibuf);
2601                                 IMB_cache_limiter_ref(se->ibuf);
2602                                 IMB_cache_limiter_touch(se->ibuf);
2603                         }
2604                         if (i == 0) {
2605                                 se->ibuf_comp = se->ibuf;
2606                                 IMB_refImBuf(se->ibuf_comp);
2607                         }
2608                         break;
2609                 }
2610         
2611                 if (se->ibuf_comp) {
2612                         break;
2613                 }
2614         }
2615
2616         i++;
2617
2618         for (; i < count; i++) {
2619                 Sequence * seq = seq_arr[i];
2620                 struct SeqEffectHandle sh = get_sequence_blend(seq);
2621                 TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
2622                 TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
2623
2624                 float facf = seq->blend_opacity / 100.0;
2625                 int swap_input = seq_must_swap_input_in_blend_mode(seq);
2626                 int early_out = seq_get_early_out_for_blend_mode(seq);
2627
2628                 switch (early_out) {
2629                 case 0: {
2630                         int x= se2->ibuf->x;
2631                         int y= se2->ibuf->y;
2632
2633                         if(se1->ibuf_comp == NULL)
2634                                 continue;
2635
2636                         if (se1->ibuf_comp->rect_float ||
2637                             se2->ibuf->rect_float) {
2638                                 se2->ibuf_comp = IMB_allocImBuf(
2639                                         (short)seqrectx, (short)seqrecty, 
2640                                         32, IB_rectfloat, 0);
2641                         } else {
2642                                 se2->ibuf_comp = IMB_allocImBuf(
2643                                         (short)seqrectx, (short)seqrecty, 
2644                                         32, IB_rect, 0);
2645                         }
2646
2647
2648                         if (!se1->ibuf_comp->rect_float && 
2649                             se2->ibuf_comp->rect_float) {
2650                                 IMB_float_from_rect(se1->ibuf_comp);
2651                         }
2652                         if (!se2->ibuf->rect_float && 
2653                             se2->ibuf_comp->rect_float) {
2654                                 IMB_float_from_rect(se2->ibuf);
2655                         }
2656
2657                         if (!se1->ibuf_comp->rect && 
2658                             !se2->ibuf_comp->rect_float) {
2659                                 IMB_rect_from_float(se1->ibuf_comp);
2660                         }
2661                         if (!se2->ibuf->rect && 
2662                             !se2->ibuf_comp->rect_float) {
2663                                 IMB_rect_from_float(se2->ibuf);
2664                         }
2665                         
2666                         if (swap_input) {
2667                                 sh.execute(scene, seq, cfra, 
2668                                            facf, facf, x, y, 
2669                                            se2->ibuf, se1->ibuf_comp, 0,
2670                                            se2->ibuf_comp);
2671                         } else {
2672                                 sh.execute(scene, seq, cfra, 
2673                                            facf, facf, x, y, 
2674                                            se1->ibuf_comp, se2->ibuf, 0,
2675                                            se2->ibuf_comp);
2676                         }
2677                         
2678                         IMB_cache_limiter_insert(se2->ibuf_comp);
2679                         IMB_cache_limiter_ref(se2->ibuf_comp);
2680                         IMB_cache_limiter_touch(se2->ibuf_comp);
2681
2682                         IMB_cache_limiter_unref(se1->ibuf_comp);
2683                         IMB_cache_limiter_unref(se2->ibuf);
2684
2685                         break;
2686                 }
2687                 case 1: {
2688                         se2->ibuf_comp = se1->ibuf_comp;
2689                         if(se2->ibuf_comp)
2690                                 IMB_refImBuf(se2->ibuf_comp);
2691
2692                         break;
2693                 }
2694                 }
2695                 se = se2;
2696         }
2697
2698         return se;
2699 }
2700
2701 /*
2702  * returned ImBuf is refed!
2703  * you have to unref after usage!
2704  */
2705
2706 static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2707 {
2708         Editing *ed= seq_give_editing(scene, FALSE);
2709         int count;
2710         ListBase *seqbasep;
2711         TStripElem *se;
2712
2713         
2714         if(ed==NULL) return NULL;
2715
2716         count = BLI_countlist(&ed->metastack);
2717         if((chanshown < 0) && (count > 0)) {
2718                 count = MAX2(count + chanshown, 0);
2719                 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2720         } else {
2721                 seqbasep= ed->seqbasep;
2722         }
2723
2724         seqrectx= rectx;        /* bad bad global! */
2725         seqrecty= recty;
2726
2727         se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size);
2728
2729         if(!se) { 
2730                 return 0;
2731         }
2732
2733         check_limiter_refcount_comp("give_ibuf_seq_impl", se);
2734
2735         return se->ibuf_comp;
2736 }
2737
2738 ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
2739 {
2740         TStripElem* se;
2741
2742         seqrectx= rectx;        /* bad bad global! */
2743         seqrecty= recty;
2744
2745         se = do_build_seq_recursively(scene, seq, cfra, render_size);
2746
2747         if(!se) { 
2748                 return 0;
2749         }
2750
2751         check_limiter_refcount("give_ibuf_seq_direct", se);
2752
2753         if (se->ibuf) {
2754                 IMB_cache_limiter_unref(se->ibuf);
2755         }
2756
2757         return se->ibuf;
2758 }
2759
2760 ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2761 {
2762         ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size);
2763
2764         if (i) {
2765                 IMB_cache_limiter_unref(i);
2766         }
2767         return i;
2768 }
2769
2770 #if 0
2771 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2772 static int seq_can_blend(Sequence *seq)
2773 {
2774         if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2775                 return 1;
2776         } else {
2777                 return 0;
2778         }
2779 }
2780 #endif
2781
2782 /* *********************** threading api ******************* */
2783
2784 static ListBase running_threads;
2785 static ListBase prefetch_wait;
2786 static ListBase prefetch_done;
2787
2788 static pthread_mutex_t queue_lock          = PTHREAD_MUTEX_INITIALIZER;
2789 static pthread_mutex_t wakeup_lock         = PTHREAD_MUTEX_INITIALIZER;
2790 static pthread_cond_t  wakeup_cond         = PTHREAD_COND_INITIALIZER;
2791
2792 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2793 //static pthread_cond_t  prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2794
2795 static pthread_mutex_t frame_done_lock     = PTHREAD_MUTEX_INITIALIZER;
2796 static pthread_cond_t  frame_done_cond     = PTHREAD_COND_INITIALIZER;
2797
2798 static volatile int seq_thread_shutdown = FALSE;
2799 static volatile int seq_last_given_monoton_cfra = 0;
2800 static int monoton_cfra = 0;
2801
2802 typedef struct PrefetchThread {
2803         struct PrefetchThread *next, *prev;
2804         
2805         Scene *scene;
2806         struct PrefetchQueueElem *current;
2807         pthread_t pthread;
2808         int running;
2809         
2810 } PrefetchThread;
2811
2812 typedef struct PrefetchQueueElem {
2813         struct PrefetchQueueElem *next, *prev;
2814         
2815         int rectx;
2816         int recty;
2817         int cfra;
2818         int chanshown;
2819         int render_size;
2820
2821         int monoton_cfra;
2822
2823         struct ImBuf * ibuf;
2824 } PrefetchQueueElem;
2825
2826 #if 0
2827 static void *seq_prefetch_thread(void * This_)
2828 {
2829         PrefetchThread * This = This_;
2830
2831         while (!seq_thread_shutdown) {
2832                 PrefetchQueueElem *e;
2833                 int s_last;
2834
2835                 pthread_mutex_lock(&queue_lock);
2836                 e = prefetch_wait.first;
2837                 if (e) {
2838                         BLI_remlink(&prefetch_wait, e);
2839                 }
2840                 s_last = seq_last_given_monoton_cfra;
2841
2842                 This->current = e;
2843
2844                 pthread_mutex_unlock(&queue_lock);
2845
2846                 if (!e) {
2847                         pthread_mutex_lock(&prefetch_ready_lock);
2848
2849                         This->running = FALSE;
2850
2851                         pthread_cond_signal(&prefetch_ready_cond);
2852                         pthread_mutex_unlock(&prefetch_ready_lock);
2853
2854                         pthread_mutex_lock(&wakeup_lock);
2855                         if (!seq_thread_shutdown) {
2856                                 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2857                         }
2858                         pthread_mutex_unlock(&wakeup_lock);
2859                         continue;
2860                 }
2861
2862                 This->running = TRUE;
2863                 
2864                 if (e->cfra >= s_last) { 
2865                         e->ibuf = give_ibuf_seq_impl(This->scene, 
2866                                 e->rectx, e->recty, e->cfra, e->chanshown,
2867                                 e->render_size);
2868                 }
2869
2870                 pthread_mutex_lock(&queue_lock);
2871
2872                 BLI_addtail(&prefetch_done, e);
2873
2874                 for (e = prefetch_wait.first; e; e = e->next) {
2875                         if (s_last > e->monoton_cfra) {
2876                                 BLI_remlink(&prefetch_wait, e);
2877                                 MEM_freeN(e);
2878                         }
2879                 }
2880
2881                 for (e = prefetch_done.first; e; e = e->next) {
2882                         if (s_last > e->monoton_cfra) {
2883                                 if (e->ibuf) {
2884                                         IMB_cache_limiter_unref(e->ibuf);
2885                                 }
2886                                 BLI_remlink(&prefetch_done, e);
2887                                 MEM_freeN(e);
2888                         }
2889                 }
2890
2891                 pthread_mutex_unlock(&queue_lock);
2892
2893                 pthread_mutex_lock(&frame_done_lock);
2894                 pthread_cond_signal(&frame_done_cond);
2895                 pthread_mutex_unlock(&frame_done_lock);
2896         }
2897         return 0;
2898 }
2899
2900 static void seq_start_threads(Scene *scene)
2901 {
2902         int i;
2903
2904         running_threads.first = running_threads.last = NULL;
2905         prefetch_wait.first = prefetch_wait.last = NULL;
2906         prefetch_done.first = prefetch_done.last = NULL;
2907
2908         seq_thread_shutdown = FALSE;
2909         seq_last_given_monoton_cfra = monoton_cfra = 0;
2910
2911         /* since global structures are modified during the processing
2912            of one frame, only one render thread is currently possible... 
2913
2914            (but we code, in the hope, that we can remove this restriction
2915            soon...)
2916         */
2917
2918         fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2919
2920         for (i = 0; i < 1; i++) {
2921                 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
2922                 t->scene= scene;
2923                 t->running = TRUE;
2924                 BLI_addtail(&running_threads, t);
2925
2926                 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2927         }
2928
2929         /* init malloc mutex */
2930         BLI_init_threads(0, 0, 0);
2931 }
2932
2933 static void seq_stop_threads()
2934 {
2935         PrefetchThread *tslot;
2936         PrefetchQueueElem *e;
2937
2938         fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2939
2940         if (seq_thread_shutdown) {
2941                 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2942                 return;
2943         }
2944         
2945         pthread_mutex_lock(&wakeup_lock);
2946
2947         seq_thread_shutdown = TRUE;
2948
2949         pthread_cond_broadcast(&wakeup_cond);
2950         pthread_mutex_unlock(&wakeup_lock);
2951
2952         for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2953                 pthread_join(tslot->pthread, NULL);
2954         }
2955
2956
2957         for (e = prefetch_wait.first; e; e = e->next) {
2958                 BLI_remlink(&prefetch_wait, e);
2959                 MEM_freeN(e);
2960         }
2961
2962         for (e = prefetch_done.first; e; e = e->next) {
2963                 if (e->ibuf) {
2964                         IMB_cache_limiter_unref(e->ibuf);
2965                 }
2966                 BLI_remlink(&prefetch_done, e);
2967                 MEM_freeN(e);
2968         }
2969
2970         BLI_freelistN(&running_threads);
2971
2972         /* deinit malloc mutex */
2973         BLI_end_threads(0);
2974 }
2975 #endif
2976
2977 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
2978                                 int render_size)
2979 {
2980         PrefetchQueueElem *e;
2981         if (seq_thread_shutdown) {
2982                 return;
2983         }
2984
2985         e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2986         e->rectx = rectx;
2987         e->recty = recty;
2988         e->cfra = cfra;
2989         e->chanshown = chanshown;
2990         e->render_size = render_size;
2991         e->monoton_cfra = monoton_cfra++;
2992
2993         pthread_mutex_lock(&queue_lock);
2994         BLI_addtail(&prefetch_wait, e);
2995         pthread_mutex_unlock(&queue_lock);
2996         
2997         pthread_mutex_lock(&wakeup_lock);
2998         pthread_cond_signal(&wakeup_cond);
2999         pthread_mutex_unlock(&wakeup_lock);
3000 }
3001
3002 #if 0
3003 static void seq_wait_for_prefetch_ready()
3004 {
3005         PrefetchThread *tslot;
3006
3007         if (seq_thread_shutdown) {
3008                 return;
3009         }
3010
3011         fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
3012
3013         pthread_mutex_lock(&prefetch_ready_lock);
3014
3015         for(;;) {
3016                 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
3017                         if (tslot->running) {
3018                                 break;
3019                         }
3020                 }
3021                 if (!tslot) {
3022                         break;
3023                 }
3024                 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
3025         }
3026
3027         pthread_mutex_unlock(&prefetch_ready_lock);
3028
3029         fprintf(stderr, "SEQ-THREAD: prefetch done\n");
3030 }
3031 #endif
3032
3033 ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
3034 {
3035         PrefetchQueueElem *e = NULL;
3036         int found_something = FALSE;
3037
3038         if (seq_thread_shutdown) {
3039                 return give_ibuf_seq(scene, rectx, recty, cfra, chanshown, render_size);
3040         }
3041
3042         while (!e) {
3043                 int success = FALSE;
3044                 pthread_mutex_lock(&queue_lock);
3045
3046                 for (e = prefetch_done.first; e; e = e->next) {
3047                         if (cfra == e->cfra &&
3048                             chanshown == e->chanshown &&
3049                             rectx == e->rectx && 
3050                             recty == e->recty &&
3051                             render_size == e->render_size) {
3052                                 success = TRUE;
3053                                 found_something = TRUE;
3054                                 break;
3055                         }
3056                 }
3057
3058                 if (!e) {
3059                         for (e = prefetch_wait.first; e; e = e->next) {
3060                                 if (cfra == e->cfra &&
3061                                     chanshown == e->chanshown &&
3062                                     rectx == e->rectx && 
3063                                     recty == e->recty &&
3064                                     render_size == e->render_size) {
3065                                         found_something = TRUE;
3066                                         break;
3067                                 }
3068                         }
3069                 }
3070
3071                 if (!e) {
3072                         PrefetchThread *tslot;
3073
3074                         for(tslot = running_threads.first; 
3075                             tslot; tslot= tslot->next) {
3076                                 if (tslot->current &&
3077                                     cfra == tslot->current->cfra &&
3078                                     chanshown == tslot->current->chanshown &&
3079                                     rectx == tslot->current->rectx && 
3080                                     recty == tslot->current->recty &&
3081                                     render_size== tslot->current->render_size){
3082                                         found_something = TRUE;
3083                                         break;
3084                                 }
3085                         }
3086                 }
3087
3088                 /* e->ibuf is unrefed by render thread on next round. */
3089
3090                 if (e) {
3091                         seq_last_given_monoton_cfra = e->monoton_cfra;
3092                 }
3093
3094                 pthread_mutex_unlock(&queue_lock);
3095
3096                 if (!success) {
3097                         e = NULL;
3098
3099                         if (!found_something) {
3100                                 fprintf(stderr, 
3101                                         "SEQ-THREAD: Requested frame "
3102                                         "not in queue ???\n");
3103                                 break;
3104                         }
3105                         pthread_mutex_lock(&frame_done_lock);
3106                         pthread_cond_wait(&frame_done_cond, &frame_done_lock);
3107                         pthread_mutex_unlock(&frame_done_lock);
3108                 }
3109         }
3110         
3111         return e ? e->ibuf : 0;
3112 }
3113
3114 /* Functions to free imbuf and anim data on changes */
3115
3116 static void free_imbuf_strip_elem(TStripElem *se)
3117 {
3118         if(se->ibuf) {
3119                 IMB_freeImBuf(se->ibuf);
3120         }
3121         if(se->ibuf_comp) {
3122                 IMB_freeImBuf(se->ibuf_comp);
3123         }
3124         se->ibuf_comp = 0;
3125         se->ibuf= 0;
3126         se->ok= STRIPELEM_OK;
3127         se->se1= se->se2= se->se3= 0;
3128 }
3129
3130 static void free_anim_seq(Sequence *seq)
3131 {
3132         if(seq->anim) {
3133                 IMB_free_anim(seq->anim);
3134                 seq->anim = 0;
3135         }
3136 }
3137
3138 #if 0
3139 static void free_imbuf_seq_except(Scene *scene, int cfra)
3140 {
3141         Editing *ed= seq_give_editing(scene, FALSE);
3142         Sequence *seq;
3143         TStripElem *se;
3144         int a;
3145
3146         if(ed==NULL) return;
3147
3148         SEQ_BEGIN(ed, seq) {
3149                 if(seq->strip) {
3150                         TStripElem * curelem = give_tstripelem(seq, cfra);
3151
3152                         for(a = 0, se = seq->strip->tstripdata; 
3153                             a < seq->strip->len && se; a++, se++) {
3154                                 if(se != curelem) {
3155                                         free_imbuf_strip_elem(se);
3156                                 }
3157                         }
3158                         for(a = 0, se = seq->strip->tstripdata_startstill;
3159                             a < seq->strip->startstill && se; a++, se++) {
3160                                 if(se != curelem) {
3161                                         free_imbuf_strip_elem(se);
3162                                 }
3163                         }
3164                         for(a = 0, se = seq->strip->tstripdata_endstill;
3165                             a < seq->strip->endstill && se; a++, se++) {
3166                                 if(se != curelem) {
3167                                         free_imbuf_strip_elem(se);
3168                                 }
3169                         }
3170                         if(seq->strip->ibuf_startstill) {
3171                                 IMB_freeImBuf(seq->strip->ibuf_startstill);
3172                                 seq->strip->ibuf_startstill = 0;
3173                         }
3174
3175                         if(seq->strip->ibuf_endstill) {
3176                                 IMB_freeImBuf(seq->strip->ibuf_endstill);
3177                                 seq->strip->ibuf_endstill = 0;
3178                         }
3179
3180                         if(seq->type==SEQ_MOVIE)
3181                                 if(seq->startdisp > cfra || seq->enddisp < cfra)
3182                                         free_anim_seq(seq);
3183                         free_proxy_seq(seq);
3184                 }
3185         }
3186         SEQ_END
3187 }
3188 #endif
3189
3190 void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage)
3191 {
3192         Sequence *seq;
3193         TStripElem *se;
3194         int a;
3195
3196         if (check_mem_usage) {
3197                 /* Let the cache limitor take care of this (schlaile) */
3198                 /* While render let's keep all memory available for render 
3199                    (ton)
3200                    At least if free memory is tight...
3201                    This can make a big difference in encoding speed
3202                    (it is around 4 times(!) faster, if we do not waste time
3203                    on freeing _all_ buffers every time on long timelines...)
3204                    (schlaile)
3205                 */
3206         
3207                 uintptr_t mem_in_use;
3208                 uintptr_t mmap_in_use;
3209                 uintptr_t max;
3210         
3211                 mem_in_use= MEM_get_memory_in_use();
3212                 mmap_in_use= MEM_get_mapped_memory_in_use();