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