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