== Sequencer ==

Major sequencer rewrite to add Speed Control effect.
Changes:
- Cleaned up large parts of sequence.c removing a lot of unnecessary code.
  (We first built old seqar array to decide, what is visible, then build
   dependencies with new code, then used old code to iterate through the
   strips and deciding using new code what is used and so forth and so on...)
  Should be much faster now.
- Now we build the strips recursively thereby elemenating the need of a
  seperate dependency calculation.
- Added a Speed-Control effect to change strip speed afterwards.
  (Offers global speed as well as IPO-controlled speed.
   There are several modes to play with:
   - Control by velocity (IPO = velocity where 1.0 is normal speed)
   - Control by frame number (IPO = target frame)
   - IPO-Value can be rescaled to frame-value, to make frame exact matching
     possible. (Matching video tracks to audio tracks with IPOs ;-)

Demo-Blend file is here http://peter.schlaile.de/blender/sequencer/speedcontroltest.blend

Since this was also a Plumiferos request I hope to be mentioned in the
credits ;-)

Enjoy! And please test the new sequencer thoroughly. It is really more like
a rewrite this time.
This commit is contained in:
2006-11-11 22:35:40 +00:00
parent 05c59da48f
commit c1b4132e8d
8 changed files with 659 additions and 470 deletions

View File

@@ -1262,6 +1262,9 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
case SEQ_COLOR: case SEQ_COLOR:
writestruct(wd, DATA, "SolidColorVars", 1, seq->effectdata); writestruct(wd, DATA, "SolidColorVars", 1, seq->effectdata);
break; break;
case SEQ_SPEED:
writestruct(wd, DATA, "SpeedControlVars", 1, seq->effectdata);
break;
case SEQ_WIPE: case SEQ_WIPE:
writestruct(wd, DATA, "WipeVars", 1, seq->effectdata); writestruct(wd, DATA, "WipeVars", 1, seq->effectdata);
break; break;

View File

@@ -86,6 +86,7 @@ struct SeqEffectHandle {
struct SeqEffectHandle get_sequence_effect(struct Sequence * seq); struct SeqEffectHandle get_sequence_effect(struct Sequence * seq);
int get_sequence_effect_num_inputs(int seq_type); int get_sequence_effect_num_inputs(int seq_type);
void sequence_effect_speed_rebuild_map(struct Sequence * seq, int force);
#endif #endif

View File

@@ -48,18 +48,12 @@ void free_stripdata(int len, struct StripElem *se);
void free_strip(struct Strip *strip); void free_strip(struct Strip *strip);
void new_stripdata(struct Sequence *seq); void new_stripdata(struct Sequence *seq);
void free_sequence(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 build_seqar(struct ListBase *seqbase, struct Sequence ***seqar, int *totseq);
void free_editing(struct Editing *ed); void free_editing(struct Editing *ed);
void calc_sequence(struct Sequence *seq); void calc_sequence(struct Sequence *seq);
void sort_seq(void); void sort_seq(void);
void clear_scene_in_allseqs(struct Scene *sce); 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); int evaluate_seq_frame(int cfra);
struct StripElem *give_stripelem(struct Sequence *seq, int cfra); struct StripElem *give_stripelem(struct Sequence *seq, int cfra);
void set_meta_stripdata(struct Sequence *seqm); void set_meta_stripdata(struct Sequence *seqm);

View File

@@ -49,8 +49,7 @@ typedef struct StripElem {
struct ImBuf *ibuf; struct ImBuf *ibuf;
struct StripElem *se1, *se2, *se3; struct StripElem *se1, *se2, *se3;
short ok; short ok;
unsigned char isneeded; short pad;
unsigned char pad;
int nr; int nr;
} StripElem; } StripElem;
@@ -178,6 +177,18 @@ typedef struct SolidColorVars {
float pad; float pad;
} SolidColorVars; } 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 ****************** */ /* ***************** SEQUENCE ****************** */
@@ -216,6 +227,7 @@ typedef struct SolidColorVars {
#define SEQ_GLOW 26 #define SEQ_GLOW 26
#define SEQ_TRANSFORM 27 #define SEQ_TRANSFORM 27
#define SEQ_COLOR 28 #define SEQ_COLOR 28
#define SEQ_SPEED 29
#endif #endif

View File

@@ -118,6 +118,7 @@ static char *give_seqname(Sequence *seq)
else if(seq->type==SEQ_GLOW) return "Glow"; else if(seq->type==SEQ_GLOW) return "Glow";
else if(seq->type==SEQ_TRANSFORM) return "Transform"; else if(seq->type==SEQ_TRANSFORM) return "Transform";
else if(seq->type==SEQ_COLOR) return "Color"; else if(seq->type==SEQ_COLOR) return "Color";
else if(seq->type==SEQ_SPEED) return "Speed";
else if(seq->type==SEQ_PLUGIN) { else if(seq->type==SEQ_PLUGIN) {
if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) && if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
seq->plugin && seq->plugin->doit) return seq->plugin->pname; seq->plugin && seq->plugin->doit) return seq->plugin->pname;
@@ -182,6 +183,7 @@ static void get_seq_color3ubv(Sequence *seq, char *col)
/* effects */ /* effects */
case SEQ_TRANSFORM: case SEQ_TRANSFORM:
case SEQ_SPEED:
case SEQ_ADD: case SEQ_ADD:
case SEQ_SUB: case SEQ_SUB:
case SEQ_MUL: case SEQ_MUL:
@@ -1189,7 +1191,37 @@ static void seq_panel_properties(short cntrl) // SEQ_HANDLER_PROPERTIES
} else if(last_seq->type==SEQ_COLOR) { } else if(last_seq->type==SEQ_COLOR) {
SolidColorVars *colvars = (SolidColorVars *)last_seq->effectdata; SolidColorVars *colvars = (SolidColorVars *)last_seq->effectdata;
uiDefButF(block, COL, SEQ_BUT_RELOAD, "",10,90,150,19, colvars->col, 0, 0, 0, 0, ""); 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); uiBlockEndAlign(block);
} }
} }

