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 *****
30 /** \file blender/blenkernel/intern/sequencer.c
40 #include "MEM_guardedalloc.h"
41 #include "MEM_CacheLimiterC-Api.h"
43 #include "DNA_sequence_types.h"
44 #include "DNA_scene_types.h"
45 #include "DNA_anim_types.h"
46 #include "DNA_object_types.h"
47 #include "DNA_sound_types.h"
50 #include "BLI_fileops.h"
51 #include "BLI_listbase.h"
52 #include "BLI_path_util.h"
53 #include "BLI_string.h"
54 #include "BLI_threads.h"
55 #include "BLI_utildefines.h"
57 #include "BKE_animsys.h"
58 #include "BKE_global.h"
59 #include "BKE_image.h"
61 #include "BKE_sequencer.h"
62 #include "BKE_fcurve.h"
63 #include "BKE_scene.h"
64 #include "RNA_access.h"
65 #include "BKE_utildefines.h"
67 #include "RE_pipeline.h"
71 #include "IMB_imbuf.h"
72 #include "IMB_imbuf_types.h"
74 #include "BKE_context.h"
75 #include "BKE_sound.h"
78 # include "AUD_C-API.h"
81 static ImBuf* seq_render_strip_stack(
82 SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown);
84 static ImBuf * seq_render_strip(
85 SeqRenderData context, Sequence * seq, float cfra);
87 static void seq_free_animdata(Scene *scene, Sequence *seq);
90 /* **** XXX ******** */
92 ListBase seqbase_clipboard;
93 int seqbase_clipboard_frame;
94 SequencerDrawView sequencer_view3d_cb= NULL; /* NULL in background mode */
97 void printf_strip(Sequence *seq)
99 fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n",
100 seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp);
101 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));
104 int seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg)
107 for(iseq= seqbase->first; iseq; iseq= iseq->next) {
108 if(seq_recursive_apply(iseq, apply_func, arg) == -1)
109 return -1; /* bail out */
114 int seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg)
116 int ret= apply_func(seq, arg);
119 return -1; /* bail out */
121 if(ret && seq->seqbase.first)
122 ret = seqbase_recursive_apply(&seq->seqbase, apply_func, arg);
127 /* **********************************************************************
128 alloc / free functions
129 ********************************************************************** */
133 void new_tstripdata(Sequence *seq)
136 seq->strip->len= seq->len;
143 static void free_proxy_seq(Sequence *seq)
145 if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
146 IMB_free_anim(seq->strip->proxy->anim);
147 seq->strip->proxy->anim = NULL;
151 void seq_free_strip(Strip *strip)
154 if(strip->us>0) return;
156 printf("error: negative users in strip\n");
160 if (strip->stripdata) {
161 MEM_freeN(strip->stripdata);
165 if (strip->proxy->anim) {
166 IMB_free_anim(strip->proxy->anim);
169 MEM_freeN(strip->proxy);
172 MEM_freeN(strip->crop);
174 if (strip->transform) {
175 MEM_freeN(strip->transform);
177 if (strip->color_balance) {
178 MEM_freeN(strip->color_balance);
184 void seq_free_sequence(Scene *scene, Sequence *seq)
186 if(seq->strip) seq_free_strip(seq->strip);
188 if(seq->anim) IMB_free_anim(seq->anim);
190 if (seq->type & SEQ_EFFECT) {
191 struct SeqEffectHandle sh = get_sequence_effect(seq);
197 ((ID *)seq->sound)->us--;
200 /* clipboard has no scene and will never have a sound handle or be active */
202 Editing *ed = scene->ed;
204 if (ed->act_seq==seq)
207 if(seq->scene_sound && ELEM(seq->type, SEQ_SOUND, SEQ_SCENE))
208 sound_remove_scene_sound(scene, seq->scene_sound);
210 seq_free_animdata(scene, seq);
216 void seq_free_sequence_recurse(Scene *scene, Sequence *seq)
220 for(iseq= seq->seqbase.first; iseq; iseq= iseq->next) {
221 seq_free_sequence_recurse(scene, iseq);
224 seq_free_sequence(scene, seq);
228 Editing *seq_give_editing(Scene *scene, int alloc)
230 if (scene->ed == NULL && alloc) {
233 ed= scene->ed= MEM_callocN( sizeof(Editing), "addseq");
234 ed->seqbasep= &ed->seqbase;
239 static void seq_free_clipboard_recursive(Sequence *seq_parent)
241 Sequence *seq, *nseq;
243 for(seq= seq_parent->seqbase.first; seq; seq= nseq) {
245 seq_free_clipboard_recursive(seq);
248 seq_free_sequence(NULL, seq_parent);
251 void seq_free_clipboard(void)
253 Sequence *seq, *nseq;
255 for(seq= seqbase_clipboard.first; seq; seq= nseq) {
257 seq_free_clipboard_recursive(seq);
259 seqbase_clipboard.first= seqbase_clipboard.last= NULL;
262 void seq_free_editing(Scene *scene)
264 Editing *ed = scene->ed;
272 seq_free_sequence(scene, seq);
276 while((ms= ed->metastack.first)) {
277 BLI_remlink(&ed->metastack, ms);
284 /* **********************************************************************
285 * sequencer pipeline functions
286 ********************************************************************** */
288 SeqRenderData seq_new_render_data(
289 struct Main * bmain, struct Scene * scene,
290 int rectx, int recty, int preview_render_size)
298 rval.preview_render_size = preview_render_size;
299 rval.motion_blur_samples = 0;
300 rval.motion_blur_shutter = 0;
305 int seq_cmp_render_data(const SeqRenderData * a, const SeqRenderData * b)
307 if (a->preview_render_size < b->preview_render_size) {
310 if (a->preview_render_size > b->preview_render_size) {
314 if (a->rectx < b->rectx) {
317 if (a->rectx > b->rectx) {
321 if (a->recty < b->recty) {
324 if (a->recty > b->recty) {
328 if (a->bmain < b->bmain) {
331 if (a->bmain > b->bmain) {
335 if (a->scene < b->scene) {
338 if (a->scene > b->scene) {
342 if (a->motion_blur_shutter < b->motion_blur_shutter) {
345 if (a->motion_blur_shutter > b->motion_blur_shutter) {
349 if (a->motion_blur_samples < b->motion_blur_samples) {
352 if (a->motion_blur_samples > b->motion_blur_samples) {
359 unsigned int seq_hash_render_data(const SeqRenderData * a)
361 unsigned int rval = a->rectx + a->recty;
363 rval ^= a->preview_render_size;
364 rval ^= ((intptr_t) a->bmain) << 6;
365 rval ^= ((intptr_t) a->scene) << 6;
366 rval ^= (int) (a->motion_blur_shutter * 100.0f) << 10;
367 rval ^= a->motion_blur_samples << 24;
372 /* ************************* iterator ************************** */
373 /* *************** (replaces old WHILE_SEQ) ********************* */
374 /* **************** use now SEQ_BEGIN() SEQ_END ***************** */
376 /* sequence strip iterator:
377 * - builds a full array, recursively into meta strips */
379 static void seq_count(ListBase *seqbase, int *tot)
383 for(seq=seqbase->first; seq; seq=seq->next) {
386 if(seq->seqbase.first)
387 seq_count(&seq->seqbase, tot);
391 static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
395 for(seq=seqbase->first; seq; seq=seq->next) {
398 if(seq->seqbase.first)
399 seq_build_array(&seq->seqbase, array, depth+1);
406 void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_pointer)
417 seq_count(ed->seqbasep, tot);
419 seq_count(&ed->seqbase, tot);
424 *seqarray= array= MEM_mallocN(sizeof(Sequence *)*(*tot), "SeqArray");
426 seq_build_array(ed->seqbasep, &array, 0);
428 seq_build_array(&ed->seqbase, &array, 0);
431 void seq_begin(Editing *ed, SeqIterator *iter, int use_pointer)
433 memset(iter, 0, sizeof(*iter));
434 seq_array(ed, &iter->array, &iter->tot, use_pointer);
438 iter->seq= iter->array[iter->cur];
443 void seq_next(SeqIterator *iter)
445 if(++iter->cur < iter->tot)
446 iter->seq= iter->array[iter->cur];
451 void seq_end(SeqIterator *iter)
454 MEM_freeN(iter->array);
460 **********************************************************************
462 **********************************************************************
463 * Build a complete array of _all_ sequencies (including those
465 **********************************************************************
468 static void do_seq_count_cb(ListBase *seqbase, int *totseq,
469 int (*test_func)(Sequence * seq))
475 int test = test_func(seq);
476 if (test & BUILD_SEQAR_COUNT_CURRENT) {
479 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
480 do_seq_count_cb(&seq->seqbase, totseq, test_func);
486 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
487 int (*test_func)(Sequence * seq))
493 int test = test_func(seq);
496 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
497 do_build_seqar_cb(&seq->seqbase, seqar, depth+1, test_func);
499 if (test & BUILD_SEQAR_COUNT_CURRENT) {
507 void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq,
508 int (*test_func)(Sequence * seq))
513 do_seq_count_cb(seqbase, totseq, test_func);
519 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
522 do_build_seqar_cb(seqbase, seqar, 0, test_func);
527 void calc_sequence_disp(Scene *scene, Sequence *seq)
529 if(seq->startofs && seq->startstill) seq->startstill= 0;
530 if(seq->endofs && seq->endstill) seq->endstill= 0;
532 seq->startdisp= seq->start + seq->startofs - seq->startstill;
533 seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
535 seq->handsize= 10.0; /* 10 frames */
536 if( seq->enddisp-seq->startdisp < 10 ) {
537 seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
539 else if(seq->enddisp-seq->startdisp > 250) {
540 seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
543 seq_update_sound_bounds(scene, seq);
546 static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
550 /* for sound we go over full meta tree to update bounds of the sound strips,
551 since sound is played outside of evaluating the imbufs, */
552 for(seq=metaseq->seqbase.first; seq; seq=seq->next) {
553 if(seq->type == SEQ_META) {
554 seq_update_sound_bounds_recursive(scene, seq);
556 else if(ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) {
557 if(seq->scene_sound) {
558 int startofs = seq->startofs;
559 int endofs = seq->endofs;
560 if(seq->startofs + seq->start < metaseq->start + metaseq->startofs)
561 startofs = metaseq->start + metaseq->startofs - seq->start;
563 if(seq->start + seq->len - seq->endofs > metaseq->start + metaseq->len - metaseq->endofs)
564 endofs = seq->start + seq->len - metaseq->start - metaseq->len + metaseq->endofs;
565 sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs, seq->start+seq->len - endofs, startofs);
571 void calc_sequence(Scene *scene, Sequence *seq)
576 /* check all metas recursively */
577 seqm= seq->seqbase.first;
579 if(seqm->seqbase.first) calc_sequence(scene, seqm);
583 /* effects and meta: automatic start and end */
585 if(seq->type & SEQ_EFFECT) {
587 if(seq->seq2==NULL) seq->seq2= seq->seq1;
588 if(seq->seq3==NULL) seq->seq3= seq->seq1;
590 /* effecten go from seq1 -> seq2: test */
592 /* we take the largest start and smallest end */
594 // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
595 // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
598 seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
599 seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
600 /* we cant help if strips don't overlap, it wont give useful results.
601 * but at least ensure 'len' is never negative which causes bad bugs elsewhere. */
602 if(seq->enddisp < seq->startdisp) {
603 /* simple start/end swap */
604 seq->start= seq->enddisp;
605 seq->enddisp = seq->startdisp;
606 seq->startdisp= seq->start;
607 seq->flag |= SEQ_INVALID_EFFECT;
610 seq->flag &= ~SEQ_INVALID_EFFECT;
613 seq->len= seq->enddisp - seq->startdisp;
616 calc_sequence_disp(scene, seq);
619 if(seq->strip && seq->len!=seq->strip->len) {
625 if(seq->type==SEQ_META) {
626 seqm= seq->seqbase.first;
631 if(seqm->startdisp < min) min= seqm->startdisp;
632 if(seqm->enddisp > max) max= seqm->enddisp;
635 seq->start= min + seq->anim_startofs;
637 seq->len -= seq->anim_startofs;
638 seq->len -= seq->anim_endofs;
640 if(seq->strip && seq->len!=seq->strip->len) {
644 seq_update_sound_bounds_recursive(scene, seq);
646 calc_sequence_disp(scene, seq);
650 /* note: caller should run calc_sequence(scene, seq) after */
651 void reload_sequence_new_file(Scene *scene, Sequence * seq, int lock_range)
653 char str[FILE_MAXDIR+FILE_MAXFILE];
654 int prev_startdisp=0, prev_enddisp=0;
655 /* note: dont rename the strip, will break animation curves */
657 if (ELEM5(seq->type, SEQ_MOVIE, SEQ_IMAGE, SEQ_SOUND, SEQ_SCENE, SEQ_META)==0) {
662 /* keep so we dont have to move the actual start and end points (only the data) */
663 calc_sequence_disp(scene, seq);
664 prev_startdisp= seq->startdisp;
665 prev_enddisp= seq->enddisp;
671 if (ELEM3(seq->type, SEQ_SCENE, SEQ_META, SEQ_IMAGE)==0) {
672 BLI_join_dirfile(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name);
673 BLI_path_abs(str, G.main->name);
680 size_t olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem);
683 seq->len -= seq->anim_startofs;
684 seq->len -= seq->anim_endofs;
688 seq->strip->len = seq->len;
692 if(seq->anim) IMB_free_anim(seq->anim);
693 seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex);
699 seq->len = IMB_anim_get_duration(seq->anim,
701 seq->strip->proxy->tc :
704 seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
706 seq->len -= seq->anim_startofs;
707 seq->len -= seq->anim_endofs;
711 seq->strip->len = seq->len;
714 #ifdef WITH_AUDASPACE
717 seq->len = ceil(AUD_getInfo(seq->sound->playback_handle).length * FPS);
718 seq->len -= seq->anim_startofs;
719 seq->len -= seq->anim_endofs;
723 seq->strip->len = seq->len;
730 /* 'seq->scenenr' should be replaced with something more reliable */
731 Scene * sce = G.main->scene.first;
735 if(nr == seq->scenenr) {
746 seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
747 seq->len -= seq->anim_startofs;
748 seq->len -= seq->anim_endofs;
752 seq->strip->len = seq->len;
760 seq_tx_set_final_left(seq, prev_startdisp);
761 seq_tx_set_final_right(seq, prev_enddisp);
765 calc_sequence(scene, seq);
768 void sort_seq(Scene *scene)
770 /* all strips together per kind, and in order of y location ("machine") */
771 ListBase seqbase, effbase;
772 Editing *ed= seq_give_editing(scene, FALSE);
773 Sequence *seq, *seqt;
778 seqbase.first= seqbase.last= NULL;
779 effbase.first= effbase.last= NULL;
781 while( (seq= ed->seqbasep->first) ) {
782 BLI_remlink(ed->seqbasep, seq);
784 if(seq->type & SEQ_EFFECT) {
787 if(seqt->machine>=seq->machine) {
788 BLI_insertlinkbefore(&effbase, seqt, seq);
793 if(seqt==NULL) BLI_addtail(&effbase, seq);
798 if(seqt->machine>=seq->machine) {
799 BLI_insertlinkbefore(&seqbase, seqt, seq);
804 if(seqt==NULL) BLI_addtail(&seqbase, seq);
808 BLI_movelisttolist(&seqbase, &effbase);
809 *(ed->seqbasep)= seqbase;
813 static int clear_scene_in_allseqs_cb(Sequence *seq, void *arg_pt)
815 if(seq->scene==(Scene *)arg_pt)
820 void clear_scene_in_allseqs(Main *bmain, Scene *scene)
824 /* when a scene is deleted: test all seqs */
825 for(scene_iter= bmain->scene.first; scene_iter; scene_iter= scene_iter->id.next) {
826 if(scene_iter != scene && scene_iter->ed) {
827 seqbase_recursive_apply(&scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene);
832 typedef struct SeqUniqueInfo {
841 static void seqbase_unique_name(ListBase *seqbasep, Sequence *seq)
843 BLI_uniquename(seqbasep, seq, "Sequence", '.', offsetof(Sequence, name), SEQ_NAME_MAXSTR);
846 static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
849 for(seq=seqbasep->first; seq; seq= seq->next) {
850 if (sui->seq != seq && strcmp(sui->name_dest, seq->name+2)==0) {
851 sprintf(sui->name_dest, "%.17s.%03d", sui->name_src, sui->count++); /*24 - 2 for prefix, -1 for \0 */
852 sui->match= 1; /* be sure to re-scan */
857 static int seqbase_unique_name_recursive_cb(Sequence *seq, void *arg_pt)
859 if(seq->seqbase.first)
860 seqbase_unique_name(&seq->seqbase, (SeqUniqueInfo *)arg_pt);
864 void seqbase_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq)
869 strcpy(sui.name_src, seq->name+2);
870 strcpy(sui.name_dest, seq->name+2);
873 sui.match= 1; /* assume the worst to start the loop */
875 /* Strip off the suffix */
876 if ((dot=strrchr(sui.name_src, '.'))) {
881 sui.count= atoi(dot) + 1;
886 seqbase_unique_name(seqbasep, &sui);
887 seqbase_recursive_apply(seqbasep, seqbase_unique_name_recursive_cb, &sui);
890 strcpy(seq->name+2, sui.name_dest);
893 static const char *give_seqname_by_type(int type)
896 case SEQ_META: return "Meta";
897 case SEQ_IMAGE: return "Image";
898 case SEQ_SCENE: return "Scene";
899 case SEQ_MOVIE: return "Movie";
900 case SEQ_SOUND: return "Audio";
901 case SEQ_CROSS: return "Cross";
902 case SEQ_GAMCROSS: return "Gamma Cross";
903 case SEQ_ADD: return "Add";
904 case SEQ_SUB: return "Sub";
905 case SEQ_MUL: return "Mul";
906 case SEQ_ALPHAOVER: return "Alpha Over";
907 case SEQ_ALPHAUNDER: return "Alpha Under";
908 case SEQ_OVERDROP: return "Over Drop";
909 case SEQ_WIPE: return "Wipe";
910 case SEQ_GLOW: return "Glow";
911 case SEQ_TRANSFORM: return "Transform";
912 case SEQ_COLOR: return "Color";
913 case SEQ_MULTICAM: return "Multicam";
914 case SEQ_ADJUSTMENT: return "Adjustment";
915 case SEQ_SPEED: return "Speed";
921 const char *give_seqname(Sequence *seq)
923 const char *name = give_seqname_by_type(seq->type);
926 if(seq->type<SEQ_EFFECT) {
927 return seq->strip->dir;
928 } else if(seq->type==SEQ_PLUGIN) {
929 if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
930 seq->plugin && seq->plugin->doit) {
931 return seq->plugin->pname;
942 /* ***************** DO THE SEQUENCE ***************** */
944 static void make_black_ibuf(ImBuf *ibuf)
950 if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) return;
952 tot= ibuf->x*ibuf->y;
955 rect_float = ibuf->rect_float;
958 memset(rect, 0, tot * sizeof(char) * 4);
962 memset(rect_float, 0, tot * sizeof(float) * 4);
966 static void multibuf(ImBuf *ibuf, float fmul)
973 mul= (int)(256.0f * fmul);
974 rt= (char *)ibuf->rect;
975 rt_float = ibuf->rect_float;
981 icol= (mul*rt[0])>>8;
982 if(icol>254) rt[0]= 255; else rt[0]= icol;
983 icol= (mul*rt[1])>>8;
984 if(icol>254) rt[1]= 255; else rt[1]= icol;
985 icol= (mul*rt[2])>>8;
986 if(icol>254) rt[2]= 255; else rt[2]= icol;
987 icol= (mul*rt[3])>>8;
988 if(icol>254) rt[3]= 255; else rt[3]= icol;
1006 static float give_stripelem_index(Sequence *seq, float cfra)
1009 int sta = seq->start;
1010 int end = seq->start+seq->len-1;
1012 if (seq->type & SEQ_EFFECT) {
1020 if(seq->flag&SEQ_REVERSE_FRAMES) {
1021 /*reverse frame in this sequence */
1022 if(cfra <= sta) nr= end - sta;
1023 else if(cfra >= end) nr= 0;
1024 else nr= end - cfra;
1026 if(cfra <= sta) nr= 0;
1027 else if(cfra >= end) nr= end - sta;
1028 else nr= cfra - sta;
1031 if (seq->strobe < 1.0f) seq->strobe = 1.0f;
1033 if (seq->strobe > 1.0f) {
1034 nr -= fmodf((double)nr, (double)seq->strobe);
1040 StripElem *give_stripelem(Sequence *seq, int cfra)
1042 StripElem *se= seq->strip->stripdata;
1044 if(seq->type == SEQ_IMAGE) { /* only
1045 IMAGE strips use the whole array,
1046 MOVIE strips use only
1047 the first element, all other strips
1048 don't use this... */
1049 int nr = (int) give_stripelem_index(seq, cfra);
1051 if (nr == -1 || se == NULL) return NULL;
1053 se += nr + seq->anim_startofs;
1058 static int evaluate_seq_frame_gen(Sequence ** seq_arr, ListBase *seqbase, int cfra)
1063 memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1));
1065 seq= seqbase->first;
1067 if(seq->startdisp <=cfra && seq->enddisp > cfra) {
1068 seq_arr[seq->machine]= seq;
1077 int evaluate_seq_frame(Scene *scene, int cfra)
1079 Editing *ed= seq_give_editing(scene, FALSE);
1080 Sequence *seq_arr[MAXSEQ+1];
1082 if(ed==NULL) return 0;
1083 return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
1086 static int video_seq_is_rendered(Sequence * seq)
1088 return (seq && !(seq->flag & SEQ_MUTE) && seq->type != SEQ_SOUND);
1091 static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
1093 Sequence *seq_arr[MAXSEQ+1];
1101 if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
1105 for (; b > 0; b--) {
1106 if (video_seq_is_rendered(seq_arr[b])) {
1115 if (video_seq_is_rendered(seq_arr[b])) {
1116 if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
1122 for (;b <= chanshown && b >= 0; b++) {
1123 if (video_seq_is_rendered(seq_arr[b])) {
1124 seq_arr_out[cnt++] = seq_arr[b];
1132 /* **********************************************************************
1134 ********************************************************************** */
1136 #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
1138 static IMB_Proxy_Size seq_rendersize_to_proxysize(int size)
1141 return IMB_PROXY_NONE;
1144 return IMB_PROXY_100;
1147 return IMB_PROXY_75;
1150 return IMB_PROXY_50;
1152 return IMB_PROXY_25;
1155 static void seq_open_anim_file(Sequence * seq)
1157 char name[FILE_MAXDIR+FILE_MAXFILE];
1160 if(seq->anim != NULL) {
1164 BLI_join_dirfile(name, sizeof(name),
1165 seq->strip->dir, seq->strip->stripdata->name);
1166 BLI_path_abs(name, G.main->name);
1168 seq->anim = openanim(name, IB_rect |
1169 ((seq->flag & SEQ_FILTERY) ?
1170 IB_animdeinterlace : 0), seq->streamindex);
1172 if (seq->anim == NULL) {
1176 proxy = seq->strip->proxy;
1178 if (proxy == NULL) {
1182 if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
1183 IMB_anim_set_index_dir(seq->anim, seq->strip->proxy->dir);
1188 static int seq_proxy_get_fname(SeqRenderData context, Sequence * seq, int cfra, char * name)
1191 char dir[PROXY_MAXFILE];
1192 int render_size = context.preview_render_size;
1194 if (!seq->strip->proxy) {
1198 /* MOVIE tracks (only exception: custom files) are now handled
1199 internally by ImBuf module for various reasons: proper time code
1200 support, quicker index build, using one file instead
1201 of a full directory of jpeg files, etc. Trying to support old
1202 and new method at once could lead to funny effects, if people
1203 have both, a directory full of jpeg files and proxy avis, so
1204 sorry folks, please rebuild your proxies... */
1206 if (seq->flag & (SEQ_USE_PROXY_CUSTOM_DIR|SEQ_USE_PROXY_CUSTOM_FILE)) {
1207 strcpy(dir, seq->strip->proxy->dir);
1208 } else if (seq->type == SEQ_IMAGE) {
1209 BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir);
1214 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1215 BLI_join_dirfile(name, PROXY_MAXFILE,
1216 dir, seq->strip->proxy->file);
1217 BLI_path_abs(name, G.main->name);
1222 /* dirty hack to distinguish 100% render size from PROXY_100 */
1223 if (render_size == 99) {
1227 /* generate a separate proxy directory for each preview size */
1229 if (seq->type == SEQ_IMAGE) {
1230 BLI_snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy", dir,
1231 context.preview_render_size,
1232 give_stripelem(seq, cfra)->name);
1235 frameno = (int) give_stripelem_index(seq, cfra)
1236 + seq->anim_startofs;
1237 BLI_snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
1238 context.preview_render_size);
1241 BLI_path_abs(name, G.main->name);
1242 BLI_path_frame(name, frameno, 0);
1244 strcat(name, ".jpg");
1249 static struct ImBuf * seq_proxy_fetch(SeqRenderData context, Sequence * seq, int cfra)
1251 char name[PROXY_MAXFILE];
1252 IMB_Proxy_Size psize = seq_rendersize_to_proxysize(
1253 context.preview_render_size);
1256 if (!(seq->flag & SEQ_USE_PROXY)) {
1260 size_flags = seq->strip->proxy->build_size_flags;
1262 /* only use proxies, if they are enabled (even if present!) */
1263 if (psize == IMB_PROXY_NONE || ((size_flags & psize) != psize)) {
1267 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1268 int frameno = (int) give_stripelem_index(seq, cfra) + seq->anim_startofs;
1269 if (seq->strip->proxy->anim == NULL) {
1270 if (seq_proxy_get_fname(context, seq, cfra, name)==0) {
1274 seq->strip->proxy->anim = openanim(name, IB_rect, 0);
1276 if (seq->strip->proxy->anim==NULL) {
1280 seq_open_anim_file(seq);
1282 frameno = IMB_anim_index_get_frame_index(
1283 seq->anim, seq->strip->proxy->tc, frameno);
1285 return IMB_anim_absolute(seq->strip->proxy->anim, frameno,
1286 IMB_TC_NONE, IMB_PROXY_NONE);
1289 if (seq_proxy_get_fname(context, seq, cfra, name) == 0) {
1293 if (BLI_exists(name)) {
1294 return IMB_loadiffname(name, IB_rect);
1300 static void seq_proxy_build_frame(SeqRenderData context,
1301 Sequence* seq, int cfra,
1302 int proxy_render_size)
1304 char name[PROXY_MAXFILE];
1308 struct ImBuf * ibuf;
1310 if (!seq_proxy_get_fname(context, seq, cfra, name)) {
1314 ibuf = seq_render_strip(context, seq, cfra);
1316 rectx = (proxy_render_size * context.scene->r.xsch) / 100;
1317 recty = (proxy_render_size * context.scene->r.ysch) / 100;
1319 if (ibuf->x != rectx || ibuf->y != recty) {
1320 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1323 /* depth = 32 is intentionally left in, otherwise ALPHA channels
1325 quality = seq->strip->proxy->quality;
1326 ibuf->ftype= JPG | quality;
1328 /* unsupported feature only confuses other s/w */
1332 BLI_make_existing_file(name);
1334 ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
1339 IMB_freeImBuf(ibuf);
1342 void seq_proxy_rebuild(struct Main * bmain, Scene *scene, Sequence * seq,
1343 short *stop, short *do_update, float *progress)
1345 SeqRenderData context;
1351 if (!seq->strip || !seq->strip->proxy) {
1355 if (!(seq->flag & SEQ_USE_PROXY)) {
1359 tc_flags = seq->strip->proxy->build_tc_flags;
1360 size_flags = seq->strip->proxy->build_size_flags;
1361 quality = seq->strip->proxy->quality;
1363 if (seq->type == SEQ_MOVIE) {
1364 seq_open_anim_file(seq);
1367 IMB_anim_index_rebuild(
1368 seq->anim, tc_flags, size_flags, quality,
1369 stop, do_update, progress);
1374 if (!(seq->flag & SEQ_USE_PROXY)) {
1378 /* that's why it is called custom... */
1379 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1383 /* fail safe code */
1385 context = seq_new_render_data(
1387 (scene->r.size * (float) scene->r.xsch) / 100.0f + 0.5f,
1388 (scene->r.size * (float) scene->r.ysch) / 100.0f + 0.5f,
1391 for (cfra = seq->startdisp + seq->startstill;
1392 cfra < seq->enddisp - seq->endstill; cfra++) {
1393 if (size_flags & IMB_PROXY_25) {
1394 seq_proxy_build_frame(context, seq, cfra, 25);
1396 if (size_flags & IMB_PROXY_50) {
1397 seq_proxy_build_frame(context, seq, cfra, 50);
1399 if (size_flags & IMB_PROXY_75) {
1400 seq_proxy_build_frame(context, seq, cfra, 75);
1402 if (size_flags & IMB_PROXY_100) {
1403 seq_proxy_build_frame(context, seq, cfra, 100);
1406 *progress= (float)cfra/(seq->enddisp - seq->endstill
1407 - seq->startdisp + seq->startstill);
1410 if(*stop || G.afbreek)
1416 /* **********************************************************************
1418 ********************************************************************** */
1420 static StripColorBalance calc_cb(StripColorBalance * cb_)
1422 StripColorBalance cb = *cb_;
1425 for (c = 0; c < 3; c++) {
1426 cb.lift[c] = 2.0f - cb.lift[c];
1429 if(cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
1430 for (c = 0; c < 3; c++) {
1431 /* tweak to give more subtle results
1432 * values above 1.0 are scaled */
1433 if(cb.lift[c] > 1.0f)
1434 cb.lift[c] = pow(cb.lift[c] - 1.0f, 2.0) + 1.0;
1436 cb.lift[c] = 2.0f - cb.lift[c];
1440 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
1441 for (c = 0; c < 3; c++) {
1442 if (cb.gain[c] != 0.0f) {
1443 cb.gain[c] = 1.0f / cb.gain[c];
1445 cb.gain[c] = 1000000; /* should be enough :) */
1450 if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
1451 for (c = 0; c < 3; c++) {
1452 if (cb.gamma[c] != 0.0f) {
1453 cb.gamma[c] = 1.0f/cb.gamma[c];
1455 cb.gamma[c] = 1000000; /* should be enough :) */
1463 /* note: lift is actually 2-lift */
1464 MINLINE float color_balance_fl(float in, const float lift, const float gain, const float gamma, const float mul)
1466 float x= (((in - 1.0f) * lift) + 1.0f) * gain;
1469 if (x < 0.f) x = 0.f;
1471 return powf(x, gamma) * mul;
1474 static void make_cb_table_byte(float lift, float gain, float gamma,
1475 unsigned char * table, float mul)
1479 for (y = 0; y < 256; y++) {
1480 float v= color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
1481 CLAMP(v, 0.0f, 1.0f);
1486 static void make_cb_table_float(float lift, float gain, float gamma,
1487 float * table, float mul)
1491 for (y = 0; y < 256; y++) {
1492 float v= color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
1497 static void color_balance_byte_byte(Sequence * seq, ImBuf* ibuf, float mul)
1499 unsigned char cb_tab[3][256];
1501 unsigned char * p = (unsigned char*) ibuf->rect;
1502 unsigned char * e = p + ibuf->x * 4 * ibuf->y;
1504 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1506 for (c = 0; c < 3; c++) {
1507 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1512 p[0] = cb_tab[0][p[0]];
1513 p[1] = cb_tab[1][p[1]];
1514 p[2] = cb_tab[2][p[2]];
1520 static void color_balance_byte_float(Sequence * seq, ImBuf* ibuf, float mul)
1522 float cb_tab[4][256];
1524 unsigned char * p = (unsigned char*) ibuf->rect;
1525 unsigned char * e = p + ibuf->x * 4 * ibuf->y;
1527 StripColorBalance cb;
1529 imb_addrectfloatImBuf(ibuf);
1531 o = ibuf->rect_float;
1533 cb = calc_cb(seq->strip->color_balance);
1535 for (c = 0; c < 3; c++) {
1536 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
1539 for (i = 0; i < 256; i++) {
1540 cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
1544 o[0] = cb_tab[0][p[0]];
1545 o[1] = cb_tab[1][p[1]];
1546 o[2] = cb_tab[2][p[2]];
1547 o[3] = cb_tab[3][p[3]];
1553 static void color_balance_float_float(Sequence * seq, ImBuf* ibuf, float mul)
1555 float * p = ibuf->rect_float;
1556 float * e = ibuf->rect_float + ibuf->x * 4* ibuf->y;
1557 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1561 for (c = 0; c < 3; c++) {
1562 p[c]= color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
1568 static void color_balance(Sequence * seq, ImBuf* ibuf, float mul)
1570 if (ibuf->rect_float) {
1571 color_balance_float_float(seq, ibuf, mul);
1572 } else if(seq->flag & SEQ_MAKE_FLOAT) {
1573 color_balance_byte_float(seq, ibuf, mul);
1575 color_balance_byte_byte(seq, ibuf, mul);
1580 input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
1582 Do all the things you can't really do afterwards using sequence effects
1583 (read: before rescaling to render resolution has been done)
1588 - Crop and transform in image source coordinate space
1589 - Flip X + Flip Y (could be done afterwards, backward compatibility)
1590 - Promote image to float data (affects pipeline operations afterwards)
1591 - Color balance (is most efficient in the byte -> float
1592 (future: half -> float should also work fine!)
1593 case, if done on load, since we can use lookup tables)
1598 int input_have_to_preprocess(
1599 SeqRenderData UNUSED(context), Sequence * seq, float UNUSED(cfra))
1603 if (seq->flag & (SEQ_FILTERY|SEQ_USE_CROP|SEQ_USE_TRANSFORM|SEQ_FLIPX|
1604 SEQ_FLIPY|SEQ_USE_COLOR_BALANCE|SEQ_MAKE_PREMUL)) {
1610 if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1611 mul *= seq->blend_opacity / 100.0f;
1618 if (seq->sat != 1.0f) {
1625 static ImBuf * input_preprocess(
1626 SeqRenderData context, Sequence *seq, float UNUSED(cfra), ImBuf * ibuf)
1630 ibuf = IMB_makeSingleUser(ibuf);
1632 if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
1636 if(seq->flag & (SEQ_USE_CROP|SEQ_USE_TRANSFORM)) {
1638 StripTransform t= {0};
1641 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1642 c = *seq->strip->crop;
1644 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1645 t = *seq->strip->transform;
1648 sx = ibuf->x - c.left - c.right;
1649 sy = ibuf->y - c.top - c.bottom;
1653 if (seq->flag & SEQ_USE_TRANSFORM) {
1654 dx = context.scene->r.xsch;
1655 dy = context.scene->r.ysch;
1658 if (c.top + c.bottom >= ibuf->y || c.left + c.right >= ibuf->x ||
1659 t.xofs >= dx || t.yofs >= dy) {
1660 make_black_ibuf(ibuf);
1662 ImBuf * i = IMB_allocImBuf(dx, dy,32, ibuf->rect_float ? IB_rectfloat : IB_rect);
1664 IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
1666 IMB_freeImBuf(ibuf);
1672 if(seq->flag & SEQ_FLIPX) {
1676 if(seq->flag & SEQ_FLIPY) {
1680 if(seq->sat != 1.0f) {
1681 /* inline for now, could become an imbuf function */
1683 unsigned char *rct= (unsigned char *)ibuf->rect;
1684 float *rctf= ibuf->rect_float;
1685 const float sat= seq->sat;
1690 for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) {
1691 rgb_byte_to_float(rct, rgb);
1692 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
1693 hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb+1, rgb+2);
1694 rgb_float_to_byte(rgb, rct);
1699 for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) {
1700 rgb_to_hsv(rctf[0], rctf[1], rctf[2], hsv, hsv+1, hsv+2);
1701 hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rctf, rctf+1, rctf+2);
1708 if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1709 mul *= seq->blend_opacity / 100.0f;
1712 if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1713 color_balance(seq, ibuf, mul);
1717 if(seq->flag & SEQ_MAKE_FLOAT) {
1718 if (!ibuf->rect_float)
1719 IMB_float_from_rect_simple(ibuf);
1722 imb_freerectImBuf(ibuf);
1727 multibuf(ibuf, mul);
1730 if(seq->flag & SEQ_MAKE_PREMUL) {
1731 if(ibuf->depth == 32 && ibuf->zbuf == NULL) {
1732 IMB_premultiply_alpha(ibuf);
1737 if(ibuf->x != context.rectx || ibuf->y != context.recty ) {
1738 if(context.scene->r.mode & R_OSA) {
1739 IMB_scaleImBuf(ibuf, (short)context.rectx, (short)context.recty);
1741 IMB_scalefastImBuf(ibuf, (short)context.rectx, (short)context.recty);
1747 static ImBuf * copy_from_ibuf_still(SeqRenderData context, Sequence * seq,
1750 ImBuf * rval = NULL;
1751 ImBuf * ibuf = NULL;
1754 ibuf = seq_stripelem_cache_get(
1755 context, seq, seq->start,
1756 SEQ_STRIPELEM_IBUF_STARTSTILL);
1757 } else if (nr == seq->len - 1) {
1758 ibuf = seq_stripelem_cache_get(
1759 context, seq, seq->start,
1760 SEQ_STRIPELEM_IBUF_ENDSTILL);
1764 rval = IMB_dupImBuf(ibuf);
1765 IMB_freeImBuf(ibuf);
1771 static void copy_to_ibuf_still(SeqRenderData context, Sequence * seq, float nr,
1774 if (nr == 0 || nr == seq->len - 1) {
1775 /* we have to store a copy, since the passed ibuf
1776 could be preprocessed afterwards (thereby silently
1777 changing the cached image... */
1778 ibuf = IMB_dupImBuf(ibuf);
1781 seq_stripelem_cache_put(
1782 context, seq, seq->start,
1783 SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf);
1786 if (nr == seq->len - 1) {
1787 seq_stripelem_cache_put(
1788 context, seq, seq->start,
1789 SEQ_STRIPELEM_IBUF_ENDSTILL, ibuf);
1792 IMB_freeImBuf(ibuf);
1796 /* **********************************************************************
1797 strip rendering functions
1798 ********************************************************************** */
1800 static ImBuf* seq_render_strip_stack(
1801 SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown);
1803 static ImBuf * seq_render_strip(
1804 SeqRenderData context, Sequence * seq, float cfra);
1807 static ImBuf* seq_render_effect_strip_impl(
1808 SeqRenderData context, Sequence *seq, float cfra)
1813 struct SeqEffectHandle sh = get_sequence_effect(seq);
1819 ibuf[0] = ibuf[1] = ibuf[2] = NULL;
1821 input[0] = seq->seq1; input[1] = seq->seq2; input[2] = seq->seq3;
1823 if (!sh.execute) { /* effect not supported in this version... */
1824 out = IMB_allocImBuf((short)context.rectx,
1825 (short)context.recty, 32, IB_rect);
1829 if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
1830 sh.get_default_fac(seq, cfra, &fac, &facf);
1832 if ((context.scene->r.mode & R_FIELDS)==0)
1836 fcu = id_data_find_fcurve(&context.scene->id, seq, &RNA_Sequence, "effect_fader", 0, NULL);
1838 fac = facf = evaluate_fcurve(fcu, cfra);
1839 if( context.scene->r.mode & R_FIELDS ) {
1840 facf = evaluate_fcurve(fcu, cfra + 0.5f);
1843 fac = facf = seq->effect_fader;
1847 early_out = sh.early_out(seq, fac, facf);
1849 switch (early_out) {
1850 case EARLY_NO_INPUT:
1851 out = sh.execute(context, seq, cfra, fac, facf,
1854 case EARLY_DO_EFFECT:
1855 for(i=0; i<3; i++) {
1857 ibuf[i] = seq_render_strip(
1858 context, input[i], cfra);
1861 if (ibuf[0] && ibuf[1]) {
1862 out = sh.execute(context, seq, cfra, fac, facf,
1863 ibuf[0], ibuf[1], ibuf[2]);
1866 case EARLY_USE_INPUT_1:
1868 ibuf[0] = seq_render_strip(context, input[0], cfra);
1871 if (input_have_to_preprocess(context, seq, cfra)) {
1872 out = IMB_dupImBuf(ibuf[0]);
1879 case EARLY_USE_INPUT_2:
1881 ibuf[1] = seq_render_strip(context, input[1], cfra);
1884 if (input_have_to_preprocess(context, seq, cfra)) {
1885 out = IMB_dupImBuf(ibuf[1]);
1894 for (i = 0; i < 3; i++) {
1895 IMB_freeImBuf(ibuf[i]);
1899 out = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect);
1906 static ImBuf * seq_render_scene_strip_impl(
1907 SeqRenderData context, Sequence * seq, float nr)
1909 ImBuf * ibuf = NULL;
1910 float frame= seq->sfra + nr + seq->anim_startofs;
1913 ListBase oldmarkers;
1916 Hack! This function can be called from do_render_seq(), in that case
1917 the seq->scene can already have a Render initialized with same name,
1918 so we have to use a default name. (compositor uses scene name to
1920 However, when called from within the UI (image preview in sequencer)
1921 we do want to use scene Render, that way the render result is defined
1922 for display in render/imagewindow
1924 Hmm, don't see, why we can't do that all the time,
1925 and since G.rendering is uhm, gone... (Peter)
1929 Using the same name for the renders works just fine as the do_render_seq()
1930 render is not used while the scene strips are rendered.
1932 However rendering from UI (through sequencer_preview_area_draw) can crash in
1933 very many cases since other renders (material preview, an actual render etc.)
1934 can be started while this sequence preview render is running. The only proper
1935 solution is to make the sequencer preview render a proper job, which can be
1936 stopped when needed. This would also give a nice progress bar for the preview
1937 space so that users know there's something happening.
1939 As a result the active scene now only uses OpenGL rendering for the sequencer
1940 preview. This is far from nice, but is the only way to prevent crashes at this
1946 int rendering = G.rendering;
1948 int doseq_gl= G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : /*(scene->r.seq_flag & R_SEQ_GL_PREV)*/ 1;
1949 int have_seq= FALSE;
1952 /* dont refer to seq->scene above this point!, it can be NULL */
1953 if(seq->scene == NULL) {
1959 have_seq= (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first;
1961 oldcfra= scene->r.cfra;
1962 scene->r.cfra= frame;
1964 if(seq->scene_camera)
1965 camera= seq->scene_camera;
1967 scene_camera_switch_update(scene);
1968 camera= scene->camera;
1971 if(have_seq==FALSE && camera==NULL) {
1972 scene->r.cfra= oldcfra;
1976 /* prevent eternal loop */
1977 doseq= context.scene->r.scemode & R_DOSEQ;
1978 context.scene->r.scemode &= ~R_DOSEQ;
1980 #ifdef DURIAN_CAMERA_SWITCH
1981 /* stooping to new low's in hackyness :( */
1982 oldmarkers= scene->markers;
1983 scene->markers.first= scene->markers.last= NULL;
1986 if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (scene == context.scene || have_seq==0) && camera) {
1987 char err_out[256]= "unknown";
1988 /* for old scened this can be uninitialized, should probably be added to do_versions at some point if the functionality stays */
1989 if(context.scene->r.seq_prev_type==0)
1990 context.scene->r.seq_prev_type = 3 /* ==OB_SOLID */;
1992 /* opengl offscreen render */
1993 scene_update_for_newframe(context.bmain, scene, scene->lay);
1994 ibuf= sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect, context.scene->r.seq_prev_type, err_out);
1996 fprintf(stderr, "seq_render_scene_strip_impl failed to get opengl buffer: %s\n", err_out);
2000 Render *re = RE_GetRender(scene->id.name);
2003 /* XXX: this if can be removed when sequence preview rendering uses the job system */
2004 if(rendering || context.scene != scene) {
2006 re= RE_NewRender(scene->id.name);
2008 RE_BlenderFrame(re, context.bmain, scene, NULL, camera, scene->lay, frame, FALSE);
2010 /* restore previous state after it was toggled on & off by RE_BlenderFrame */
2011 G.rendering = rendering;
2014 RE_AcquireResultImage(re, &rres);
2017 ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat);
2018 memcpy(ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
2020 addzbuffloatImBuf(ibuf);
2021 memcpy(ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
2024 /* float buffers in the sequencer are not linear */
2025 ibuf->profile= IB_PROFILE_LINEAR_RGB;
2026 IMB_convert_profile(ibuf, IB_PROFILE_SRGB);
2028 else if (rres.rect32) {
2029 ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect);
2030 memcpy(ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
2033 RE_ReleaseResultImage(re);
2035 // BIF_end_render_callbacks();
2039 context.scene->r.scemode |= doseq;
2041 scene->r.cfra = oldcfra;
2043 if(frame != oldcfra)
2044 scene_update_for_newframe(context.bmain, scene, scene->lay);
2046 #ifdef DURIAN_CAMERA_SWITCH
2047 /* stooping to new low's in hackyness :( */
2048 scene->markers= oldmarkers;
2054 static ImBuf * seq_render_strip(SeqRenderData context, Sequence * seq, float cfra)
2056 ImBuf * ibuf = NULL;
2057 char name[FILE_MAXDIR+FILE_MAXFILE];
2058 int use_preprocess = input_have_to_preprocess(context, seq, cfra);
2059 float nr = give_stripelem_index(seq, cfra);
2060 /* all effects are handled similarly with the exception of speed effect */
2061 int type = (seq->type & SEQ_EFFECT && seq->type != SEQ_SPEED) ? SEQ_EFFECT : seq->type;
2063 ibuf = seq_stripelem_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
2065 /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF,
2066 but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL */
2068 use_preprocess = FALSE;
2071 ibuf = copy_from_ibuf_still(context, seq, nr);
2074 ibuf = seq_proxy_fetch(context, seq, cfra);
2076 if(ibuf == NULL) switch(type) {
2079 ImBuf * meta_ibuf = NULL;
2081 if(seq->seqbase.first)
2082 meta_ibuf = seq_render_strip_stack(
2083 context, &seq->seqbase,
2084 seq->start + nr, 0);
2088 if(ibuf && use_preprocess) {
2089 struct ImBuf * i = IMB_dupImBuf(ibuf);
2091 IMB_freeImBuf(ibuf);
2100 ImBuf * child_ibuf = NULL;
2103 SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
2105 sequence_effect_speed_rebuild_map(context.scene,seq, 0);
2108 f_cfra = seq->start + s->frameMap[(int) nr];
2110 child_ibuf = seq_render_strip(context,seq->seq1,f_cfra);
2114 if(ibuf && use_preprocess) {
2115 struct ImBuf * i = IMB_dupImBuf(ibuf);
2117 IMB_freeImBuf(ibuf);
2126 ibuf = seq_render_effect_strip_impl(
2127 context, seq, seq->start + nr);
2132 StripElem * s_elem = give_stripelem(seq, cfra);
2135 BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
2136 BLI_path_abs(name, G.main->name);
2139 if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) {
2140 /* we don't need both (speed reasons)! */
2141 if (ibuf->rect_float && ibuf->rect)
2142 imb_freerectImBuf(ibuf);
2144 /* all sequencer color is done in SRGB space, linear gives odd crossfades */
2145 if(ibuf->profile == IB_PROFILE_LINEAR_RGB)
2146 IMB_convert_profile(ibuf, IB_PROFILE_NONE);
2148 copy_to_ibuf_still(context, seq, nr, ibuf);
2150 s_elem->orig_width = ibuf->x;
2151 s_elem->orig_height = ibuf->y;
2157 seq_open_anim_file(seq);
2160 IMB_anim_set_preseek(seq->anim,
2163 ibuf = IMB_anim_absolute(
2164 seq->anim, nr + seq->anim_startofs,
2166 seq->strip->proxy->tc
2167 : IMB_TC_RECORD_RUN,
2168 seq_rendersize_to_proxysize(
2169 context.preview_render_size));
2171 /* we don't need both (speed reasons)! */
2172 if (ibuf && ibuf->rect_float && ibuf->rect)
2173 imb_freerectImBuf(ibuf);
2175 seq->strip->stripdata->orig_width = ibuf->x;
2176 seq->strip->stripdata->orig_height = ibuf->y;
2179 copy_to_ibuf_still(context, seq, nr, ibuf);
2183 { // scene can be NULL after deletions
2184 ibuf = seq_render_scene_strip_impl(context, seq, nr);
2186 /* Scene strips update all animation, so we need to restore original state.*/
2187 BKE_animsys_evaluate_all_animation(context.bmain, context.scene, cfra);
2189 copy_to_ibuf_still(context, seq, nr, ibuf);
2195 ibuf = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect);
2197 if (ibuf->x != context.rectx || ibuf->y != context.recty)
2198 use_preprocess = TRUE;
2201 ibuf = input_preprocess(context, seq, cfra, ibuf);
2203 seq_stripelem_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
2208 /* **********************************************************************
2209 strip stack rendering functions
2210 ********************************************************************** */
2212 static int seq_must_swap_input_in_blend_mode(Sequence * seq)
2214 int swap_input = FALSE;
2216 /* bad hack, to fix crazy input ordering of
2217 those two effects */
2219 if (ELEM3(seq->blend_mode, SEQ_ALPHAOVER, SEQ_ALPHAUNDER, SEQ_OVERDROP)) {
2226 static int seq_get_early_out_for_blend_mode(Sequence * seq)
2228 struct SeqEffectHandle sh = get_sequence_blend(seq);
2229 float facf = seq->blend_opacity / 100.0f;
2230 int early_out = sh.early_out(seq, facf, facf);
2232 if (ELEM(early_out, EARLY_DO_EFFECT, EARLY_NO_INPUT)) {
2236 if (seq_must_swap_input_in_blend_mode(seq)) {
2237 if (early_out == EARLY_USE_INPUT_2) {
2238 return EARLY_USE_INPUT_1;
2239 } else if (early_out == EARLY_USE_INPUT_1) {
2240 return EARLY_USE_INPUT_2;
2246 static ImBuf* seq_render_strip_stack(
2247 SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown)
2249 Sequence* seq_arr[MAXSEQ+1];
2254 count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
2260 #if 0 /* commentind since this breaks keyframing, since it resets the value on draw */
2261 if(scene->r.cfra != cfra) {
2262 // XXX for prefetch and overlay offset!..., very bad!!!
2263 AnimData *adt= BKE_animdata_from_id(&scene->id);
2264 BKE_animsys_evaluate_animdata(scene, &scene->id, adt, cfra, ADT_RECALC_ANIM);
2268 out = seq_stripelem_cache_get(context, seq_arr[count - 1],
2269 cfra, SEQ_STRIPELEM_IBUF_COMP);
2276 out = seq_render_strip(context, seq_arr[0], cfra);
2277 seq_stripelem_cache_put(context, seq_arr[0], cfra,
2278 SEQ_STRIPELEM_IBUF_COMP, out);
2284 for (i = count - 1; i >= 0; i--) {
2286 Sequence *seq = seq_arr[i];
2288 out = seq_stripelem_cache_get(
2289 context, seq, cfra, SEQ_STRIPELEM_IBUF_COMP);
2294 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2295 out = seq_render_strip(context, seq, cfra);
2299 early_out = seq_get_early_out_for_blend_mode(seq);
2301 switch (early_out) {
2302 case EARLY_NO_INPUT:
2303 case EARLY_USE_INPUT_2:
2304 out = seq_render_strip(context, seq, cfra);
2306 case EARLY_USE_INPUT_1:
2308 out = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect);
2311 case EARLY_DO_EFFECT:
2313 out = seq_render_strip(context, seq, cfra);
2323 seq_stripelem_cache_put(context, seq_arr[i], cfra,
2324 SEQ_STRIPELEM_IBUF_COMP, out);
2329 for (; i < count; i++) {
2330 Sequence * seq = seq_arr[i];
2332 if (seq_get_early_out_for_blend_mode(seq) == EARLY_DO_EFFECT) {
2333 struct SeqEffectHandle sh = get_sequence_blend(seq);
2334 ImBuf * ibuf1 = out;
2335 ImBuf * ibuf2 = seq_render_strip(context, seq, cfra);
2337 float facf = seq->blend_opacity / 100.0f;
2338 int swap_input = seq_must_swap_input_in_blend_mode(seq);
2341 out = sh.execute(context, seq, cfra,
2343 ibuf2, ibuf1, NULL);
2345 out = sh.execute(context, seq, cfra,
2347 ibuf1, ibuf2, NULL);
2350 IMB_freeImBuf(ibuf1);
2351 IMB_freeImBuf(ibuf2);
2354 seq_stripelem_cache_put(context, seq_arr[i], cfra,
2355 SEQ_STRIPELEM_IBUF_COMP, out);
2362 * returned ImBuf is refed!
2363 * you have to free after usage!
2366 ImBuf *give_ibuf_seq(SeqRenderData context, float cfra, int chanshown)
2368 Editing *ed= seq_give_editing(context.scene, FALSE);
2372 if(ed==NULL) return NULL;
2374 count = BLI_countlist(&ed->metastack);
2375 if((chanshown < 0) && (count > 0)) {
2376 count = MAX2(count + chanshown, 0);
2377 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2379 seqbasep= ed->seqbasep;
2382 return seq_render_strip_stack(context, seqbasep, cfra, chanshown);
2385 ImBuf *give_ibuf_seqbase(SeqRenderData context, float cfra, int chanshown, ListBase *seqbasep)
2387 return seq_render_strip_stack(context, seqbasep, cfra, chanshown);
2391 ImBuf *give_ibuf_seq_direct(SeqRenderData context, float cfra, Sequence *seq)
2393 return seq_render_strip(context, seq, cfra);
2397 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2398 static int seq_can_blend(Sequence *seq)
2400 if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2408 /* *********************** threading api ******************* */
2410 static ListBase running_threads;
2411 static ListBase prefetch_wait;
2412 static ListBase prefetch_done;
2414 static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
2415 static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER;
2416 static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
2418 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2419 //static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2421 static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
2422 static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
2424 static volatile int seq_thread_shutdown = TRUE;
2425 static volatile int seq_last_given_monoton_cfra = 0;
2426 static int monoton_cfra = 0;
2428 typedef struct PrefetchThread {
2429 struct PrefetchThread *next, *prev;
2432 struct PrefetchQueueElem *current;
2438 typedef struct PrefetchQueueElem {
2439 struct PrefetchQueueElem *next, *prev;
2445 int preview_render_size;
2449 struct ImBuf * ibuf;
2450 } PrefetchQueueElem;
2453 static void *seq_prefetch_thread(void * This_)
2455 PrefetchThread * This = This_;
2457 while (!seq_thread_shutdown) {
2458 PrefetchQueueElem *e;
2461 pthread_mutex_lock(&queue_lock);
2462 e = prefetch_wait.first;
2464 BLI_remlink(&prefetch_wait, e);
2466 s_last = seq_last_given_monoton_cfra;
2470 pthread_mutex_unlock(&queue_lock);
2473 pthread_mutex_lock(&prefetch_ready_lock);
2475 This->running = FALSE;
2477 pthread_cond_signal(&prefetch_ready_cond);
2478 pthread_mutex_unlock(&prefetch_ready_lock);
2480 pthread_mutex_lock(&wakeup_lock);
2481 if (!seq_thread_shutdown) {
2482 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2484 pthread_mutex_unlock(&wakeup_lock);
2488 This->running = TRUE;
2490 if (e->cfra >= s_last) {
2491 e->ibuf = give_ibuf_seq_impl(This->scene,
2492 e->rectx, e->recty, e->cfra, e->chanshown,
2493 e->preview_render_size);
2496 pthread_mutex_lock(&queue_lock);
2498 BLI_addtail(&prefetch_done, e);
2500 for (e = prefetch_wait.first; e; e = e->next) {
2501 if (s_last > e->monoton_cfra) {
2502 BLI_remlink(&prefetch_wait, e);
2507 for (e = prefetch_done.first; e; e = e->next) {
2508 if (s_last > e->monoton_cfra) {
2510 IMB_cache_limiter_unref(e->ibuf);
2512 BLI_remlink(&prefetch_done, e);
2517 pthread_mutex_unlock(&queue_lock);
2519 pthread_mutex_lock(&frame_done_lock);
2520 pthread_cond_signal(&frame_done_cond);
2521 pthread_mutex_unlock(&frame_done_lock);
2526 static void seq_start_threads(Scene *scene)
2530 running_threads.first = running_threads.last = NULL;
2531 prefetch_wait.first = prefetch_wait.last = NULL;
2532 prefetch_done.first = prefetch_done.last = NULL;
2534 seq_thread_shutdown = FALSE;
2535 seq_last_given_monoton_cfra = monoton_cfra = 0;
2537 /* since global structures are modified during the processing
2538 of one frame, only one render thread is currently possible...
2540 (but we code, in the hope, that we can remove this restriction
2544 fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2546 for (i = 0; i < 1; i++) {
2547 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
2550 BLI_addtail(&running_threads, t);
2552 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2555 /* init malloc mutex */
2556 BLI_init_threads(0, 0, 0);
2559 static void seq_stop_threads()
2561 PrefetchThread *tslot;
2562 PrefetchQueueElem *e;
2564 fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2566 if (seq_thread_shutdown) {
2567 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2571 pthread_mutex_lock(&wakeup_lock);
2573 seq_thread_shutdown = TRUE;
2575 pthread_cond_broadcast(&wakeup_cond);
2576 pthread_mutex_unlock(&wakeup_lock);
2578 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2579 pthread_join(tslot->pthread, NULL);
2583 for (e = prefetch_wait.first; e; e = e->next) {
2584 BLI_remlink(&prefetch_wait, e);
2588 for (e = prefetch_done.first; e; e = e->next) {
2590 IMB_cache_limiter_unref(e->ibuf);
2592 BLI_remlink(&prefetch_done, e);
2596 BLI_freelistN(&running_threads);
2598 /* deinit malloc mutex */
2603 void give_ibuf_prefetch_request(SeqRenderData context, float cfra, int chanshown)
2605 PrefetchQueueElem *e;
2606 if (seq_thread_shutdown) {
2610 e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2611 e->rectx = context.rectx;
2612 e->recty = context.recty;
2614 e->chanshown = chanshown;
2615 e->preview_render_size = context.preview_render_size;
2616 e->monoton_cfra = monoton_cfra++;
2618 pthread_mutex_lock(&queue_lock);
2619 BLI_addtail(&prefetch_wait, e);
2620 pthread_mutex_unlock(&queue_lock);
2622 pthread_mutex_lock(&wakeup_lock);
2623 pthread_cond_signal(&wakeup_cond);
2624 pthread_mutex_unlock(&wakeup_lock);
2628 static void seq_wait_for_prefetch_ready()
2630 PrefetchThread *tslot;
2632 if (seq_thread_shutdown) {
2636 fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
2638 pthread_mutex_lock(&prefetch_ready_lock);
2641 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2642 if (tslot->running) {
2649 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
2652 pthread_mutex_unlock(&prefetch_ready_lock);
2654 fprintf(stderr, "SEQ-THREAD: prefetch done\n");
2658 ImBuf *give_ibuf_seq_threaded(SeqRenderData context, float cfra, int chanshown)
2660 PrefetchQueueElem *e = NULL;
2661 int found_something = FALSE;
2663 if (seq_thread_shutdown) {
2664 return give_ibuf_seq(context, cfra, chanshown);
2668 int success = FALSE;
2669 pthread_mutex_lock(&queue_lock);
2671 for (e = prefetch_done.first; e; e = e->next) {
2672 if (cfra == e->cfra &&
2673 chanshown == e->chanshown &&
2674 context.rectx == e->rectx &&
2675 context.recty == e->recty &&
2676 context.preview_render_size == e->preview_render_size) {
2678 found_something = TRUE;
2684 for (e = prefetch_wait.first; e; e = e->next) {
2685 if (cfra == e->cfra &&
2686 chanshown == e->chanshown &&
2687 context.rectx == e->rectx &&
2688 context.recty == e->recty &&
2689 context.preview_render_size == e->preview_render_size) {
2690 found_something = TRUE;
2697 PrefetchThread *tslot;
2699 for(tslot = running_threads.first;
2700 tslot; tslot= tslot->next) {
2701 if (tslot->current &&
2702 cfra == tslot->current->cfra &&
2703 chanshown == tslot->current->chanshown &&
2704 context.rectx == tslot->current->rectx &&
2705 context.recty == tslot->current->recty &&
2706 context.preview_render_size== tslot->current->preview_render_size){
2707 found_something = TRUE;
2713 /* e->ibuf is unrefed by render thread on next round. */
2716 seq_last_given_monoton_cfra = e->monoton_cfra;
2719 pthread_mutex_unlock(&queue_lock);
2724 if (!found_something) {
2726 "SEQ-THREAD: Requested frame "
2727 "not in queue ???\n");
2730 pthread_mutex_lock(&frame_done_lock);
2731 pthread_cond_wait(&frame_done_cond, &frame_done_lock);
2732 pthread_mutex_unlock(&frame_done_lock);
2736 return e ? e->ibuf : NULL;
2739 /* Functions to free imbuf and anim data on changes */
2741 static void free_anim_seq(Sequence *seq)
2744 IMB_free_anim(seq->anim);
2749 void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage,
2750 int keep_file_handles)
2754 if (check_mem_usage) {
2755 /* Let the cache limitor take care of this (schlaile) */
2756 /* While render let's keep all memory available for render
2758 At least if free memory is tight...
2759 This can make a big difference in encoding speed
2760 (it is around 4 times(!) faster, if we do not waste time
2761 on freeing _all_ buffers every time on long timelines...)
2765 uintptr_t mem_in_use;
2766 uintptr_t mmap_in_use;
2769 mem_in_use= MEM_get_memory_in_use();
2770 mmap_in_use= MEM_get_mapped_memory_in_use();
2771 max = MEM_CacheLimiter_get_maximum();
2773 if (max == 0 || mem_in_use + mmap_in_use <= max) {
2778 seq_stripelem_cache_cleanup();
2780 for(seq= seqbase->first; seq; seq= seq->next) {
2782 if(seq->type==SEQ_MOVIE && !keep_file_handles)
2784 if(seq->type==SEQ_SPEED) {
2785 sequence_effect_speed_rebuild_map(scene, seq, 1);
2788 if(seq->type==SEQ_META) {
2789 free_imbuf_seq(scene, &seq->seqbase, FALSE, keep_file_handles);
2791 if(seq->type==SEQ_SCENE) {
2792 /* FIXME: recurs downwards,
2793 but do recurs protection somehow! */
2799 static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
2804 /* recurs downwards to see if this seq depends on the changed seq */
2809 if(seq == changed_seq)
2812 for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
2813 if(update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change))
2817 if(update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change))
2819 if(seq->seq2 && (seq->seq2 != seq->seq1))
2820 if(update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change))
2822 if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
2823 if(update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change))
2828 if(seq->type == SEQ_MOVIE)
2830 if(seq->type == SEQ_SPEED) {
2831 sequence_effect_speed_rebuild_map(scene, seq, 1);
2836 calc_sequence(scene, seq);
2842 void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
2844 Editing *ed= seq_give_editing(scene, FALSE);
2847 if (ed==NULL) return;
2849 for (seq=ed->seqbase.first; seq; seq=seq->next)
2850 update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change);
2853 /* seq funcs's for transforming internally
2854 notice the difference between start/end and left/right.
2856 left and right are the bounds at which the sequence is rendered,
2857 start and end are from the start and fixed length of the sequence.
2859 int seq_tx_get_start(Sequence *seq) {
2862 int seq_tx_get_end(Sequence *seq)
2864 return seq->start+seq->len;
2867 int seq_tx_get_final_left(Sequence *seq, int metaclip)
2869 if (metaclip && seq->tmp) {
2870 /* return the range clipped by the parents range */
2871 return MAX2( seq_tx_get_final_left(seq, 0), seq_tx_get_final_left((Sequence *)seq->tmp, 1) );
2873 return (seq->start - seq->startstill) + seq->startofs;
2877 int seq_tx_get_final_right(Sequence *seq, int metaclip)
2879 if (metaclip && seq->tmp) {
2880 /* return the range clipped by the parents range */
2881 return MIN2( seq_tx_get_final_right(seq, 0), seq_tx_get_final_right((Sequence *)seq->tmp, 1) );
2883 return ((seq->start+seq->len) + seq->endstill) - seq->endofs;
2887 void seq_tx_set_final_left(Sequence *seq, int val)
2889 if (val < (seq)->start) {
2890 seq->startstill = abs(val - (seq)->start);
2893 seq->startofs = abs(val - (seq)->start);
2894 seq->startstill = 0;
2898 void seq_tx_set_final_right(Sequence *seq, int val)
2900 if (val > (seq)->start + (seq)->len) {
2901 seq->endstill = abs(val - (seq->start + (seq)->len));
2904 seq->endofs = abs(val - ((seq)->start + (seq)->len));
2909 /* used so we can do a quick check for single image seq
2910 since they work a bit differently to normal image seq's (during transform) */
2911 int seq_single_check(Sequence *seq)
2913 return (seq->len==1 && (
2914 seq->type == SEQ_IMAGE
2915 || ((seq->type & SEQ_EFFECT) &&
2916 get_sequence_effect_num_inputs(seq->type) == 0)));
2919 /* check if the selected seq's reference unselected seq's */
2920 int seqbase_isolated_sel_check(ListBase *seqbase)
2923 /* is there more than 1 select */
2926 for(seq= seqbase->first; seq; seq= seq->next) {
2927 if(seq->flag & SELECT) {
2936 /* test relationships */
2937 for(seq= seqbase->first; seq; seq= seq->next) {
2938 if((seq->type & SEQ_EFFECT)==0)
2941 if(seq->flag & SELECT) {
2942 if( (seq->seq1 && (seq->seq1->flag & SELECT)==0) ||
2943 (seq->seq2 && (seq->seq2->flag & SELECT)==0) ||
2944 (seq->seq3 && (seq->seq3->flag & SELECT)==0) )
2948 if( (seq->seq1 && (seq->seq1->flag & SELECT)) ||
2949 (seq->seq2 && (seq->seq2->flag & SELECT)) ||
2950 (seq->seq3 && (seq->seq3->flag & SELECT)) )
2958 /* use to impose limits when dragging/extending - so impossible situations dont happen
2959 * Cant use the SEQ_LEFTSEL and SEQ_LEFTSEL directly because the strip may be in a metastrip */
2960 void seq_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
2963 if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_final_right(seq, 0)) {
2964 seq_tx_set_final_left(seq, seq_tx_get_final_right(seq, 0)-1);
2967 if (seq_single_check(seq)==0) {
2968 if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_end(seq)) {
2969 seq_tx_set_final_left(seq, seq_tx_get_end(seq)-1);
2972 /* dosnt work now - TODO */
2974 if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq, 0)) {
2976 ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq, 0);
2978 seq_tx_set_final_left(seq, seq_tx_get_final_left(seq, 0) + ofs );
2985 if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_final_left(seq, 0)) {
2986 seq_tx_set_final_right(seq, seq_tx_get_final_left(seq, 0)+1);
2989 if (seq_single_check(seq)==0) {
2990 if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_start(seq)) {
2991 seq_tx_set_final_right(seq, seq_tx_get_start(seq)+1);
2996 /* sounds cannot be extended past their endpoints */
2997 if (seq->type == SEQ_SOUND) {
3003 void seq_single_fix(Sequence *seq)
3005 int left, start, offset;
3006 if (!seq_single_check(seq))
3009 /* make sure the image is always at the start since there is only one,
3010 adjusting its start should be ok */
3011 left = seq_tx_get_final_left(seq, 0);
3013 if (start != left) {
3014 offset = left - start;
3015 seq_tx_set_final_left( seq, seq_tx_get_final_left(seq, 0) - offset );
3016 seq_tx_set_final_right( seq, seq_tx_get_final_right(seq, 0) - offset );
3017 seq->start += offset;
3021 int seq_tx_test(Sequence * seq)
3023 return (seq->type < SEQ_EFFECT) || (get_sequence_effect_num_inputs(seq->type) == 0);
3026 static int seq_overlap(Sequence *seq1, Sequence *seq2)
3028 return (seq1 != seq2 && seq1->machine == seq2->machine &&
3029 ((seq1->enddisp <= seq2->startdisp) || (seq1->startdisp >= seq2->enddisp))==0);
3032 int seq_test_overlap(ListBase * seqbasep, Sequence *test)
3036 seq= seqbasep->first;
3038 if(seq_overlap(test, seq))
3047 void seq_translate(Scene *evil_scene, Sequence *seq, int delta)
3049 seq_offset_animdata(evil_scene, seq, delta);
3050 seq->start += delta;
3052 if(seq->type==SEQ_META) {
3053 Sequence *seq_child;
3054 for(seq_child= seq->seqbase.first; seq_child; seq_child= seq_child->next) {
3055 seq_translate(evil_scene, seq_child, delta);
3059 calc_sequence_disp(evil_scene, seq);
3062 void seq_sound_init(Scene *scene, Sequence *seq)
3064 if(seq->type==SEQ_META) {
3065 Sequence *seq_child;
3066 for(seq_child= seq->seqbase.first; seq_child; seq_child= seq_child->next) {
3067 seq_sound_init(scene, seq_child);
3072 seq->scene_sound = sound_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
3075 sound_scene_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
3080 Sequence *seq_foreground_frame_get(Scene *scene, int frame)
3082 Editing *ed= seq_give_editing(scene, FALSE);
3083 Sequence *seq, *best_seq=NULL;
3084 int best_machine = -1;
3086 if(!ed) return NULL;
3088 for (seq=ed->seqbasep->first; seq; seq= seq->next) {
3089 if(seq->flag & SEQ_MUTE || seq->startdisp > frame || seq->enddisp <= frame)
3091 /* only use elements you can see - not */
3092 if (ELEM5(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE, SEQ_COLOR)) {
3093 if (seq->machine > best_machine) {
3095 best_machine = seq->machine;
3102 /* return 0 if there werent enough space */
3103 int shuffle_seq(ListBase * seqbasep, Sequence *test, Scene *evil_scene)
3105 int orig_machine= test->machine;
3107 calc_sequence(evil_scene, test);
3108 while( seq_test_overlap(seqbasep, test) ) {
3109 if(test->machine >= MAXSEQ) {
3113 calc_sequence(evil_scene, test); // XXX - I dont think this is needed since were only moving vertically, Campbell.
3117 if(test->machine >= MAXSEQ) {
3118 /* Blender 2.4x would remove the strip.
3119 * nicer to move it to the end */
3122 int new_frame= test->enddisp;
3124 for(seq= seqbasep->first; seq; seq= seq->next) {
3125 if (seq->machine == orig_machine)
3126 new_frame = MAX2(new_frame, seq->enddisp);
3129 test->machine= orig_machine;
3130 new_frame = new_frame + (test->start-test->startdisp); /* adjust by the startdisp */
3131 seq_translate(evil_scene, test, new_frame - test->start);
3133 calc_sequence(evil_scene, test);
3140 static int shuffle_seq_time_offset_test(ListBase * seqbasep, char dir)
3143 Sequence *seq, *seq_other;
3145 for(seq= seqbasep->first; seq; seq= seq->next) {
3147 for(seq_other= seqbasep->first; seq_other; seq_other= seq_other->next) {
3148 if(!seq_other->tmp && seq_overlap(seq, seq_other)) {
3150 offset= MIN2(offset, seq_other->startdisp - seq->enddisp);
3153 offset= MAX2(offset, seq_other->enddisp - seq->startdisp);
3162 static int shuffle_seq_time_offset(Scene* scene, ListBase * seqbasep, char dir)
3167 while( (ofs= shuffle_seq_time_offset_test(seqbasep, dir)) ) {
3168 for(seq= seqbasep->first; seq; seq= seq->next) {
3170 /* seq_test_overlap only tests display values */
3171 seq->startdisp += ofs;
3172 seq->enddisp += ofs;
3179 for(seq= seqbasep->first; seq; seq= seq->next) {
3181 calc_sequence_disp(scene, seq); /* corrects dummy startdisp/enddisp values */
3187 int shuffle_seq_time(ListBase * seqbasep, Scene *evil_scene)
3189 /* note: seq->tmp is used to tag strips to move */
3193 int offset_l = shuffle_seq_time_offset(evil_scene, seqbasep, 'L');
3194 int offset_r = shuffle_seq_time_offset(evil_scene, seqbasep, 'R');
3195 int offset = (-offset_l < offset_r) ? offset_l:offset_r;
3198 for(seq= seqbasep->first; seq; seq= seq->next) {
3200 seq_translate(evil_scene, seq, offset);
3201 seq->flag &= ~SEQ_OVERLAP;
3209 void seq_update_sound_bounds_all(Scene *scene)
3211 Editing *ed = scene->ed;