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