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