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