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