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