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