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