J-key render switching back, now with 10 slots.
[blender-staging.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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                 seqUniqueName(scene->ed->seqbasep, 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 static char *give_seqname_by_type(int type)
724 {
725         switch(type) {
726         case SEQ_META:       return "Meta";
727         case SEQ_IMAGE:      return "Image";
728         case SEQ_SCENE:      return "Scene";
729         case SEQ_MOVIE:      return "Movie";
730         case SEQ_SOUND:      return "Audio";
731         case SEQ_CROSS:      return "Cross";
732         case SEQ_GAMCROSS:   return "Gamma Cross";
733         case SEQ_ADD:        return "Add";
734         case SEQ_SUB:        return "Sub";
735         case SEQ_MUL:        return "Mul";
736         case SEQ_ALPHAOVER:  return "Alpha Over";
737         case SEQ_ALPHAUNDER: return "Alpha Under";
738         case SEQ_OVERDROP:   return "Over Drop";
739         case SEQ_WIPE:       return "Wipe";
740         case SEQ_GLOW:       return "Glow";
741         case SEQ_TRANSFORM:  return "Transform";
742         case SEQ_COLOR:      return "Color";
743         case SEQ_SPEED:      return "Speed";
744         default:
745                 return 0;
746         }
747 }
748
749 char *give_seqname(Sequence *seq)
750 {
751         char * name = give_seqname_by_type(seq->type);
752
753         if (!name) {
754                 if(seq->type<SEQ_EFFECT) {
755                         return seq->strip->dir;
756                 } else if(seq->type==SEQ_PLUGIN) {
757                         if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
758                            seq->plugin && seq->plugin->doit) {
759                                 return seq->plugin->pname;
760                         } else {
761                                 return "Plugin";
762                         }
763                 } else {
764                         return "Effect";
765                 }
766         }
767         return name;
768 }
769
770 /* ***************** DO THE SEQUENCE ***************** */
771
772 static void make_black_ibuf(ImBuf *ibuf)
773 {
774         unsigned int *rect;
775         float *rect_float;
776         int tot;
777
778         if(ibuf==0 || (ibuf->rect==0 && ibuf->rect_float==0)) return;
779
780         tot= ibuf->x*ibuf->y;
781
782         rect= ibuf->rect;
783         rect_float = ibuf->rect_float;
784
785         if (rect) {
786                 memset(rect,       0, tot * sizeof(char) * 4);
787         }
788
789         if (rect_float) {
790                 memset(rect_float, 0, tot * sizeof(float) * 4);
791         }
792 }
793
794 static void multibuf(ImBuf *ibuf, float fmul)
795 {
796         char *rt;
797         float *rt_float;
798
799         int a, mul, icol;
800
801         mul= (int)(256.0*fmul);
802         rt= (char *)ibuf->rect;
803         rt_float = ibuf->rect_float;
804
805         if (rt) {
806                 a= ibuf->x*ibuf->y;
807                 while(a--) {
808
809                         icol= (mul*rt[0])>>8;
810                         if(icol>254) rt[0]= 255; else rt[0]= icol;
811                         icol= (mul*rt[1])>>8;
812                         if(icol>254) rt[1]= 255; else rt[1]= icol;
813                         icol= (mul*rt[2])>>8;
814                         if(icol>254) rt[2]= 255; else rt[2]= icol;
815                         icol= (mul*rt[3])>>8;
816                         if(icol>254) rt[3]= 255; else rt[3]= icol;
817                         
818                         rt+= 4;
819                 }
820         }
821         if (rt_float) {
822                 a= ibuf->x*ibuf->y;
823                 while(a--) {
824                         rt_float[0] *= fmul;
825                         rt_float[1] *= fmul;
826                         rt_float[2] *= fmul;
827                         rt_float[3] *= fmul;
828                         
829                         rt_float += 4;
830                 }
831         }
832 }
833
834 static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se)
835 {
836         TStripElem *se1, *se2, *se3;
837         float fac, facf;
838         int x, y;
839         int early_out;
840         struct SeqEffectHandle sh = get_sequence_effect(seq);
841         FCurve *fcu= NULL;
842
843         if (!sh.execute) { /* effect not supported in this version... */
844                 make_black_ibuf(se->ibuf);
845                 return;
846         }
847
848         if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
849                 sh.get_default_fac(seq, cfra, &fac, &facf);
850                 if( scene->r.mode & R_FIELDS ); else facf= fac;
851         } else {
852                 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, 
853                                           "effect_fader", 0);
854                 if (fcu) {
855                         fac = facf = evaluate_fcurve(fcu, cfra);
856                         if( scene->r.mode & R_FIELDS ) {
857                                 facf = evaluate_fcurve(fcu, cfra + 0.5);
858                         }
859                 } else {
860                         fac = facf = seq->effect_fader;
861                 }
862         }
863
864         early_out = sh.early_out(seq, fac, facf);
865
866         if (early_out == -1) { /* no input needed */
867                 sh.execute(scene, seq, cfra, fac, facf, 
868                            se->ibuf->x, se->ibuf->y, 
869                            0, 0, 0, se->ibuf);
870                 return;
871         }
872
873         switch (early_out) {
874         case 0:
875                 if (se->se1==0 || se->se2==0 || se->se3==0) {
876                         make_black_ibuf(se->ibuf);
877                         return;
878                 }
879
880                 se1= se->se1;
881                 se2= se->se2;
882                 se3= se->se3;
883
884                 if (   (se1==0 || se2==0 || se3==0)
885                     || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) {
886                         make_black_ibuf(se->ibuf);
887                         return;
888                 }
889
890                 break;
891         case 1:
892                 if (se->se1 == 0) {
893                         make_black_ibuf(se->ibuf);
894                         return;
895                 }
896
897                 se1= se->se1;
898
899                 if (se1 == 0 || se1->ibuf == 0) {
900                         make_black_ibuf(se->ibuf);
901                         return;
902                 }
903
904                 if (se->ibuf != se1->ibuf) {
905                         IMB_freeImBuf(se->ibuf);
906                         se->ibuf = se1->ibuf;
907                         IMB_refImBuf(se->ibuf);
908                 }
909                 return;
910         case 2:
911                 if (se->se2 == 0) {
912                         make_black_ibuf(se->ibuf);
913                         return;
914                 }
915
916                 se2= se->se2;
917
918                 if (se2 == 0 || se2->ibuf == 0) {
919                         make_black_ibuf(se->ibuf);
920                         return;
921                 }
922                 if (se->ibuf != se2->ibuf) {
923                         IMB_freeImBuf(se->ibuf);
924                         se->ibuf = se2->ibuf;
925                         IMB_refImBuf(se->ibuf);
926                 }
927                 return;
928         default:
929                 make_black_ibuf(se->ibuf);
930                 return;
931         }
932
933         x= se2->ibuf->x;
934         y= se2->ibuf->y;
935
936         if (!se1->ibuf->rect_float && se->ibuf->rect_float) {
937                 IMB_float_from_rect(se1->ibuf);
938         }
939         if (!se2->ibuf->rect_float && se->ibuf->rect_float) {
940                 IMB_float_from_rect(se2->ibuf);
941         }
942         if (!se3->ibuf->rect_float && se->ibuf->rect_float) {
943                 IMB_float_from_rect(se3->ibuf);
944         }
945         
946         if (!se1->ibuf->rect && !se->ibuf->rect_float) {
947                 IMB_rect_from_float(se1->ibuf);
948         }
949         if (!se2->ibuf->rect && !se->ibuf->rect_float) {
950                 IMB_rect_from_float(se2->ibuf);
951         }
952         if (!se3->ibuf->rect && !se->ibuf->rect_float) {
953                 IMB_rect_from_float(se3->ibuf);
954         }
955
956         sh.execute(scene, seq, cfra, fac, facf, x, y, se1->ibuf, se2->ibuf, se3->ibuf,
957                    se->ibuf);
958 }
959
960 static int give_stripelem_index(Sequence *seq, int cfra)
961 {
962         int nr;
963
964         if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1;
965         if(seq->len == 0) return -1;
966         if(seq->flag&SEQ_REVERSE_FRAMES) {      
967                 /*reverse frame in this sequence */
968                 if(cfra <= seq->start) nr= seq->len-1;
969                 else if(cfra >= seq->start+seq->len-1) nr= 0;
970                 else nr= (seq->start + seq->len) - cfra;
971         } else {
972                 if(cfra <= seq->start) nr= 0;
973                 else if(cfra >= seq->start+seq->len-1) nr= seq->len-1;
974                 else nr= cfra-seq->start;
975         }
976         if (seq->strobe < 1.0) seq->strobe = 1.0;
977         if (seq->strobe > 1.0) {
978                 nr -= (int)fmod((double)nr, (double)seq->strobe);
979         }
980
981         return nr;
982 }
983
984 static TStripElem* alloc_tstripdata(int len, const char * name)
985 {
986         int i;
987         TStripElem *se = MEM_callocN(len * sizeof(TStripElem), name);
988         for (i = 0; i < len; i++) {
989                 se[i].ok = STRIPELEM_OK;
990         }
991         return se;
992 }
993
994 static TStripElem *give_tstripelem(Sequence *seq, int cfra)
995 {
996         TStripElem *se;
997         int nr;
998
999         se = seq->strip->tstripdata;
1000         if (se == 0 && seq->len > 0) {
1001                 se = seq->strip->tstripdata = alloc_tstripdata(seq->len,
1002                                                                "tstripelems");
1003         }
1004         nr = give_stripelem_index(seq, cfra);
1005
1006         if (nr == -1) return 0;
1007         if (se == 0) return 0;
1008
1009         se += nr; 
1010
1011         /* if there are IPOs with blend modes active, one has to watch out
1012            for startstill + endstill area: we can't use the same tstripelem
1013            here for all ibufs, since then, blending with IPOs won't work!
1014            
1015            Rather common case, if you use a single image and try to fade
1016            it in and out... or want to use your strip as a watermark in
1017            alpha over mode...
1018         */
1019         if (seq->blend_mode != SEQ_BLEND_REPLACE ||
1020             (/*seq->ipo && seq->ipo->curve.first &&*/ 
1021                    (!(seq->type & SEQ_EFFECT) || !seq->seq1))) {
1022                 Strip * s = seq->strip;
1023                 if (cfra < seq->start) {
1024                         se = s->tstripdata_startstill;
1025                         if (seq->startstill > s->startstill) {
1026                                 free_tstripdata(s->startstill, 
1027                                                 s->tstripdata_startstill);
1028                                 se = 0;
1029                         }
1030
1031                         if (se == 0) {
1032                                 s->startstill = seq->startstill;
1033                                 se = seq->strip->tstripdata_startstill
1034                                         = alloc_tstripdata(
1035                                                 s->startstill,
1036                                                 "tstripelems_startstill");
1037                         }
1038                         se += seq->start - cfra - 1;
1039
1040                 } else if (cfra > seq->start + seq->len-1) {
1041                         se = s->tstripdata_endstill;
1042                         if (seq->endstill > s->endstill) {
1043                                 free_tstripdata(s->endstill, 
1044                                                 s->tstripdata_endstill);
1045                                 se = 0;
1046                         }
1047
1048                         if (se == 0) {
1049                                 s->endstill = seq->endstill;
1050                                 se = seq->strip->tstripdata_endstill
1051                                         = alloc_tstripdata(
1052                                                 s->endstill,
1053                                                 "tstripelems_endstill");
1054                         }
1055                         se += cfra - (seq->start + seq->len-1) - 1;
1056                 }
1057         }
1058
1059         
1060         se->nr= nr;
1061
1062         return se;
1063 }
1064
1065 StripElem *give_stripelem(Sequence *seq, int cfra)
1066 {
1067         StripElem *se= seq->strip->stripdata;
1068
1069         if(seq->type == SEQ_MOVIE) {
1070                 /* use the first */
1071         }
1072         else {
1073                 int nr = give_stripelem_index(seq, cfra);
1074
1075                 if (nr == -1) return 0;
1076                 if (se == 0) return 0;
1077         
1078                 se += nr + seq->anim_startofs;
1079         }
1080         return se;
1081 }
1082
1083 static int evaluate_seq_frame_gen(Sequence ** seq_arr, ListBase *seqbase, int cfra)
1084 {
1085         Sequence *seq;
1086         int totseq=0;
1087
1088         memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1));
1089
1090         seq= seqbase->first;
1091         while(seq) {
1092                 if(seq->startdisp <=cfra && seq->enddisp > cfra) {
1093                         seq_arr[seq->machine]= seq;
1094                         totseq++;
1095                 }
1096                 seq= seq->next;
1097         }
1098
1099         return totseq;
1100 }
1101
1102 int evaluate_seq_frame(Scene *scene, int cfra)
1103 {
1104         Editing *ed= seq_give_editing(scene, FALSE);
1105         Sequence *seq_arr[MAXSEQ+1];
1106
1107         if(ed==NULL) return 0;
1108         return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
1109 }
1110
1111 static int video_seq_is_rendered(Sequence * seq)
1112 {
1113         return (seq
1114                 && !(seq->flag & SEQ_MUTE)
1115                 && seq->type != SEQ_SOUND);
1116 }
1117
1118 static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
1119 {
1120         Sequence *seq_arr[MAXSEQ+1];
1121         int b = chanshown;
1122         int cnt = 0;
1123
1124         if (b > MAXSEQ) {
1125                 return 0;
1126         }
1127
1128         if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
1129                 if (b > 0) {
1130                         if (seq_arr[b] == 0) {
1131                                 return 0;
1132                         }
1133                 } else {
1134                         for (b = MAXSEQ; b > 0; b--) {
1135                                 if (video_seq_is_rendered(seq_arr[b])) {
1136                                         break;
1137                                 }
1138                         }
1139                 }
1140         }
1141         
1142         chanshown = b;
1143
1144         for (;b > 0; b--) {
1145                 if (video_seq_is_rendered(seq_arr[b])) {
1146                         if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
1147                                 break;
1148                         }
1149                 }
1150         }
1151
1152         for (;b <= chanshown; b++) {
1153                 if (video_seq_is_rendered(seq_arr[b])) {
1154                         seq_arr_out[cnt++] = seq_arr[b];
1155                 }
1156         }
1157
1158         return cnt;
1159 }
1160  
1161
1162 /* **********************************************************************
1163    proxy management
1164    ********************************************************************** */
1165
1166 #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
1167
1168 static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * name, int render_size)
1169 {
1170         int frameno;
1171         char dir[FILE_MAXDIR];
1172
1173         if (!seq->strip->proxy) {
1174                 return FALSE;
1175         }
1176
1177         if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
1178                 strcpy(dir, seq->strip->proxy->dir);
1179         } else {
1180                 if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
1181                         snprintf(dir, FILE_MAXDIR, "%s/BL_proxy", 
1182                                  seq->strip->dir);
1183                 } else {
1184                         return FALSE;
1185                 }
1186         }
1187
1188         if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1189                 BLI_join_dirfile(name, dir, seq->strip->proxy->file);
1190                 BLI_convertstringcode(name, G.sce);
1191
1192                 return TRUE;
1193         }
1194
1195         /* generate a separate proxy directory for each preview size */
1196
1197         if (seq->type == SEQ_IMAGE) {
1198                 StripElem * se = give_stripelem(seq, cfra);
1199                 snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy",
1200                          dir, render_size, se->name);
1201                 frameno = 1;
1202         } else if (seq->type == SEQ_MOVIE) {
1203                 TStripElem * tse = give_tstripelem(seq, cfra);
1204
1205                 frameno = tse->nr + seq->anim_startofs;
1206
1207                 snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir,
1208                          seq->strip->stripdata->name,
1209                          render_size);
1210         } else {
1211                 TStripElem * tse = give_tstripelem(seq, cfra);
1212
1213                 frameno = tse->nr + seq->anim_startofs;
1214
1215                 snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
1216                          render_size);
1217         }
1218
1219         BLI_convertstringcode(name, G.sce);
1220         BLI_convertstringframe(name, frameno, 0);
1221
1222
1223         strcat(name, ".jpg");
1224
1225         return TRUE;
1226 }
1227
1228 static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra, int render_size)
1229 {
1230         char name[PROXY_MAXFILE];
1231
1232         if (!(seq->flag & SEQ_USE_PROXY)) {
1233                 return 0;
1234         }
1235
1236         /* rendering at 100% ? No real sense in proxy-ing, right? */
1237         if (render_size == 100) {
1238                 return 0;
1239         }
1240
1241         if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1242                 TStripElem * tse = give_tstripelem(seq, cfra);
1243                 int frameno = tse->nr + seq->anim_startofs;
1244                 if (!seq->strip->proxy->anim) {
1245                         if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1246                                 return 0;
1247                         }
1248  
1249                         seq->strip->proxy->anim = openanim(name, IB_rect);
1250                 }
1251                 if (!seq->strip->proxy->anim) {
1252                         return 0;
1253                 }
1254  
1255                 return IMB_anim_absolute(seq->strip->proxy->anim, frameno);
1256         }
1257  
1258         if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1259                 return 0;
1260         }
1261
1262         if (BLI_exists(name)) {
1263                 return IMB_loadiffname(name, IB_rect);
1264         } else {
1265                 return 0;
1266         }
1267 }
1268
1269 #if 0
1270 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1271                               int build_proxy_run, int render_size);
1272
1273 static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int render_size)
1274 {
1275         char name[PROXY_MAXFILE];
1276         int quality;
1277         TStripElem * se;
1278         int ok;
1279         int rectx, recty;
1280         struct ImBuf * ibuf;
1281
1282         if (!(seq->flag & SEQ_USE_PROXY)) {
1283                 return;
1284         }
1285
1286         /* rendering at 100% ? No real sense in proxy-ing, right? */
1287         if (render_size == 100) {
1288                 return;
1289         }
1290
1291         /* that's why it is called custom... */
1292         if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1293                 return;
1294     }
1295
1296         if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1297                 return;
1298         }
1299
1300         se = give_tstripelem(seq, cfra);
1301         if (!se) {
1302                 return;
1303         }
1304
1305         if(se->ibuf) {
1306                 IMB_freeImBuf(se->ibuf);
1307                 se->ibuf = 0;
1308         }
1309         
1310         do_build_seq_ibuf(scene, seq, se, cfra, TRUE, render_size);
1311
1312         if (!se->ibuf) {
1313                 return;
1314         }
1315
1316         rectx= (render_size*scene->r.xsch)/100;
1317         recty= (render_size*scene->r.ysch)/100;
1318
1319         ibuf = se->ibuf;
1320
1321         if (ibuf->x != rectx || ibuf->y != recty) {
1322                 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1323         }
1324
1325         /* quality is fixed, otherwise one has to generate separate
1326            directories for every quality...
1327
1328            depth = 32 is intentionally left in, otherwise ALPHA channels
1329            won't work... */
1330         quality = seq->strip->proxy->quality;
1331         ibuf->ftype= JPG | quality;
1332
1333         BLI_make_existing_file(name);
1334         
1335         ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
1336         if (ok == 0) {
1337                 perror(name);
1338         }
1339
1340         IMB_freeImBuf(ibuf);
1341         se->ibuf = 0;
1342 }
1343
1344 static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
1345 {
1346         int cfra;
1347         float rsize = seq->strip->proxy->size;
1348
1349         waitcursor(1);
1350
1351         G.afbreek = 0;
1352
1353         /* flag management tries to account for strobe and 
1354            other "non-linearities", that might come in the future...
1355            better way would be to "touch" the files, so that _really_
1356            no one is rebuild twice.
1357          */
1358
1359         for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
1360                 TStripElem * tse = give_tstripelem(seq, cfra);
1361
1362                 tse->flag &= ~STRIPELEM_PREVIEW_DONE;
1363         }
1364
1365         
1366
1367         /* a _lot_ faster for movie files, if we read frames in
1368            sequential order */
1369         if (seq->flag & SEQ_REVERSE_FRAMES) {
1370                 for (cfra = seq->enddisp-seq->endstill-1; 
1371                      cfra >= seq->startdisp + seq->startstill; cfra--) {
1372                         TStripElem * tse = give_tstripelem(seq, cfra);
1373
1374                         if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1375 //XXX                           set_timecursor(cfra);
1376                                 seq_proxy_build_frame(scene, seq, cfra, rsize);
1377                                 tse->flag |= STRIPELEM_PREVIEW_DONE;
1378                         }
1379                         if (blender_test_break()) {
1380                                 break;
1381                         }
1382                 }
1383         } else {
1384                 for (cfra = seq->startdisp + seq->startstill; 
1385                      cfra < seq->enddisp - seq->endstill; cfra++) {
1386                         TStripElem * tse = give_tstripelem(seq, cfra);
1387
1388                         if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1389 //XXX                           set_timecursor(cfra);
1390                                 seq_proxy_build_frame(scene, seq, cfra, rsize);
1391                                 tse->flag |= STRIPELEM_PREVIEW_DONE;
1392                         }
1393                         if (blender_test_break()) {
1394                                 break;
1395                         }
1396                 }
1397         }
1398         waitcursor(0);
1399 }
1400 #endif
1401
1402
1403 /* **********************************************************************
1404    color balance 
1405    ********************************************************************** */
1406
1407 static StripColorBalance calc_cb(StripColorBalance * cb_)
1408 {
1409         StripColorBalance cb = *cb_;
1410         int c;
1411
1412         if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
1413                 for (c = 0; c < 3; c++) {
1414                         cb.lift[c] = 1.0 - cb.lift[c];
1415                 }
1416         } else {
1417                 for (c = 0; c < 3; c++) {
1418                         cb.lift[c] = -(1.0 - cb.lift[c]);
1419                 }
1420         }
1421         if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
1422                 for (c = 0; c < 3; c++) {
1423                         if (cb.gain[c] != 0.0) {
1424                                 cb.gain[c] = 1.0/cb.gain[c];
1425                         } else {
1426                                 cb.gain[c] = 1000000; /* should be enough :) */
1427                         }
1428                 }
1429         }
1430
1431         if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
1432                 for (c = 0; c < 3; c++) {
1433                         if (cb.gamma[c] != 0.0) {
1434                                 cb.gamma[c] = 1.0/cb.gamma[c];
1435                         } else {
1436                                 cb.gamma[c] = 1000000; /* should be enough :) */
1437                         }
1438                 }
1439         }
1440
1441         return cb;
1442 }
1443
1444 static void make_cb_table_byte(float lift, float gain, float gamma,
1445                                unsigned char * table, float mul)
1446 {
1447         int y;
1448
1449         for (y = 0; y < 256; y++) {
1450                 float v = 1.0 * y / 255;
1451                 v *= gain;
1452                 v += lift; 
1453                 v = pow(v, gamma);
1454                 v *= mul;
1455                 if ( v > 1.0) {
1456                         v = 1.0;
1457                 } else if (v < 0.0) {
1458                         v = 0.0;
1459                 }
1460                 table[y] = v * 255;
1461         }
1462
1463 }
1464
1465 static void make_cb_table_float(float lift, float gain, float gamma,
1466                                 float * table, float mul)
1467 {
1468         int y;
1469
1470         for (y = 0; y < 256; y++) {
1471                 float v = (float) y * 1.0 / 255.0;
1472                 v *= gain;
1473                 v += lift;
1474                 v = pow(v, gamma);
1475                 v *= mul;
1476                 table[y] = v;
1477         }
1478 }
1479
1480 static void color_balance_byte_byte(Sequence * seq, TStripElem* se, float mul)
1481 {
1482         unsigned char cb_tab[3][256];
1483         int c;
1484         unsigned char * p = (unsigned char*) se->ibuf->rect;
1485         unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1486
1487         StripColorBalance cb = calc_cb(seq->strip->color_balance);
1488
1489         for (c = 0; c < 3; c++) {
1490                 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1491                                    cb_tab[c], mul);
1492         }
1493
1494         while (p < e) {
1495                 p[0] = cb_tab[0][p[0]];
1496                 p[1] = cb_tab[1][p[1]];
1497                 p[2] = cb_tab[2][p[2]];
1498                 
1499                 p += 4;
1500         }
1501 }
1502
1503 static void color_balance_byte_float(Sequence * seq, TStripElem* se, float mul)
1504 {
1505         float cb_tab[4][256];
1506         int c,i;
1507         unsigned char * p = (unsigned char*) se->ibuf->rect;
1508         unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1509         float * o;
1510         StripColorBalance cb;
1511
1512         imb_addrectfloatImBuf(se->ibuf);
1513
1514         o = se->ibuf->rect_float;
1515
1516         cb = calc_cb(seq->strip->color_balance);
1517
1518         for (c = 0; c < 3; c++) {
1519                 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
1520                                     cb_tab[c], mul);
1521         }
1522
1523         for (i = 0; i < 256; i++) {
1524                 cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
1525         }
1526
1527         while (p < e) {
1528                 o[0] = cb_tab[0][p[0]];
1529                 o[1] = cb_tab[1][p[1]];
1530                 o[2] = cb_tab[2][p[2]];
1531                 o[3] = cb_tab[3][p[3]];
1532
1533                 p += 4; o += 4;
1534         }
1535 }
1536
1537 static void color_balance_float_float(Sequence * seq, TStripElem* se, float mul)
1538 {
1539         float * p = se->ibuf->rect_float;
1540         float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y;
1541         StripColorBalance cb = calc_cb(seq->strip->color_balance);
1542
1543         while (p < e) {
1544                 int c;
1545                 for (c = 0; c < 3; c++) {
1546                         p[c] = pow(p[c] * cb.gain[c] + cb.lift[c], 
1547                                    cb.gamma[c]) * mul;
1548                 }
1549                 p += 4;
1550         }
1551 }
1552
1553 static void color_balance(Sequence * seq, TStripElem* se, float mul)
1554 {
1555         if (se->ibuf->rect_float) {
1556                 color_balance_float_float(seq, se, mul);
1557         } else if(seq->flag & SEQ_MAKE_FLOAT) {
1558                 color_balance_byte_float(seq, se, mul);
1559         } else {
1560                 color_balance_byte_byte(seq, se, mul);
1561         }
1562 }
1563
1564 /*
1565   input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
1566
1567   Do all the things you can't really do afterwards using sequence effects
1568   (read: before rescaling to render resolution has been done)
1569
1570   Order is important!
1571
1572   - Deinterlace
1573   - Crop and transform in image source coordinate space
1574   - Flip X + Flip Y (could be done afterwards, backward compatibility)
1575   - Promote image to float data (affects pipeline operations afterwards)
1576   - Color balance (is most efficient in the byte -> float 
1577     (future: half -> float should also work fine!)
1578     case, if done on load, since we can use lookup tables)
1579   - Premultiply
1580
1581 */
1582
1583 static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se, int cfra)
1584 {
1585         float mul;
1586
1587         if ((seq->flag & SEQ_FILTERY) || 
1588             (seq->flag & SEQ_USE_CROP) ||
1589             (seq->flag & SEQ_USE_TRANSFORM) ||
1590             (seq->flag & SEQ_FLIPX) ||
1591             (seq->flag & SEQ_FLIPY) ||
1592             (seq->flag & SEQ_USE_COLOR_BALANCE) ||
1593             (seq->flag & SEQ_MAKE_PREMUL) ||
1594             (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
1595                 return TRUE;
1596         }
1597
1598         mul = seq->mul;
1599
1600         if(seq->blend_mode == SEQ_BLEND_REPLACE &&
1601            !(seq->type & SEQ_EFFECT)) {
1602                 mul *= seq->blend_opacity / 100.0;
1603         }
1604
1605         if (mul != 1.0) {
1606                 return TRUE;
1607         }
1608                 
1609         return FALSE;
1610 }
1611
1612 static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cfra)
1613 {
1614         float mul;
1615
1616         seq->strip->orx= se->ibuf->x;
1617         seq->strip->ory= se->ibuf->y;
1618
1619         if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
1620                 IMB_filtery(se->ibuf);
1621         }
1622
1623         if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
1624                 StripCrop c;
1625                 StripTransform t;
1626                 int sx,sy,dx,dy;
1627
1628                 memset(&c, 0, sizeof(StripCrop));
1629                 memset(&t, 0, sizeof(StripTransform));
1630
1631                 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1632                         c = *seq->strip->crop;
1633                 }
1634                 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1635                         t = *seq->strip->transform;
1636                 }
1637
1638                 sx = se->ibuf->x - c.left - c.right;
1639                 sy = se->ibuf->y - c.top - c.bottom;
1640                 dx = sx;
1641                 dy = sy;
1642
1643                 if (seq->flag & SEQ_USE_TRANSFORM) {
1644                         dx = scene->r.xsch;
1645                         dy = scene->r.ysch;
1646                 }
1647
1648                 if (c.top + c.bottom >= se->ibuf->y ||
1649                     c.left + c.right >= se->ibuf->x ||
1650                     t.xofs >= dx || t.yofs >= dy) {
1651                         make_black_ibuf(se->ibuf);
1652                 } else {
1653                         ImBuf * i;
1654
1655                         if (se->ibuf->rect_float) {
1656                                 i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0);
1657                         } else {
1658                                 i = IMB_allocImBuf(dx, dy,32, IB_rect, 0);
1659                         }
1660
1661                         IMB_rectcpy(i, se->ibuf, 
1662                                     t.xofs, t.yofs, 
1663                                     c.left, c.bottom, 
1664                                     sx, sy);
1665
1666                         IMB_freeImBuf(se->ibuf);
1667
1668                         se->ibuf = i;
1669                 }
1670         } 
1671
1672         if(seq->flag & SEQ_FLIPX) {
1673                 IMB_flipx(se->ibuf);
1674         }
1675         if(seq->flag & SEQ_FLIPY) {
1676                 IMB_flipy(se->ibuf);
1677         }
1678
1679         if(seq->mul == 0.0) {
1680                 seq->mul = 1.0;
1681         }
1682
1683         mul = seq->mul;
1684
1685         if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1686                 mul *= seq->blend_opacity / 100.0;
1687         }
1688
1689         if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1690                 color_balance(seq, se, mul);
1691                 mul = 1.0;
1692         }
1693
1694         if(seq->flag & SEQ_MAKE_FLOAT) {
1695                 if (!se->ibuf->rect_float) {
1696                         if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
1697                                 IMB_float_from_rect(se->ibuf);
1698                         } else {
1699                                 int profile = IB_PROFILE_NONE;
1700                                 
1701                                 /* no color management:
1702                                  * don't disturb the existing profiles */
1703                                 SWAP(int, se->ibuf->profile, profile);
1704
1705                                 IMB_float_from_rect(se->ibuf);
1706                                 
1707                                 SWAP(int, se->ibuf->profile, profile);
1708                         }
1709                 }
1710                 if (se->ibuf->rect) {
1711                         imb_freerectImBuf(se->ibuf);
1712                 }
1713         }
1714
1715         if(mul != 1.0) {
1716                 multibuf(se->ibuf, mul);
1717         }
1718
1719         if(seq->flag & SEQ_MAKE_PREMUL) {
1720                 if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
1721                         converttopremul(se->ibuf);
1722                 }
1723         }
1724
1725
1726         if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
1727                 if(scene->r.mode & R_OSA) {
1728                         IMB_scaleImBuf(se->ibuf, 
1729                                        (short)seqrectx, (short)seqrecty);
1730                 } else {
1731                         IMB_scalefastImBuf(se->ibuf, 
1732                                            (short)seqrectx, (short)seqrecty);
1733                 }
1734         }
1735 }
1736
1737 /* test if image too small or discarded from cache: reload */
1738
1739 static void test_and_auto_discard_ibuf(TStripElem * se)
1740 {
1741         if (se->ibuf) {
1742                 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty 
1743                    || !(se->ibuf->rect || se->ibuf->rect_float)) {
1744                         IMB_freeImBuf(se->ibuf);
1745
1746                         se->ibuf= 0;
1747                         se->ok= STRIPELEM_OK;
1748                 }
1749         }
1750         if (se->ibuf_comp) {
1751                 if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty 
1752                    || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) {
1753                         IMB_freeImBuf(se->ibuf_comp);
1754
1755                         se->ibuf_comp = 0;
1756                 }
1757         }
1758 }
1759
1760 static void test_and_auto_discard_ibuf_stills(Strip * strip)
1761 {
1762         if (strip->ibuf_startstill) {
1763                 if (!strip->ibuf_startstill->rect &&
1764                     !strip->ibuf_startstill->rect_float) {
1765                         IMB_freeImBuf(strip->ibuf_startstill);
1766                         strip->ibuf_startstill = 0;
1767                 }
1768         }
1769         if (strip->ibuf_endstill) {
1770                 if (!strip->ibuf_endstill->rect &&
1771                     !strip->ibuf_endstill->rect_float) {
1772                         IMB_freeImBuf(strip->ibuf_endstill);
1773                         strip->ibuf_endstill = 0;
1774                 }
1775         }
1776 }
1777
1778 static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
1779 {
1780         if (!se->ibuf) {
1781                 if (se->nr == 0 && seq->strip->ibuf_startstill) {
1782                         IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1783
1784                         se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
1785                 }
1786                 if (se->nr == seq->len - 1 
1787                     && (seq->len != 1)
1788                     && seq->strip->ibuf_endstill) {
1789                         IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1790
1791                         se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
1792                 }
1793         }
1794 }
1795
1796 static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
1797 {
1798         if (se->ibuf) {
1799                 if (se->nr == 0) {
1800                         seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
1801
1802                         IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
1803                         IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1804                 }
1805                 if (se->nr == seq->len - 1 && seq->len != 1) {
1806                         seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
1807
1808                         IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
1809                         IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1810                 }
1811         }
1812 }
1813
1814 static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown)
1815 {
1816         Sequence* seq_arr[MAXSEQ+1];
1817         int i;
1818         TStripElem* se = 0;
1819
1820         evaluate_seq_frame_gen(seq_arr, seqbasep, cfra);
1821
1822         for (i = 0; i < MAXSEQ; i++) {
1823                 if (!video_seq_is_rendered(seq_arr[i])) {
1824                         continue;
1825                 }
1826                 se = give_tstripelem(seq_arr[i], cfra);
1827                 if (se) {
1828                         if (se->ibuf) {
1829                                 IMB_freeImBuf(se->ibuf);
1830
1831                                 se->ibuf= 0;
1832                                 se->ok= STRIPELEM_OK;
1833                         }
1834
1835                         if (se->ibuf_comp) {
1836                                 IMB_freeImBuf(se->ibuf_comp);
1837
1838                                 se->ibuf_comp = 0;
1839                         }
1840                 }
1841         }
1842         
1843 }
1844
1845 static void check_limiter_refcount(const char * func, TStripElem *se)
1846 {
1847         if (se && se->ibuf) {
1848                 int refcount = IMB_cache_limiter_get_refcount(se->ibuf);
1849                 if (refcount != 1) {
1850                         /* can happen on complex pipelines */
1851                         if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1852                                 return;
1853                         }
1854  
1855                         fprintf(stderr, 
1856                                 "sequencer: (ibuf) %s: "
1857                                 "suspicious memcache "
1858                                 "limiter refcount: %d\n", func, refcount);
1859                 }
1860         }
1861 }
1862  
1863 static void check_limiter_refcount_comp(const char * func, TStripElem *se)
1864 {
1865         if (se && se->ibuf_comp) {
1866                 int refcount = IMB_cache_limiter_get_refcount(se->ibuf_comp);
1867                 if (refcount != 1) {
1868                         /* can happen on complex pipelines */
1869                         if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1870                                 return;
1871                         }
1872                         fprintf(stderr, 
1873                                 "sequencer: (ibuf comp) %s: "
1874                                 "suspicious memcache "
1875                                 "limiter refcount: %d\n", func, refcount);
1876                 }
1877         }
1878 }
1879
1880 static TStripElem* do_build_seq_array_recursively(Scene *scene,
1881                                 ListBase *seqbasep, int cfra, int chanshown, int render_size);
1882
1883 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1884                               int build_proxy_run, int render_size)
1885 {
1886         char name[FILE_MAXDIR+FILE_MAXFILE];
1887         int use_limiter = TRUE;
1888
1889         test_and_auto_discard_ibuf(se);
1890         test_and_auto_discard_ibuf_stills(seq->strip);
1891
1892         if(seq->type == SEQ_META) {
1893                 TStripElem * meta_se = 0;
1894                 int use_preprocess = FALSE;
1895                 use_limiter = FALSE;
1896
1897                 if (!build_proxy_run && se->ibuf == 0) {
1898                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1899                         if (se->ibuf) {
1900                                 use_limiter = TRUE;
1901                                 use_preprocess = TRUE;
1902                         }
1903                 }
1904
1905                 if(!se->ibuf && seq->seqbase.first) {
1906                         meta_se = do_build_seq_array_recursively(scene,
1907                                 &seq->seqbase, seq->start + se->nr, 0,
1908                                 render_size);
1909
1910                         check_limiter_refcount("do_build_seq_ibuf: for META", meta_se);
1911                 }
1912
1913                 se->ok = STRIPELEM_OK;
1914
1915                 if(!se->ibuf && meta_se) {
1916                         se->ibuf = meta_se->ibuf_comp;
1917                         if(se->ibuf &&
1918                            (!input_have_to_preprocess(scene, seq, se, cfra) ||
1919                             build_proxy_run)) {
1920                                 IMB_refImBuf(se->ibuf);
1921                                 if (build_proxy_run) {
1922                                         IMB_cache_limiter_unref(se->ibuf);
1923                                 }
1924                         } else if (se->ibuf) {
1925                                 struct ImBuf * i = IMB_dupImBuf(se->ibuf);
1926
1927                                 IMB_cache_limiter_unref(se->ibuf);
1928
1929                                 se->ibuf = i;
1930
1931                                 use_limiter = TRUE;
1932                                 use_preprocess = TRUE;
1933                         }
1934                 } else if (se->ibuf) {
1935                         use_limiter = TRUE;
1936                 }
1937                 if (meta_se) {
1938                         free_metastrip_imbufs(
1939                                 &seq->seqbase, seq->start + se->nr, 0);
1940                 }
1941
1942                 if (use_preprocess) {
1943                         input_preprocess(scene, seq, se, cfra);
1944                 }
1945         } else if(seq->type & SEQ_EFFECT) {
1946                 int use_preprocess = FALSE;
1947                 /* should the effect be recalculated? */
1948                 
1949                 if (!build_proxy_run && se->ibuf == 0) {
1950                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1951                         if (se->ibuf) {
1952                                 use_preprocess = TRUE;
1953                         }
1954                 }
1955
1956                 if(se->ibuf == 0) {
1957                         /* if any inputs are rectfloat, output is float too */
1958                         if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
1959                            (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float) ||
1960                            (se->se3 && se->se3->ibuf && se->se3->ibuf->rect_float))
1961                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
1962                         else
1963                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
1964                         
1965                         do_effect(scene, cfra, seq, se);
1966                         if (input_have_to_preprocess(scene, seq, se, cfra) &&
1967                             !build_proxy_run) {
1968                                 if ((se->se1 && (se->ibuf == se->se1->ibuf)) ||
1969                                     (se->se2 && (se->ibuf == se->se2->ibuf))) {
1970                                         struct ImBuf * i
1971                                                 = IMB_dupImBuf(se->ibuf);
1972
1973                                         IMB_freeImBuf(se->ibuf);
1974
1975                                         se->ibuf = i;
1976                                 }
1977                                 use_preprocess = TRUE;
1978                         }
1979                 }
1980                 if (use_preprocess) {
1981                         input_preprocess(scene, seq, se, cfra);
1982                 }
1983         } else if(seq->type == SEQ_IMAGE) {
1984                 if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
1985                         StripElem * s_elem = give_stripelem(seq, cfra);
1986                         BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
1987                         BLI_convertstringcode(name, G.sce);
1988                         if (!build_proxy_run) {
1989                                 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1990                         }
1991                         copy_from_ibuf_still(seq, se);
1992
1993                         if (!se->ibuf) {
1994                                 se->ibuf= IMB_loadiffname(
1995                                         name, IB_rect);
1996                                 /* we don't need both (speed reasons)! */
1997                                 if (se->ibuf &&
1998                                         se->ibuf->rect_float && se->ibuf->rect) {
1999                                         imb_freerectImBuf(se->ibuf);
2000                                 }
2001
2002                                 copy_to_ibuf_still(seq, se);
2003                         }
2004                         
2005                         if(se->ibuf == 0) {
2006                                 se->ok = STRIPELEM_FAILED;
2007                         } else if (!build_proxy_run) {
2008                                 input_preprocess(scene, seq, se, cfra);
2009                         }
2010                 }
2011         } else if(seq->type == SEQ_MOVIE) {
2012                 if(se->ok == STRIPELEM_OK && se->ibuf==0) {
2013                         if(!build_proxy_run) {
2014                                 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2015                         }
2016                         copy_from_ibuf_still(seq, se);
2017
2018                         if (se->ibuf == 0) {
2019                                 if(seq->anim==0) {
2020                                         BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
2021                                         BLI_convertstringcode(name, G.sce);
2022                                         
2023                                         seq->anim = openanim(
2024                                                 name, IB_rect | 
2025                                                 ((seq->flag & SEQ_FILTERY) 
2026                                                  ? IB_animdeinterlace : 0));
2027                                 }
2028                                 if(seq->anim) {
2029                                         IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
2030                                         se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
2031                                         /* we don't need both (speed reasons)! */
2032                                         if (se->ibuf 
2033                                             && se->ibuf->rect_float 
2034                                             && se->ibuf->rect) {
2035                                                 imb_freerectImBuf(se->ibuf);
2036                                         }
2037
2038                                 }
2039                                 copy_to_ibuf_still(seq, se);
2040                         }
2041                         
2042                         if(se->ibuf == 0) {
2043                                 se->ok = STRIPELEM_FAILED;
2044                         } else if (!build_proxy_run) {
2045                                 input_preprocess(scene, seq, se, cfra);
2046                         }
2047                 }
2048         } else if(seq->type == SEQ_SCENE) {     // scene can be NULL after deletions
2049                 Scene *sce= seq->scene;// *oldsce= scene;
2050                 Render *re;
2051                 RenderResult rres;
2052                 int have_seq= FALSE;
2053                 int sce_valid= FALSE;
2054
2055                 if(sce) {
2056                         have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first;
2057                         sce_valid= (sce->camera || have_seq);
2058                 }
2059
2060                 if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
2061                         se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2062                         if (se->ibuf) {
2063                                 input_preprocess(scene, seq, se, cfra);
2064                         }
2065                 }
2066
2067                 if (se->ibuf == NULL && sce_valid) {
2068                         copy_from_ibuf_still(seq, se);
2069                         if (se->ibuf) {
2070                                 input_preprocess(scene, seq, se, cfra);
2071                         }
2072                 }
2073                 
2074                 if (!sce_valid) {
2075                         se->ok = STRIPELEM_FAILED;
2076                 } else if (se->ibuf==NULL && sce_valid) {
2077                         int oldcfra;
2078                         /* Hack! This function can be called from do_render_seq(), in that case
2079                            the seq->scene can already have a Render initialized with same name, 
2080                            so we have to use a default name. (compositor uses scene name to
2081                            find render).
2082                            However, when called from within the UI (image preview in sequencer)
2083                            we do want to use scene Render, that way the render result is defined
2084                            for display in render/imagewindow 
2085
2086                            Hmm, don't see, why we can't do that all the time, 
2087                            and since G.rendering is uhm, gone... (Peter)
2088                         */
2089
2090                         int rendering = 1;
2091                         int doseq;
2092
2093                         oldcfra = seq->scene->r.cfra;
2094
2095                         if(rendering)
2096                                 re= RE_NewRender(" do_build_seq_ibuf", RE_SLOT_DEFAULT);
2097                         else
2098                                 re= RE_NewRender(sce->id.name, RE_SLOT_VIEW);
2099                         
2100                         /* prevent eternal loop */
2101                         doseq= scene->r.scemode & R_DOSEQ;
2102                         scene->r.scemode &= ~R_DOSEQ;
2103                         
2104                         RE_BlenderFrame(re, sce, NULL,
2105                                         seq->sfra+se->nr+seq->anim_startofs);
2106                         
2107                         RE_AcquireResultImage(re, &rres);
2108                         
2109                         if(rres.rectf) {
2110                                 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
2111                                 memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
2112                                 if(rres.rectz) {
2113                                         addzbuffloatImBuf(se->ibuf);
2114                                         memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
2115                                 }
2116                         } else if (rres.rect32) {
2117                                 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
2118                                 memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
2119                         }
2120
2121                         RE_ReleaseResultImage(re);
2122                         
2123                         // BIF_end_render_callbacks();
2124                         
2125                         /* restore */
2126                         scene->r.scemode |= doseq;
2127                 
2128                         seq->scene->r.cfra = oldcfra;
2129
2130                         copy_to_ibuf_still(seq, se);
2131
2132                         if (!build_proxy_run) {
2133                                 if(se->ibuf == NULL) {
2134                                         se->ok = STRIPELEM_FAILED;
2135                                 } else {
2136                                         input_preprocess(scene, seq, se, cfra);
2137                                 }
2138                         }
2139
2140                 }
2141         }
2142         if (!build_proxy_run) {
2143                 if (se->ibuf && use_limiter) {
2144                         IMB_cache_limiter_insert(se->ibuf);
2145                         IMB_cache_limiter_ref(se->ibuf);
2146                         IMB_cache_limiter_touch(se->ibuf);
2147                 }
2148         }
2149 }
2150
2151 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size);
2152
2153 static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size)
2154 {
2155         float fac, facf;
2156         struct SeqEffectHandle sh = get_sequence_effect(seq);
2157         int early_out;
2158         FCurve *fcu= NULL;
2159
2160         se->se1 = 0;
2161         se->se2 = 0;
2162         se->se3 = 0;
2163
2164         if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
2165                 sh.get_default_fac(seq, cfra, &fac, &facf);
2166                 if( scene->r.mode & R_FIELDS ); else facf= fac;
2167         } else {
2168                 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, 
2169                                           "effect_fader", 0);
2170                 if (fcu) {
2171                         fac = facf = evaluate_fcurve(fcu, cfra);
2172                         if( scene->r.mode & R_FIELDS ) {
2173                                 facf = evaluate_fcurve(fcu, cfra + 0.5);
2174                         }
2175                 } else {
2176                         fac = facf = seq->effect_fader;
2177                 }
2178         }
2179
2180         early_out = sh.early_out(seq, fac, facf);
2181         switch (early_out) {
2182         case -1:
2183                 /* no input needed */
2184                 break;
2185         case 0:
2186                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2187                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2188                 if (seq->seq3) {
2189                         se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size);
2190                 }
2191                 break;
2192         case 1:
2193                 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2194                 break;
2195         case 2:
2196                 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2197                 break;
2198         }
2199
2200
2201         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2202
2203         /* children are not needed anymore ... */
2204
2205         if (se->se1 && se->se1->ibuf) {
2206                 IMB_cache_limiter_unref(se->se1->ibuf);
2207         }
2208         if (se->se2 && se->se2->ibuf) {
2209                 IMB_cache_limiter_unref(se->se2->ibuf);
2210         }
2211         if (se->se3 && se->se3->ibuf) {
2212                 IMB_cache_limiter_unref(se->se3->ibuf);
2213         }
2214         check_limiter_refcount("do_effect_seq_recursively", se);
2215 }
2216
2217 static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size)
2218 {
2219         TStripElem *se;
2220
2221         se = give_tstripelem(seq, cfra);
2222
2223         if(se) {
2224                 if (seq->type & SEQ_EFFECT) {
2225                         do_effect_seq_recursively(scene, seq, se, cfra, render_size);
2226                 } else {
2227                         do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2228                 }
2229         }
2230         return se;
2231 }
2232
2233 /* FIXME:
2234    
2235 If cfra was float throughout blender (especially in the render
2236 pipeline) one could even _render_ with subframe precision
2237 instead of faking using the blend code below...
2238
2239 */
2240
2241 static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size)
2242 {
2243         SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
2244         int nr = cfra - seq->start;
2245         float f_cfra;
2246         int cfra_left;
2247         int cfra_right;
2248         TStripElem * se = 0;
2249         TStripElem * se1 = 0;
2250         TStripElem * se2 = 0;
2251         
2252         sequence_effect_speed_rebuild_map(scene, seq, 0);
2253         
2254         f_cfra = seq->start + s->frameMap[nr];
2255         
2256         cfra_left = (int) floor(f_cfra);
2257         cfra_right = (int) ceil(f_cfra);
2258
2259         se = give_tstripelem(seq, cfra);
2260
2261         if (!se) {
2262                 return se;
2263         }
2264
2265         if (cfra_left == cfra_right || 
2266             (s->flags & SEQ_SPEED_BLEND) == 0) {
2267                 test_and_auto_discard_ibuf(se);
2268
2269                 if (se->ibuf == NULL) {
2270                         se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2271
2272                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2273                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2274                         else
2275                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2276
2277                         if (se1 == 0 || se1->ibuf == 0) {
2278                                 make_black_ibuf(se->ibuf);
2279                         } else {
2280                                 if (se->ibuf != se1->ibuf) {
2281                                         if (se->ibuf) {
2282                                                 IMB_freeImBuf(se->ibuf);
2283                                         }
2284
2285                                         se->ibuf = se1->ibuf;
2286                                         IMB_refImBuf(se->ibuf);
2287                                 }
2288                         }
2289                 }
2290         } else {
2291                 struct SeqEffectHandle sh;
2292
2293                 if(se->ibuf) {
2294                         if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty 
2295                            || !(se->ibuf->rect || se->ibuf->rect_float)) {
2296                                 IMB_freeImBuf(se->ibuf);
2297                                 se->ibuf= 0;
2298                         }
2299                 }
2300
2301                 if (se->ibuf == NULL) {
2302                         se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2303                         se2 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_right, render_size);
2304
2305                         if((se1 && se1->ibuf && se1->ibuf->rect_float))
2306                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2307                         else
2308                                 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2309                         
2310                         if (!se1 || !se2) {
2311                                 make_black_ibuf(se->ibuf);
2312                         } else {
2313                                 sh = get_sequence_effect(seq);
2314
2315                                 sh.execute(scene, seq, cfra, 
2316                                            f_cfra - (float) cfra_left, 
2317                                            f_cfra - (float) cfra_left, 
2318                                            se->ibuf->x, se->ibuf->y, 
2319                                            se1->ibuf, se2->ibuf, 0, se->ibuf);
2320                         }
2321                 }
2322
2323         }
2324
2325         /* caller expects this to be referenced, so do it! */
2326         if (se->ibuf) {
2327                 IMB_cache_limiter_insert(se->ibuf);
2328                 IMB_cache_limiter_ref(se->ibuf);
2329                 IMB_cache_limiter_touch(se->ibuf);
2330         }
2331
2332         /* children are no longer needed */
2333         if (se1 && se1->ibuf)
2334                 IMB_cache_limiter_unref(se1->ibuf);
2335         if (se2 && se2->ibuf)
2336                 IMB_cache_limiter_unref(se2->ibuf);
2337
2338         check_limiter_refcount("do_handle_speed_effect", se);
2339
2340         return se;
2341 }
2342
2343 /* 
2344  * build all ibufs recursively
2345  * 
2346  * if successfull, the returned TStripElem contains the (referenced!) imbuf
2347  * that means: you _must_ call 
2348  *
2349  * IMB_cache_limiter_unref(rval);
2350  * 
2351  * if rval != 0
2352  * 
2353  */
2354
2355 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size)
2356 {
2357         TStripElem *se;
2358         if (seq->type == SEQ_SPEED) {
2359                 se = do_handle_speed_effect(scene, seq, cfra, render_size);
2360         } else {
2361                 se = do_build_seq_recursively_impl(scene, seq, cfra, render_size);
2362         }
2363
2364         check_limiter_refcount("do_build_seq_recursively", se);
2365
2366         return se;
2367 }
2368
2369 static TStripElem* do_build_seq_array_recursively(Scene *scene,
2370         ListBase *seqbasep, int cfra, int chanshown, int render_size)
2371 {
2372         Sequence* seq_arr[MAXSEQ+1];
2373         int count;
2374         int i;
2375         TStripElem* se = 0;
2376
2377         count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
2378
2379         if (!count) {
2380                 return 0;
2381         }
2382
2383         se = give_tstripelem(seq_arr[count - 1], cfra);
2384
2385         if (!se) {
2386                 return 0;
2387         }
2388
2389         test_and_auto_discard_ibuf(se);
2390
2391         if (se->ibuf_comp != 0) {
2392                 IMB_cache_limiter_insert(se->ibuf_comp);
2393                 IMB_cache_limiter_ref(se->ibuf_comp);
2394                 IMB_cache_limiter_touch(se->ibuf_comp);
2395                 return se;
2396         }
2397
2398         
2399         if(count == 1) {
2400                 se = do_build_seq_recursively(scene, seq_arr[0], cfra, render_size);
2401                 if (se->ibuf) {
2402                         se->ibuf_comp = se->ibuf;
2403                         IMB_refImBuf(se->ibuf_comp);
2404                 }
2405                 return se;
2406         }
2407
2408
2409         for (i = count - 1; i >= 0; i--) {
2410                 int early_out;
2411                 Sequence * seq = seq_arr[i];
2412                 struct SeqEffectHandle sh;
2413                 float facf;
2414
2415                 se = give_tstripelem(seq, cfra);
2416
2417                 test_and_auto_discard_ibuf(se);
2418
2419                 if (se->ibuf_comp != 0) {
2420                         break;
2421                 }
2422                 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2423                         do_build_seq_recursively(scene, seq, cfra, render_size);
2424                         if (se->ibuf) {
2425                                 se->ibuf_comp = se->ibuf;
2426                                 IMB_refImBuf(se->ibuf);
2427                         } else {
2428                                 se->ibuf_comp = IMB_allocImBuf(
2429                                         (short)seqrectx, (short)seqrecty, 
2430                                         32, IB_rect, 0);
2431                                 IMB_cache_limiter_insert(se->ibuf_comp);
2432                                 IMB_cache_limiter_ref(se->ibuf_comp);
2433                                 IMB_cache_limiter_touch(se->ibuf_comp);
2434                         }
2435                         break;
2436                 }
2437
2438                 sh = get_sequence_blend(seq);
2439
2440                 facf = seq->blend_opacity / 100.0;
2441
2442                 early_out = sh.early_out(seq, facf, facf);
2443
2444                 switch (early_out) {
2445                 case -1:
2446                 case 2:
2447                         do_build_seq_recursively(scene, seq, cfra, render_size);
2448                         if (se->ibuf) {
2449                                 se->ibuf_comp = se->ibuf;
2450                                 IMB_refImBuf(se->ibuf_comp);
2451                         } else {
2452                                 se->ibuf_comp = IMB_allocImBuf(
2453                                         (short)seqrectx, (short)seqrecty, 
2454                                         32, IB_rect, 0);
2455                                 IMB_cache_limiter_insert(se->ibuf_comp);
2456                                 IMB_cache_limiter_ref(se->ibuf_comp);
2457                                 IMB_cache_limiter_touch(se->ibuf_comp);
2458                         }
2459                         break;
2460                 case 1:
2461                         if (i == 0) {
2462                                 se->ibuf_comp = IMB_allocImBuf(
2463                                         (short)seqrectx, (short)seqrecty, 
2464                                         32, IB_rect, 0);
2465                                 IMB_cache_limiter_insert(se->ibuf_comp);
2466                                 IMB_cache_limiter_ref(se->ibuf_comp);
2467                                 IMB_cache_limiter_touch(se->ibuf_comp);
2468                         }
2469                         break;
2470                 case 0:
2471                         do_build_seq_recursively(scene, seq, cfra, render_size);
2472                         if (!se->ibuf) {
2473                                 se->ibuf = IMB_allocImBuf(
2474                                         (short)seqrectx, (short)seqrecty, 
2475                                         32, IB_rect, 0);
2476                                 IMB_cache_limiter_insert(se->ibuf);
2477                                 IMB_cache_limiter_ref(se->ibuf);
2478                                 IMB_cache_limiter_touch(se->ibuf);
2479                         }
2480                         if (i == 0) {
2481                                 se->ibuf_comp = se->ibuf;
2482                                 IMB_refImBuf(se->ibuf_comp);
2483                         }
2484                         break;
2485                 }
2486         
2487                 if (se->ibuf_comp) {
2488                         break;
2489                 }
2490         }
2491
2492         i++;
2493
2494         for (; i < count; i++) {
2495                 Sequence * seq = seq_arr[i];
2496                 struct SeqEffectHandle sh = get_sequence_blend(seq);
2497                 TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
2498                 TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
2499
2500                 float facf = seq->blend_opacity / 100.0;
2501         
2502                 int early_out = sh.early_out(seq, facf, facf);
2503                 switch (early_out) {
2504                 case 0: {
2505                         int x= se2->ibuf->x;
2506                         int y= se2->ibuf->y;
2507                         int swap_input = FALSE;
2508
2509                         if (se1->ibuf_comp->rect_float ||
2510                             se2->ibuf->rect_float) {
2511                                 se2->ibuf_comp = IMB_allocImBuf(
2512                                         (short)seqrectx, (short)seqrecty, 
2513                                         32, IB_rectfloat, 0);
2514                         } else {
2515                                 se2->ibuf_comp = IMB_allocImBuf(
2516                                         (short)seqrectx, (short)seqrecty, 
2517                                         32, IB_rect, 0);
2518                         }
2519
2520
2521                         if (!se1->ibuf_comp->rect_float && 
2522                             se2->ibuf_comp->rect_float) {
2523                                 IMB_float_from_rect(se1->ibuf_comp);
2524                         }
2525                         if (!se2->ibuf->rect_float && 
2526                             se2->ibuf_comp->rect_float) {
2527                                 IMB_float_from_rect(se2->ibuf);
2528                         }
2529
2530                         if (!se1->ibuf_comp->rect && 
2531                             !se2->ibuf_comp->rect_float) {
2532                                 IMB_rect_from_float(se1->ibuf_comp);
2533                         }
2534                         if (!se2->ibuf->rect && 
2535                             !se2->ibuf_comp->rect_float) {
2536                                 IMB_rect_from_float(se2->ibuf);
2537                         }
2538                         
2539                         /* bad hack, to fix crazy input ordering of 
2540                            those two effects */
2541
2542                         if (seq->blend_mode == SEQ_ALPHAOVER ||
2543                             seq->blend_mode == SEQ_ALPHAUNDER ||
2544                             seq->blend_mode == SEQ_OVERDROP) {
2545                                 swap_input = TRUE;
2546                         }
2547
2548                         if (swap_input) {
2549                                 sh.execute(scene, seq, cfra, 
2550                                            facf, facf, x, y, 
2551                                            se2->ibuf, se1->ibuf_comp, 0,
2552                                            se2->ibuf_comp);
2553                         } else {
2554                                 sh.execute(scene, seq, cfra, 
2555                                            facf, facf, x, y, 
2556                                            se1->ibuf_comp, se2->ibuf, 0,
2557                                            se2->ibuf_comp);
2558                         }
2559                         
2560                         IMB_cache_limiter_insert(se2->ibuf_comp);
2561                         IMB_cache_limiter_ref(se2->ibuf_comp);
2562                         IMB_cache_limiter_touch(se2->ibuf_comp);
2563
2564                         IMB_cache_limiter_unref(se1->ibuf_comp);
2565                         IMB_cache_limiter_unref(se2->ibuf);
2566
2567                         break;
2568                 }
2569                 case 1: {
2570                         se2->ibuf_comp = se1->ibuf;
2571                         IMB_refImBuf(se2->ibuf_comp);
2572
2573                         break;
2574                 }
2575                 }
2576                 se = se2;
2577         }
2578
2579         return se;
2580 }
2581
2582 /*
2583  * returned ImBuf is refed!
2584  * you have to unref after usage!
2585  */
2586
2587 static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2588 {
2589         Editing *ed= seq_give_editing(scene, FALSE);
2590         int count;
2591         ListBase *seqbasep;
2592         TStripElem *se;
2593
2594         
2595         if(ed==NULL) return NULL;
2596
2597         count = BLI_countlist(&ed->metastack);
2598         if((chanshown < 0) && (count > 0)) {
2599                 count = MAX2(count + chanshown, 0);
2600                 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2601         } else {
2602                 seqbasep= ed->seqbasep;
2603         }
2604
2605         seqrectx= rectx;        /* bad bad global! */
2606         seqrecty= recty;
2607
2608         se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size);
2609
2610         if(!se) { 
2611                 return 0;
2612         }
2613
2614         check_limiter_refcount_comp("give_ibuf_seq_impl", se);
2615
2616         return se->ibuf_comp;
2617 }
2618
2619 ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
2620 {
2621         TStripElem* se;
2622
2623         seqrectx= rectx;        /* bad bad global! */
2624         seqrecty= recty;
2625
2626         se = do_build_seq_recursively(scene, seq, cfra, render_size);
2627
2628         if(!se) { 
2629                 return 0;
2630         }
2631
2632         check_limiter_refcount("give_ibuf_seq_direct", se);
2633
2634         if (se->ibuf) {
2635                 IMB_cache_limiter_unref(se->ibuf);
2636         }
2637
2638         return se->ibuf;
2639 }
2640
2641 ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2642 {
2643         ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size);
2644
2645         if (i) {
2646                 IMB_cache_limiter_unref(i);
2647         }
2648         return i;
2649 }
2650
2651 #if 0
2652 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2653 static int seq_can_blend(Sequence *seq)
2654 {
2655         if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2656                 return 1;
2657         } else {
2658                 return 0;
2659         }
2660 }
2661 #endif
2662
2663 /* *********************** threading api ******************* */
2664
2665 static ListBase running_threads;
2666 static ListBase prefetch_wait;
2667 static ListBase prefetch_done;
2668
2669 static pthread_mutex_t queue_lock          = PTHREAD_MUTEX_INITIALIZER;
2670 static pthread_mutex_t wakeup_lock         = PTHREAD_MUTEX_INITIALIZER;
2671 static pthread_cond_t  wakeup_cond         = PTHREAD_COND_INITIALIZER;
2672
2673 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2674 //static pthread_cond_t  prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2675
2676 static pthread_mutex_t frame_done_lock     = PTHREAD_MUTEX_INITIALIZER;
2677 static pthread_cond_t  frame_done_cond     = PTHREAD_COND_INITIALIZER;
2678
2679 static volatile int seq_thread_shutdown = FALSE;
2680 static volatile int seq_last_given_monoton_cfra = 0;
2681 static int monoton_cfra = 0;
2682
2683 typedef struct PrefetchThread {
2684         struct PrefetchThread *next, *prev;
2685         
2686         Scene *scene;
2687         struct PrefetchQueueElem *current;
2688         pthread_t pthread;
2689         int running;
2690         
2691 } PrefetchThread;
2692
2693 typedef struct PrefetchQueueElem {
2694         struct PrefetchQueueElem *next, *prev;
2695         
2696         int rectx;
2697         int recty;
2698         int cfra;
2699         int chanshown;
2700         int render_size;
2701
2702         int monoton_cfra;
2703
2704         struct ImBuf * ibuf;
2705 } PrefetchQueueElem;
2706
2707 #if 0
2708 static void *seq_prefetch_thread(void * This_)
2709 {
2710         PrefetchThread * This = This_;
2711
2712         while (!seq_thread_shutdown) {
2713                 PrefetchQueueElem *e;
2714                 int s_last;
2715
2716                 pthread_mutex_lock(&queue_lock);
2717                 e = prefetch_wait.first;
2718                 if (e) {
2719                         BLI_remlink(&prefetch_wait, e);
2720                 }
2721                 s_last = seq_last_given_monoton_cfra;
2722
2723                 This->current = e;
2724
2725                 pthread_mutex_unlock(&queue_lock);
2726
2727                 if (!e) {
2728                         pthread_mutex_lock(&prefetch_ready_lock);
2729
2730                         This->running = FALSE;
2731
2732                         pthread_cond_signal(&prefetch_ready_cond);
2733                         pthread_mutex_unlock(&prefetch_ready_lock);
2734
2735                         pthread_mutex_lock(&wakeup_lock);
2736                         if (!seq_thread_shutdown) {
2737                                 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2738                         }
2739                         pthread_mutex_unlock(&wakeup_lock);
2740                         continue;
2741                 }
2742
2743                 This->running = TRUE;
2744                 
2745                 if (e->cfra >= s_last) { 
2746                         e->ibuf = give_ibuf_seq_impl(This->scene, 
2747                                 e->rectx, e->recty, e->cfra, e->chanshown,
2748                                 e->render_size);
2749                 }
2750
2751                 pthread_mutex_lock(&queue_lock);
2752
2753                 BLI_addtail(&prefetch_done, e);
2754
2755                 for (e = prefetch_wait.first; e; e = e->next) {
2756                         if (s_last > e->monoton_cfra) {
2757                                 BLI_remlink(&prefetch_wait, e);
2758                                 MEM_freeN(e);
2759                         }
2760                 }
2761
2762                 for (e = prefetch_done.first; e; e = e->next) {
2763                         if (s_last > e->monoton_cfra) {
2764                                 if (e->ibuf) {
2765                                         IMB_cache_limiter_unref(e->ibuf);
2766                                 }
2767                                 BLI_remlink(&prefetch_done, e);
2768                                 MEM_freeN(e);
2769                         }
2770                 }
2771
2772                 pthread_mutex_unlock(&queue_lock);
2773
2774                 pthread_mutex_lock(&frame_done_lock);
2775                 pthread_cond_signal(&frame_done_cond);
2776                 pthread_mutex_unlock(&frame_done_lock);
2777         }
2778         return 0;
2779 }
2780
2781 static void seq_start_threads(Scene *scene)
2782 {
2783         int i;
2784
2785         running_threads.first = running_threads.last = NULL;
2786         prefetch_wait.first = prefetch_wait.last = NULL;
2787         prefetch_done.first = prefetch_done.last = NULL;
2788
2789         seq_thread_shutdown = FALSE;
2790         seq_last_given_monoton_cfra = monoton_cfra = 0;
2791
2792         /* since global structures are modified during the processing
2793            of one frame, only one render thread is currently possible... 
2794
2795            (but we code, in the hope, that we can remove this restriction
2796            soon...)
2797         */
2798
2799         fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2800
2801         for (i = 0; i < 1; i++) {
2802                 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
2803                 t->scene= scene;
2804                 t->running = TRUE;
2805                 BLI_addtail(&running_threads, t);
2806
2807                 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2808         }
2809
2810         /* init malloc mutex */
2811         BLI_init_threads(0, 0, 0);
2812 }
2813
2814 static void seq_stop_threads()
2815 {
2816         PrefetchThread *tslot;
2817         PrefetchQueueElem *e;
2818
2819         fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2820
2821         if (seq_thread_shutdown) {
2822                 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2823                 return;
2824         }
2825         
2826         pthread_mutex_lock(&wakeup_lock);
2827
2828         seq_thread_shutdown = TRUE;
2829
2830         pthread_cond_broadcast(&wakeup_cond);
2831         pthread_mutex_unlock(&wakeup_lock);
2832
2833         for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2834                 pthread_join(tslot->pthread, NULL);
2835         }
2836
2837
2838         for (e = prefetch_wait.first; e; e = e->next) {
2839                 BLI_remlink(&prefetch_wait, e);
2840                 MEM_freeN(e);
2841         }
2842
2843         for (e = prefetch_done.first; e; e = e->next) {
2844                 if (e->ibuf) {
2845                         IMB_cache_limiter_unref(e->ibuf);
2846                 }
2847                 BLI_remlink(&prefetch_done, e);
2848                 MEM_freeN(e);
2849         }
2850
2851         BLI_freelistN(&running_threads);
2852
2853         /* deinit malloc mutex */
2854         BLI_end_threads(0);
2855 }
2856 #endif
2857
2858 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
2859                                 int render_size)
2860 {
2861         PrefetchQueueElem *e;
2862         if (seq_thread_shutdown) {
2863                 return;
2864         }
2865
2866         e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2867         e->rectx = rectx;
2868         e->recty = recty;
2869         e->cfra = cfra;
2870         e->chanshown = chanshown;
2871         e->render_size = render_size;
2872         e->monoton_cfra = monoton_cfra++;
2873
2874         pthread_mutex_lock(&queue_lock);
2875         BLI_addtail(&prefetch_wait, e);
2876         pthread_mutex_unlock(&queue_lock);
2877         
2878         pthread_mutex_lock(&wakeup_lock);
2879         pthread_cond_signal(&wakeup_cond);
2880         pthread_mutex_unlock(&wakeup_lock);
2881 }
2882
2883 #if 0
2884 static void seq_wait_for_prefetch_ready()
2885 {
2886         PrefetchThread *tslot;
2887
2888         if (seq_thread_shutdown) {
2889                 return;
2890         }
2891
2892         fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
2893
2894         pthread_mutex_lock(&prefetch_ready_lock);
2895
2896         for(;;) {
2897                 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2898                         if (tslot->running) {
2899                                 break;
2900                         }
2901                 }
2902                 if (!tslot) {
2903                         break;
2904                 }
2905                 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
2906         }
2907
2908         pthread_mutex_unlock(&prefetch_ready_lock);
2909
2910         fprintf(stderr, "SEQ-THREAD: prefetch done\n");
2911 }
2912 #endif
2913
2914 ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2915 {
2916         PrefetchQueueElem *e = NULL;
2917         int found_something = FALSE;
2918
2919         if (seq_thread_shutdown) {
2920                 return give_ibuf_seq(scene, rectx, recty, cfra, chanshown, render_size);
2921         }
2922
2923         while (!e) {
2924                 int success = FALSE;
2925                 pthread_mutex_lock(&queue_lock);
2926
2927                 for (e = prefetch_done.first; e; e = e->next) {
2928                         if (cfra == e->cfra &&
2929                             chanshown == e->chanshown &&
2930                             rectx == e->rectx && 
2931                             recty == e->recty &&
2932                             render_size == e->render_size) {
2933                                 success = TRUE;
2934                                 found_something = TRUE;
2935                                 break;
2936                         }
2937                 }
2938
2939                 if (!e) {
2940                         for (e = prefetch_wait.first; e; e = e->next) {
2941                                 if (cfra == e->cfra &&
2942                                     chanshown == e->chanshown &&
2943                                     rectx == e->rectx && 
2944                                     recty == e->recty &&
2945                                     render_size == e->render_size) {
2946                                         found_something = TRUE;
2947                                         break;
2948                                 }
2949                         }
2950                 }
2951
2952                 if (!e) {
2953                         PrefetchThread *tslot;
2954
2955                         for(tslot = running_threads.first; 
2956                             tslot; tslot= tslot->next) {
2957                                 if (tslot->current &&
2958                                     cfra == tslot->current->cfra &&
2959                                     chanshown == tslot->current->chanshown &&
2960                                     rectx == tslot->current->rectx && 
2961                                     recty == tslot->current->recty &&
2962                                     render_size== tslot->current->render_size){
2963                                         found_something = TRUE;
2964                                         break;
2965                                 }
2966                         }
2967                 }
2968
2969                 /* e->ibuf is unrefed by render thread on next round. */
2970
2971                 if (e) {
2972                         seq_last_given_monoton_cfra = e->monoton_cfra;
2973                 }
2974
2975                 pthread_mutex_unlock(&queue_lock);
2976
2977                 if (!success) {
2978                         e = NULL;
2979
2980                         if (!found_something) {
2981                                 fprintf(stderr, 
2982                                         "SEQ-THREAD: Requested frame "
2983                                         "not in queue ???\n");
2984                                 break;
2985                         }
2986                         pthread_mutex_lock(&frame_done_lock);
2987                         pthread_cond_wait(&frame_done_cond, &frame_done_lock);
2988                         pthread_mutex_unlock(&frame_done_lock);
2989                 }
2990         }
2991         
2992         return e ? e->ibuf : 0;
2993 }
2994
2995 /* Functions to free imbuf and anim data on changes */
2996
2997 static void free_imbuf_strip_elem(TStripElem *se)
2998 {
2999         if(se->ibuf) {
3000                 IMB_freeImBuf(se->ibuf);
3001         }
3002         if(se->ibuf_comp) {
3003                 IMB_freeImBuf(se->ibuf_comp);
3004         }
3005         se->ibuf_comp = 0;
3006         se->ibuf= 0;
3007         se->ok= STRIPELEM_OK;
3008         se->se1= se->se2= se->se3= 0;
3009 }
3010
3011 static void free_anim_seq(Sequence *seq)
3012 {
3013         if(seq->anim) {
3014                 IMB_free_anim(seq->anim);
3015                 seq->anim = 0;
3016         }
3017 }
3018
3019 #if 0
3020 static void free_imbuf_seq_except(Scene *scene, int cfra)
3021 {
3022         Editing *ed= seq_give_editing(scene, FALSE);
3023         Sequence *seq;
3024         TStripElem *se;
3025         int a;
3026
3027         if(ed==NULL) return;
3028
3029         SEQ_BEGIN(ed, seq) {
3030                 if(seq->strip) {
3031                         TStripElem * curelem = give_tstripelem(seq, cfra);
3032
3033                         for(a = 0, se = seq->strip->tstripdata; 
3034                             a < seq->strip->len && se; a++, se++) {
3035                                 if(se != curelem) {
3036                                         free_imbuf_strip_elem(se);
3037                                 }
3038                         }
3039                         for(a = 0, se = seq->strip->tstripdata_startstill;
3040                             a < seq->strip->startstill && se; a++, se++) {
3041                                 if(se != curelem) {
3042                                         free_imbuf_strip_elem(se);
3043                                 }
3044                         }
3045                         for(a = 0, se = seq->strip->tstripdata_endstill;
3046                             a < seq->strip->endstill && se; a++, se++) {
3047                                 if(se != curelem) {
3048                                         free_imbuf_strip_elem(se);
3049                                 }
3050                         }
3051                         if(seq->strip->ibuf_startstill) {
3052                                 IMB_freeImBuf(seq->strip->ibuf_startstill);
3053                                 seq->strip->ibuf_startstill = 0;
3054                         }
3055
3056                         if(seq->strip->ibuf_endstill) {
3057                                 IMB_freeImBuf(seq->strip->ibuf_endstill);
3058                                 seq->strip->ibuf_endstill = 0;
3059                         }
3060
3061                         if(seq->type==SEQ_MOVIE)
3062                                 if(seq->startdisp > cfra || seq->enddisp < cfra)
3063                                         free_anim_seq(seq);
3064                         free_proxy_seq(seq);
3065                 }
3066         }
3067         SEQ_END
3068 }
3069 #endif
3070
3071 void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage)
3072 {
3073         Sequence *seq;
3074         TStripElem *se;
3075         int a;
3076
3077         if (check_mem_usage) {
3078                 /* Let the cache limitor take care of this (schlaile) */
3079                 /* While render let's keep all memory available for render 
3080                    (ton)
3081                    At least if free memory is tight...
3082                    This can make a big difference in encoding speed
3083                    (it is around 4 times(!) faster, if we do not waste time
3084                    on freeing _all_ buffers every time on long timelines...)
3085                    (schlaile)
3086                 */
3087         
3088                 uintptr_t mem_in_use;
3089                 uintptr_t mmap_in_use;
3090                 uintptr_t max;
3091         
3092                 mem_in_use= MEM_get_memory_in_use();
3093                 mmap_in_use= MEM_get_mapped_memory_in_use();
3094                 max = MEM_CacheLimiter_get_maximum();
3095         
3096                 if (max == 0 || mem_in_use + mmap_in_use <= max) {
3097                         return;
3098                 }
3099         }
3100
3101         
3102         for(seq= seqbase->first; seq; seq= seq->next) {
3103                 if(seq->strip) {
3104                         for(a = 0, se = seq->strip->tstripdata; 
3105                             a < seq->strip->len && se; a++, se++) {
3106                                 free_imbuf_strip_elem(se);
3107                         }
3108                         for(a = 0, se = seq->strip->tstripdata_startstill; 
3109                             a < seq->strip->startstill && se; a++, se++) {
3110                                 free_imbuf_strip_elem(se);
3111                         }
3112                         for(a = 0, se = seq->strip->tstripdata_endstill; 
3113                             a < seq->strip->endstill && se; a++, se++) {
3114                                 free_imbuf_strip_elem(se);
3115                         }
3116                         if(seq->strip->ibuf_startstill) {
3117                                 IMB_freeImBuf(seq->strip->ibuf_startstill);
3118                                 seq->strip->ibuf_startstill = 0;
3119                         }
3120
3121                         if(seq->strip->ibuf_endstill) {
3122                                 IMB_freeImBuf(seq->strip->ibuf_endstill);
3123                                 seq->strip->ibuf_endstill = 0;