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