Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenloader/intern/writefile.c3
-rw-r--r--source/blender/include/BSE_seqeffects.h1
-rw-r--r--source/blender/include/BSE_sequence.h6
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h16
-rw-r--r--source/blender/src/drawseq.c32
-rw-r--r--source/blender/src/editseq.c11
-rw-r--r--source/blender/src/seqeffects.c162
-rw-r--r--source/blender/src/sequence.c844
8 files changed, 632 insertions, 443 deletions
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 5577c7aa8a6..2ee553824ef 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1262,6 +1262,9 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
case SEQ_COLOR:
writestruct(wd, DATA, "SolidColorVars", 1, seq->effectdata);
break;
+ case SEQ_SPEED:
+ writestruct(wd, DATA, "SpeedControlVars", 1, seq->effectdata);
+ break;
case SEQ_WIPE:
writestruct(wd, DATA, "WipeVars", 1, seq->effectdata);
break;
diff --git a/source/blender/include/BSE_seqeffects.h b/source/blender/include/BSE_seqeffects.h
index 0c3eab82e0b..d4d40654ada 100644
--- a/source/blender/include/BSE_seqeffects.h
+++ b/source/blender/include/BSE_seqeffects.h
@@ -86,6 +86,7 @@ struct SeqEffectHandle {
struct SeqEffectHandle get_sequence_effect(struct Sequence * seq);
int get_sequence_effect_num_inputs(int seq_type);
+void sequence_effect_speed_rebuild_map(struct Sequence * seq, int force);
#endif
diff --git a/source/blender/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h
index 66fa22a5918..c975e8de8ff 100644
--- a/source/blender/include/BSE_sequence.h
+++ b/source/blender/include/BSE_sequence.h
@@ -48,18 +48,12 @@ void free_stripdata(int len, struct StripElem *se);
void free_strip(struct Strip *strip);
void new_stripdata(struct Sequence *seq);
void free_sequence(struct Sequence *seq);
-void do_seq_count(struct ListBase *seqbase, int *totseq);
-void do_build_seqar(struct ListBase *seqbase, struct Sequence ***seqar, int depth);
void build_seqar(struct ListBase *seqbase, struct Sequence ***seqar, int *totseq);
void free_editing(struct Editing *ed);
void calc_sequence(struct Sequence *seq);
void sort_seq(void);
void clear_scene_in_allseqs(struct Scene *sce);
-struct Sequence *get_shown_seq_from_metastrip(struct Sequence *seqm, int cfra);
-void make_black_ibuf(struct ImBuf *ibuf);
-void multibuf(struct ImBuf *ibuf, float fmul);
-void do_effect(int cfra, struct Sequence *seq, struct StripElem *se);
int evaluate_seq_frame(int cfra);
struct StripElem *give_stripelem(struct Sequence *seq, int cfra);
void set_meta_stripdata(struct Sequence *seqm);
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index 71908ded6af..5bb9f61f71e 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -49,8 +49,7 @@ typedef struct StripElem {
struct ImBuf *ibuf;
struct StripElem *se1, *se2, *se3;
short ok;
- unsigned char isneeded;
- unsigned char pad;
+ short pad;
int nr;
} StripElem;
@@ -178,6 +177,18 @@ typedef struct SolidColorVars {
float pad;
} SolidColorVars;
+typedef struct SpeedControlVars {
+ float * frameMap;
+ float globalSpeed;
+ int flags;
+ int length;
+ int pad;
+} SpeedControlVars;
+
+/* SpeedControlVars->flags */
+#define SEQ_SPEED_INTEGRATE 1
+#define SEQ_SPEED_BLEND 2
+#define SEQ_SPEED_COMPRESS_IPO_Y 4
/* ***************** SEQUENCE ****************** */
@@ -216,6 +227,7 @@ typedef struct SolidColorVars {
#define SEQ_GLOW 26
#define SEQ_TRANSFORM 27
#define SEQ_COLOR 28
+#define SEQ_SPEED 29
#endif
diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c
index 36c58bd8d5c..24c5f3d45fe 100644
--- a/source/blender/src/drawseq.c
+++ b/source/blender/src/drawseq.c
@@ -118,6 +118,7 @@ static char *give_seqname(Sequence *seq)
else if(seq->type==SEQ_GLOW) return "Glow";
else if(seq->type==SEQ_TRANSFORM) return "Transform";
else if(seq->type==SEQ_COLOR) return "Color";
+ else if(seq->type==SEQ_SPEED) return "Speed";
else if(seq->type==SEQ_PLUGIN) {
if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
seq->plugin && seq->plugin->doit) return seq->plugin->pname;
@@ -182,6 +183,7 @@ static void get_seq_color3ubv(Sequence *seq, char *col)
/* effects */
case SEQ_TRANSFORM:
+ case SEQ_SPEED:
case SEQ_ADD:
case SEQ_SUB:
case SEQ_MUL:
@@ -1189,7 +1191,37 @@ static void seq_panel_properties(short cntrl) // SEQ_HANDLER_PROPERTIES
} else if(last_seq->type==SEQ_COLOR) {
SolidColorVars *colvars = (SolidColorVars *)last_seq->effectdata;
uiDefButF(block, COL, SEQ_BUT_RELOAD, "",10,90,150,19, colvars->col, 0, 0, 0, 0, "");
+ } else if(last_seq->type==SEQ_SPEED){
+ SpeedControlVars *sp =
+ (SpeedControlVars *)last_seq->effectdata;
+
+ uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Global Speed:", 10,70,150,19, &sp->globalSpeed, 0.0, 100.0, 0, 0, "Global Speed");
+
+ uiDefButBitI(block, TOG, SEQ_SPEED_INTEGRATE,
+ SEQ_BUT_EFFECT,
+ "IPO is velocity",
+ 10,50,150,19, &sp->flags,
+ 0.0, 1.0, 0, 0,
+ "Interpret the IPO value as a "
+ "velocity instead of a frame number");
+
+ uiDefButBitI(block, TOG, SEQ_SPEED_BLEND,
+ SEQ_BUT_EFFECT,
+ "Enable frame blending",
+ 10,30,150,19, &sp->flags,
+ 0.0, 1.0, 0, 0,
+ "Blend two frames into the "
+ "target for a smoother result");
+
+ uiDefButBitI(block, TOG, SEQ_SPEED_COMPRESS_IPO_Y,
+ SEQ_BUT_EFFECT,
+ "IPO value runs from [0..1]",
+ 10,10,150,19, &sp->flags,
+ 0.0, 1.0, 0, 0,
+ "Scale IPO value to get the "
+ "target frame number.");
}
+
uiBlockEndAlign(block);
}
}
diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c
index f5f8228697f..ec7d14c980b 100644
--- a/source/blender/src/editseq.c
+++ b/source/blender/src/editseq.c
@@ -1046,6 +1046,7 @@ static int event_to_efftype(int event)
if(event==14) return SEQ_GLOW;
if(event==15) return SEQ_TRANSFORM;
if(event==16) return SEQ_COLOR;
+ if(event==17) return SEQ_SPEED;
return 0;
}
@@ -1345,6 +1346,9 @@ void add_sequence(int type)
case SEQ_COLOR:
event = 16;
break;
+ case SEQ_SPEED:
+ event = 17;
+ break;
default:
event = 0;
break;
@@ -1374,7 +1378,8 @@ void add_sequence(int type)
"|Wipe%x13"
"|Glow%x14"
"|Transforms%x15"
- "|Color Generator%x16");
+ "|Color Generator%x16"
+ "|Speed Control%x17");
}
if(event<1) return;
@@ -1454,6 +1459,7 @@ void add_sequence(int type)
case 14:
case 15:
case 16:
+ case 17:
if(get_last_seq()==0 &&
get_sequence_effect_num_inputs( event_to_efftype(event))> 0)
error("Need at least one active sequence strip");
@@ -1499,7 +1505,8 @@ void change_sequence(void)
"|Wipe%x13"
"|Glow%x14"
"|Transform%x15"
- "|Color Generator%x16");
+ "|Color Generator%x16"
+ "|Speed Control%x17");
if(event > 0) {
if(event==1) {
SWAP(Sequence *,last_seq->seq1,last_seq->seq2);
diff --git a/source/blender/src/seqeffects.c b/source/blender/src/seqeffects.c
index 9196f02c28b..3a0adfdaa39 100644
--- a/source/blender/src/seqeffects.c
+++ b/source/blender/src/seqeffects.c
@@ -743,6 +743,8 @@ void do_cross_effect_float(float facf0, float facf1, int x, int y,
}
}
+/* carefull: also used by speed effect! */
+
static void do_cross_effect(Sequence * seq,int cfra,
float facf0, float facf1, int x, int y,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
@@ -2786,6 +2788,154 @@ static void do_solid_color(Sequence * seq,int cfra,
}
/* **********************************************************************
+ SPEED
+ ********************************************************************** */
+static void init_speed_effect(Sequence *seq)
+{
+ SpeedControlVars * v;
+
+ if(seq->effectdata) MEM_freeN(seq->effectdata);
+ seq->effectdata = MEM_callocN(sizeof(struct SpeedControlVars),
+ "speedcontrolvars");
+
+ v = (SpeedControlVars *)seq->effectdata;
+ v->globalSpeed = 1.0;
+ v->frameMap = 0;
+ v->flags = SEQ_SPEED_COMPRESS_IPO_Y;
+ v->length = 0;
+}
+
+static void load_speed_effect(Sequence * seq)
+{
+ SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
+
+ v->frameMap = 0;
+ v->length = 0;
+}
+
+static int num_inputs_speed()
+{
+ return 1;
+}
+
+static void free_speed_effect(Sequence *seq)
+{
+ SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
+ if(v->frameMap) MEM_freeN(v->frameMap);
+ if(seq->effectdata) MEM_freeN(seq->effectdata);
+ seq->effectdata = 0;
+}
+
+static void copy_speed_effect(Sequence *dst, Sequence *src)
+{
+ dst->effectdata = MEM_dupallocN(src->effectdata);
+}
+
+static int early_out_speed(struct Sequence *seq,
+ float facf0, float facf1)
+{
+ return 1;
+}
+
+void sequence_effect_speed_rebuild_map(struct Sequence * seq, int force)
+{
+ float facf0 = seq->facf0;
+ float ctime, div;
+ int cfra;
+ SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
+
+ /* if not already done, load / initialize data */
+ get_sequence_effect(seq);
+
+ if (!(force || seq->len != v->length || !v->frameMap)) {
+ return;
+ }
+
+ if (!v->frameMap || v->length != seq->len) {
+ if (v->frameMap) MEM_freeN(v->frameMap);
+
+ v->length = seq->len;
+
+ v->frameMap = MEM_callocN(sizeof(float) * v->length,
+ "speedcontrol frameMap");
+ }
+ if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
+ float cursor = 0;
+
+ for (cfra = 0; cfra < v->length; cfra++) {
+ if(seq->ipo) {
+ if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
+ ctime = frame_to_float(seq->startdisp
+ + cfra);
+ div = 1.0;
+ } else {
+ ctime= frame_to_float(cfra);
+ div= v->length / 100.0f;
+ if(div==0.0) return;
+ }
+
+ calc_ipo(seq->ipo, ctime/div);
+ execute_ipo((ID *)seq, seq->ipo);
+ } else {
+ seq->facf0 = 1.0;
+ }
+ seq->facf0 *= v->globalSpeed;
+
+ cursor += seq->facf0;
+
+ if (cursor >= v->length) {
+ v->frameMap[cfra] = v->length - 1;
+ } else {
+ v->frameMap[cfra] = cursor;
+ }
+ }
+ } else {
+ for (cfra = 0; cfra < v->length; cfra++) {
+ if(seq->ipo) {
+ if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
+ ctime = frame_to_float(seq->startdisp
+ + cfra);
+ div = 1.0;
+ } else {
+ ctime= frame_to_float(cfra);
+ div= v->length / 100.0f;
+ if(div==0.0) return;
+ }
+
+ calc_ipo(seq->ipo, ctime/div);
+ execute_ipo((ID *)seq, seq->ipo);
+ }
+
+ if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
+ seq->facf0 *= v->length;
+ }
+ if (!seq->ipo) {
+ seq->facf0 = cfra;
+ }
+ seq->facf0 *= v->globalSpeed;
+ if (seq->facf0 >= v->length) {
+ seq->facf0 = v->length - 1;
+ }
+ v->frameMap[cfra] = seq->facf0;
+ }
+ }
+ seq->facf0 = facf0;
+}
+
+/*
+ simply reuse do_cross_effect for blending...
+
+static void do_speed_effect(Sequence * seq,int cfra,
+ float facf0, float facf1, int x, int y,
+ struct ImBuf *ibuf1, struct ImBuf *ibuf2,
+ struct ImBuf *ibuf3, struct ImBuf *out)
+{
+
+}
+*/
+
+
+/* **********************************************************************
sequence effect factory
********************************************************************** */
@@ -2944,6 +3094,15 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
rval.copy = copy_transform_effect;
rval.execute = do_transform_effect;
break;
+ case SEQ_SPEED:
+ rval.init = init_speed_effect;
+ rval.num_inputs = num_inputs_speed;
+ rval.load = load_speed_effect;
+ rval.free = free_speed_effect;
+ rval.copy = copy_speed_effect;
+ rval.execute = do_cross_effect;
+ rval.early_out = early_out_speed;
+ break;
case SEQ_COLOR:
rval.init = init_solid_color;
rval.num_inputs = num_inputs_color;
@@ -2952,7 +3111,6 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
rval.copy = copy_solid_color;
rval.execute = do_solid_color;
break;
-
case SEQ_PLUGIN:
rval.init_plugin = init_plugin;
rval.num_inputs = num_inputs_plugin;
@@ -2973,7 +3131,7 @@ struct SeqEffectHandle get_sequence_effect(Sequence * seq)
{
struct SeqEffectHandle rval = get_sequence_effect_impl(seq->type);
- if (seq->flag & SEQ_EFFECT_NOT_LOADED) {
+ if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
rval.load(seq);
seq->flag &= ~SEQ_EFFECT_NOT_LOADED;
}
diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c
index f34484fea14..090d821a342 100644
--- a/source/blender/src/sequence.c
+++ b/source/blender/src/sequence.c
@@ -72,8 +72,6 @@
int seqrectx, seqrecty;
-/* ***************** END PLUGIN ************************ */
-
void free_stripdata(int len, StripElem *se)
{
StripElem *seo;
@@ -137,7 +135,16 @@ void free_sequence(Sequence *seq)
MEM_freeN(seq);
}
-void do_seq_count(ListBase *seqbase, int *totseq)
+/*
+ **********************************************************************
+ * build_seqar
+ **********************************************************************
+ * Build a complete array of _all_ sequencies (including those
+ * in metastrips!)
+ **********************************************************************
+*/
+
+static void do_seq_count(ListBase *seqbase, int *totseq)
{
Sequence *seq;
@@ -149,7 +156,7 @@ void do_seq_count(ListBase *seqbase, int *totseq)
}
}
-void do_build_seqar(ListBase *seqbase, Sequence ***seqar, int depth)
+static void do_build_seqar(ListBase *seqbase, Sequence ***seqar, int depth)
{
Sequence *seq;
@@ -363,7 +370,7 @@ void clear_scene_in_allseqs(Scene *sce)
/* ***************** DO THE SEQUENCE ***************** */
-void make_black_ibuf(ImBuf *ibuf)
+static void make_black_ibuf(ImBuf *ibuf)
{
unsigned int *rect;
float *rect_float;
@@ -385,7 +392,7 @@ void make_black_ibuf(ImBuf *ibuf)
}
}
-void multibuf(ImBuf *ibuf, float fmul)
+static void multibuf(ImBuf *ibuf, float fmul)
{
char *rt;
float *rt_float;
@@ -425,7 +432,7 @@ void multibuf(ImBuf *ibuf, float fmul)
}
}
-void do_effect(int cfra, Sequence *seq, StripElem *se)
+static void do_effect(int cfra, Sequence *seq, StripElem *se)
{
StripElem *se1, *se2, *se3;
float fac, facf;
@@ -555,10 +562,10 @@ StripElem *give_stripelem(Sequence *seq, int cfra)
if (seq->strobe > 1.0) {
nr -= (int)fmod((double)nr, (double)seq->strobe);
}
-
+
se+= nr; /* don't get confused by the increment, this is the same as strip->stripdata[nr], which works on some compilers...*/
se->nr= nr;
-
+
return se;
}
@@ -594,7 +601,7 @@ int evaluate_seq_frame(int cfra)
}
-Sequence *get_shown_seq_from_metastrip(Sequence * seqm, int cfra)
+Sequence *get_shown_sequence(ListBase * seqbasep, int cfra, int chanshown)
{
Sequence *seq, *seqim, *seqeff;
Sequence *seq_arr[MAXSEQ+1];
@@ -602,7 +609,14 @@ Sequence *get_shown_seq_from_metastrip(Sequence * seqm, int cfra)
seq = 0;
- if(evaluate_seq_frame_gen(seq_arr, &seqm->seqbase, cfra)) {
+ if (chanshown > MAXSEQ) {
+ return 0;
+ }
+
+ if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
+ if (chanshown > 0) {
+ return seq_arr[chanshown];
+ }
/* we take the upper effect strip or
the lowest imagestrip/metastrip */
@@ -615,8 +629,7 @@ Sequence *get_shown_seq_from_metastrip(Sequence * seqm, int cfra)
if(seqeff==0) seqeff= seq;
else if(seqeff->machine < seq->machine)
seqeff= seq;
- }
- else {
+ } else if (seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND) {
if(seqim==0) seqim= seq;
else if(seqim->machine > seq->machine)
seqim= seq;
@@ -631,6 +644,11 @@ Sequence *get_shown_seq_from_metastrip(Sequence * seqm, int cfra)
return seq;
}
+static Sequence * get_shown_seq_from_metastrip(Sequence * seqm, int cfra)
+{
+ return get_shown_sequence(&seqm->seqbase, cfra, 0);
+}
+
void set_meta_stripdata(Sequence *seqm)
{
Sequence *seq;
@@ -649,94 +667,229 @@ void set_meta_stripdata(Sequence *seqm)
se->se1= 0;
}
}
-
}
-
-
-/* HELP FUNCTIONS FOR GIVE_IBUF_SEQ */
-
-static void do_seq_count_cfra(ListBase *seqbase, int *totseq, int cfra)
+static void do_build_seq_ibuf(Sequence * seq, int cfra)
{
- Sequence *seq;
+ StripElem *se = seq->curelem;
+ char name[FILE_MAXDIR+FILE_MAXFILE];
- seq= seqbase->first;
- while(seq) {
- if(seq->startdisp <=cfra && seq->enddisp > cfra) {
- (*totseq)++;
+ if(seq->type == SEQ_META) {
+ se->ok= 2;
+ if(se->se1==0) set_meta_stripdata(seq);
+ if(se->se1) {
+ se->ibuf= se->se1->ibuf;
}
- seq= seq->next;
- }
-}
-
-static void do_seq_unref_cfra(ListBase *seqbase, int cfra)
-{
- Sequence *seq;
-
- seq= seqbase->first;
- while(seq) {
- if(seq->startdisp <=cfra && seq->enddisp > cfra) {
-
- if(seq->seqbase.first) {
-
- if(cfra< seq->start) do_seq_unref_cfra(
- &seq->seqbase, seq->start);
- else if(cfra> seq->start+seq->len-1)
- do_seq_unref_cfra(
- &seq->seqbase,
- seq->start+seq->len-1);
- else do_seq_unref_cfra(&seq->seqbase, cfra);
+ } else if(seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) {
+ se->ok= 2;
+ } else if(seq->type & SEQ_EFFECT) {
+
+ /* test if image is too small or discarded from cache: reload */
+ if(se->ibuf) {
+ if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty || !(se->ibuf->rect || se->ibuf->rect_float)) {
+ IMB_freeImBuf(se->ibuf);
+ se->ibuf= 0;
}
-
- if (seq->curelem && seq->curelem->ibuf && seq->curelem->isneeded)
- IMB_cache_limiter_unref(seq->curelem->ibuf);
}
- seq= seq->next;
- }
-}
-
-static void do_seq_test_unref_cfra(ListBase *seqbase, int cfra)
-{
- Sequence *seq;
-
- seq= seqbase->first;
- while(seq) {
- if(seq->startdisp <=cfra && seq->enddisp > cfra) {
-
- if(seq->seqbase.first) {
-
- if(cfra< seq->start)
- do_seq_test_unref_cfra(
- &seq->seqbase, seq->start);
- else if(cfra> seq->start+seq->len-1)
- do_seq_test_unref_cfra(
- &seq->seqbase,
- seq->start+seq->len-1);
- else do_seq_test_unref_cfra(
- &seq->seqbase, cfra);
+
+ /* should the effect be recalculated? */
+
+ if(se->ibuf==0
+ || (seq->seq1 && se->se1 != seq->seq1->curelem)
+ || (seq->seq2 && se->se2 != seq->seq2->curelem)
+ || (seq->seq3 && se->se3 != seq->seq3->curelem)) {
+ if (seq->seq1) se->se1= seq->seq1->curelem;
+ if (seq->seq2) se->se2= seq->seq2->curelem;
+ if (seq->seq3) se->se3= seq->seq3->curelem;
+
+ if(se->ibuf==NULL) {
+ /* if one of two first inputs are rectfloat, output is float too */
+ if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
+ (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float))
+ se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
+ else
+ se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
}
-
- if (seq->curelem && seq->curelem->ibuf
- && seq->curelem->isneeded) {
- if (IMB_cache_limiter_get_refcount(
- seq->curelem->ibuf)) {
- fprintf(stderr,
- "sequence.c: imbuf-refcount "
- "Arggh: %p, %d\n",
- seq, seq->type);
- }
+
+ do_effect(cfra, seq, se);
+ }
+
+ /* test size */
+ if(se->ibuf) {
+ if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
+ if(G.scene->r.mode & R_OSA) {
+ IMB_scaleImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
+ } else {
+ IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
+ }
}
}
- seq= seq->next;
+ } else if(seq->type < SEQ_EFFECT) {
+ if(se->ibuf) {
+ /* test if image too small
+ or discarded from cache: reload */
+ if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty || !(se->ibuf->rect || se->ibuf->rect_float)) {
+ IMB_freeImBuf(se->ibuf);
+ se->ibuf= 0;
+ se->ok= 1;
+ }
+ }
+
+ if(seq->type==SEQ_IMAGE) {
+ if(se->ok && se->ibuf==0) {
+ /* if playanim or render:
+ no waitcursor */
+ if((G.f & G_PLAYANIM)==0)
+ waitcursor(1);
+
+ strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
+ strncat(name, se->name, FILE_MAXFILE);
+ BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+ se->ibuf= IMB_loadiffname(name, IB_rect);
+
+ if((G.f & G_PLAYANIM)==0)
+ waitcursor(0);
+
+ if(se->ibuf==0) se->ok= 0;
+ else {
+ if(seq->flag & SEQ_MAKE_PREMUL) {
+ if(se->ibuf->depth==32 && se->ibuf->zbuf==0) converttopremul(se->ibuf);
+ }
+ seq->strip->orx= se->ibuf->x;
+ seq->strip->ory= se->ibuf->y;
+ if(seq->flag & SEQ_FILTERY) IMB_filtery(se->ibuf);
+ if(seq->mul==0.0) seq->mul= 1.0;
+ if(seq->mul != 1.0) multibuf(se->ibuf, seq->mul);
+ }
+ }
+ }
+ else if(seq->type==SEQ_MOVIE) {
+ if(se->ok && se->ibuf==0) {
+ if(seq->anim==0) {
+ strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
+ strncat(name, seq->strip->stripdata->name, FILE_MAXFILE-1);
+ BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+
+ seq->anim = openanim(name, IB_rect);
+ }
+ if(seq->anim) {
+ IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
+ se->ibuf = IMB_anim_absolute(seq->anim, se->nr);
+ }
+
+ if(se->ibuf==0) se->ok= 0;
+ else {
+ if(seq->flag & SEQ_MAKE_PREMUL) {
+ if(se->ibuf->depth==32) converttopremul(se->ibuf);
+ }
+ seq->strip->orx= se->ibuf->x;
+ seq->strip->ory= se->ibuf->y;
+ if(seq->flag & SEQ_FILTERY) IMB_filtery(se->ibuf);
+ if(seq->mul==0.0) seq->mul= 1.0;
+ if(seq->mul != 1.0) multibuf(se->ibuf, seq->mul);
+ }
+ }
+ } else if(seq->type==SEQ_SCENE && se->ibuf==NULL && seq->scene) { // scene can be NULL after deletions
+ int oldcfra = CFRA;
+ Scene *sce= seq->scene, *oldsce= G.scene;
+ Render *re;
+ RenderResult rres;
+ int doseq, rendering= G.rendering;
+ char scenename[64];
+
+ waitcursor(1);
+
+ /* Hack! This function can be called from do_render_seq(), in that case
+ the seq->scene can already have a Render initialized with same name,
+ so we have to use a default name. (compositor uses G.scene name to
+ find render).
+ However, when called from within the UI (image preview in sequencer)
+ we do want to use scene Render, that way the render result is defined
+ for display in render/imagewindow */
+ if(rendering) {
+ BLI_strncpy(scenename, sce->id.name+2, 64);
+ strcpy(sce->id.name+2, " do_build_seq_ibuf");
+ }
+ re= RE_NewRender(sce->id.name);
+
+ /* prevent eternal loop */
+ doseq= sce->r.scemode & R_DOSEQ;
+ sce->r.scemode &= ~R_DOSEQ;
+
+ BIF_init_render_callbacks(re, 0); /* 0= no display callbacks */
+
+ /* hrms, set_scene still needed? work on that... */
+ if(sce!=oldsce) set_scene_bg(sce);
+ RE_BlenderFrame(re, sce, seq->sfra + se->nr);
+ if(sce!=oldsce) set_scene_bg(oldsce);
+
+ /* UGLY WARNING, it is set to zero in RE_BlenderFrame */
+ G.rendering= rendering;
+ if(rendering)
+ BLI_strncpy(sce->id.name+2, scenename, 64);
+
+ RE_GetResultImage(re, &rres);
+
+ if(rres.rectf) {
+ se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
+ memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
+ if(rres.rectz) {
+ addzbuffloatImBuf(se->ibuf);
+ memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
+ }
+ }
+
+ BIF_end_render_callbacks();
+
+ /* restore */
+ sce->r.scemode |= doseq;
+
+ if((G.f & G_PLAYANIM)==0) /* bad, is set on do_render_seq */
+ waitcursor(0);
+ CFRA = oldcfra;
+ }
+
+ /* size test */
+ if(se->ibuf) {
+ if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
+
+ if (0) { // G.scene->r.mode & R_FIELDS) {
+
+ if (seqrecty > 288)
+ IMB_scalefieldImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
+ else {
+ IMB_de_interlace(se->ibuf);
+
+ if(G.scene->r.mode & R_OSA)
+ IMB_scaleImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
+ else
+ IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
+ }
+ }
+ else {
+ if(G.scene->r.mode & R_OSA)
+ IMB_scaleImBuf(se->ibuf,(short)seqrectx, (short)seqrecty);
+ else
+ IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
+ }
+ }
+
+ }
+ }
+ if (se->ibuf) {
+ IMB_cache_limiter_insert(se->ibuf);
+ IMB_cache_limiter_ref(se->ibuf);
+ IMB_cache_limiter_touch(se->ibuf);
}
}
-static void do_build_seq_depend(Sequence * seq, int cfra);
+static void do_build_seq_recursively(Sequence * seq, int cfra);
-static void do_effect_depend(int cfra, Sequence * seq, StripElem *se)
+static void do_effect_seq_recursively(int cfra, Sequence * seq, StripElem *se)
{
float fac, facf;
struct SeqEffectHandle sh = get_sequence_effect(seq);
+ int early_out;
if(seq->ipo && seq->ipo->curve.first) {
do_seq_ipo(seq);
@@ -748,351 +901,220 @@ static void do_effect_depend(int cfra, Sequence * seq, StripElem *se)
if( G.scene->r.mode & R_FIELDS ); else facf= fac;
- switch (sh.early_out(seq, fac, facf)) {
+ early_out = sh.early_out(seq, fac, facf);
+ switch (early_out) {
case -1:
/* no input needed */
break;
case 0:
- do_build_seq_depend(seq->seq1, cfra);
- do_build_seq_depend(seq->seq2, cfra);
+ do_build_seq_recursively(seq->seq1, cfra);
+ do_build_seq_recursively(seq->seq2, cfra);
break;
case 1:
- do_build_seq_depend(seq->seq1, cfra);
+ do_build_seq_recursively(seq->seq1, cfra);
break;
case 2:
- do_build_seq_depend(seq->seq2, cfra);
+ do_build_seq_recursively(seq->seq2, cfra);
break;
}
if (seq->seq3) {
- do_build_seq_depend(seq->seq3, cfra);
+ do_build_seq_recursively(seq->seq3, cfra);
+ }
+
+ do_build_seq_ibuf(seq, cfra);
+
+ /* children are not needed anymore ... */
+
+ switch (early_out) {
+ case 0:
+ if (seq->seq1->curelem && seq->seq1->curelem->ibuf)
+ IMB_cache_limiter_unref(seq->seq1->curelem->ibuf);
+ if (seq->seq2->curelem && seq->seq2->curelem->ibuf)
+ IMB_cache_limiter_unref(seq->seq2->curelem->ibuf);
+ break;
+ case 1:
+ if (seq->seq1->curelem && seq->seq1->curelem->ibuf)
+ IMB_cache_limiter_unref(seq->seq1->curelem->ibuf);
+ break;
+ case 2:
+ if (seq->seq2->curelem && seq->seq2->curelem->ibuf)
+ IMB_cache_limiter_unref(seq->seq2->curelem->ibuf);
+ break;
+ }
+ if (seq->seq3) {
+ if (seq->seq3->curelem && seq->seq3->curelem->ibuf)
+ IMB_cache_limiter_unref(seq->seq3->curelem->ibuf);
}
}
-static void do_build_seq_depend(Sequence * seq, int cfra)
+static void do_build_seq_recursively_impl(Sequence * seq, int cfra)
{
- StripElem *se = seq->curelem;
+ StripElem *se;
+
+ se = seq->curelem = give_stripelem(seq, cfra);
- if(se && !se->isneeded) {
- se->isneeded = 1;
+ if(se) {
if(seq->seqbase.first) {
Sequence * seqmshown= get_shown_seq_from_metastrip(seq, cfra);
if (seqmshown) {
if(cfra< seq->start)
- do_build_seq_depend(seqmshown, seq->start);
+ do_build_seq_recursively(seqmshown, seq->start);
else if(cfra> seq->start+seq->len-1)
- do_build_seq_depend(seqmshown, seq->start + seq->len-1);
- else do_build_seq_depend(seqmshown, cfra);
+ do_build_seq_recursively(seqmshown, seq->start + seq->len-1);
+ else do_build_seq_recursively(seqmshown, cfra);
}
}
if (seq->type & SEQ_EFFECT) {
- do_effect_depend(cfra, seq, se);
+ do_effect_seq_recursively(cfra, seq, se);
+ } else {
+ do_build_seq_ibuf(seq, cfra);
}
}
}
-static void do_build_seq_ibuf(Sequence * seq, int cfra)
-{
- StripElem *se = seq->curelem;
- char name[FILE_MAXDIR+FILE_MAXFILE];
+/* FIXME:
+
+If cfra was float throughout blender (especially in the render
+pipeline) one could even _render_ with subframe precision
+instead of faking using the blend code below...
- if(se && se->isneeded) {
- if(seq->type == SEQ_META) {
- se->ok= 2;
- if(se->se1==0) set_meta_stripdata(seq);
- if(se->se1) {
- se->ibuf= se->se1->ibuf;
- }
- }
- else if(seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) {
- se->ok= 2;
- }
- else if(seq->type & SEQ_EFFECT) {
-
- /* test if image is too small or discarded from cache: reload */
- if(se->ibuf) {
- if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty || !(se->ibuf->rect || se->ibuf->rect_float)) {
- IMB_freeImBuf(se->ibuf);
- se->ibuf= 0;
- }
- }
-
- /* should the effect be recalculated? */
-
- if(se->ibuf==0
- || (seq->seq1 && se->se1 != seq->seq1->curelem)
- || (seq->seq2 && se->se2 != seq->seq2->curelem)
- || (seq->seq3 && se->se3 != seq->seq3->curelem)) {
- if (seq->seq1) se->se1= seq->seq1->curelem;
- if (seq->seq2) se->se2= seq->seq2->curelem;
- if (seq->seq3) se->se3= seq->seq3->curelem;
-
- if(se->ibuf==NULL) {
- /* if one of two first inputs are rectfloat, output is float too */
- if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
- (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float))
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
- else
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
- }
+*/
- do_effect(cfra, seq, se);
- }
-
- /* test size */
- if(se->ibuf) {
- if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
- if(G.scene->r.mode & R_OSA) {
- IMB_scaleImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
- } else {
- IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
- }
- }
+static void do_handle_speed_effect(Sequence * seq, int cfra)
+{
+ SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
+ int nr = cfra - seq->start;
+ float f_cfra;
+ int cfra_left;
+ int cfra_right;
+ StripElem * se = 0;
+ StripElem * se1 = 0;
+ StripElem * se2 = 0;
+
+ sequence_effect_speed_rebuild_map(seq, 0);
+
+ f_cfra = seq->start + s->frameMap[nr];
+
+ cfra_left = (int) floor(f_cfra);
+ cfra_right = (int) ceil(f_cfra);
+
+ se = seq->curelem = give_stripelem(seq, cfra);
+
+ if (cfra_left == cfra_right ||
+ (s->flags & SEQ_SPEED_BLEND) == 0) {
+ if(se->ibuf) {
+ if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty
+ || !(se->ibuf->rect || se->ibuf->rect_float)) {
+ IMB_freeImBuf(se->ibuf);
+ se->ibuf= 0;
}
}
- else if(seq->type < SEQ_EFFECT) {
- if(se->ibuf) {
- /* test if image too small
- or discarded from cache: reload */
- if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty || !(se->ibuf->rect || se->ibuf->rect_float)) {
- IMB_freeImBuf(se->ibuf);
- se->ibuf= 0;
- se->ok= 1;
- }
- }
-
- if(seq->type==SEQ_IMAGE) {
- if(se->ok && se->ibuf==0) {
- /* if playanim or render:
- no waitcursor */
- if((G.f & G_PLAYANIM)==0)
- waitcursor(1);
-
- strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
- strncat(name, se->name, FILE_MAXFILE);
- BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
- se->ibuf= IMB_loadiffname(name, IB_rect);
-
- if((G.f & G_PLAYANIM)==0)
- waitcursor(0);
-
- if(se->ibuf==0) se->ok= 0;
- else {
- if(seq->flag & SEQ_MAKE_PREMUL) {
- if(se->ibuf->depth==32 && se->ibuf->zbuf==0) converttopremul(se->ibuf);
- }
- seq->strip->orx= se->ibuf->x;
- seq->strip->ory= se->ibuf->y;
- if(seq->flag & SEQ_FILTERY) IMB_filtery(se->ibuf);
- if(seq->mul==0.0) seq->mul= 1.0;
- if(seq->mul != 1.0) multibuf(se->ibuf, seq->mul);
- }
- }
- }
- else if(seq->type==SEQ_MOVIE) {
- if(se->ok && se->ibuf==0) {
- if(seq->anim==0) {
- strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
- strncat(name, seq->strip->stripdata->name, FILE_MAXFILE-1);
- BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
-
- seq->anim = openanim(name, IB_rect);
- }
- if(seq->anim) {
- IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
- se->ibuf = IMB_anim_absolute(seq->anim, se->nr);
- }
-
- if(se->ibuf==0) se->ok= 0;
- else {
- if(seq->flag & SEQ_MAKE_PREMUL) {
- if(se->ibuf->depth==32) converttopremul(se->ibuf);
- }
- seq->strip->orx= se->ibuf->x;
- seq->strip->ory= se->ibuf->y;
- if(seq->flag & SEQ_FILTERY) IMB_filtery(se->ibuf);
- if(seq->mul==0.0) seq->mul= 1.0;
- if(seq->mul != 1.0) multibuf(se->ibuf, seq->mul);
- }
- }
- }
- else if(seq->type==SEQ_SCENE && se->ibuf==NULL && seq->scene) { // scene can be NULL after deletions
- int oldcfra = CFRA;
- Scene *sce= seq->scene, *oldsce= G.scene;
- Render *re;
- RenderResult rres;
- int doseq, rendering= G.rendering;
- char scenename[64];
-
- waitcursor(1);
-
- /* Hack! This function can be called from do_render_seq(), in that case
- the seq->scene can already have a Render initialized with same name,
- so we have to use a default name. (compositor uses G.scene name to
- find render).
- However, when called from within the UI (image preview in sequencer)
- we do want to use scene Render, that way the render result is defined
- for display in render/imagewindow */
- if(rendering) {
- BLI_strncpy(scenename, sce->id.name+2, 64);
- strcpy(sce->id.name+2, " do_build_seq_ibuf");
- }
- re= RE_NewRender(sce->id.name);
-
- /* prevent eternal loop */
- doseq= sce->r.scemode & R_DOSEQ;
- sce->r.scemode &= ~R_DOSEQ;
-
- BIF_init_render_callbacks(re, 0); /* 0= no display callbacks */
-
- /* hrms, set_scene still needed? work on that... */
- if(sce!=oldsce) set_scene_bg(sce);
- RE_BlenderFrame(re, sce, seq->sfra + se->nr);
- if(sce!=oldsce) set_scene_bg(oldsce);
-
- /* UGLY WARNING, it is set to zero in RE_BlenderFrame */
- G.rendering= rendering;
- if(rendering)
- BLI_strncpy(sce->id.name+2, scenename, 64);
-
- RE_GetResultImage(re, &rres);
-
- if(rres.rectf) {
- se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
- memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
- if(rres.rectz) {
- addzbuffloatImBuf(se->ibuf);
- memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
- }
- }
-
- BIF_end_render_callbacks();
- /* restore */
- sce->r.scemode |= doseq;
-
- if((G.f & G_PLAYANIM)==0) /* bad, is set on do_render_seq */
- waitcursor(0);
- CFRA = oldcfra;
- }
-
- /* size test */
- if(se->ibuf) {
- if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
-
- if (0) { // G.scene->r.mode & R_FIELDS) {
-
- if (seqrecty > 288)
- IMB_scalefieldImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
- else {
- IMB_de_interlace(se->ibuf);
-
- if(G.scene->r.mode & R_OSA)
- IMB_scaleImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
- else
- IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
- }
- }
- else {
- if(G.scene->r.mode & R_OSA)
- IMB_scaleImBuf(se->ibuf,(short)seqrectx, (short)seqrecty);
- else
- IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
+ if (se->ibuf == NULL) {
+ do_build_seq_recursively_impl(seq->seq1, cfra_left);
+
+ se1 = seq->seq1->curelem;
+
+ if((se1 && se1->ibuf && se1->ibuf->rect_float))
+ se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
+ else
+ se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
+
+ if (se1 == 0 || se1->ibuf == 0) {
+ make_black_ibuf(se->ibuf);
+ } else {
+ if (se->ibuf != se1->ibuf) {
+ if (se->ibuf) {
+ IMB_freeImBuf(se->ibuf);
}
+
+ se->ibuf = se1->ibuf;
+ IMB_refImBuf(se->ibuf);
}
-
}
}
- if (se->ibuf) {
- IMB_cache_limiter_insert(se->ibuf);
- IMB_cache_limiter_ref(se->ibuf);
- IMB_cache_limiter_touch(se->ibuf);
- }
- }
-}
-
-static void do_set_seq_curelem(ListBase *seqbase, int cfra)
-{
- Sequence *seq;
-
- for(seq=seqbase->first; seq; seq=seq->next) {
- seq->curelem= give_stripelem(seq, cfra);
-
- if (seq->curelem) {
- seq->curelem->isneeded= 0; /* nobody is needed a priori */
+ } else {
+ struct SeqEffectHandle sh;
- if (seq->seqbase.first)
- do_set_seq_curelem(&seq->seqbase, cfra);
+ if(se->ibuf) {
+ if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty
+ || !(se->ibuf->rect || se->ibuf->rect_float)) {
+ IMB_freeImBuf(se->ibuf);
+ se->ibuf= 0;
+ }
}
- }
-}
-static void do_build_seqar_cfra(ListBase *seqbase, Sequence ***seqar, int cfra)
-{
- Sequence *seq;
+ if (se->ibuf == NULL) {
+ do_build_seq_recursively_impl(seq->seq1, cfra_left);
+ se1 = seq->seq1->curelem;
+ do_build_seq_recursively_impl(seq->seq1, cfra_right);
+ se2 = seq->seq1->curelem;
- if(seqar==NULL) return;
-
- seq= seqbase->first;
- while(seq) {
- if ((seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) && (seq->ipo)
- && (seq->startdisp <= cfra+2) && (seq->enddisp > cfra)) {
- do_seq_ipo(seq);
- }
- if(seq->curelem) {
- **seqar= seq;
- (*seqar)++;
+ if((se1 && se1->ibuf && se1->ibuf->rect_float))
+ se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
+ else
+ se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
+
+ if (!se1 || !se2) {
+ make_black_ibuf(se->ibuf);
+ } else {
+ sh = get_sequence_effect(seq);
+
+ sh.execute(seq, cfra,
+ f_cfra - (float) cfra_left,
+ f_cfra - (float) cfra_left,
+ se->ibuf->x, se->ibuf->y,
+ se1->ibuf, se2->ibuf, 0, se->ibuf);
+ }
}
- seq= seq->next;
}
-}
-
-static void do_build_seq_ibufs(ListBase *seqbase, int cfra)
-{
- Sequence *seq;
- seq= seqbase->first;
- while(seq) {
- if ((seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) && (seq->ipo)
- && (seq->startdisp <= cfra+2) && (seq->enddisp > cfra)) {
- do_seq_ipo(seq);
- }
+ /* caller expects this to be referenced, so do it! */
+ if (se->ibuf) {
+ IMB_cache_limiter_insert(se->ibuf);
+ IMB_cache_limiter_ref(se->ibuf);
+ IMB_cache_limiter_touch(se->ibuf);
+ }
- if(seq->startdisp <=cfra && seq->enddisp > cfra) {
- if(seq->seqbase.first) {
- if(cfra< seq->start)
- do_build_seq_ibufs(&seq->seqbase, seq->start);
- else if(cfra> seq->start+seq->len-1)
- do_build_seq_ibufs(&seq->seqbase, seq->start + seq->len-1);
- else do_build_seq_ibufs(&seq->seqbase, cfra);
- }
+ /* children are no longer needed */
+ if (se1 && se1->ibuf)
+ IMB_cache_limiter_unref(se1->ibuf);
+ if (se2 && se2->ibuf)
+ IMB_cache_limiter_unref(se2->ibuf);
+}
- do_build_seq_ibuf(seq, cfra);
- }
+/*
+ * build all ibufs recursively
+ *
+ * if successfull, seq->curelem->ibuf contains the (referenced!) imbuf
+ * that means: you _must_ call
+ *
+ * IMB_cache_limiter_unref(seq->curelem->ibuf);
+ *
+ * if seq->curelem exists!
+ *
+ */
- seq= seq->next;
+static void do_build_seq_recursively(Sequence * seq, int cfra)
+{
+ if (seq->type == SEQ_SPEED) {
+ do_handle_speed_effect(seq, cfra);
+ } else {
+ do_build_seq_recursively_impl(seq, cfra);
}
}
ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
{
- Sequence **tseqar, **seqar;
- Sequence *seq, *seqfirst=0;/* , *effirst=0; */
+ Sequence *seqfirst=0;
Editing *ed;
- StripElem *se;
- int seqnr, totseq, count;
+ int count;
ListBase *seqbasep;
- /* we make recursively a 'stack' of sequences, these are
- * sorted nicely as well.
- * this method has been developed especially for
- * stills before or after metas
- */
-
- totseq= 0;
ed= G.scene->ed;
if(ed==0) return 0;
@@ -1100,77 +1122,27 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
if((chanshown < 0) && (count > 0)) {
count = MAX2(count + chanshown, 0);
seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
- }
- else
+ } else {
seqbasep= ed->seqbasep;
-
- do_seq_count_cfra(seqbasep, &totseq, cfra);
-
- if(totseq==0) return 0;
+ }
seqrectx= rectx; /* bad bad global! */
seqrecty= recty;
- /* tseqar is needed because in do_build_... the pointer changes */
- seqar= tseqar= MEM_callocN(sizeof(void *)*totseq, "seqar");
-
- /* set curelem pointers to stripelem */
- do_set_seq_curelem(seqbasep, cfra);
-
- /* this call creates the sequence order array */
- do_build_seqar_cfra(seqbasep, &seqar, cfra);
-
- seqar= tseqar;
+ seqfirst = get_shown_sequence(seqbasep, cfra, chanshown);
- for(seqnr=0; seqnr<totseq; seqnr++) {
- seq= seqar[seqnr];
-
- se= seq->curelem;
- if((seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND)
- && (se) && (chanshown <= 0 || seq->machine == chanshown)) {
- if(seq->type==SEQ_META) {
-
- /* bottom strip! */
- if(seqfirst==0) seqfirst= seq;
- else if(seqfirst->depth > seq->depth) seqfirst= seq;
- else if(seqfirst->machine > seq->machine) seqfirst= seq;
-
- }
- else if(seq->type & SEQ_EFFECT) {
-
- /* top strip! */
- if(seqfirst==0) seqfirst= seq;
- else if(seqfirst->depth > seq->depth) seqfirst= seq;
- else if(seqfirst->machine < seq->machine) seqfirst= seq;
-
-
- }
- else if(seq->type < SEQ_EFFECT) { /* images */
-
- /* bottom strip! a feature that allows you to store junk in locations above */
-
- if(seqfirst==0) seqfirst= seq;
- else if(seqfirst->depth > seq->depth) seqfirst= seq;
- else if(seqfirst->machine > seq->machine) seqfirst= seq;
-
- }
- }
+ if (!seqfirst) {
+ return 0;
}
- MEM_freeN(seqar);
-
- /* we know, that we have to build the ibuf of seqfirst,
- now build the dependencies and later the ibufs */
+ do_build_seq_recursively(seqfirst, cfra);
- if (seqfirst) {
- do_build_seq_depend(seqfirst, cfra);
- do_build_seq_ibufs(seqbasep, cfra);
- do_seq_unref_cfra(seqbasep, cfra);
- do_seq_test_unref_cfra(seqbasep, cfra);
+ if(!seqfirst->curelem) {
+ return 0;
}
- if(!seqfirst) return 0;
- if(!seqfirst->curelem) return 0;
+ IMB_cache_limiter_unref(seqfirst->curelem->ibuf);
+
return seqfirst->curelem->ibuf;
}
@@ -1235,6 +1207,9 @@ void free_imbuf_seq()
if(seq->type==SEQ_MOVIE)
free_anim_seq(seq);
+ if(seq->type==SEQ_SPEED) {
+ sequence_effect_speed_rebuild_map(seq, 1);
+ }
}
}
END_SEQ
@@ -1249,8 +1224,12 @@ void free_imbuf_seq_with_ipo(struct Ipo *ipo)
if(ed==0) return;
WHILE_SEQ(&ed->seqbase) {
- if(seq->ipo == ipo)
+ if(seq->ipo == ipo) {
update_changed_seq_and_deps(seq, 0, 1);
+ if(seq->type == SEQ_SPEED) {
+ sequence_effect_speed_rebuild_map(seq, 1);
+ }
+ }
}
END_SEQ
}
@@ -1290,6 +1269,9 @@ static int update_changed_seq_recurs(Sequence *seq, Sequence *changed_seq, int l
if(seq->type==SEQ_MOVIE)
free_anim_seq(seq);
+ if(seq->type == SEQ_SPEED) {
+ sequence_effect_speed_rebuild_map(seq, 1);
+ }
}
if(len_change)