4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
24 * - Blender Foundation, 2003-2009
25 * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
27 * ***** END GPL LICENSE BLOCK *****
35 #include "MEM_guardedalloc.h"
36 #include "MEM_CacheLimiterC-Api.h"
38 #include "DNA_sequence_types.h"
39 #include "DNA_scene_types.h"
40 #include "DNA_anim_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_sound_types.h"
44 #include "BKE_animsys.h"
45 #include "BKE_global.h"
46 #include "BKE_image.h"
48 #include "BKE_sequencer.h"
49 #include "BKE_fcurve.h"
50 #include "BKE_scene.h"
51 #include "RNA_access.h"
52 #include "RE_pipeline.h"
55 #include "BLI_fileops.h"
56 #include "BLI_listbase.h"
57 #include "BLI_path_util.h"
58 #include "BLI_string.h"
59 #include "BLI_threads.h"
62 #include "IMB_imbuf.h"
63 #include "IMB_imbuf_types.h"
67 #include "BKE_context.h"
68 #include "BKE_sound.h"
69 #include "AUD_C-API.h"
72 #define snprintf _snprintf
75 /* **** XXX ******** */
76 //static void waitcursor(int val) {}
77 //static int blender_test_break() {return 0;}
79 /* **** XXX ******** */
81 ListBase seqbase_clipboard;
82 int seqbase_clipboard_frame;
83 SequencerDrawView sequencer_view3d_cb= NULL; /* NULL in background mode */
86 void printf_strip(Sequence *seq)
88 fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n",
89 seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp);
90 fprintf(stderr, "\tseq_tx_set_final_left: %d %d\n\n", seq_tx_get_final_left(seq, 0), seq_tx_get_final_right(seq, 0));
93 int seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg)
96 for(iseq= seqbase->first; iseq; iseq= iseq->next) {
97 if(seq_recursive_apply(iseq, apply_func, arg) == -1)
98 return -1; /* bail out */
103 int seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg)
105 int ret= apply_func(seq, arg);
108 return -1; /* bail out */
110 if(ret && seq->seqbase.first)
111 ret = seqbase_recursive_apply(&seq->seqbase, apply_func, arg);
116 /* **********************************************************************
117 alloc / free functions
118 ********************************************************************** */
122 void new_tstripdata(Sequence *seq)
125 seq->strip->len= seq->len;
132 static void free_proxy_seq(Sequence *seq)
134 if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
135 IMB_free_anim(seq->strip->proxy->anim);
136 seq->strip->proxy->anim = 0;
140 void seq_free_strip(Strip *strip)
143 if(strip->us>0) return;
145 printf("error: negative users in strip\n");
149 if (strip->stripdata) {
150 MEM_freeN(strip->stripdata);
154 if (strip->proxy->anim) {
155 IMB_free_anim(strip->proxy->anim);
158 MEM_freeN(strip->proxy);
161 MEM_freeN(strip->crop);
163 if (strip->transform) {
164 MEM_freeN(strip->transform);
166 if (strip->color_balance) {
167 MEM_freeN(strip->color_balance);
173 static void seq_free_animdata(Scene *scene, Sequence *seq);
175 void seq_free_sequence(Scene *scene, Sequence *seq)
177 if(seq->strip) seq_free_strip(seq->strip);
179 if(seq->anim) IMB_free_anim(seq->anim);
181 if (seq->type & SEQ_EFFECT) {
182 struct SeqEffectHandle sh = get_sequence_effect(seq);
187 /* clipboard has no scene and will never have a sound handle or be active */
189 Editing *ed = scene->ed;
191 if (ed->act_seq==seq)
195 sound_remove_scene_sound(scene, seq->scene_sound);
197 seq_free_animdata(scene, seq);
203 Editing *seq_give_editing(Scene *scene, int alloc)
205 if (scene->ed == NULL && alloc) {
208 ed= scene->ed= MEM_callocN( sizeof(Editing), "addseq");
209 ed->seqbasep= &ed->seqbase;
214 void seq_free_clipboard(void)
216 Sequence *seq, *nseq;
218 for(seq= seqbase_clipboard.first; seq; seq= nseq) {
220 seq_free_sequence(NULL, seq);
222 seqbase_clipboard.first= seqbase_clipboard.last= NULL;
225 void seq_free_editing(Scene *scene)
227 Editing *ed = scene->ed;
235 seq_free_sequence(scene, seq);
239 while((ms= ed->metastack.first)) {
240 BLI_remlink(&ed->metastack, ms);
247 /* ************************* itterator ************************** */
248 /* *************** (replaces old WHILE_SEQ) ********************* */
249 /* **************** use now SEQ_BEGIN() SEQ_END ***************** */
251 /* sequence strip iterator:
252 * - builds a full array, recursively into meta strips */
254 static void seq_count(ListBase *seqbase, int *tot)
258 for(seq=seqbase->first; seq; seq=seq->next) {
261 if(seq->seqbase.first)
262 seq_count(&seq->seqbase, tot);
266 static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
270 for(seq=seqbase->first; seq; seq=seq->next) {
273 if(seq->seqbase.first)
274 seq_build_array(&seq->seqbase, array, depth+1);
281 void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_pointer)
292 seq_count(ed->seqbasep, tot);
294 seq_count(&ed->seqbase, tot);
299 *seqarray= array= MEM_mallocN(sizeof(Sequence *)*(*tot), "SeqArray");
301 seq_build_array(ed->seqbasep, &array, 0);
303 seq_build_array(&ed->seqbase, &array, 0);
306 void seq_begin(Editing *ed, SeqIterator *iter, int use_pointer)
308 memset(iter, 0, sizeof(*iter));
309 seq_array(ed, &iter->array, &iter->tot, use_pointer);
313 iter->seq= iter->array[iter->cur];
318 void seq_next(SeqIterator *iter)
320 if(++iter->cur < iter->tot)
321 iter->seq= iter->array[iter->cur];
326 void seq_end(SeqIterator *iter)
329 MEM_freeN(iter->array);
335 **********************************************************************
337 **********************************************************************
338 * Build a complete array of _all_ sequencies (including those
340 **********************************************************************
343 static void do_seq_count(ListBase *seqbase, int *totseq)
350 if(seq->seqbase.first) do_seq_count(&seq->seqbase, totseq);
355 static void do_build_seqar(ListBase *seqbase, Sequence ***seqar, int depth)
362 if(seq->seqbase.first) do_build_seqar(&seq->seqbase, seqar, depth+1);
369 void build_seqar(ListBase *seqbase, Sequence ***seqar, int *totseq)
374 do_seq_count(seqbase, totseq);
380 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
383 do_build_seqar(seqbase, seqar, 0);
387 static void do_seq_count_cb(ListBase *seqbase, int *totseq,
388 int (*test_func)(Sequence * seq))
394 int test = test_func(seq);
395 if (test & BUILD_SEQAR_COUNT_CURRENT) {
398 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
399 do_seq_count_cb(&seq->seqbase, totseq, test_func);
405 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
406 int (*test_func)(Sequence * seq))
412 int test = test_func(seq);
415 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
416 do_build_seqar_cb(&seq->seqbase, seqar, depth+1,
419 if (test & BUILD_SEQAR_COUNT_CURRENT) {
427 void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq,
428 int (*test_func)(Sequence * seq))
433 do_seq_count_cb(seqbase, totseq, test_func);
439 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
442 do_build_seqar_cb(seqbase, seqar, 0, test_func);
447 void calc_sequence_disp(Scene *scene, Sequence *seq)
449 if(seq->startofs && seq->startstill) seq->startstill= 0;
450 if(seq->endofs && seq->endstill) seq->endstill= 0;
452 seq->startdisp= seq->start + seq->startofs - seq->startstill;
453 seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
455 seq->handsize= 10.0; /* 10 frames */
456 if( seq->enddisp-seq->startdisp < 10 ) {
457 seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
459 else if(seq->enddisp-seq->startdisp > 250) {
460 seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
463 seq_update_sound(scene, seq);
466 static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
470 /* for sound we go over full meta tree to update bounds of the sound strips,
471 since sound is played outside of evaluating the imbufs, */
472 for(seq=metaseq->seqbase.first; seq; seq=seq->next) {
473 if(seq->type == SEQ_META) {
474 seq_update_sound_bounds_recursive(scene, seq);
476 else if((seq->type == SEQ_SOUND) || (seq->type == SEQ_SCENE)) {
477 if(seq->scene_sound) {
478 int startofs = seq->startofs;
479 int endofs = seq->endofs;
480 if(seq->startofs + seq->start < metaseq->start + metaseq->startofs)
481 startofs = metaseq->start + metaseq->startofs - seq->start;
483 if(seq->start + seq->len - seq->endofs > metaseq->start + metaseq->len - metaseq->endofs)
484 endofs = seq->start + seq->len - metaseq->start - metaseq->len + metaseq->endofs;
485 sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs, seq->start+seq->len - endofs, startofs);
491 void calc_sequence(Scene *scene, Sequence *seq)
496 /* check all metas recursively */
497 seqm= seq->seqbase.first;
499 if(seqm->seqbase.first) calc_sequence(scene, seqm);
503 /* effects and meta: automatic start and end */
505 if(seq->type & SEQ_EFFECT) {
507 if(seq->seq2==0) seq->seq2= seq->seq1;
508 if(seq->seq3==0) seq->seq3= seq->seq1;
510 /* effecten go from seq1 -> seq2: test */
512 /* we take the largest start and smallest end */
514 // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
515 // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
518 seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
519 seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
520 seq->len= seq->enddisp - seq->startdisp;
522 calc_sequence_disp(scene, seq);
525 if(seq->strip && seq->len!=seq->strip->len) {
531 if(seq->type==SEQ_META) {
532 seqm= seq->seqbase.first;
537 if(seqm->startdisp < min) min= seqm->startdisp;
538 if(seqm->enddisp > max) max= seqm->enddisp;
541 seq->start= min + seq->anim_startofs;
543 seq->len -= seq->anim_startofs;
544 seq->len -= seq->anim_endofs;
546 if(seq->strip && seq->len!=seq->strip->len) {
550 seq_update_sound_bounds_recursive(scene, seq);
552 calc_sequence_disp(scene, seq);
556 /* note: caller should run calc_sequence(scene, seq) after */
557 void reload_sequence_new_file(Scene *scene, Sequence * seq, int lock_range)
559 char str[FILE_MAXDIR+FILE_MAXFILE];
560 int prev_startdisp, prev_enddisp;
561 /* note: dont rename the strip, will break animation curves */
563 if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
564 seq->type == SEQ_SOUND ||
565 seq->type == SEQ_SCENE || seq->type == SEQ_META)) {
570 /* keep so we dont have to move the actual start and end points (only the data) */
571 calc_sequence_disp(scene, seq);
572 prev_startdisp= seq->startdisp;
573 prev_enddisp= seq->enddisp;
579 if (seq->type != SEQ_SCENE && seq->type != SEQ_META &&
580 seq->type != SEQ_IMAGE) {
581 BLI_join_dirfile(str, seq->strip->dir, seq->strip->stripdata->name);
582 BLI_path_abs(str, G.main->name);
585 if (seq->type == SEQ_IMAGE) {
587 size_t olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem);
590 seq->len -= seq->anim_startofs;
591 seq->len -= seq->anim_endofs;
595 seq->strip->len = seq->len;
596 } else if (seq->type == SEQ_MOVIE) {
597 if(seq->anim) IMB_free_anim(seq->anim);
598 seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0));
604 seq->len = IMB_anim_get_duration(seq->anim);
606 seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
608 seq->len -= seq->anim_startofs;
609 seq->len -= seq->anim_endofs;
613 seq->strip->len = seq->len;
614 } else if (seq->type == SEQ_SOUND) {
615 seq->len = ceil(AUD_getInfo(seq->sound->playback_handle).length * FPS);
616 seq->len -= seq->anim_startofs;
617 seq->len -= seq->anim_endofs;
621 seq->strip->len = seq->len;
622 } else if (seq->type == SEQ_SCENE) {
623 /* 'seq->scenenr' should be replaced with something more reliable */
624 Scene * sce = G.main->scene.first;
628 if(nr == seq->scenenr) {
641 seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
642 seq->len -= seq->anim_startofs;
643 seq->len -= seq->anim_endofs;
647 seq->strip->len = seq->len;
653 seq_tx_set_final_left(seq, prev_startdisp);
654 seq_tx_set_final_right(seq, prev_enddisp);
658 calc_sequence(scene, seq);
661 void sort_seq(Scene *scene)
663 /* all strips together per kind, and in order of y location ("machine") */
664 ListBase seqbase, effbase;
665 Editing *ed= seq_give_editing(scene, FALSE);
666 Sequence *seq, *seqt;
671 seqbase.first= seqbase.last= 0;
672 effbase.first= effbase.last= 0;
674 while( (seq= ed->seqbasep->first) ) {
675 BLI_remlink(ed->seqbasep, seq);
677 if(seq->type & SEQ_EFFECT) {
680 if(seqt->machine>=seq->machine) {
681 BLI_insertlinkbefore(&effbase, seqt, seq);
686 if(seqt==0) BLI_addtail(&effbase, seq);
691 if(seqt->machine>=seq->machine) {
692 BLI_insertlinkbefore(&seqbase, seqt, seq);
697 if(seqt==0) BLI_addtail(&seqbase, seq);
701 addlisttolist(&seqbase, &effbase);
702 *(ed->seqbasep)= seqbase;
706 static int clear_scene_in_allseqs_cb(Sequence *seq, void *arg_pt)
708 if(seq->scene==(Scene *)arg_pt)
713 void clear_scene_in_allseqs(Main *bmain, Scene *scene)
717 /* when a scene is deleted: test all seqs */
718 for(scene_iter= bmain->scene.first; scene_iter; scene_iter= scene_iter->id.next) {
719 if(scene_iter != scene && scene_iter->ed) {
720 seqbase_recursive_apply(&scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene);
725 typedef struct SeqUniqueInfo {
734 static void seqbase_unique_name(ListBase *seqbasep, Sequence *seq)
736 BLI_uniquename(seqbasep, seq, "Sequence", '.', offsetof(Sequence, name), SEQ_NAME_MAXSTR);
739 static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
742 for(seq=seqbasep->first; seq; seq= seq->next) {
743 if (sui->seq != seq && strcmp(sui->name_dest, seq->name+2)==0) {
744 sprintf(sui->name_dest, "%.17s.%03d", sui->name_src, sui->count++); /*24 - 2 for prefix, -1 for \0 */
745 sui->match= 1; /* be sure to re-scan */
750 static int seqbase_unique_name_recursive_cb(Sequence *seq, void *arg_pt)
752 if(seq->seqbase.first)
753 seqbase_unique_name(&seq->seqbase, (SeqUniqueInfo *)arg_pt);
757 void seqbase_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq)
762 strcpy(sui.name_src, seq->name+2);
763 strcpy(sui.name_dest, seq->name+2);
766 sui.match= 1; /* assume the worst to start the loop */
768 /* Strip off the suffix */
769 if ((dot=strrchr(sui.name_src, '.'))) {
774 sui.count= atoi(dot) + 1;
779 seqbase_unique_name(seqbasep, &sui);
780 seqbase_recursive_apply(seqbasep, seqbase_unique_name_recursive_cb, &sui);
783 strcpy(seq->name+2, sui.name_dest);
786 static char *give_seqname_by_type(int type)
789 case SEQ_META: return "Meta";
790 case SEQ_IMAGE: return "Image";
791 case SEQ_SCENE: return "Scene";
792 case SEQ_MOVIE: return "Movie";
793 case SEQ_SOUND: return "Audio";
794 case SEQ_CROSS: return "Cross";
795 case SEQ_GAMCROSS: return "Gamma Cross";
796 case SEQ_ADD: return "Add";
797 case SEQ_SUB: return "Sub";
798 case SEQ_MUL: return "Mul";
799 case SEQ_ALPHAOVER: return "Alpha Over";
800 case SEQ_ALPHAUNDER: return "Alpha Under";
801 case SEQ_OVERDROP: return "Over Drop";
802 case SEQ_WIPE: return "Wipe";
803 case SEQ_GLOW: return "Glow";
804 case SEQ_TRANSFORM: return "Transform";
805 case SEQ_COLOR: return "Color";
806 case SEQ_MULTICAM: return "Multicam";
807 case SEQ_SPEED: return "Speed";
813 char *give_seqname(Sequence *seq)
815 char * name = give_seqname_by_type(seq->type);
818 if(seq->type<SEQ_EFFECT) {
819 return seq->strip->dir;
820 } else if(seq->type==SEQ_PLUGIN) {
821 if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
822 seq->plugin && seq->plugin->doit) {
823 return seq->plugin->pname;
834 /* ***************** DO THE SEQUENCE ***************** */
836 static void make_black_ibuf(ImBuf *ibuf)
842 if(ibuf==0 || (ibuf->rect==0 && ibuf->rect_float==0)) return;
844 tot= ibuf->x*ibuf->y;
847 rect_float = ibuf->rect_float;
850 memset(rect, 0, tot * sizeof(char) * 4);
854 memset(rect_float, 0, tot * sizeof(float) * 4);
858 static void multibuf(ImBuf *ibuf, float fmul)
865 mul= (int)(256.0*fmul);
866 rt= (char *)ibuf->rect;
867 rt_float = ibuf->rect_float;
873 icol= (mul*rt[0])>>8;
874 if(icol>254) rt[0]= 255; else rt[0]= icol;
875 icol= (mul*rt[1])>>8;
876 if(icol>254) rt[1]= 255; else rt[1]= icol;
877 icol= (mul*rt[2])>>8;
878 if(icol>254) rt[2]= 255; else rt[2]= icol;
879 icol= (mul*rt[3])>>8;
880 if(icol>254) rt[3]= 255; else rt[3]= icol;
898 static float give_stripelem_index(Sequence *seq, float cfra)
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;
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;
913 if (seq->strobe < 1.0) seq->strobe = 1.0;
914 if (seq->strobe > 1.0) {
915 nr -= fmod((double)nr, (double)seq->strobe);
921 StripElem *give_stripelem(Sequence *seq, int cfra)
923 StripElem *se= seq->strip->stripdata;
925 if(seq->type == SEQ_MOVIE) {
929 int nr = (int) give_stripelem_index(seq, cfra);
931 if (nr == -1) return 0;
932 if (se == 0) return 0;
934 se += nr + seq->anim_startofs;
939 static int evaluate_seq_frame_gen(Sequence ** seq_arr, ListBase *seqbase, int cfra)
944 memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1));
948 if(seq->startdisp <=cfra && seq->enddisp > cfra) {
949 seq_arr[seq->machine]= seq;
958 int evaluate_seq_frame(Scene *scene, int cfra)
960 Editing *ed= seq_give_editing(scene, FALSE);
961 Sequence *seq_arr[MAXSEQ+1];
963 if(ed==NULL) return 0;
964 return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
967 static int video_seq_is_rendered(Sequence * seq)
970 && !(seq->flag & SEQ_MUTE)
971 && seq->type != SEQ_SOUND);
974 static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
976 Sequence *seq_arr[MAXSEQ+1];
984 if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
986 if (seq_arr[b] == 0) {
990 for (b = MAXSEQ; b > 0; b--) {
991 if (video_seq_is_rendered(seq_arr[b])) {
1001 if (video_seq_is_rendered(seq_arr[b])) {
1002 if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
1008 for (;b <= chanshown && b >= 0; b++) {
1009 if (video_seq_is_rendered(seq_arr[b])) {
1010 seq_arr_out[cnt++] = seq_arr[b];
1018 /* **********************************************************************
1020 ********************************************************************** */
1022 #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
1024 static int seq_proxy_get_fname(Scene *UNUSED(scene), Sequence * seq, int cfra, char * name, int render_size)
1027 char dir[FILE_MAXDIR];
1029 if (!seq->strip->proxy) {
1033 if ((seq->flag & SEQ_USE_PROXY_CUSTOM_DIR)
1034 || (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE)) {
1035 strcpy(dir, seq->strip->proxy->dir);
1037 if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
1038 snprintf(dir, FILE_MAXDIR, "%s/BL_proxy",
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.main->name);
1052 /* generate a separate proxy directory for each preview size */
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);
1059 } else if (seq->type == SEQ_MOVIE) {
1060 frameno = (int) give_stripelem_index(seq, cfra)
1061 + seq->anim_startofs;
1063 snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir,
1064 seq->strip->stripdata->name,
1067 frameno = (int) give_stripelem_index(seq, cfra)
1068 + seq->anim_startofs;
1070 snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
1074 BLI_path_abs(name, G.main->name);
1075 BLI_path_frame(name, frameno, 0);
1078 strcat(name, ".jpg");
1083 static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra, int render_size)
1085 char name[PROXY_MAXFILE];
1087 if (!(seq->flag & SEQ_USE_PROXY)) {
1091 /* rendering at 100% ? No real sense in proxy-ing, right? */
1092 if (render_size == 100) {
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)) {
1105 seq->strip->proxy->anim = openanim(name, IB_rect);
1107 if (!seq->strip->proxy->anim) {
1111 return IMB_anim_absolute(seq->strip->proxy->anim, frameno);
1114 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1118 if (BLI_exists(name)) {
1119 return IMB_loadiffname(name, IB_rect);
1126 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1127 int build_proxy_run, int render_size);
1129 static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty)
1131 char name[PROXY_MAXFILE];
1136 struct ImBuf * ibuf;
1138 if (!(seq->flag & SEQ_USE_PROXY)) {
1142 /* rendering at 100% ? No real sense in proxy-ing, right? */
1143 if (render_size == 100) {
1147 /* that's why it is called custom... */
1148 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1152 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1156 se = give_tstripelem(seq, cfra);
1162 IMB_freeImBuf(se->ibuf);
1166 do_build_seq_ibuf(scene, seq, se, cfra, TRUE, render_size,
1167 seqrectx, seqrecty);
1173 rectx= (render_size*scene->r.xsch)/100;
1174 recty= (render_size*scene->r.ysch)/100;
1178 if (ibuf->x != rectx || ibuf->y != recty) {
1179 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1182 /* quality is fixed, otherwise one has to generate separate
1183 directories for every quality...
1185 depth = 32 is intentionally left in, otherwise ALPHA channels
1187 quality = seq->strip->proxy->quality;
1188 ibuf->ftype= JPG | quality;
1190 BLI_make_existing_file(name);
1192 ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
1197 IMB_freeImBuf(ibuf);
1201 static void seq_proxy_rebuild(Scene *scene, Sequence * seq, int seqrectx,
1205 float rsize = seq->strip->proxy->size;
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.
1217 for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
1218 TStripElem * tse = give_tstripelem(seq, cfra);
1220 tse->flag &= ~STRIPELEM_PREVIEW_DONE;
1225 /* a _lot_ faster for movie files, if we read frames in
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);
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;
1238 if (blender_test_break()) {
1243 for (cfra = seq->startdisp + seq->startstill;
1244 cfra < seq->enddisp - seq->endstill; cfra++) {
1245 TStripElem * tse = give_tstripelem(seq, cfra);
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;
1253 if (blender_test_break()) {
1263 /* **********************************************************************
1265 ********************************************************************** */
1267 static StripColorBalance calc_cb(StripColorBalance * cb_)
1269 StripColorBalance cb = *cb_;
1272 for (c = 0; c < 3; c++) {
1273 cb.lift[c] = 2.0f - cb.lift[c];
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;
1283 cb.lift[c] = 2.0f - cb.lift[c];
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];
1292 cb.gain[c] = 1000000; /* should be enough :) */
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];
1302 cb.gamma[c] = 1000000; /* should be enough :) */
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)
1313 float x= (((in - 1.0f) * lift) + 1.0f) * gain;
1316 if (x < 0.f) x = 0.f;
1318 return powf(x, gamma) * mul;
1321 static void make_cb_table_byte(float lift, float gain, float gamma,
1322 unsigned char * table, float mul)
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);
1333 static void make_cb_table_float(float lift, float gain, float gamma,
1334 float * table, float mul)
1338 for (y = 0; y < 256; y++) {
1339 float v= color_balance_fl((float)y * (1.0 / 255.0f), lift, gain, gamma, mul);
1344 static void color_balance_byte_byte(Sequence * seq, ImBuf* ibuf, float mul)
1346 unsigned char cb_tab[3][256];
1348 unsigned char * p = (unsigned char*) ibuf->rect;
1349 unsigned char * e = p + ibuf->x * 4 * ibuf->y;
1351 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1353 for (c = 0; c < 3; c++) {
1354 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1359 p[0] = cb_tab[0][p[0]];
1360 p[1] = cb_tab[1][p[1]];
1361 p[2] = cb_tab[2][p[2]];
1367 static void color_balance_byte_float(Sequence * seq, ImBuf* ibuf, float mul)
1369 float cb_tab[4][256];
1371 unsigned char * p = (unsigned char*) ibuf->rect;
1372 unsigned char * e = p + ibuf->x * 4 * ibuf->y;
1374 StripColorBalance cb;
1376 imb_addrectfloatImBuf(ibuf);
1378 o = ibuf->rect_float;
1380 cb = calc_cb(seq->strip->color_balance);
1382 for (c = 0; c < 3; c++) {
1383 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
1387 for (i = 0; i < 256; i++) {
1388 cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
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]];
1401 static void color_balance_float_float(Sequence * seq, ImBuf* ibuf, float mul)
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);
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);
1416 static void color_balance(Sequence * seq, ImBuf* ibuf, float mul)
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);
1423 color_balance_byte_byte(seq, ibuf, mul);
1428 input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
1430 Do all the things you can't really do afterwards using sequence effects
1431 (read: before rescaling to render resolution has been done)
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)
1446 int input_have_to_preprocess(
1447 Scene *UNUSED(scene), Sequence * seq, float UNUSED(cfra), int UNUSED(seqrectx), int UNUSED(seqrecty))
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)) {
1463 if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1464 mul *= seq->blend_opacity / 100.0;
1471 if (seq->sat != 1.0) {
1478 static ImBuf * input_preprocess(
1479 Scene *scene, Sequence *seq, float UNUSED(cfra), int seqrectx, int seqrecty,
1484 seq->strip->orx= ibuf->x;
1485 seq->strip->ory= ibuf->y;
1487 if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
1491 if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
1496 memset(&c, 0, sizeof(StripCrop));
1497 memset(&t, 0, sizeof(StripTransform));
1499 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1500 c = *seq->strip->crop;
1502 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1503 t = *seq->strip->transform;
1506 sx = ibuf->x - c.left - c.right;
1507 sy = ibuf->y - c.top - c.bottom;
1511 if (seq->flag & SEQ_USE_TRANSFORM) {
1516 if (c.top + c.bottom >= ibuf->y ||
1517 c.left + c.right >= ibuf->x ||
1518 t.xofs >= dx || t.yofs >= dy) {
1519 make_black_ibuf(ibuf);
1523 if (ibuf->rect_float) {
1524 i = IMB_allocImBuf(dx, dy,32, IB_rectfloat);
1526 i = IMB_allocImBuf(dx, dy,32, IB_rect);
1529 IMB_rectcpy(i, ibuf,
1534 IMB_freeImBuf(ibuf);
1540 if(seq->flag & SEQ_FLIPX) {
1544 if(seq->flag & SEQ_FLIPY) {
1548 if(seq->sat != 1.0f) {
1549 /* inline for now, could become an imbuf function */
1551 char *rct= (char *)ibuf->rect;
1552 float *rctf= ibuf->rect_float;
1553 const float sat= seq->sat;
1558 for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) {
1559 rgb_byte_to_float(rct, rgb);
1560 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
1561 hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb+1, rgb+2);
1562 rgb_float_to_byte(rgb, rct);
1567 for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) {
1568 rgb_to_hsv(rctf[0], rctf[1], rctf[2], hsv, hsv+1, hsv+2);
1569 hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rctf, rctf+1, rctf+2);
1576 if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1577 mul *= seq->blend_opacity / 100.0;
1580 if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1581 color_balance(seq, ibuf, mul);
1585 if(seq->flag & SEQ_MAKE_FLOAT) {
1586 if (!ibuf->rect_float)
1587 IMB_float_from_rect_simple(ibuf);
1590 imb_freerectImBuf(ibuf);
1595 multibuf(ibuf, mul);
1598 if(seq->flag & SEQ_MAKE_PREMUL) {
1599 if(ibuf->depth == 32 && ibuf->zbuf == 0) {
1600 IMB_premultiply_alpha(ibuf);
1605 if(ibuf->x != seqrectx || ibuf->y != seqrecty ) {
1606 if(scene->r.mode & R_OSA) {
1607 IMB_scaleImBuf(ibuf,
1608 (short)seqrectx, (short)seqrecty);
1610 IMB_scalefastImBuf(ibuf,
1611 (short)seqrectx, (short)seqrecty);
1617 static ImBuf * copy_from_ibuf_still(Sequence * seq, float nr,
1618 int seqrectx, int seqrecty)
1624 ibuf = seq_stripelem_cache_get(
1625 seq, seqrectx, seqrecty, seq->start,
1626 SEQ_STRIPELEM_IBUF_STARTSTILL);
1628 if (nr == seq->len - 1) {
1629 ibuf = seq_stripelem_cache_get(
1630 seq, seqrectx, seqrecty, seq->start,
1631 SEQ_STRIPELEM_IBUF_ENDSTILL);
1635 rval = IMB_dupImBuf(ibuf);
1636 IMB_freeImBuf(ibuf);
1642 static void copy_to_ibuf_still(Sequence * seq, float nr,
1646 seq_stripelem_cache_put(
1647 seq, 0, 0, seq->start,
1648 SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf);
1650 if (nr == seq->len - 1) {
1651 seq_stripelem_cache_put(
1652 seq, 0, 0, seq->start,
1653 SEQ_STRIPELEM_IBUF_ENDSTILL, ibuf);
1657 /* **********************************************************************
1658 strip rendering functions
1659 ********************************************************************** */
1661 static ImBuf* seq_render_strip_stack(
1662 Main *bmain, Scene *scene,
1663 ListBase *seqbasep, float cfra, int chanshown, int render_size,
1664 int seqrectx, int seqrecty);
1666 static ImBuf * seq_render_strip(Main *bmain, Scene *scene, Sequence * seq, float cfra,
1668 int seqrectx, int seqrecty);
1671 static ImBuf* seq_render_effect_strip_impl(
1672 Main *bmain, Scene *scene, float cfra, Sequence *seq, int render_size,
1673 int seqrectx, int seqrecty)
1678 int must_preprocess = FALSE;
1680 struct SeqEffectHandle sh = get_sequence_effect(seq);
1685 ibuf[0] = ibuf[1] = ibuf[2] = 0;
1687 if (!sh.execute) { /* effect not supported in this version... */
1691 if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
1692 sh.get_default_fac(seq, cfra, &fac, &facf);
1693 if( scene->r.mode & R_FIELDS ); else facf= fac;
1695 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence,
1698 fac = facf = evaluate_fcurve(fcu, cfra);
1699 if( scene->r.mode & R_FIELDS ) {
1700 facf = evaluate_fcurve(fcu, cfra + 0.5);
1703 fac = facf = seq->effect_fader;
1707 early_out = sh.early_out(seq, fac, facf);
1709 if (early_out == -1) { /* no input needed */
1710 out = sh.execute(bmain, scene, seq, cfra, fac, facf,
1711 seqrectx, seqrecty, render_size,
1717 must_preprocess = input_have_to_preprocess(
1718 scene, seq, cfra, seqrectx, seqrecty);
1720 switch (early_out) {
1725 ibuf[0] = seq_render_strip(bmain, scene, seq->seq1, cfra,
1727 seqrectx, seqrecty);
1730 if (must_preprocess) {
1731 out = IMB_dupImBuf(ibuf[0]);
1740 ibuf[1] = seq_render_strip(bmain, scene, seq->seq2, cfra,
1742 seqrectx, seqrecty);
1745 if (must_preprocess) {
1746 out = IMB_dupImBuf(ibuf[1]);
1758 ibuf[0] = seq_render_strip(bmain, scene, seq->seq1, cfra,
1760 seqrectx, seqrecty);
1764 ibuf[1] = seq_render_strip(bmain, scene, seq->seq2, cfra,
1766 seqrectx, seqrecty);
1770 ibuf[2] = seq_render_strip(bmain, scene, seq->seq3, cfra,
1772 seqrectx, seqrecty);
1775 if (!ibuf[0] || !ibuf[1]) {
1779 out = sh.execute(bmain, scene, seq, cfra, fac, facf, seqrectx, seqrecty,
1781 ibuf[0], ibuf[1], ibuf[2]);
1784 for (i = 0; i < 3; i++) {
1785 IMB_freeImBuf(ibuf[i]);
1789 out = IMB_allocImBuf(
1790 (short)seqrectx, (short)seqrecty, 32, IB_rect);
1797 static ImBuf * seq_render_scene_strip_impl(
1798 Main *bmain, Scene * scene, Sequence * seq, float nr, int seqrectx, int seqrecty)
1801 float frame= seq->sfra + nr + seq->anim_startofs;
1804 ListBase oldmarkers;
1806 /* Hack! This function can be called from do_render_seq(), in that case
1807 the seq->scene can already have a Render initialized with same name,
1808 so we have to use a default name. (compositor uses scene name to
1810 However, when called from within the UI (image preview in sequencer)
1811 we do want to use scene Render, that way the render result is defined
1812 for display in render/imagewindow
1814 Hmm, don't see, why we can't do that all the time,
1815 and since G.rendering is uhm, gone... (Peter)
1818 int rendering = G.rendering;
1820 int doseq_gl= G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : (scene->r.seq_flag & R_SEQ_GL_PREV);
1821 int have_seq= FALSE;
1822 Scene *sce= seq->scene; /* dont refer to seq->scene above this point!, it can be NULL */
1823 int sce_valid= FALSE;
1826 have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first;
1827 sce_valid= (sce->camera || have_seq);
1833 oldcfra= seq->scene->r.cfra;
1834 oldcamera= seq->scene->camera;
1836 /* prevent eternal loop */
1837 doseq= scene->r.scemode & R_DOSEQ;
1838 scene->r.scemode &= ~R_DOSEQ;
1840 seq->scene->r.cfra= frame;
1841 if(seq->scene_camera)
1842 seq->scene->camera= seq->scene_camera;
1844 scene_camera_switch_update(seq->scene);
1846 #ifdef DURIAN_CAMERA_SWITCH
1847 /* stooping to new low's in hackyness :( */
1848 oldmarkers= seq->scene->markers;
1849 seq->scene->markers.first= seq->scene->markers.last= NULL;
1852 if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (seq->scene == scene || have_seq==0) && seq->scene->camera) {
1853 /* opengl offscreen render */
1854 scene_update_for_newframe(bmain, seq->scene, seq->scene->lay);
1855 ibuf= sequencer_view3d_cb(seq->scene, seqrectx, seqrecty, IB_rect,
1856 scene->r.seq_prev_type);
1863 re= RE_NewRender(" do_build_seq_ibuf");
1864 /* If the top level scene that does the sequencer rendering is included
1865 * as a strip the default render name for the strip will conflict with
1866 * the original render, so override the name in this case.
1867 * See bugs #22236 and #24160 for examples.
1868 * XXX: Somebody with deeper insight to the rendering pipeline should
1869 * probably check if this is the best way to handle this. -jahka
1871 else if(seq->scene == scene)
1872 re= RE_NewRender("scene_conflict_render");
1874 re= RE_NewRender(sce->id.name);
1876 RE_BlenderFrame(re, bmain, sce, NULL, sce->lay, frame);
1878 RE_AcquireResultImage(re, &rres);
1881 ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat);
1882 memcpy(ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
1884 addzbuffloatImBuf(ibuf);
1885 memcpy(ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
1888 /* float buffers in the sequencer are not linear */
1889 ibuf->profile= IB_PROFILE_LINEAR_RGB;
1890 IMB_convert_profile(ibuf, IB_PROFILE_SRGB);
1892 else if (rres.rect32) {
1893 ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect);
1894 memcpy(ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
1897 RE_ReleaseResultImage(re);
1899 // BIF_end_render_callbacks();
1903 scene->r.scemode |= doseq;
1905 seq->scene->r.cfra = oldcfra;
1906 seq->scene->camera= oldcamera;
1908 #ifdef DURIAN_CAMERA_SWITCH
1909 /* stooping to new low's in hackyness :( */
1910 seq->scene->markers= oldmarkers;
1916 static ImBuf * seq_render_strip(Main *bmain, Scene *scene, Sequence * seq, float cfra,
1918 int seqrectx, int seqrecty)
1920 char name[FILE_MAXDIR+FILE_MAXFILE];
1921 int use_preprocess = input_have_to_preprocess(
1922 scene, seq, cfra, seqrectx, seqrecty);
1923 ImBuf * ibuf = seq_stripelem_cache_get(
1924 seq, seqrectx, seqrecty, cfra, SEQ_STRIPELEM_IBUF);
1925 float nr = give_stripelem_index(seq, cfra);
1927 /* currently, we cache preprocessed images */
1929 use_preprocess = FALSE;
1932 if(seq->type == SEQ_META) {
1933 ImBuf * meta_ibuf = 0;
1936 ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1939 if(!ibuf && seq->seqbase.first) {
1940 meta_ibuf = seq_render_strip_stack(
1942 &seq->seqbase, seq->start + nr, 0,
1943 render_size, seqrectx, seqrecty);
1946 if(!ibuf && meta_ibuf) {
1948 if(ibuf && use_preprocess) {
1949 struct ImBuf * i = IMB_dupImBuf(ibuf);
1951 IMB_freeImBuf(ibuf);
1956 } else if(seq->type == SEQ_SPEED) {
1957 ImBuf * child_ibuf = 0;
1960 ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1965 SpeedControlVars * s
1966 = (SpeedControlVars *)seq->effectdata;
1968 sequence_effect_speed_rebuild_map(scene, seq, 0);
1971 f_cfra = seq->start + s->frameMap[(int) nr];
1973 child_ibuf = seq_render_strip(bmain, scene, seq->seq1, f_cfra,
1975 seqrectx, seqrecty);
1978 if (!ibuf && child_ibuf) {
1980 if(ibuf && use_preprocess) {
1981 struct ImBuf * i = IMB_dupImBuf(ibuf);
1983 IMB_freeImBuf(ibuf);
1988 } else if(seq->type & SEQ_EFFECT) {
1989 /* should the effect be recalculated? */
1992 ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1996 ibuf = seq_render_effect_strip_impl(
1997 bmain, scene, cfra, seq, render_size,
1998 seqrectx, seqrecty);
2000 } else if(seq->type == SEQ_IMAGE) {
2001 StripElem * s_elem = give_stripelem(seq, cfra);
2003 if(ibuf == 0 && s_elem) {
2004 BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
2005 BLI_path_abs(name, G.main->name);
2007 ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2011 ibuf = copy_from_ibuf_still(seq,nr,seqrectx,seqrecty);
2014 if (ibuf == 0 && s_elem &&
2015 (ibuf = IMB_loadiffname(name, IB_rect))) {
2016 /* we don't need both (speed reasons)! */
2017 if (ibuf->rect_float && ibuf->rect)
2018 imb_freerectImBuf(ibuf);
2020 /* all sequencer color is done in SRGB space, linear gives odd crossfades */
2021 if(ibuf->profile == IB_PROFILE_LINEAR_RGB)
2022 IMB_convert_profile(ibuf, IB_PROFILE_NONE);
2024 copy_to_ibuf_still(seq, nr, ibuf);
2026 } else if(seq->type == SEQ_MOVIE) {
2028 ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2033 ibuf = copy_from_ibuf_still(seq, nr,seqrectx,seqrecty);
2038 BLI_join_dirfile(name,
2040 seq->strip->stripdata->name);
2041 BLI_path_abs(name, G.main->name);
2043 seq->anim = openanim(
2045 ((seq->flag & SEQ_FILTERY)
2046 ? IB_animdeinterlace : 0));
2049 IMB_anim_set_preseek(seq->anim,
2051 ibuf = IMB_anim_absolute(seq->anim,
2053 + seq->anim_startofs);
2054 /* we don't need both (speed reasons)! */
2055 if (ibuf && ibuf->rect_float
2057 imb_freerectImBuf(ibuf);
2061 copy_to_ibuf_still(seq, nr, ibuf);
2064 } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions
2066 ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2069 ibuf = copy_from_ibuf_still(seq, nr,seqrectx,seqrecty);
2073 ibuf = seq_render_scene_strip_impl(bmain, scene, seq, nr,
2074 seqrectx, seqrecty);
2076 copy_to_ibuf_still(seq, nr, ibuf);
2081 ibuf = IMB_allocImBuf(
2082 (short)seqrectx, (short)seqrecty, 32, IB_rect);
2085 if (ibuf->x != seqrectx || ibuf->y != seqrecty) {
2086 use_preprocess = TRUE;
2089 if (use_preprocess) {
2090 ibuf = input_preprocess(scene, seq, cfra, seqrectx,
2094 seq_stripelem_cache_put(
2095 seq, seqrectx, seqrecty, cfra, SEQ_STRIPELEM_IBUF, ibuf);
2100 /* **********************************************************************
2101 strip stack rendering functions
2102 ********************************************************************** */
2104 static int seq_must_swap_input_in_blend_mode(Sequence * seq)
2106 int swap_input = FALSE;
2108 /* bad hack, to fix crazy input ordering of
2109 those two effects */
2111 if (seq->blend_mode == SEQ_ALPHAOVER ||
2112 seq->blend_mode == SEQ_ALPHAUNDER ||
2113 seq->blend_mode == SEQ_OVERDROP) {
2120 static int seq_get_early_out_for_blend_mode(Sequence * seq)
2122 struct SeqEffectHandle sh = get_sequence_blend(seq);
2123 float facf = seq->blend_opacity / 100.0;
2124 int early_out = sh.early_out(seq, facf, facf);
2126 if (early_out < 1) {
2130 if (seq_must_swap_input_in_blend_mode(seq)) {
2131 if (early_out == 2) {
2133 } else if (early_out == 1) {
2140 static ImBuf* seq_render_strip_stack(
2141 Main *bmain, Scene *scene, ListBase *seqbasep, float cfra, int chanshown,
2142 int render_size, int seqrectx, int seqrecty)
2144 Sequence* seq_arr[MAXSEQ+1];
2149 count = get_shown_sequences(seqbasep, cfra, chanshown,
2150 (Sequence **)&seq_arr);
2156 #if 0 /* commentind since this breaks keyframing, since it resets the value on draw */
2157 if(scene->r.cfra != cfra) {
2158 // XXX for prefetch and overlay offset!..., very bad!!!
2159 AnimData *adt= BKE_animdata_from_id(&scene->id);
2160 BKE_animsys_evaluate_animdata(&scene->id, adt, cfra, ADT_RECALC_ANIM);
2164 out = seq_stripelem_cache_get(
2166 seqrectx, seqrecty, cfra, SEQ_STRIPELEM_IBUF_COMP);
2173 out = seq_render_strip(bmain, scene, seq_arr[0],
2175 seqrectx, seqrecty);
2176 seq_stripelem_cache_put(
2178 seqrectx, seqrecty, cfra,
2179 SEQ_STRIPELEM_IBUF_COMP, out);
2185 for (i = count - 1; i >= 0; i--) {
2187 Sequence * seq = seq_arr[i];
2189 out = seq_stripelem_cache_get(
2191 seqrectx, seqrecty, cfra, SEQ_STRIPELEM_IBUF_COMP);
2196 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2197 out = seq_render_strip(bmain, scene, seq, cfra,
2199 seqrectx, seqrecty);
2203 early_out = seq_get_early_out_for_blend_mode(seq);
2205 switch (early_out) {
2208 out = seq_render_strip(bmain, scene, seq, cfra,
2210 seqrectx, seqrecty);
2214 out = IMB_allocImBuf(
2215 (short)seqrectx, (short)seqrecty,
2221 out = seq_render_strip(bmain, scene, seq, cfra,
2223 seqrectx, seqrecty);
2233 seq_stripelem_cache_put(
2234 seq_arr[i], seqrectx, seqrecty, cfra,
2235 SEQ_STRIPELEM_IBUF_COMP, out);
2240 for (; i < count; i++) {
2241 Sequence * seq = seq_arr[i];
2243 if (seq_get_early_out_for_blend_mode(seq) == 0) {
2244 struct SeqEffectHandle sh = get_sequence_blend(seq);
2245 ImBuf * ibuf1 = out;
2246 ImBuf * ibuf2 = seq_render_strip(bmain, scene, seq, cfra,
2248 seqrectx, seqrecty);
2250 float facf = seq->blend_opacity / 100.0;
2252 = seq_must_swap_input_in_blend_mode(seq);
2258 out = sh.execute(bmain, scene, seq, cfra,
2259 facf, facf, x, y, render_size,
2262 out = sh.execute(bmain, scene, seq, cfra,
2263 facf, facf, x, y, render_size,
2267 IMB_freeImBuf(ibuf1);
2268 IMB_freeImBuf(ibuf2);
2271 seq_stripelem_cache_put(
2272 seq_arr[i], seqrectx, seqrecty, cfra,
2273 SEQ_STRIPELEM_IBUF_COMP, out);
2280 * returned ImBuf is refed!
2281 * you have to free after usage!
2284 ImBuf *give_ibuf_seq(Main *bmain, Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2286 Editing *ed= seq_give_editing(scene, FALSE);
2290 if(ed==NULL) return NULL;
2292 count = BLI_countlist(&ed->metastack);
2293 if((chanshown < 0) && (count > 0)) {
2294 count = MAX2(count + chanshown, 0);
2295 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2297 seqbasep= ed->seqbasep;
2300 return seq_render_strip_stack(
2301 bmain, scene, seqbasep, cfra, chanshown, render_size, rectx, recty);
2304 ImBuf *give_ibuf_seqbase(Main *bmain, Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size, ListBase *seqbasep)
2306 return seq_render_strip_stack(bmain, scene, seqbasep, cfra, chanshown, render_size, rectx, recty);
2310 ImBuf *give_ibuf_seq_direct(Main *bmain, Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
2312 return seq_render_strip(bmain, scene, seq, cfra, render_size, rectx, recty);
2316 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2317 static int seq_can_blend(Sequence *seq)
2319 if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2327 /* *********************** threading api ******************* */
2329 static ListBase running_threads;
2330 static ListBase prefetch_wait;
2331 static ListBase prefetch_done;
2333 static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
2334 static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER;
2335 static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
2337 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2338 //static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2340 static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
2341 static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
2343 static volatile int seq_thread_shutdown = TRUE;
2344 static volatile int seq_last_given_monoton_cfra = 0;
2345 static int monoton_cfra = 0;
2347 typedef struct PrefetchThread {
2348 struct PrefetchThread *next, *prev;
2351 struct PrefetchQueueElem *current;
2357 typedef struct PrefetchQueueElem {
2358 struct PrefetchQueueElem *next, *prev;
2368 struct ImBuf * ibuf;
2369 } PrefetchQueueElem;
2372 static void *seq_prefetch_thread(void * This_)
2374 PrefetchThread * This = This_;
2376 while (!seq_thread_shutdown) {
2377 PrefetchQueueElem *e;
2380 pthread_mutex_lock(&queue_lock);
2381 e = prefetch_wait.first;
2383 BLI_remlink(&prefetch_wait, e);
2385 s_last = seq_last_given_monoton_cfra;
2389 pthread_mutex_unlock(&queue_lock);
2392 pthread_mutex_lock(&prefetch_ready_lock);
2394 This->running = FALSE;
2396 pthread_cond_signal(&prefetch_ready_cond);
2397 pthread_mutex_unlock(&prefetch_ready_lock);
2399 pthread_mutex_lock(&wakeup_lock);
2400 if (!seq_thread_shutdown) {
2401 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2403 pthread_mutex_unlock(&wakeup_lock);
2407 This->running = TRUE;
2409 if (e->cfra >= s_last) {
2410 e->ibuf = give_ibuf_seq_impl(This->scene,
2411 e->rectx, e->recty, e->cfra, e->chanshown,
2415 pthread_mutex_lock(&queue_lock);
2417 BLI_addtail(&prefetch_done, e);
2419 for (e = prefetch_wait.first; e; e = e->next) {
2420 if (s_last > e->monoton_cfra) {
2421 BLI_remlink(&prefetch_wait, e);
2426 for (e = prefetch_done.first; e; e = e->next) {
2427 if (s_last > e->monoton_cfra) {
2429 IMB_cache_limiter_unref(e->ibuf);
2431 BLI_remlink(&prefetch_done, e);
2436 pthread_mutex_unlock(&queue_lock);
2438 pthread_mutex_lock(&frame_done_lock);
2439 pthread_cond_signal(&frame_done_cond);
2440 pthread_mutex_unlock(&frame_done_lock);
2445 static void seq_start_threads(Scene *scene)
2449 running_threads.first = running_threads.last = NULL;
2450 prefetch_wait.first = prefetch_wait.last = NULL;
2451 prefetch_done.first = prefetch_done.last = NULL;
2453 seq_thread_shutdown = FALSE;
2454 seq_last_given_monoton_cfra = monoton_cfra = 0;
2456 /* since global structures are modified during the processing
2457 of one frame, only one render thread is currently possible...
2459 (but we code, in the hope, that we can remove this restriction
2463 fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2465 for (i = 0; i < 1; i++) {
2466 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
2469 BLI_addtail(&running_threads, t);
2471 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2474 /* init malloc mutex */
2475 BLI_init_threads(0, 0, 0);
2478 static void seq_stop_threads()
2480 PrefetchThread *tslot;
2481 PrefetchQueueElem *e;
2483 fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2485 if (seq_thread_shutdown) {
2486 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2490 pthread_mutex_lock(&wakeup_lock);
2492 seq_thread_shutdown = TRUE;
2494 pthread_cond_broadcast(&wakeup_cond);
2495 pthread_mutex_unlock(&wakeup_lock);
2497 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2498 pthread_join(tslot->pthread, NULL);
2502 for (e = prefetch_wait.first; e; e = e->next) {
2503 BLI_remlink(&prefetch_wait, e);
2507 for (e = prefetch_done.first; e; e = e->next) {
2509 IMB_cache_limiter_unref(e->ibuf);
2511 BLI_remlink(&prefetch_done, e);
2515 BLI_freelistN(&running_threads);
2517 /* deinit malloc mutex */
2522 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
2525 PrefetchQueueElem *e;
2526 if (seq_thread_shutdown) {
2530 e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2534 e->chanshown = chanshown;
2535 e->render_size = render_size;
2536 e->monoton_cfra = monoton_cfra++;
2538 pthread_mutex_lock(&queue_lock);
2539 BLI_addtail(&prefetch_wait, e);
2540 pthread_mutex_unlock(&queue_lock);
2542 pthread_mutex_lock(&wakeup_lock);
2543 pthread_cond_signal(&wakeup_cond);
2544 pthread_mutex_unlock(&wakeup_lock);
2548 static void seq_wait_for_prefetch_ready()
2550 PrefetchThread *tslot;
2552 if (seq_thread_shutdown) {
2556 fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
2558 pthread_mutex_lock(&prefetch_ready_lock);
2561 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2562 if (tslot->running) {
2569 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
2572 pthread_mutex_unlock(&prefetch_ready_lock);
2574 fprintf(stderr, "SEQ-THREAD: prefetch done\n");
2578 ImBuf *give_ibuf_seq_threaded(Main *bmain, Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2580 PrefetchQueueElem *e = NULL;
2581 int found_something = FALSE;
2583 if (seq_thread_shutdown) {
2584 return give_ibuf_seq(bmain, scene, rectx, recty, cfra, chanshown, render_size);
2588 int success = FALSE;
2589 pthread_mutex_lock(&queue_lock);
2591 for (e = prefetch_done.first; e; e = e->next) {
2592 if (cfra == e->cfra &&
2593 chanshown == e->chanshown &&
2594 rectx == e->rectx &&
2595 recty == e->recty &&
2596 render_size == e->render_size) {
2598 found_something = TRUE;
2604 for (e = prefetch_wait.first; e; e = e->next) {
2605 if (cfra == e->cfra &&
2606 chanshown == e->chanshown &&
2607 rectx == e->rectx &&
2608 recty == e->recty &&
2609 render_size == e->render_size) {
2610 found_something = TRUE;
2617 PrefetchThread *tslot;
2619 for(tslot = running_threads.first;
2620 tslot; tslot= tslot->next) {
2621 if (tslot->current &&
2622 cfra == tslot->current->cfra &&
2623 chanshown == tslot->current->chanshown &&
2624 rectx == tslot->current->rectx &&
2625 recty == tslot->current->recty &&
2626 render_size== tslot->current->render_size){
2627 found_something = TRUE;
2633 /* e->ibuf is unrefed by render thread on next round. */
2636 seq_last_given_monoton_cfra = e->monoton_cfra;
2639 pthread_mutex_unlock(&queue_lock);
2644 if (!found_something) {
2646 "SEQ-THREAD: Requested frame "
2647 "not in queue ???\n");
2650 pthread_mutex_lock(&frame_done_lock);
2651 pthread_cond_wait(&frame_done_cond, &frame_done_lock);
2652 pthread_mutex_unlock(&frame_done_lock);
2656 return e ? e->ibuf : 0;
2659 /* Functions to free imbuf and anim data on changes */
2661 static void free_anim_seq(Sequence *seq)
2664 IMB_free_anim(seq->anim);
2669 void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage,
2670 int keep_file_handles)
2674 if (check_mem_usage) {
2675 /* Let the cache limitor take care of this (schlaile) */
2676 /* While render let's keep all memory available for render
2678 At least if free memory is tight...
2679 This can make a big difference in encoding speed
2680 (it is around 4 times(!) faster, if we do not waste time
2681 on freeing _all_ buffers every time on long timelines...)
2685 uintptr_t mem_in_use;
2686 uintptr_t mmap_in_use;
2689 mem_in_use= MEM_get_memory_in_use();
2690 mmap_in_use= MEM_get_mapped_memory_in_use();
2691 max = MEM_CacheLimiter_get_maximum();
2693 if (max == 0 || mem_in_use + mmap_in_use <= max) {
2698 seq_stripelem_cache_cleanup();
2700 for(seq= seqbase->first; seq; seq= seq->next) {
2702 if(seq->type==SEQ_MOVIE && !keep_file_handles)
2704 if(seq->type==SEQ_SPEED) {
2705 sequence_effect_speed_rebuild_map(scene, seq, 1);
2708 if(seq->type==SEQ_META) {
2709 free_imbuf_seq(scene, &seq->seqbase, FALSE,
2712 if(seq->type==SEQ_SCENE) {
2713 /* FIXME: recurs downwards,
2714 but do recurs protection somehow! */
2720 static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
2725 /* recurs downwards to see if this seq depends on the changed seq */
2730 if(seq == changed_seq)
2733 for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
2734 if(update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change))
2738 if(update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change))
2740 if(seq->seq2 && (seq->seq2 != seq->seq1))
2741 if(update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change))
2743 if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
2744 if(update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change))
2749 if(seq->type == SEQ_MOVIE)
2751 if(seq->type == SEQ_SPEED) {
2752 sequence_effect_speed_rebuild_map(scene, seq, 1);
2757 calc_sequence(scene, seq);
2763 void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
2765 Editing *ed= seq_give_editing(scene, FALSE);
2768 if (ed==NULL) return;
2770 for (seq=ed->seqbase.first; seq; seq=seq->next)
2771 update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change);
2774 /* seq funcs's for transforming internally
2775 notice the difference between start/end and left/right.
2777 left and right are the bounds at which the sequence is rendered,
2778 start and end are from the start and fixed length of the sequence.
2780 int seq_tx_get_start(Sequence *seq) {
2783 int seq_tx_get_end(Sequence *seq)
2785 return seq->start+seq->len;
2788 int seq_tx_get_final_left(Sequence *seq, int metaclip)
2790 if (metaclip && seq->tmp) {
2791 /* return the range clipped by the parents range */
2792 return MAX2( seq_tx_get_final_left(seq, 0), seq_tx_get_final_left((Sequence *)seq->tmp, 1) );
2794 return (seq->start - seq->startstill) + seq->startofs;
2798 int seq_tx_get_final_right(Sequence *seq, int metaclip)
2800 if (metaclip && seq->tmp) {
2801 /* return the range clipped by the parents range */
2802 return MIN2( seq_tx_get_final_right(seq, 0), seq_tx_get_final_right((Sequence *)seq->tmp, 1) );
2804 return ((seq->start+seq->len) + seq->endstill) - seq->endofs;
2808 void seq_tx_set_final_left(Sequence *seq, int val)
2810 if (val < (seq)->start) {
2811 seq->startstill = abs(val - (seq)->start);
2814 seq->startofs = abs(val - (seq)->start);
2815 seq->startstill = 0;
2819 void seq_tx_set_final_right(Sequence *seq, int val)
2821 if (val > (seq)->start + (seq)->len) {
2822 seq->endstill = abs(val - (seq->start + (seq)->len));
2825 seq->endofs = abs(val - ((seq)->start + (seq)->len));
2830 /* used so we can do a quick check for single image seq
2831 since they work a bit differently to normal image seq's (during transform) */
2832 int seq_single_check(Sequence *seq)
2834 if ( seq->len==1 && (seq->type == SEQ_IMAGE || seq->type == SEQ_COLOR
2835 || seq->type == SEQ_MULTICAM))
2841 /* check if the selected seq's reference unselected seq's */
2842 int seqbase_isolated_sel_check(ListBase *seqbase)
2845 /* is there more than 1 select */
2848 for(seq= seqbase->first; seq; seq= seq->next) {
2849 if(seq->flag & SELECT) {
2858 /* test relationships */
2859 for(seq= seqbase->first; seq; seq= seq->next) {
2860 if(seq->flag & SELECT) {
2861 if(seq->type & SEQ_EFFECT) {
2862 if(seq->seq1 && (seq->seq1->flag & SELECT)==0) return FALSE;
2863 if(seq->seq2 && (seq->seq2->flag & SELECT)==0) return FALSE;
2864 if(seq->seq3 && (seq->seq3->flag & SELECT)==0) return FALSE;
2867 else if(seq->type & SEQ_EFFECT) {
2868 if(seq->seq1 && (seq->seq1->flag & SELECT)) return FALSE;
2869 if(seq->seq2 && (seq->seq2->flag & SELECT)) return FALSE;
2870 if(seq->seq3 && (seq->seq3->flag & SELECT)) return FALSE;
2877 /* use to impose limits when dragging/extending - so impossible situations dont happen
2878 * Cant use the SEQ_LEFTSEL and SEQ_LEFTSEL directly because the strip may be in a metastrip */
2879 void seq_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
2882 if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_final_right(seq, 0)) {
2883 seq_tx_set_final_left(seq, seq_tx_get_final_right(seq, 0)-1);
2886 if (seq_single_check(seq)==0) {
2887 if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_end(seq)) {
2888 seq_tx_set_final_left(seq, seq_tx_get_end(seq)-1);
2891 /* dosnt work now - TODO */
2893 if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq, 0)) {
2895 ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq, 0);
2897 seq_tx_set_final_left(seq, seq_tx_get_final_left(seq, 0) + ofs );
2904 if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_final_left(seq, 0)) {
2905 seq_tx_set_final_right(seq, seq_tx_get_final_left(seq, 0)+1);
2908 if (seq_single_check(seq)==0) {
2909 if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_start(seq)) {
2910 seq_tx_set_final_right(seq, seq_tx_get_start(seq)+1);
2915 /* sounds cannot be extended past their endpoints */
2916 if (seq->type == SEQ_SOUND) {
2922 void seq_single_fix(Sequence *seq)
2924 int left, start, offset;
2925 if (!seq_single_check(seq))
2928 /* make sure the image is always at the start since there is only one,
2929 adjusting its start should be ok */
2930 left = seq_tx_get_final_left(seq, 0);
2932 if (start != left) {
2933 offset = left - start;
2934 seq_tx_set_final_left( seq, seq_tx_get_final_left(seq, 0) - offset );
2935 seq_tx_set_final_right( seq, seq_tx_get_final_right(seq, 0) - offset );
2936 seq->start += offset;
2940 int seq_tx_test(Sequence * seq)
2942 return (seq->type < SEQ_EFFECT) || (get_sequence_effect_num_inputs(seq->type) == 0);
2945 static int seq_overlap(Sequence *seq1, Sequence *seq2)
2948 if(seq1->machine==seq2->machine)
2949 if(((seq1->enddisp <= seq2->startdisp) || (seq1->startdisp >= seq2->enddisp))==0)
2955 int seq_test_overlap(ListBase * seqbasep, Sequence *test)
2959 seq= seqbasep->first;
2961 if(seq_overlap(test, seq))
2970 static void seq_translate(Scene *evil_scene, Sequence *seq, int delta)
2972 seq_offset_animdata(evil_scene, seq, delta);
2973 seq->start += delta;
2975 if(seq->type==SEQ_META) {
2976 Sequence *seq_child;
2977 for(seq_child= seq->seqbase.first; seq_child; seq_child= seq_child->next) {
2978 seq_translate(evil_scene, seq_child, delta);
2982 calc_sequence_disp(evil_scene, seq);
2985 /* return 0 if there werent enough space */
2986 int shuffle_seq(ListBase * seqbasep, Sequence *test, Scene *evil_scene)
2988 int orig_machine= test->machine;
2990 calc_sequence(evil_scene, test);
2991 while( seq_test_overlap(seqbasep, test) ) {
2992 if(test->machine >= MAXSEQ) {
2996 calc_sequence(evil_scene, test); // XXX - I dont think this is needed since were only moving vertically, Campbell.
3000 if(test->machine >= MAXSEQ) {
3001 /* Blender 2.4x would remove the strip.
3002 * nicer to move it to the end */
3005 int new_frame= test->enddisp;
3007 for(seq= seqbasep->first; seq; seq= seq->next) {
3008 if (seq->machine == orig_machine)
3009 new_frame = MAX2(new_frame, seq->enddisp);
3012 test->machine= orig_machine;
3013 new_frame = new_frame + (test->start-test->startdisp); /* adjust by the startdisp */
3014 seq_translate(evil_scene, test, new_frame - test->start);
3016 calc_sequence(evil_scene, test);
3023 static int shuffle_seq_time_offset_test(ListBase * seqbasep, char dir)
3026 Sequence *seq, *seq_other;
3028 for(seq= seqbasep->first; seq; seq= seq->next) {
3030 for(seq_other= seqbasep->first; seq_other; seq_other= seq_other->next) {
3031 if(!seq_other->tmp && seq_overlap(seq, seq_other)) {
3033 offset= MIN2(offset, seq_other->startdisp - seq->enddisp);
3036 offset= MAX2(offset, seq_other->enddisp - seq->startdisp);
3045 static int shuffle_seq_time_offset(Scene* scene, ListBase * seqbasep, char dir)
3050 while( (ofs= shuffle_seq_time_offset_test(seqbasep, dir)) ) {
3051 for(seq= seqbasep->first; seq; seq= seq->next) {
3053 /* seq_test_overlap only tests display values */
3054 seq->startdisp += ofs;
3055 seq->enddisp += ofs;
3062 for(seq= seqbasep->first; seq; seq= seq->next) {
3064 calc_sequence_disp(scene, seq); /* corrects dummy startdisp/enddisp values */
3070 int shuffle_seq_time(ListBase * seqbasep, Scene *evil_scene)
3072 /* note: seq->tmp is used to tag strips to move */
3076 int offset_l = shuffle_seq_time_offset(evil_scene, seqbasep, 'L');
3077 int offset_r = shuffle_seq_time_offset(evil_scene, seqbasep, 'R');
3078 int offset = (-offset_l < offset_r) ? offset_l:offset_r;
3081 for(seq= seqbasep->first; seq; seq= seq->next) {
3083 seq_translate(evil_scene, seq, offset);
3084 seq->flag &= ~SEQ_OVERLAP;
3092 void seq_update_sound(Scene* scene, Sequence *seq)
3094 if(seq->scene_sound)
3096 sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
3097 /* mute is set in seq_update_muting_recursive */
3101 static void seq_update_muting_recursive(Scene *scene, ListBase *seqbasep, Sequence *metaseq, int mute)
3106 /* for sound we go over full meta tree to update muted state,
3107 since sound is played outside of evaluating the imbufs, */
3108 for(seq=seqbasep->first; seq; seq=seq->next) {
3109 seqmute= (mute || (seq->flag & SEQ_MUTE));
3111 if(seq->type == SEQ_META) {
3112 /* if this is the current meta sequence, unmute because
3113 all sequences above this were set to mute */
3117 seq_update_muting_recursive(scene, &seq->seqbase, metaseq, seqmute);
3119 else if((seq->type == SEQ_SOUND) || (seq->type == SEQ_SCENE)) {
3120 if(seq->scene_sound) {
3121 sound_mute_scene_sound(scene, seq->scene_sound, seqmute);
3127 void seq_update_muting(Scene *scene, Editing *ed)
3130 /* mute all sounds up to current metastack list */
3131 MetaStack *ms= ed->metastack.last;
3134 seq_update_muting_recursive(scene, &ed->seqbase, ms->parseq, 1);
3136 seq_update_muting_recursive(scene, &ed->seqbase, NULL, 0);
3140 /* in cases where we done know the sequence's listbase */
3141 ListBase *seq_seqbase(ListBase *seqbase, Sequence *seq)
3146 for(iseq= seqbase->first; iseq; iseq= iseq->next) {
3150 else if(iseq->seqbase.first && (lb= seq_seqbase(&iseq->seqbase, seq))) {
3158 int seq_swap(Sequence *seq_a, Sequence *seq_b)
3160 char name[sizeof(seq_a->name)];
3162 if(seq_a->len != seq_b->len)
3165 /* type checking, could be more advanced but disalow sound vs non-sound copy */
3166 if(seq_a->type != seq_b->type) {
3167 if(seq_a->type == SEQ_SOUND || seq_b->type == SEQ_SOUND) {
3171 /* disallow effects to swap with non-effects strips */
3172 if((seq_a->type & SEQ_EFFECT) != (seq_b->type & SEQ_EFFECT)) {
3176 if((seq_a->type & SEQ_EFFECT) && (seq_b->type & SEQ_EFFECT)) {
3177 if(get_sequence_effect_num_inputs(seq_a->type) != get_sequence_effect_num_inputs(seq_b->type)) {
3183 SWAP(Sequence, *seq_a, *seq_b);
3185 /* swap back names so animation fcurves dont get swapped */
3186 strcpy(name, seq_a->name+2);
3187 strcpy(seq_a->name+2, seq_b->name+2);
3188 strcpy(seq_b->name+2, name);
3190 /* swap back opacity, and overlay mode */
3191 SWAP(int, seq_a->blend_mode, seq_b->blend_mode);
3192 SWAP(float, seq_a->blend_opacity, seq_b->blend_opacity);
3195 SWAP(void *, seq_a->prev, seq_b->prev);
3196 SWAP(void *, seq_a->next, seq_b->next);
3197 SWAP(int, seq_a->start, seq_b->start);
3198 SWAP(int, seq_a->startofs, seq_b->startofs);
3199 SWAP(int, seq_a->endofs, seq_b->endofs);
3200 SWAP(int, seq_a->startstill, seq_b->startstill);
3201 SWAP(int, seq_a->endstill, seq_b->endstill);
3202 SWAP(int, seq_a->machine, seq_b->machine);
3203 SWAP(int, seq_a->startdisp, seq_b->startdisp);
3204 SWAP(int, seq_a->enddisp, seq_b->enddisp);
3209 /* XXX - hackish function needed for transforming strips! TODO - have some better solution */
3210 void seq_offset_animdata(Scene *scene, Sequence *seq, int ofs)
3215 if(scene->adt==NULL || ofs==0 || scene->adt->action==NULL)
3218 sprintf(str, "[\"%s\"]", seq->name+2);
3220 for (fcu= scene->adt->action->curves.first; fcu; fcu= fcu->next) {
3221 if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str)) {
3223 for (i = 0; i < fcu->totvert; i++) {
3224 BezTriple *bezt= &fcu->bezt[i];
3225 bezt->vec[0][0] += ofs;
3226 bezt->vec[1][0] += ofs;
3227 bezt->vec[2][0] += ofs;
3233 void seq_dupe_animdata(Scene *scene, char *name_from, char *name_to)
3239 ListBase lb= {NULL, NULL};
3241 if(scene->adt==NULL || scene->adt->action==NULL)
3244 sprintf(str_from, "[\"%s\"]", name_from);
3246 fcu_last= scene->adt->action->curves.last;
3248 for (fcu= scene->adt->action->curves.first; fcu && fcu->prev != fcu_last; fcu= fcu->next) {
3249 if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str_from)) {
3250 fcu_cpy= copy_fcurve(fcu);
3251 BLI_addtail(&lb, fcu_cpy);
3255 /* notice validate is 0, keep this because the seq may not be added to the scene yet */
3256 BKE_animdata_fix_paths_rename(&scene->id, scene->adt, "sequence_editor.sequences_all", name_from, name_to, 0, 0, 0);
3258 /* add the original fcurves back */
3259 addlisttolist(&scene->adt->action->curves, &lb);
3262 /* XXX - hackish function needed to remove all fcurves belonging to a sequencer strip */
3263 static void seq_free_animdata(Scene *scene, Sequence *seq)