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