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