View File

@@ -1046,6 +1046,7 @@ static int event_to_efftype(int event)
if(event==14) return SEQ_GLOW; if(event==14) return SEQ_GLOW;
if(event==15) return SEQ_TRANSFORM; if(event==15) return SEQ_TRANSFORM;
if(event==16) return SEQ_COLOR; if(event==16) return SEQ_COLOR;
if(event==17) return SEQ_SPEED;
return 0; return 0;
} }
@@ -1345,6 +1346,9 @@ void add_sequence(int type)
case SEQ_COLOR: case SEQ_COLOR:
event = 16; event = 16;
break; break;
case SEQ_SPEED:
event = 17;
break;
default: default:
event = 0; event = 0;
break; break;
@@ -1374,7 +1378,8 @@ void add_sequence(int type)
"|Wipe%x13" "|Wipe%x13"
"|Glow%x14" "|Glow%x14"
"|Transforms%x15" "|Transforms%x15"
"|Color Generator%x16"); "|Color Generator%x16"
"|Speed Control%x17");
} }
if(event<1) return; if(event<1) return;
@@ -1454,6 +1459,7 @@ void add_sequence(int type)
case 14: case 14:
case 15: case 15:
case 16: case 16:
case 17:
if(get_last_seq()==0 && if(get_last_seq()==0 &&
get_sequence_effect_num_inputs( event_to_efftype(event))> 0) get_sequence_effect_num_inputs( event_to_efftype(event))> 0)
error("Need at least one active sequence strip"); error("Need at least one active sequence strip");
@@ -1499,7 +1505,8 @@ void change_sequence(void)
"|Wipe%x13" "|Wipe%x13"
"|Glow%x14" "|Glow%x14"
"|Transform%x15" "|Transform%x15"
"|Color Generator%x16"); "|Color Generator%x16"
"|Speed Control%x17");
if(event > 0) { if(event > 0) {
if(event==1) { if(event==1) {
SWAP(Sequence *,last_seq->seq1,last_seq->seq2); SWAP(Sequence *,last_seq->seq1,last_seq->seq2);

View File

@@ -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, static void do_cross_effect(Sequence * seq,int cfra,
float facf0, float facf1, int x, int y, float facf0, float facf1, int x, int y,
struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf1, struct ImBuf *ibuf2,
@@ -2785,6 +2787,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 sequence effect factory
********************************************************************** */ ********************************************************************** */
@@ -2944,6 +3094,15 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
rval.copy = copy_transform_effect; rval.copy = copy_transform_effect;
rval.execute = do_transform_effect; rval.execute = do_transform_effect;
break; 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: case SEQ_COLOR:
rval.init = init_solid_color; rval.init = init_solid_color;
rval.num_inputs = num_inputs_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.copy = copy_solid_color;
rval.execute = do_solid_color; rval.execute = do_solid_color;
break; break;
case SEQ_PLUGIN: case SEQ_PLUGIN:
rval.init_plugin = init_plugin; rval.init_plugin = init_plugin;
rval.num_inputs = num_inputs_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); 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); rval.load(seq);
seq->flag &= ~SEQ_EFFECT_NOT_LOADED; seq->flag &= ~SEQ_EFFECT_NOT_LOADED;
} }

File diff suppressed because it is too large Load Diff