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