2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
22 * - Blender Foundation, 2003-2009
23 * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/blenkernel/intern/sequencer.c
38 #include "MEM_guardedalloc.h"
39 #include "MEM_CacheLimiterC-Api.h"
41 #include "DNA_sequence_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_anim_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_sound_types.h"
48 #include "BLI_fileops.h"
49 #include "BLI_listbase.h"
50 #include "BLI_path_util.h"
51 #include "BLI_string.h"
52 #include "BLI_threads.h"
53 #include "BLI_utildefines.h"
55 #include "BKE_animsys.h"
56 #include "BKE_global.h"
57 #include "BKE_image.h"
59 #include "BKE_sequencer.h"
60 #include "BKE_fcurve.h"
61 #include "BKE_scene.h"
62 #include "BKE_utildefines.h"
64 #include "RNA_access.h"
66 #include "RE_pipeline.h"
70 #include "IMB_imbuf.h"
71 #include "IMB_imbuf_types.h"
73 #include "BKE_context.h"
74 #include "BKE_sound.h"
77 # include "AUD_C-API.h"
80 static ImBuf* seq_render_strip_stack(
81 SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown);
83 static ImBuf * seq_render_strip(
84 SeqRenderData context, Sequence * seq, float cfra);
86 static void seq_free_animdata(Scene *scene, Sequence *seq);
89 /* **** XXX ******** */
91 ListBase seqbase_clipboard;
92 int seqbase_clipboard_frame;
93 SequencerDrawView sequencer_view3d_cb= NULL; /* NULL in background mode */
96 void printf_strip(Sequence *seq)
98 fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n",
99 seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp);
100 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));
103 int seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg)
106 for(iseq= seqbase->first; iseq; iseq= iseq->next) {
107 if(seq_recursive_apply(iseq, apply_func, arg) == -1)
108 return -1; /* bail out */
113 int seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg)
115 int ret= apply_func(seq, arg);
118 return -1; /* bail out */
120 if(ret && seq->seqbase.first)
121 ret = seqbase_recursive_apply(&seq->seqbase, apply_func, arg);
126 /* **********************************************************************
127 alloc / free functions
128 ********************************************************************** */
132 void new_tstripdata(Sequence *seq)
135 seq->strip->len= seq->len;
142 static void free_proxy_seq(Sequence *seq)
144 if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
145 IMB_free_anim(seq->strip->proxy->anim);
146 seq->strip->proxy->anim = NULL;
150 void seq_free_strip(Strip *strip)
153 if(strip->us>0) return;
155 printf("error: negative users in strip\n");
159 if (strip->stripdata) {
160 MEM_freeN(strip->stripdata);
164 if (strip->proxy->anim) {
165 IMB_free_anim(strip->proxy->anim);
168 MEM_freeN(strip->proxy);
171 MEM_freeN(strip->crop);
173 if (strip->transform) {
174 MEM_freeN(strip->transform);
176 if (strip->color_balance) {
177 MEM_freeN(strip->color_balance);
183 void seq_free_sequence(Scene *scene, Sequence *seq)
185 if(seq->strip) seq_free_strip(seq->strip);
187 if(seq->anim) IMB_free_anim(seq->anim);
189 if (seq->type & SEQ_EFFECT) {
190 struct SeqEffectHandle sh = get_sequence_effect(seq);
196 ((ID *)seq->sound)->us--;
199 /* clipboard has no scene and will never have a sound handle or be active */
201 Editing *ed = scene->ed;
203 if (ed->act_seq==seq)
206 if(seq->scene_sound && ELEM(seq->type, SEQ_SOUND, SEQ_SCENE))
207 sound_remove_scene_sound(scene, seq->scene_sound);
209 seq_free_animdata(scene, seq);
215 void seq_free_sequence_recurse(Scene *scene, Sequence *seq)
219 for(iseq= seq->seqbase.first; iseq; iseq= iseq->next) {
220 seq_free_sequence_recurse(scene, iseq);
223 seq_free_sequence(scene, seq);
227 Editing *seq_give_editing(Scene *scene, int alloc)
229 if (scene->ed == NULL && alloc) {
232 ed= scene->ed= MEM_callocN( sizeof(Editing), "addseq");
233 ed->seqbasep= &ed->seqbase;
238 static void seq_free_clipboard_recursive(Sequence *seq_parent)
240 Sequence *seq, *nseq;
242 for(seq= seq_parent->seqbase.first; seq; seq= nseq) {
244 seq_free_clipboard_recursive(seq);
247 seq_free_sequence(NULL, seq_parent);
250 void seq_free_clipboard(void)
252 Sequence *seq, *nseq;
254 for(seq= seqbase_clipboard.first; seq; seq= nseq) {
256 seq_free_clipboard_recursive(seq);
258 seqbase_clipboard.first= seqbase_clipboard.last= NULL;
261 void seq_free_editing(Scene *scene)
263 Editing *ed = scene->ed;
271 seq_free_sequence(scene, seq);
275 while((ms= ed->metastack.first)) {
276 BLI_remlink(&ed->metastack, ms);
283 /* **********************************************************************
284 * sequencer pipeline functions
285 ********************************************************************** */
287 SeqRenderData seq_new_render_data(
288 struct Main * bmain, struct Scene * scene,
289 int rectx, int recty, int preview_render_size)
297 rval.preview_render_size = preview_render_size;
298 rval.motion_blur_samples = 0;
299 rval.motion_blur_shutter = 0;
304 int seq_cmp_render_data(const SeqRenderData * a, const SeqRenderData * b)
306 if (a->preview_render_size < b->preview_render_size) {
309 if (a->preview_render_size > b->preview_render_size) {
313 if (a->rectx < b->rectx) {
316 if (a->rectx > b->rectx) {
320 if (a->recty < b->recty) {
323 if (a->recty > b->recty) {
327 if (a->bmain < b->bmain) {
330 if (a->bmain > b->bmain) {
334 if (a->scene < b->scene) {
337 if (a->scene > b->scene) {
341 if (a->motion_blur_shutter < b->motion_blur_shutter) {
344 if (a->motion_blur_shutter > b->motion_blur_shutter) {
348 if (a->motion_blur_samples < b->motion_blur_samples) {
351 if (a->motion_blur_samples > b->motion_blur_samples) {
358 unsigned int seq_hash_render_data(const SeqRenderData * a)
360 unsigned int rval = a->rectx + a->recty;
362 rval ^= a->preview_render_size;
363 rval ^= ((intptr_t) a->bmain) << 6;
364 rval ^= ((intptr_t) a->scene) << 6;
365 rval ^= (int) (a->motion_blur_shutter * 100.0f) << 10;
366 rval ^= a->motion_blur_samples << 24;
371 /* ************************* iterator ************************** */
372 /* *************** (replaces old WHILE_SEQ) ********************* */
373 /* **************** use now SEQ_BEGIN() SEQ_END ***************** */
375 /* sequence strip iterator:
376 * - builds a full array, recursively into meta strips */
378 static void seq_count(ListBase *seqbase, int *tot)
382 for(seq=seqbase->first; seq; seq=seq->next) {
385 if(seq->seqbase.first)
386 seq_count(&seq->seqbase, tot);
390 static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
394 for(seq=seqbase->first; seq; seq=seq->next) {
397 if(seq->seqbase.first)
398 seq_build_array(&seq->seqbase, array, depth+1);
405 void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_pointer)
416 seq_count(ed->seqbasep, tot);
418 seq_count(&ed->seqbase, tot);
423 *seqarray= array= MEM_mallocN(sizeof(Sequence *)*(*tot), "SeqArray");
425 seq_build_array(ed->seqbasep, &array, 0);
427 seq_build_array(&ed->seqbase, &array, 0);
430 void seq_begin(Editing *ed, SeqIterator *iter, int use_pointer)
432 memset(iter, 0, sizeof(*iter));
433 seq_array(ed, &iter->array, &iter->tot, use_pointer);
437 iter->seq= iter->array[iter->cur];
442 void seq_next(SeqIterator *iter)
444 if(++iter->cur < iter->tot)
445 iter->seq= iter->array[iter->cur];
450 void seq_end(SeqIterator *iter)
453 MEM_freeN(iter->array);
459 **********************************************************************
461 **********************************************************************
462 * Build a complete array of _all_ sequencies (including those
464 **********************************************************************
467 static void do_seq_count_cb(ListBase *seqbase, int *totseq,
468 int (*test_func)(Sequence * seq))
474 int test = test_func(seq);
475 if (test & BUILD_SEQAR_COUNT_CURRENT) {
478 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
479 do_seq_count_cb(&seq->seqbase, totseq, test_func);
485 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
486 int (*test_func)(Sequence * seq))
492 int test = test_func(seq);
495 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
496 do_build_seqar_cb(&seq->seqbase, seqar, depth+1, test_func);
498 if (test & BUILD_SEQAR_COUNT_CURRENT) {
506 void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq,
507 int (*test_func)(Sequence * seq))
512 do_seq_count_cb(seqbase, totseq, test_func);
518 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
521 do_build_seqar_cb(seqbase, seqar, 0, test_func);
526 void calc_sequence_disp(Scene *scene, Sequence *seq)
528 if(seq->startofs && seq->startstill) seq->startstill= 0;
529 if(seq->endofs && seq->endstill) seq->endstill= 0;
531 seq->startdisp= seq->start + seq->startofs - seq->startstill;
532 seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
534 seq->handsize= 10.0; /* 10 frames */
535 if( seq->enddisp-seq->startdisp < 10 ) {
536 seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
538 else if(seq->enddisp-seq->startdisp > 250) {
539 seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
542 seq_update_sound_bounds(scene, seq);
545 static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
549 /* for sound we go over full meta tree to update bounds of the sound strips,
550 since sound is played outside of evaluating the imbufs, */
551 for(seq=metaseq->seqbase.first; seq; seq=seq->next) {
552 if(seq->type == SEQ_META) {
553 seq_update_sound_bounds_recursive(scene, seq);
555 else if(ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) {
556 if(seq->scene_sound) {
557 int startofs = seq->startofs;
558 int endofs = seq->endofs;
559 if(seq->startofs + seq->start < metaseq->start + metaseq->startofs)
560 startofs = metaseq->start + metaseq->startofs - seq->start;
562 if(seq->start + seq->len - seq->endofs > metaseq->start + metaseq->len - metaseq->endofs)
563 endofs = seq->start + seq->len - metaseq->start - metaseq->len + metaseq->endofs;
564 sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs, seq->start+seq->len - endofs, startofs);
570 void calc_sequence(Scene *scene, Sequence *seq)
575 /* check all metas recursively */
576 seqm= seq->seqbase.first;
578 if(seqm->seqbase.first) calc_sequence(scene, seqm);
582 /* effects and meta: automatic start and end */
584 if(seq->type & SEQ_EFFECT) {
586 if(seq->seq2==NULL) seq->seq2= seq->seq1;
587 if(seq->seq3==NULL) seq->seq3= seq->seq1;
589 /* effecten go from seq1 -> seq2: test */
591 /* we take the largest start and smallest end */
593 // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
594 // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
597 /* XXX These resets should not be necessary, but users used to be able to
598 * edit effect's length, leading to strange results. See #29190. */
599 seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
600 seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
601 seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
602 /* we cant help if strips don't overlap, it wont give useful results.
603 * but at least ensure 'len' is never negative which causes bad bugs elsewhere. */
604 if(seq->enddisp < seq->startdisp) {
605 /* simple start/end swap */
606 seq->start= seq->enddisp;
607 seq->enddisp = seq->startdisp;
608 seq->startdisp= seq->start;
609 seq->flag |= SEQ_INVALID_EFFECT;
612 seq->flag &= ~SEQ_INVALID_EFFECT;
615 seq->len= seq->enddisp - seq->startdisp;
618 calc_sequence_disp(scene, seq);
621 if(seq->strip && seq->len!=seq->strip->len) {
627 if(seq->type==SEQ_META) {
628 seqm= seq->seqbase.first;
633 if(seqm->startdisp < min) min= seqm->startdisp;
634 if(seqm->enddisp > max) max= seqm->enddisp;
637 seq->start= min + seq->anim_startofs;
639 seq->len -= seq->anim_startofs;
640 seq->len -= seq->anim_endofs;
642 if(seq->strip && seq->len!=seq->strip->len) {
646 seq_update_sound_bounds_recursive(scene, seq);
648 calc_sequence_disp(scene, seq);
652 /* note: caller should run calc_sequence(scene, seq) after */
653 void reload_sequence_new_file(Scene *scene, Sequence * seq, int lock_range)
656 int prev_startdisp=0, prev_enddisp=0;
657 /* note: dont rename the strip, will break animation curves */
659 if (ELEM5(seq->type, SEQ_MOVIE, SEQ_IMAGE, SEQ_SOUND, SEQ_SCENE, SEQ_META)==0) {
664 /* keep so we dont have to move the actual start and end points (only the data) */
665 calc_sequence_disp(scene, seq);
666 prev_startdisp= seq->startdisp;
667 prev_enddisp= seq->enddisp;
673 if (ELEM3(seq->type, SEQ_SCENE, SEQ_META, SEQ_IMAGE)==0) {
674 BLI_join_dirfile(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name);
675 BLI_path_abs(str, G.main->name);
682 size_t olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem);
685 seq->len -= seq->anim_startofs;
686 seq->len -= seq->anim_endofs;
690 seq->strip->len = seq->len;
694 if(seq->anim) IMB_free_anim(seq->anim);
695 seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex);
701 seq->len = IMB_anim_get_duration(seq->anim,
703 seq->strip->proxy->tc :
706 seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
708 seq->len -= seq->anim_startofs;
709 seq->len -= seq->anim_endofs;
713 seq->strip->len = seq->len;
716 #ifdef WITH_AUDASPACE
719 seq->len = ceil(AUD_getInfo(seq->sound->playback_handle).length * FPS);
720 seq->len -= seq->anim_startofs;
721 seq->len -= seq->anim_endofs;
725 seq->strip->len = seq->len;
732 /* 'seq->scenenr' should be replaced with something more reliable */
733 Scene * sce = G.main->scene.first;
737 if(nr == seq->scenenr) {
748 seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
749 seq->len -= seq->anim_startofs;
750 seq->len -= seq->anim_endofs;
754 seq->strip->len = seq->len;
762 seq_tx_set_final_left(seq, prev_startdisp);
763 seq_tx_set_final_right(seq, prev_enddisp);
767 calc_sequence(scene, seq);
770 void sort_seq(Scene *scene)
772 /* all strips together per kind, and in order of y location ("machine") */
773 ListBase seqbase, effbase;
774 Editing *ed= seq_give_editing(scene, FALSE);
775 Sequence *seq, *seqt;
780 seqbase.first= seqbase.last= NULL;
781 effbase.first= effbase.last= NULL;
783 while( (seq= ed->seqbasep->first) ) {
784 BLI_remlink(ed->seqbasep, seq);
786 if(seq->type & SEQ_EFFECT) {
789 if(seqt->machine>=seq->machine) {
790 BLI_insertlinkbefore(&effbase, seqt, seq);
795 if(seqt==NULL) BLI_addtail(&effbase, seq);
800 if(seqt->machine>=seq->machine) {
801 BLI_insertlinkbefore(&seqbase, seqt, seq);
806 if(seqt==NULL) BLI_addtail(&seqbase, seq);
810 BLI_movelisttolist(&seqbase, &effbase);
811 *(ed->seqbasep)= seqbase;
815 static int clear_scene_in_allseqs_cb(Sequence *seq, void *arg_pt)
817 if(seq->scene==(Scene *)arg_pt)
822 void clear_scene_in_allseqs(Main *bmain, Scene *scene)
826 /* when a scene is deleted: test all seqs */
827 for(scene_iter= bmain->scene.first; scene_iter; scene_iter= scene_iter->id.next) {
828 if(scene_iter != scene && scene_iter->ed) {
829 seqbase_recursive_apply(&scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene);
834 typedef struct SeqUniqueInfo {
843 static void seqbase_unique_name(ListBase *seqbasep, Sequence *seq)
845 BLI_uniquename(seqbasep, seq, "Sequence", '.', offsetof(Sequence, name), SEQ_NAME_MAXSTR);
848 static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
851 for(seq=seqbasep->first; seq; seq= seq->next) {
852 if (sui->seq != seq && strcmp(sui->name_dest, seq->name+2)==0) {
853 sprintf(sui->name_dest, "%.17s.%03d", sui->name_src, sui->count++); /*24 - 2 for prefix, -1 for \0 */
854 sui->match= 1; /* be sure to re-scan */
859 static int seqbase_unique_name_recursive_cb(Sequence *seq, void *arg_pt)
861 if(seq->seqbase.first)
862 seqbase_unique_name(&seq->seqbase, (SeqUniqueInfo *)arg_pt);
866 void seqbase_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq)
871 BLI_strncpy(sui.name_src, seq->name+2, sizeof(sui.name_src));
872 BLI_strncpy(sui.name_dest, seq->name+2, sizeof(sui.name_dest));
875 sui.match= 1; /* assume the worst to start the loop */
877 /* Strip off the suffix */
878 if ((dot=strrchr(sui.name_src, '.'))) {
883 sui.count= atoi(dot) + 1;
888 seqbase_unique_name(seqbasep, &sui);
889 seqbase_recursive_apply(seqbasep, seqbase_unique_name_recursive_cb, &sui);
892 BLI_strncpy(seq->name+2, sui.name_dest, sizeof(seq->name)-2);
895 static const char *give_seqname_by_type(int type)
898 case SEQ_META: return "Meta";
899 case SEQ_IMAGE: return "Image";
900 case SEQ_SCENE: return "Scene";
901 case SEQ_MOVIE: return "Movie";
902 case SEQ_SOUND: return "Audio";
903 case SEQ_CROSS: return "Cross";
904 case SEQ_GAMCROSS: return "Gamma Cross";
905 case SEQ_ADD: return "Add";
906 case SEQ_SUB: return "Sub";
907 case SEQ_MUL: return "Mul";
908 case SEQ_ALPHAOVER: return "Alpha Over";
909 case SEQ_ALPHAUNDER: return "Alpha Under";
910 case SEQ_OVERDROP: return "Over Drop";
911 case SEQ_WIPE: return "Wipe";
912 case SEQ_GLOW: return "Glow";
913 case SEQ_TRANSFORM: return "Transform";
914 case SEQ_COLOR: return "Color";
915 case SEQ_MULTICAM: return "Multicam";
916 case SEQ_ADJUSTMENT: return "Adjustment";
917 case SEQ_SPEED: return "Speed";
923 const char *give_seqname(Sequence *seq)
925 const char *name = give_seqname_by_type(seq->type);
928 if(seq->type<SEQ_EFFECT) {
929 return seq->strip->dir;
930 } else if(seq->type==SEQ_PLUGIN) {
931 if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
932 seq->plugin && seq->plugin->doit) {
933 return seq->plugin->pname;
944 /* ***************** DO THE SEQUENCE ***************** */
946 static void make_black_ibuf(ImBuf *ibuf)
952 if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) return;
954 tot= ibuf->x*ibuf->y;
957 rect_float = ibuf->rect_float;
960 memset(rect, 0, tot * sizeof(char) * 4);
964 memset(rect_float, 0, tot * sizeof(float) * 4);
968 static void multibuf(ImBuf *ibuf, float fmul)
975 mul= (int)(256.0f * fmul);
976 rt= (char *)ibuf->rect;
977 rt_float = ibuf->rect_float;
983 icol= (mul*rt[0])>>8;
984 if(icol>254) rt[0]= 255; else rt[0]= icol;
985 icol= (mul*rt[1])>>8;
986 if(icol>254) rt[1]= 255; else rt[1]= icol;
987 icol= (mul*rt[2])>>8;
988 if(icol>254) rt[2]= 255; else rt[2]= icol;
989 icol= (mul*rt[3])>>8;
990 if(icol>254) rt[3]= 255; else rt[3]= icol;
1000 rt_float[2] *= fmul;
1001 rt_float[3] *= fmul;
1008 static float give_stripelem_index(Sequence *seq, float cfra)
1011 int sta = seq->start;
1012 int end = seq->start+seq->len-1;
1014 if (seq->type & SEQ_EFFECT) {
1022 if(seq->flag&SEQ_REVERSE_FRAMES) {
1023 /*reverse frame in this sequence */
1024 if(cfra <= sta) nr= end - sta;
1025 else if(cfra >= end) nr= 0;
1026 else nr= end - cfra;
1028 if(cfra <= sta) nr= 0;
1029 else if(cfra >= end) nr= end - sta;
1030 else nr= cfra - sta;
1033 if (seq->strobe < 1.0f) seq->strobe = 1.0f;
1035 if (seq->strobe > 1.0f) {
1036 nr -= fmodf((double)nr, (double)seq->strobe);
1042 StripElem *give_stripelem(Sequence *seq, int cfra)
1044 StripElem *se= seq->strip->stripdata;
1046 if(seq->type == SEQ_IMAGE) { /* only
1047 IMAGE strips use the whole array,
1048 MOVIE strips use only
1049 the first element, all other strips
1050 don't use this... */
1051 int nr = (int) give_stripelem_index(seq, cfra);
1053 if (nr == -1 || se == NULL) return NULL;
1055 se += nr + seq->anim_startofs;
1060 static int evaluate_seq_frame_gen(Sequence ** seq_arr, ListBase *seqbase, int cfra)
1065 memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1));
1067 seq= seqbase->first;
1069 if(seq->startdisp <=cfra && seq->enddisp > cfra) {
1070 seq_arr[seq->machine]= seq;
1079 int evaluate_seq_frame(Scene *scene, int cfra)
1081 Editing *ed= seq_give_editing(scene, FALSE);
1082 Sequence *seq_arr[MAXSEQ+1];
1084 if(ed==NULL) return 0;
1085 return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
1088 static int video_seq_is_rendered(Sequence * seq)
1090 return (seq && !(seq->flag & SEQ_MUTE) && seq->type != SEQ_SOUND);
1093 static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
1095 Sequence *seq_arr[MAXSEQ+1];
1103 if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
1107 for (; b > 0; b--) {
1108 if (video_seq_is_rendered(seq_arr[b])) {
1117 if (video_seq_is_rendered(seq_arr[b])) {
1118 if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
1124 for (;b <= chanshown && b >= 0; b++) {
1125 if (video_seq_is_rendered(seq_arr[b])) {
1126 seq_arr_out[cnt++] = seq_arr[b];
1134 /* **********************************************************************
1136 ********************************************************************** */
1138 #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
1140 static IMB_Proxy_Size seq_rendersize_to_proxysize(int size)
1143 return IMB_PROXY_NONE;
1146 return IMB_PROXY_100;
1149 return IMB_PROXY_75;
1152 return IMB_PROXY_50;
1154 return IMB_PROXY_25;
1157 static void seq_open_anim_file(Sequence * seq)
1159 char name[FILE_MAX];
1162 if(seq->anim != NULL) {
1166 BLI_join_dirfile(name, sizeof(name),
1167 seq->strip->dir, seq->strip->stripdata->name);
1168 BLI_path_abs(name, G.main->name);
1170 seq->anim = openanim(name, IB_rect |
1171 ((seq->flag & SEQ_FILTERY) ?
1172 IB_animdeinterlace : 0), seq->streamindex);
1174 if (seq->anim == NULL) {
1178 proxy = seq->strip->proxy;
1180 if (proxy == NULL) {
1184 if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
1185 IMB_anim_set_index_dir(seq->anim, seq->strip->proxy->dir);
1190 static int seq_proxy_get_fname(SeqRenderData context, Sequence * seq, int cfra, char * name)
1193 char dir[PROXY_MAXFILE];
1194 int render_size = context.preview_render_size;
1196 if (!seq->strip->proxy) {
1200 /* MOVIE tracks (only exception: custom files) are now handled
1201 internally by ImBuf module for various reasons: proper time code
1202 support, quicker index build, using one file instead
1203 of a full directory of jpeg files, etc. Trying to support old
1204 and new method at once could lead to funny effects, if people
1205 have both, a directory full of jpeg files and proxy avis, so
1206 sorry folks, please rebuild your proxies... */
1208 if (seq->flag & (SEQ_USE_PROXY_CUSTOM_DIR|SEQ_USE_PROXY_CUSTOM_FILE)) {
1209 BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
1210 } else if (seq->type == SEQ_IMAGE) {
1211 BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir);
1216 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1217 BLI_join_dirfile(name, PROXY_MAXFILE,
1218 dir, seq->strip->proxy->file);
1219 BLI_path_abs(name, G.main->name);
1224 /* dirty hack to distinguish 100% render size from PROXY_100 */
1225 if (render_size == 99) {
1229 /* generate a separate proxy directory for each preview size */
1231 if (seq->type == SEQ_IMAGE) {
1232 BLI_snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy", dir,
1233 context.preview_render_size,
1234 give_stripelem(seq, cfra)->name);
1237 frameno = (int) give_stripelem_index(seq, cfra) + seq->anim_startofs;
1238 BLI_snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
1239 context.preview_render_size);
1242 BLI_path_abs(name, G.main->name);
1243 BLI_path_frame(name, frameno, 0);
1245 strcat(name, ".jpg");
1250 static struct ImBuf * seq_proxy_fetch(SeqRenderData context, Sequence * seq, int cfra)
1252 char name[PROXY_MAXFILE];
1253 IMB_Proxy_Size psize = seq_rendersize_to_proxysize(
1254 context.preview_render_size);
1257 if (!(seq->flag & SEQ_USE_PROXY)) {
1261 size_flags = seq->strip->proxy->build_size_flags;
1263 /* only use proxies, if they are enabled (even if present!) */
1264 if (psize == IMB_PROXY_NONE || ((size_flags & psize) != psize)) {
1268 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1269 int frameno = (int) give_stripelem_index(seq, cfra) + seq->anim_startofs;
1270 if (seq->strip->proxy->anim == NULL) {
1271 if (seq_proxy_get_fname(context, seq, cfra, name)==0) {
1275 seq->strip->proxy->anim = openanim(name, IB_rect, 0);
1277 if (seq->strip->proxy->anim==NULL) {
1281 seq_open_anim_file(seq);
1283 frameno = IMB_anim_index_get_frame_index(
1284 seq->anim, seq->strip->proxy->tc, frameno);
1286 return IMB_anim_absolute(seq->strip->proxy->anim, frameno,
1287 IMB_TC_NONE, IMB_PROXY_NONE);
1290 if (seq_proxy_get_fname(context, seq, cfra, name) == 0) {
1294 if (BLI_exists(name)) {
1295 return IMB_loadiffname(name, IB_rect);
1301 static void seq_proxy_build_frame(SeqRenderData context,
1302 Sequence* seq, int cfra,
1303 int proxy_render_size)
1305 char name[PROXY_MAXFILE];
1309 struct ImBuf * ibuf;
1311 if (!seq_proxy_get_fname(context, seq, cfra, name)) {
1315 ibuf = seq_render_strip(context, seq, cfra);
1317 rectx = (proxy_render_size * context.scene->r.xsch) / 100;
1318 recty = (proxy_render_size * context.scene->r.ysch) / 100;
1320 if (ibuf->x != rectx || ibuf->y != recty) {
1321 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1324 /* depth = 32 is intentionally left in, otherwise ALPHA channels
1326 quality = seq->strip->proxy->quality;
1327 ibuf->ftype= JPG | quality;
1329 /* unsupported feature only confuses other s/w */
1330 if(ibuf->planes==32)
1333 BLI_make_existing_file(name);
1335 ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
1340 IMB_freeImBuf(ibuf);
1343 void seq_proxy_rebuild(struct Main * bmain, Scene *scene, Sequence * seq,
1344 short *stop, short *do_update, float *progress)
1346 SeqRenderData context;
1352 if (!seq->strip || !seq->strip->proxy) {
1356 if (!(seq->flag & SEQ_USE_PROXY)) {
1360 tc_flags = seq->strip->proxy->build_tc_flags;
1361 size_flags = seq->strip->proxy->build_size_flags;
1362 quality = seq->strip->proxy->quality;
1364 if (seq->type == SEQ_MOVIE) {
1365 seq_open_anim_file(seq);
1368 IMB_anim_index_rebuild(
1369 seq->anim, tc_flags, size_flags, quality,
1370 stop, do_update, progress);
1375 if (!(seq->flag & SEQ_USE_PROXY)) {
1379 /* that's why it is called custom... */
1380 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1384 /* fail safe code */
1386 context = seq_new_render_data(
1388 (scene->r.size * (float) scene->r.xsch) / 100.0f + 0.5f,
1389 (scene->r.size * (float) scene->r.ysch) / 100.0f + 0.5f,
1392 for (cfra = seq->startdisp + seq->startstill;
1393 cfra < seq->enddisp - seq->endstill; cfra++) {
1394 if (size_flags & IMB_PROXY_25) {
1395 seq_proxy_build_frame(context, seq, cfra, 25);
1397 if (size_flags & IMB_PROXY_50) {
1398 seq_proxy_build_frame(context, seq, cfra, 50);
1400 if (size_flags & IMB_PROXY_75) {
1401 seq_proxy_build_frame(context, seq, cfra, 75);
1403 if (size_flags & IMB_PROXY_100) {
1404 seq_proxy_build_frame(context, seq, cfra, 100);
1407 *progress= (float)cfra/(seq->enddisp - seq->endstill
1408 - seq->startdisp + seq->startstill);
1411 if(*stop || G.afbreek)
1417 /* **********************************************************************
1419 ********************************************************************** */
1421 static StripColorBalance calc_cb(StripColorBalance * cb_)
1423 StripColorBalance cb = *cb_;
1426 for (c = 0; c < 3; c++) {
1427 cb.lift[c] = 2.0f - cb.lift[c];
1430 if(cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
1431 for (c = 0; c < 3; c++) {
1432 /* tweak to give more subtle results
1433 * values above 1.0 are scaled */
1434 if(cb.lift[c] > 1.0f)
1435 cb.lift[c] = pow(cb.lift[c] - 1.0f, 2.0) + 1.0;
1437 cb.lift[c] = 2.0f - cb.lift[c];
1441 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
1442 for (c = 0; c < 3; c++) {
1443 if (cb.gain[c] != 0.0f) {
1444 cb.gain[c] = 1.0f / cb.gain[c];
1446 cb.gain[c] = 1000000; /* should be enough :) */
1451 if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
1452 for (c = 0; c < 3; c++) {
1453 if (cb.gamma[c] != 0.0f) {
1454 cb.gamma[c] = 1.0f/cb.gamma[c];
1456 cb.gamma[c] = 1000000; /* should be enough :) */
1464 /* note: lift is actually 2-lift */
1465 MINLINE float color_balance_fl(float in, const float lift, const float gain, const float gamma, const float mul)
1467 float x= (((in - 1.0f) * lift) + 1.0f) * gain;
1470 if (x < 0.f) x = 0.f;
1472 return powf(x, gamma) * mul;
1475 static void make_cb_table_byte(float lift, float gain, float gamma,
1476 unsigned char * table, float mul)
1480 for (y = 0; y < 256; y++) {
1481 float v= color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
1482 CLAMP(v, 0.0f, 1.0f);
1487 static void make_cb_table_float(float lift, float gain, float gamma,
1488 float * table, float mul)
1492 for (y = 0; y < 256; y++) {
1493 float v= color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
1498 static void color_balance_byte_byte(Sequence * seq, ImBuf* ibuf, float mul)
1500 unsigned char cb_tab[3][256];
1502 unsigned char * p = (unsigned char*) ibuf->rect;
1503 unsigned char * e = p + ibuf->x * 4 * ibuf->y;
1505 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1507 for (c = 0; c < 3; c++) {
1508 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1513 p[0] = cb_tab[0][p[0]];
1514 p[1] = cb_tab[1][p[1]];
1515 p[2] = cb_tab[2][p[2]];
1521 static void color_balance_byte_float(Sequence * seq, ImBuf* ibuf, float mul)
1523 float cb_tab[4][256];
1525 unsigned char * p = (unsigned char*) ibuf->rect;
1526 unsigned char * e = p + ibuf->x * 4 * ibuf->y;
1528 StripColorBalance cb;
1530 imb_addrectfloatImBuf(ibuf);
1532 o = ibuf->rect_float;
1534 cb = calc_cb(seq->strip->color_balance);
1536 for (c = 0; c < 3; c++) {
1537 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
1540 for (i = 0; i < 256; i++) {
1541 cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
1545 o[0] = cb_tab[0][p[0]];
1546 o[1] = cb_tab[1][p[1]];
1547 o[2] = cb_tab[2][p[2]];
1548 o[3] = cb_tab[3][p[3]];
1554 static void color_balance_float_float(Sequence * seq, ImBuf* ibuf, float mul)
1556 float * p = ibuf->rect_float;
1557 float * e = ibuf->rect_float + ibuf->x * 4* ibuf->y;
1558 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1562 for (c = 0; c < 3; c++) {
1563 p[c]= color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
1569 static void color_balance(Sequence * seq, ImBuf* ibuf, float mul)
1571 if (ibuf->rect_float) {
1572 color_balance_float_float(seq, ibuf, mul);
1573 } else if(seq->flag & SEQ_MAKE_FLOAT) {
1574 color_balance_byte_float(seq, ibuf, mul);
1576 color_balance_byte_byte(seq, ibuf, mul);
1581 input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
1583 Do all the things you can't really do afterwards using sequence effects
1584 (read: before rescaling to render resolution has been done)
1589 - Crop and transform in image source coordinate space
1590 - Flip X + Flip Y (could be done afterwards, backward compatibility)
1591 - Promote image to float data (affects pipeline operations afterwards)
1592 - Color balance (is most efficient in the byte -> float
1593 (future: half -> float should also work fine!)
1594 case, if done on load, since we can use lookup tables)
1599 int input_have_to_preprocess(
1600 SeqRenderData UNUSED(context), Sequence * seq, float UNUSED(cfra))
1604 if (seq->flag & (SEQ_FILTERY|SEQ_USE_CROP|SEQ_USE_TRANSFORM|SEQ_FLIPX|
1605 SEQ_FLIPY|SEQ_USE_COLOR_BALANCE|SEQ_MAKE_PREMUL)) {
1611 if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1612 mul *= seq->blend_opacity / 100.0f;
1619 if (seq->sat != 1.0f) {
1626 static ImBuf * input_preprocess(
1627 SeqRenderData context, Sequence *seq, float UNUSED(cfra), ImBuf * ibuf)
1631 ibuf = IMB_makeSingleUser(ibuf);
1633 if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
1637 if(seq->flag & (SEQ_USE_CROP|SEQ_USE_TRANSFORM)) {
1639 StripTransform t= {0};
1642 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1643 c = *seq->strip->crop;
1645 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1646 t = *seq->strip->transform;
1649 sx = ibuf->x - c.left - c.right;
1650 sy = ibuf->y - c.top - c.bottom;
1654 if (seq->flag & SEQ_USE_TRANSFORM) {
1655 dx = context.scene->r.xsch;
1656 dy = context.scene->r.ysch;
1659 if (c.top + c.bottom >= ibuf->y || c.left + c.right >= ibuf->x ||
1660 t.xofs >= dx || t.yofs >= dy) {
1661 make_black_ibuf(ibuf);
1663 ImBuf * i = IMB_allocImBuf(dx, dy,32, ibuf->rect_float ? IB_rectfloat : IB_rect);
1665 IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
1667 IMB_freeImBuf(ibuf);
1673 if(seq->flag & SEQ_FLIPX) {
1677 if(seq->flag & SEQ_FLIPY) {
1681 if(seq->sat != 1.0f) {
1682 /* inline for now, could become an imbuf function */
1684 unsigned char *rct= (unsigned char *)ibuf->rect;
1685 float *rctf= ibuf->rect_float;
1686 const float sat= seq->sat;
1691 for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) {
1692 rgb_byte_to_float(rct, rgb);
1693 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
1694 hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb+1, rgb+2);
1695 rgb_float_to_byte(rgb, rct);
1700 for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) {
1701 rgb_to_hsv(rctf[0], rctf[1], rctf[2], hsv, hsv+1, hsv+2);
1702 hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rctf, rctf+1, rctf+2);
1709 if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1710 mul *= seq->blend_opacity / 100.0f;
1713 if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1714 color_balance(seq, ibuf, mul);
1718 if(seq->flag & SEQ_MAKE_FLOAT) {
1719 if (!ibuf->rect_float)
1720 IMB_float_from_rect_simple(ibuf);
1723 imb_freerectImBuf(ibuf);
1728 multibuf(ibuf, mul);
1731 if(seq->flag & SEQ_MAKE_PREMUL) {
1732 if(ibuf->planes == 32 && ibuf->zbuf == NULL) {
1733 IMB_premultiply_alpha(ibuf);
1738 if(ibuf->x != context.rectx || ibuf->y != context.recty ) {
1739 if(context.scene->r.mode & R_OSA) {
1740 IMB_scaleImBuf(ibuf, (short)context.rectx, (short)context.recty);
1742 IMB_scalefastImBuf(ibuf, (short)context.rectx, (short)context.recty);
1748 static ImBuf * copy_from_ibuf_still(SeqRenderData context, Sequence * seq,
1751 ImBuf * rval = NULL;
1752 ImBuf * ibuf = NULL;
1755 ibuf = seq_stripelem_cache_get(
1756 context, seq, seq->start,
1757 SEQ_STRIPELEM_IBUF_STARTSTILL);
1758 } else if (nr == seq->len - 1) {
1759 ibuf = seq_stripelem_cache_get(
1760 context, seq, seq->start,
1761 SEQ_STRIPELEM_IBUF_ENDSTILL);
1765 rval = IMB_dupImBuf(ibuf);
1766 IMB_freeImBuf(ibuf);
1772 static void copy_to_ibuf_still(SeqRenderData context, Sequence * seq, float nr,
1775 if (nr == 0 || nr == seq->len - 1) {
1776 /* we have to store a copy, since the passed ibuf
1777 could be preprocessed afterwards (thereby silently
1778 changing the cached image... */
1779 ibuf = IMB_dupImBuf(ibuf);
1782 seq_stripelem_cache_put(
1783 context, seq, seq->start,
1784 SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf);
1787 if (nr == seq->len - 1) {
1788 seq_stripelem_cache_put(
1789 context, seq, seq->start,
1790 SEQ_STRIPELEM_IBUF_ENDSTILL, ibuf);
1793 IMB_freeImBuf(ibuf);
1797 /* **********************************************************************
1798 strip rendering functions
1799 ********************************************************************** */
1801 static ImBuf* seq_render_strip_stack(
1802 SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown);
1804 static ImBuf * seq_render_strip(
1805 SeqRenderData context, Sequence * seq, float cfra);
1808 static ImBuf* seq_render_effect_strip_impl(
1809 SeqRenderData context, Sequence *seq, float cfra)
1814 struct SeqEffectHandle sh = get_sequence_effect(seq);
1820 ibuf[0] = ibuf[1] = ibuf[2] = NULL;
1822 input[0] = seq->seq1; input[1] = seq->seq2; input[2] = seq->seq3;
1824 if (!sh.execute) { /* effect not supported in this version... */
1825 out = IMB_allocImBuf((short)context.rectx,
1826 (short)context.recty, 32, IB_rect);
1830 if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
1831 sh.get_default_fac(seq, cfra, &fac, &facf);
1833 if ((context.scene->r.mode & R_FIELDS)==0)
1837 fcu = id_data_find_fcurve(&context.scene->id, seq, &RNA_Sequence, "effect_fader", 0, NULL);
1839 fac = facf = evaluate_fcurve(fcu, cfra);
1840 if( context.scene->r.mode & R_FIELDS ) {
1841 facf = evaluate_fcurve(fcu, cfra + 0.5f);
1844 fac = facf = seq->effect_fader;
1848 early_out = sh.early_out(seq, fac, facf);
1850 switch (early_out) {
1851 case EARLY_NO_INPUT:
1852 out = sh.execute(context, seq, cfra, fac, facf,
1855 case EARLY_DO_EFFECT:
1856 for(i=0; i<3; i++) {
1858 ibuf[i] = seq_render_strip(
1859 context, input[i], cfra);
1862 if (ibuf[0] && ibuf[1]) {
1863 out = sh.execute(context, seq, cfra, fac, facf,
1864 ibuf[0], ibuf[1], ibuf[2]);
1867 case EARLY_USE_INPUT_1:
1869 ibuf[0] = seq_render_strip(context, input[0], cfra);
1872 if (input_have_to_preprocess(context, seq, cfra)) {
1873 out = IMB_dupImBuf(ibuf[0]);
1880 case EARLY_USE_INPUT_2:
1882 ibuf[1] = seq_render_strip(context, input[1], cfra);
1885 if (input_have_to_preprocess(context, seq, cfra)) {
1886 out = IMB_dupImBuf(ibuf[1]);
1895 for (i = 0; i < 3; i++) {
1896 IMB_freeImBuf(ibuf[i]);
1900 out = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect);
1907 static ImBuf * seq_render_scene_strip_impl(
1908 SeqRenderData context, Sequence * seq, float nr)
1910 ImBuf * ibuf = NULL;
1911 float frame= seq->sfra + nr + seq->anim_startofs;
1914 ListBase oldmarkers;
1917 Hack! This function can be called from do_render_seq(), in that case
1918 the seq->scene can already have a Render initialized with same name,
1919 so we have to use a default name. (compositor uses scene name to
1921 However, when called from within the UI (image preview in sequencer)
1922 we do want to use scene Render, that way the render result is defined
1923 for display in render/imagewindow
1925 Hmm, don't see, why we can't do that all the time,
1926 and since G.rendering is uhm, gone... (Peter)
1930 Using the same name for the renders works just fine as the do_render_seq()
1931 render is not used while the scene strips are rendered.
1933 However rendering from UI (through sequencer_preview_area_draw) can crash in
1934 very many cases since other renders (material preview, an actual render etc.)
1935 can be started while this sequence preview render is running. The only proper
1936 solution is to make the sequencer preview render a proper job, which can be
1937 stopped when needed. This would also give a nice progress bar for the preview
1938 space so that users know there's something happening.
1940 As a result the active scene now only uses OpenGL rendering for the sequencer
1941 preview. This is far from nice, but is the only way to prevent crashes at this
1947 int rendering = G.rendering;
1949 int doseq_gl= G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : /*(scene->r.seq_flag & R_SEQ_GL_PREV)*/ 1;
1950 int have_seq= FALSE;
1953 /* dont refer to seq->scene above this point!, it can be NULL */
1954 if(seq->scene == NULL) {
1960 have_seq= (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first;
1962 oldcfra= scene->r.cfra;
1963 scene->r.cfra= frame;
1965 if(seq->scene_camera)
1966 camera= seq->scene_camera;
1968 scene_camera_switch_update(scene);
1969 camera= scene->camera;
1972 if(have_seq==FALSE && camera==NULL) {
1973 scene->r.cfra= oldcfra;
1977 /* prevent eternal loop */
1978 doseq= context.scene->r.scemode & R_DOSEQ;
1979 context.scene->r.scemode &= ~R_DOSEQ;
1981 #ifdef DURIAN_CAMERA_SWITCH
1982 /* stooping to new low's in hackyness :( */
1983 oldmarkers= scene->markers;
1984 scene->markers.first= scene->markers.last= NULL;
1989 if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (scene == context.scene || have_seq==0) && camera) {
1990 char err_out[256]= "unknown";
1991 /* for old scened this can be uninitialized, should probably be added to do_versions at some point if the functionality stays */
1992 if(context.scene->r.seq_prev_type==0)
1993 context.scene->r.seq_prev_type = 3 /* ==OB_SOLID */;
1995 /* opengl offscreen render */
1996 scene_update_for_newframe(context.bmain, scene, scene->lay);
1997 ibuf= sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect, context.scene->r.seq_prev_type, err_out);
1999 fprintf(stderr, "seq_render_scene_strip_impl failed to get opengl buffer: %s\n", err_out);
2003 Render *re = RE_GetRender(scene->id.name);
2006 /* XXX: this if can be removed when sequence preview rendering uses the job system */
2007 if(rendering || context.scene != scene) {
2009 re= RE_NewRender(scene->id.name);
2011 RE_BlenderFrame(re, context.bmain, scene, NULL, camera, scene->lay, frame, FALSE);
2013 /* restore previous state after it was toggled on & off by RE_BlenderFrame */
2014 G.rendering = rendering;
2017 RE_AcquireResultImage(re, &rres);
2020 ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat);
2021 memcpy(ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
2023 addzbuffloatImBuf(ibuf);
2024 memcpy(ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
2027 /* float buffers in the sequencer are not linear */
2028 ibuf->profile= IB_PROFILE_LINEAR_RGB;
2029 IMB_convert_profile(ibuf, IB_PROFILE_SRGB);
2031 else if (rres.rect32) {
2032 ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect);
2033 memcpy(ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
2036 RE_ReleaseResultImage(re);
2038 // BIF_end_render_callbacks();
2042 context.scene->r.scemode |= doseq;
2044 scene->r.cfra = oldcfra;
2046 if(frame != oldcfra)
2047 scene_update_for_newframe(context.bmain, scene, scene->lay);
2049 #ifdef DURIAN_CAMERA_SWITCH
2050 /* stooping to new low's in hackyness :( */
2051 scene->markers= oldmarkers;
2057 static ImBuf * seq_render_strip(SeqRenderData context, Sequence * seq, float cfra)
2059 ImBuf * ibuf = NULL;
2060 char name[FILE_MAX];
2061 int use_preprocess = input_have_to_preprocess(context, seq, cfra);
2062 float nr = give_stripelem_index(seq, cfra);
2063 /* all effects are handled similarly with the exception of speed effect */
2064 int type = (seq->type & SEQ_EFFECT && seq->type != SEQ_SPEED) ? SEQ_EFFECT : seq->type;
2066 ibuf = seq_stripelem_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
2068 /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF,
2069 but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL */
2071 use_preprocess = FALSE;
2074 ibuf = copy_from_ibuf_still(context, seq, nr);
2077 ibuf = seq_proxy_fetch(context, seq, cfra);
2079 if(ibuf == NULL) switch(type) {
2082 ImBuf * meta_ibuf = NULL;
2084 if(seq->seqbase.first)
2085 meta_ibuf = seq_render_strip_stack(
2086 context, &seq->seqbase,
2087 seq->start + nr, 0);
2091 if(ibuf && use_preprocess) {
2092 struct ImBuf * i = IMB_dupImBuf(ibuf);
2094 IMB_freeImBuf(ibuf);
2103 ImBuf * child_ibuf = NULL;
2106 SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
2108 sequence_effect_speed_rebuild_map(context.scene,seq, 0);
2111 f_cfra = seq->start + s->frameMap[(int) nr];
2113 child_ibuf = seq_render_strip(context,seq->seq1,f_cfra);
2117 if(ibuf && use_preprocess) {
2118 struct ImBuf * i = IMB_dupImBuf(ibuf);
2120 IMB_freeImBuf(ibuf);
2129 ibuf = seq_render_effect_strip_impl(
2130 context, seq, seq->start + nr);
2135 StripElem * s_elem = give_stripelem(seq, cfra);
2138 BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
2139 BLI_path_abs(name, G.main->name);
2142 if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) {
2143 /* we don't need both (speed reasons)! */
2144 if (ibuf->rect_float && ibuf->rect)
2145 imb_freerectImBuf(ibuf);
2147 /* all sequencer color is done in SRGB space, linear gives odd crossfades */
2148 if(ibuf->profile == IB_PROFILE_LINEAR_RGB)
2149 IMB_convert_profile(ibuf, IB_PROFILE_NONE);
2151 copy_to_ibuf_still(context, seq, nr, ibuf);
2153 s_elem->orig_width = ibuf->x;
2154 s_elem->orig_height = ibuf->y;
2160 seq_open_anim_file(seq);
2163 IMB_anim_set_preseek(seq->anim,
2166 ibuf = IMB_anim_absolute(
2167 seq->anim, nr + seq->anim_startofs,
2169 seq->strip->proxy->tc
2170 : IMB_TC_RECORD_RUN,
2171 seq_rendersize_to_proxysize(
2172 context.preview_render_size));
2174 /* we don't need both (speed reasons)! */
2175 if (ibuf && ibuf->rect_float && ibuf->rect)
2176 imb_freerectImBuf(ibuf);
2178 seq->strip->stripdata->orig_width = ibuf->x;
2179 seq->strip->stripdata->orig_height = ibuf->y;
2182 copy_to_ibuf_still(context, seq, nr, ibuf);
2186 { // scene can be NULL after deletions
2187 ibuf = seq_render_scene_strip_impl(context, seq, nr);
2189 /* Scene strips update all animation, so we need to restore original state.*/
2190 BKE_animsys_evaluate_all_animation(context.bmain, context.scene, cfra);
2192 copy_to_ibuf_still(context, seq, nr, ibuf);
2198 ibuf = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect);
2200 if (ibuf->x != context.rectx || ibuf->y != context.recty)
2201 use_preprocess = TRUE;
2204 ibuf = input_preprocess(context, seq, cfra, ibuf);
2206 seq_stripelem_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
2211 /* **********************************************************************
2212 strip stack rendering functions
2213 ********************************************************************** */
2215 static int seq_must_swap_input_in_blend_mode(Sequence * seq)
2217 int swap_input = FALSE;
2219 /* bad hack, to fix crazy input ordering of
2220 those two effects */
2222 if (ELEM3(seq->blend_mode, SEQ_ALPHAOVER, SEQ_ALPHAUNDER, SEQ_OVERDROP)) {
2229 static int seq_get_early_out_for_blend_mode(Sequence * seq)
2231 struct SeqEffectHandle sh = get_sequence_blend(seq);
2232 float facf = seq->blend_opacity / 100.0f;
2233 int early_out = sh.early_out(seq, facf, facf);
2235 if (ELEM(early_out, EARLY_DO_EFFECT, EARLY_NO_INPUT)) {
2239 if (seq_must_swap_input_in_blend_mode(seq)) {
2240 if (early_out == EARLY_USE_INPUT_2) {
2241 return EARLY_USE_INPUT_1;
2242 } else if (early_out == EARLY_USE_INPUT_1) {
2243 return EARLY_USE_INPUT_2;
2249 static ImBuf* seq_render_strip_stack(
2250 SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown)
2252 Sequence* seq_arr[MAXSEQ+1];
2257 count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
2263 #if 0 /* commentind since this breaks keyframing, since it resets the value on draw */
2264 if(scene->r.cfra != cfra) {
2265 // XXX for prefetch and overlay offset!..., very bad!!!
2266 AnimData *adt= BKE_animdata_from_id(&scene->id);
2267 BKE_animsys_evaluate_animdata(scene, &scene->id, adt, cfra, ADT_RECALC_ANIM);
2271 out = seq_stripelem_cache_get(context, seq_arr[count - 1],
2272 cfra, SEQ_STRIPELEM_IBUF_COMP);
2279 out = seq_render_strip(context, seq_arr[0], cfra);
2280 seq_stripelem_cache_put(context, seq_arr[0], cfra,
2281 SEQ_STRIPELEM_IBUF_COMP, out);
2287 for (i = count - 1; i >= 0; i--) {
2289 Sequence *seq = seq_arr[i];
2291 out = seq_stripelem_cache_get(
2292 context, seq, cfra, SEQ_STRIPELEM_IBUF_COMP);
2297 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2298 out = seq_render_strip(context, seq, cfra);
2302 early_out = seq_get_early_out_for_blend_mode(seq);
2304 switch (early_out) {
2305 case EARLY_NO_INPUT:
2306 case EARLY_USE_INPUT_2:
2307 out = seq_render_strip(context, seq, cfra);
2309 case EARLY_USE_INPUT_1:
2311 out = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect);
2314 case EARLY_DO_EFFECT:
2316 out = seq_render_strip(context, seq, cfra);
2326 seq_stripelem_cache_put(context, seq_arr[i], cfra,
2327 SEQ_STRIPELEM_IBUF_COMP, out);
2332 for (; i < count; i++) {
2333 Sequence * seq = seq_arr[i];
2335 if (seq_get_early_out_for_blend_mode(seq) == EARLY_DO_EFFECT) {
2336 struct SeqEffectHandle sh = get_sequence_blend(seq);
2337 ImBuf * ibuf1 = out;
2338 ImBuf * ibuf2 = seq_render_strip(context, seq, cfra);
2340 float facf = seq->blend_opacity / 100.0f;
2341 int swap_input = seq_must_swap_input_in_blend_mode(seq);
2344 out = sh.execute(context, seq, cfra,
2346 ibuf2, ibuf1, NULL);
2348 out = sh.execute(context, seq, cfra,
2350 ibuf1, ibuf2, NULL);
2353 IMB_freeImBuf(ibuf1);
2354 IMB_freeImBuf(ibuf2);
2357 seq_stripelem_cache_put(context, seq_arr[i], cfra,
2358 SEQ_STRIPELEM_IBUF_COMP, out);
2365 * returned ImBuf is refed!
2366 * you have to free after usage!
2369 ImBuf *give_ibuf_seq(SeqRenderData context, float cfra, int chanshown)
2371 Editing *ed= seq_give_editing(context.scene, FALSE);
2375 if(ed==NULL) return NULL;
2377 count = BLI_countlist(&ed->metastack);
2378 if((chanshown < 0) && (count > 0)) {
2379 count = MAX2(count + chanshown, 0);
2380 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2382 seqbasep= ed->seqbasep;
2385 return seq_render_strip_stack(context, seqbasep, cfra, chanshown);
2388 ImBuf *give_ibuf_seqbase(SeqRenderData context, float cfra, int chanshown, ListBase *seqbasep)
2390 return seq_render_strip_stack(context, seqbasep, cfra, chanshown);
2394 ImBuf *give_ibuf_seq_direct(SeqRenderData context, float cfra, Sequence *seq)
2396 return seq_render_strip(context, seq, cfra);
2400 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2401 static int seq_can_blend(Sequence *seq)
2403 if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2411 /* *********************** threading api ******************* */
2413 static ListBase running_threads;
2414 static ListBase prefetch_wait;
2415 static ListBase prefetch_done;
2417 static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
2418 static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER;
2419 static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
2421 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2422 //static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2424 static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
2425 static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
2427 static volatile int seq_thread_shutdown = TRUE;
2428 static volatile int seq_last_given_monoton_cfra = 0;
2429 static int monoton_cfra = 0;
2431 typedef struct PrefetchThread {
2432 struct PrefetchThread *next, *prev;
2435 struct PrefetchQueueElem *current;
2441 typedef struct PrefetchQueueElem {
2442 struct PrefetchQueueElem *next, *prev;
2448 int preview_render_size;
2452 struct ImBuf * ibuf;
2453 } PrefetchQueueElem;
2456 static void *seq_prefetch_thread(void * This_)
2458 PrefetchThread * This = This_;
2460 while (!seq_thread_shutdown) {
2461 PrefetchQueueElem *e;
2464 pthread_mutex_lock(&queue_lock);
2465 e = prefetch_wait.first;
2467 BLI_remlink(&prefetch_wait, e);
2469 s_last = seq_last_given_monoton_cfra;
2473 pthread_mutex_unlock(&queue_lock);
2476 pthread_mutex_lock(&prefetch_ready_lock);
2478 This->running = FALSE;
2480 pthread_cond_signal(&prefetch_ready_cond);
2481 pthread_mutex_unlock(&prefetch_ready_lock);
2483 pthread_mutex_lock(&wakeup_lock);
2484 if (!seq_thread_shutdown) {
2485 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2487 pthread_mutex_unlock(&wakeup_lock);
2491 This->running = TRUE;
2493 if (e->cfra >= s_last) {
2494 e->ibuf = give_ibuf_seq_impl(This->scene,
2495 e->rectx, e->recty, e->cfra, e->chanshown,
2496 e->preview_render_size);
2499 pthread_mutex_lock(&queue_lock);
2501 BLI_addtail(&prefetch_done, e);
2503 for (e = prefetch_wait.first; e; e = e->next) {
2504 if (s_last > e->monoton_cfra) {
2505 BLI_remlink(&prefetch_wait, e);
2510 for (e = prefetch_done.first; e; e = e->next) {
2511 if (s_last > e->monoton_cfra) {
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) {
2589 BLI_remlink(&prefetch_done, e);
2593 BLI_freelistN(&running_threads);
2595 /* deinit malloc mutex */
2600 void give_ibuf_prefetch_request(SeqRenderData context, float cfra, int chanshown)
2602 PrefetchQueueElem *e;
2603 if (seq_thread_shutdown) {
2607 e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2608 e->rectx = context.rectx;
2609 e->recty = context.recty;
2611 e->chanshown = chanshown;
2612 e->preview_render_size = context.preview_render_size;
2613 e->monoton_cfra = monoton_cfra++;
2615 pthread_mutex_lock(&queue_lock);
2616 BLI_addtail(&prefetch_wait, e);
2617 pthread_mutex_unlock(&queue_lock);
2619 pthread_mutex_lock(&wakeup_lock);
2620 pthread_cond_signal(&wakeup_cond);
2621 pthread_mutex_unlock(&wakeup_lock);
2625 static void seq_wait_for_prefetch_ready()
2627 PrefetchThread *tslot;
2629 if (seq_thread_shutdown) {
2633 fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
2635 pthread_mutex_lock(&prefetch_ready_lock);
2638 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2639 if (tslot->running) {
2646 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
2649 pthread_mutex_unlock(&prefetch_ready_lock);
2651 fprintf(stderr, "SEQ-THREAD: prefetch done\n");
2655 ImBuf *give_ibuf_seq_threaded(SeqRenderData context, float cfra, int chanshown)
2657 PrefetchQueueElem *e = NULL;
2658 int found_something = FALSE;
2660 if (seq_thread_shutdown) {
2661 return give_ibuf_seq(context, cfra, chanshown);
2665 int success = FALSE;
2666 pthread_mutex_lock(&queue_lock);
2668 for (e = prefetch_done.first; e; e = e->next) {
2669 if (cfra == e->cfra &&
2670 chanshown == e->chanshown &&
2671 context.rectx == e->rectx &&
2672 context.recty == e->recty &&
2673 context.preview_render_size == e->preview_render_size) {
2675 found_something = TRUE;
2681 for (e = prefetch_wait.first; e; e = e->next) {
2682 if (cfra == e->cfra &&
2683 chanshown == e->chanshown &&
2684 context.rectx == e->rectx &&
2685 context.recty == e->recty &&
2686 context.preview_render_size == e->preview_render_size) {
2687 found_something = TRUE;
2694 PrefetchThread *tslot;
2696 for(tslot = running_threads.first;
2697 tslot; tslot= tslot->next) {
2698 if (tslot->current &&
2699 cfra == tslot->current->cfra &&
2700 chanshown == tslot->current->chanshown &&
2701 context.rectx == tslot->current->rectx &&
2702 context.recty == tslot->current->recty &&
2703 context.preview_render_size== tslot->current->preview_render_size){
2704 found_something = TRUE;
2710 /* e->ibuf is unrefed by render thread on next round. */
2713 seq_last_given_monoton_cfra = e->monoton_cfra;
2716 pthread_mutex_unlock(&queue_lock);
2721 if (!found_something) {
2723 "SEQ-THREAD: Requested frame "
2724 "not in queue ???\n");
2727 pthread_mutex_lock(&frame_done_lock);
2728 pthread_cond_wait(&frame_done_cond, &frame_done_lock);
2729 pthread_mutex_unlock(&frame_done_lock);
2733 return e ? e->ibuf : NULL;
2736 /* Functions to free imbuf and anim data on changes */
2738 static void free_anim_seq(Sequence *seq)
2741 IMB_free_anim(seq->anim);
2746 void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage,
2747 int keep_file_handles)
2751 if (check_mem_usage) {
2752 /* Let the cache limitor take care of this (schlaile) */
2753 /* While render let's keep all memory available for render
2755 At least if free memory is tight...
2756 This can make a big difference in encoding speed
2757 (it is around 4 times(!) faster, if we do not waste time
2758 on freeing _all_ buffers every time on long timelines...)
2762 uintptr_t mem_in_use;
2763 uintptr_t mmap_in_use;
2766 mem_in_use= MEM_get_memory_in_use();
2767 mmap_in_use= MEM_get_mapped_memory_in_use();
2768 max = MEM_CacheLimiter_get_maximum();
2770 if (max == 0 || mem_in_use + mmap_in_use <= max) {
2775 seq_stripelem_cache_cleanup();
2777 for(seq= seqbase->first; seq; seq= seq->next) {
2779 if(seq->type==SEQ_MOVIE && !keep_file_handles)
2781 if(seq->type==SEQ_SPEED) {
2782 sequence_effect_speed_rebuild_map(scene, seq, 1);
2785 if(seq->type==SEQ_META) {
2786 free_imbuf_seq(scene, &seq->seqbase, FALSE, keep_file_handles);
2788 if(seq->type==SEQ_SCENE) {
2789 /* FIXME: recurs downwards,
2790 but do recurs protection somehow! */
2796 static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
2801 /* recurs downwards to see if this seq depends on the changed seq */
2806 if(seq == changed_seq)
2809 for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
2810 if(update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change))
2814 if(update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change))
2816 if(seq->seq2 && (seq->seq2 != seq->seq1))
2817 if(update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change))
2819 if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
2820 if(update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change))
2825 if(seq->type == SEQ_MOVIE)
2827 if(seq->type == SEQ_SPEED) {
2828 sequence_effect_speed_rebuild_map(scene, seq, 1);
2833 calc_sequence(scene, seq);
2839 void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
2841 Editing *ed= seq_give_editing(scene, FALSE);
2844 if (ed==NULL) return;
2846 for (seq=ed->seqbase.first; seq; seq=seq->next)
2847 update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change);
2850 /* seq funcs's for transforming internally
2851 notice the difference between start/end and left/right.
2853 left and right are the bounds at which the sequence is rendered,
2854 start and end are from the start and fixed length of the sequence.
2856 int seq_tx_get_start(Sequence *seq)
2860 int seq_tx_get_end(Sequence *seq)
2862 return seq->start+seq->len;
2865 int seq_tx_get_final_left(Sequence *seq, int metaclip)
2867 if (metaclip && seq->tmp) {
2868 /* return the range clipped by the parents range */
2869 return MAX2( seq_tx_get_final_left(seq, 0), seq_tx_get_final_left((Sequence *)seq->tmp, 1) );
2871 return (seq->start - seq->startstill) + seq->startofs;
2875 int seq_tx_get_final_right(Sequence *seq, int metaclip)
2877 if (metaclip && seq->tmp) {
2878 /* return the range clipped by the parents range */
2879 return MIN2( seq_tx_get_final_right(seq, 0), seq_tx_get_final_right((Sequence *)seq->tmp, 1) );
2881 return ((seq->start+seq->len) + seq->endstill) - seq->endofs;
2885 void seq_tx_set_final_left(Sequence *seq, int val)
2887 if (val < (seq)->start) {
2888 seq->startstill = abs(val - (seq)->start);
2891 seq->startofs = abs(val - (seq)->start);
2892 seq->startstill = 0;
2896 void seq_tx_set_final_right(Sequence *seq, int val)
2898 if (val > (seq)->start + (seq)->len) {
2899 seq->endstill = abs(val - (seq->start + (seq)->len));
2902 seq->endofs = abs(val - ((seq)->start + (seq)->len));
2907 /* used so we can do a quick check for single image seq
2908 since they work a bit differently to normal image seq's (during transform) */
2909 int seq_single_check(Sequence *seq)
2911 return (seq->len==1 && (
2912 seq->type == SEQ_IMAGE
2913 || ((seq->type & SEQ_EFFECT) &&
2914 get_sequence_effect_num_inputs(seq->type) == 0)));
2917 /* check if the selected seq's reference unselected seq's */
2918 int seqbase_isolated_sel_check(ListBase *seqbase)
2921 /* is there more than 1 select */
2924 for(seq= seqbase->first; seq; seq= seq->next) {
2925 if(seq->flag & SELECT) {
2934 /* test relationships */
2935 for(seq= seqbase->first; seq; seq= seq->next) {
2936 if((seq->type & SEQ_EFFECT)==0)
2939 if(seq->flag & SELECT) {
2940 if( (seq->seq1 && (seq->seq1->flag & SELECT)==0) ||
2941 (seq->seq2 && (seq->seq2->flag & SELECT)==0) ||
2942 (seq->seq3 && (seq->seq3->flag & SELECT)==0) )
2946 if( (seq->seq1 && (seq->seq1->flag & SELECT)) ||
2947 (seq->seq2 && (seq->seq2->flag & SELECT)) ||
2948 (seq->seq3 && (seq->seq3->flag & SELECT)) )
2956 /* use to impose limits when dragging/extending - so impossible situations dont happen
2957 * Cant use the SEQ_LEFTSEL and SEQ_LEFTSEL directly because the strip may be in a metastrip */
2958 void seq_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
2961 if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_final_right(seq, 0)) {
2962 seq_tx_set_final_left(seq, seq_tx_get_final_right(seq, 0)-1);
2965 if (seq_single_check(seq)==0) {
2966 if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_end(seq)) {
2967 seq_tx_set_final_left(seq, seq_tx_get_end(seq)-1);
2970 /* dosnt work now - TODO */
2972 if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq, 0)) {
2974 ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq, 0);
2976 seq_tx_set_final_left(seq, seq_tx_get_final_left(seq, 0) + ofs );
2983 if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_final_left(seq, 0)) {
2984 seq_tx_set_final_right(seq, seq_tx_get_final_left(seq, 0)+1);
2987 if (seq_single_check(seq)==0) {
2988 if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_start(seq)) {
2989 seq_tx_set_final_right(seq, seq_tx_get_start(seq)+1);
2994 /* sounds cannot be extended past their endpoints */
2995 if (seq->type == SEQ_SOUND) {
3001 void seq_single_fix(Sequence *seq)
3003 int left, start, offset;
3004 if (!seq_single_check(seq))
3007 /* make sure the image is always at the start since there is only one,
3008 adjusting its start should be ok */
3009 left = seq_tx_get_final_left(seq, 0);
3011 if (start != left) {
3012 offset = left - start;
3013 seq_tx_set_final_left( seq, seq_tx_get_final_left(seq, 0) - offset );
3014 seq_tx_set_final_right( seq, seq_tx_get_final_right(seq, 0) - offset );
3015 seq->start += offset;
3019 int seq_tx_test(Sequence * seq)
3021 return (seq->type < SEQ_EFFECT) || (get_sequence_effect_num_inputs(seq->type) == 0);
3024 static int seq_overlap(Sequence *seq1, Sequence *seq2)
3026 return (seq1 != seq2 && seq1->machine == seq2->machine &&
3027 ((seq1->enddisp <= seq2->startdisp) || (seq1->startdisp >= seq2->enddisp))==0);
3030 int seq_test_overlap(ListBase * seqbasep, Sequence *test)
3034 seq= seqbasep->first;
3036 if(seq_overlap(test, seq))
3045 void seq_translate(Scene *evil_scene, Sequence *seq, int delta)
3047 seq_offset_animdata(evil_scene, seq, delta);
3048 seq->start += delta;
3050 if(seq->type==SEQ_META) {
3051 Sequence *seq_child;
3052 for(seq_child= seq->seqbase.first; seq_child; seq_child= seq_child->next) {
3053 seq_translate(evil_scene, seq_child, delta);
3057 calc_sequence_disp(evil_scene, seq);
3060 void seq_sound_init(Scene *scene, Sequence *seq)
3062 if(seq->type==SEQ_META) {
3063 Sequence *seq_child;
3064 for(seq_child= seq->seqbase.first; seq_child; seq_child= seq_child->next) {
3065 seq_sound_init(scene, seq_child);
3070 seq->scene_sound = sound_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
3073 sound_scene_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
3078 Sequence *seq_foreground_frame_get(Scene *scene, int frame)
3080 Editing *ed= seq_give_editing(scene, FALSE);
3081 Sequence *seq, *best_seq=NULL;
3082 int best_machine = -1;
3084 if(!ed) return NULL;
3086 for (seq=ed->seqbasep->first; seq; seq= seq->next) {
3087 if(seq->flag & SEQ_MUTE || seq->startdisp > frame || seq->enddisp <= frame)
3089 /* only use elements you can see - not */
3090 if (ELEM5(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE, SEQ_COLOR)) {
3091 if (seq->machine > best_machine) {
3093 best_machine = seq->machine;
3100 /* return 0 if there werent enough space */
3101 int shuffle_seq(ListBase * seqbasep, Sequence *test, Scene *evil_scene)
3103 int orig_machine= test->machine;
3105 calc_sequence(evil_scene, test);
3106 while( seq_test_overlap(seqbasep, test) ) {
3107 if(test->machine >= MAXSEQ) {
3111 calc_sequence(evil_scene, test); // XXX - I dont think this is needed since were only moving vertically, Campbell.
3115 if(test->machine >= MAXSEQ) {
3116 /* Blender 2.4x would remove the strip.
3117 * nicer to move it to the end */
3120 int new_frame= test->enddisp;
3122 for(seq= seqbasep->first; seq; seq= seq->next) {
3123 if (seq->machine == orig_machine)
3124 new_frame = MAX2(new_frame, seq->enddisp);
3127 test->machine= orig_machine;
3128 new_frame = new_frame + (test->start-test->startdisp); /* adjust by the startdisp */
3129 seq_translate(evil_scene, test, new_frame - test->start);
3131 calc_sequence(evil_scene, test);
3138 static int shuffle_seq_time_offset_test(ListBase * seqbasep, char dir)
3141 Sequence *seq, *seq_other;
3143 for(seq= seqbasep->first; seq; seq= seq->next) {
3145 for(seq_other= seqbasep->first; seq_other; seq_other= seq_other->next) {
3146 if(!seq_other->tmp && seq_overlap(seq, seq_other)) {
3148 offset= MIN2(offset, seq_other->startdisp - seq->enddisp);
3151 offset= MAX2(offset, seq_other->enddisp - seq->startdisp);
3160 static int shuffle_seq_time_offset(Scene* scene, ListBase * seqbasep, char dir)
3165 while( (ofs= shuffle_seq_time_offset_test(seqbasep, dir)) ) {
3166 for(seq= seqbasep->first; seq; seq= seq->next) {
3168 /* seq_test_overlap only tests display values */
3169 seq->startdisp += ofs;
3170 seq->enddisp += ofs;
3177 for(seq= seqbasep->first; seq; seq= seq->next) {
3179 calc_sequence_disp(scene, seq); /* corrects dummy startdisp/enddisp values */
3185 int shuffle_seq_time(ListBase * seqbasep, Scene *evil_scene)
3187 /* note: seq->tmp is used to tag strips to move */
3191 int offset_l = shuffle_seq_time_offset(evil_scene, seqbasep, 'L');
3192 int offset_r = shuffle_seq_time_offset(evil_scene, seqbasep, 'R');
3193 int offset = (-offset_l < offset_r) ? offset_l:offset_r;
3196 for(seq= seqbasep->first; seq; seq= seq->next) {
3198 seq_translate(evil_scene, seq, offset);
3199 seq->flag &= ~SEQ_OVERLAP;
3207 void seq_update_sound_bounds_all(Scene *scene)
3209 Editing *ed = scene->ed;
3214 for(seq = ed->seqbase.first; seq; seq = seq->next) {