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