== Sequencer ==

Additional speed control fixes:
frame blending can now be done on more than two
frames, enabling really fine grained motion blur
if you speed up a sequence with high factors (bigger
than two).

Next step: add morphing support using motion 
estimation.
This commit is contained in:
Peter Schlaile 2009-06-26 15:09:39 +00:00
parent 6f87d03b3c
commit efcdd16b07
3 changed files with 96 additions and 22 deletions

@ -234,6 +234,8 @@ typedef struct SpeedControlVars {
int flags;
int length;
int lastValidFrame;
int blendFrames;
int pad;
} SpeedControlVars;
/* SpeedControlVars->flags */

@ -1319,12 +1319,12 @@ static void seq_panel_effect()
SpeedControlVars *sp =
(SpeedControlVars *)last_seq->effectdata;
uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Global Speed:", 10,70,150,19, &sp->globalSpeed, 0.0, 100.0, 0, 0, "Global Speed");
uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Global Speed:", 10,70,240,19, &sp->globalSpeed, 0.0, 100.0, 0, 0, "Global Speed");
uiDefButBitI(block, TOG, SEQ_SPEED_INTEGRATE,
B_SEQ_BUT_RELOAD,
"IPO is velocity",
10,50,150,19, &sp->flags,
10,50,240,19, &sp->flags,
0.0, 1.0, 0, 0,
"Interpret the IPO value as a "
"velocity instead of a frame number");
@ -1332,15 +1332,24 @@ static void seq_panel_effect()
uiDefButBitI(block, TOG, SEQ_SPEED_BLEND,
B_SEQ_BUT_RELOAD,
"Enable frame blending",
10,30,150,19, &sp->flags,
10,30,240,19, &sp->flags,
0.0, 1.0, 0, 0,
"Blend two frames into the "
"target for a smoother result");
if (sp->blendFrames == 0) {
sp->blendFrames = 2;
}
uiDefButI(block, NUM, B_SEQ_BUT_RELOAD, "Blend Frames:",
10,10,240,19, &sp->blendFrames,
2.0, 100.0, 0, 0,
"Maximum number of frames to blend");
uiDefButBitI(block, TOG, SEQ_SPEED_COMPRESS_IPO_Y,
B_SEQ_BUT_RELOAD,
"IPO value runs from [0..1]",
10,10,150,19, &sp->flags,
10,-10,240,19, &sp->flags,
0.0, 1.0, 0, 0,
"Scale IPO value to get the "
"target frame number.");

@ -20,7 +20,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* Contributor(s): Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
* Contributor(s): Peter Schlaile <peter [at] schlaile [dot] de> 2005-2009
*
* ***** END GPL LICENSE BLOCK *****
*/
@ -2159,7 +2159,8 @@ static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra,
{
SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
int nr = cfra - seq->start;
float f_cfra;
float f_cfra_left;
float f_cfra_right;
int cfra_left;
int cfra_right;
TStripElem * se = 0;
@ -2168,10 +2169,12 @@ static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra,
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);
f_cfra_left = seq->start + s->frameMap[nr];
if (nr != s->length - 1) {
f_cfra_right = seq->start + s->frameMap[nr+1];
} else {
f_cfra_right = f_cfra_left;
}
se = give_tstripelem(seq, cfra, in_display_range);
@ -2179,10 +2182,11 @@ static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra,
return se;
}
if (cfra_left == cfra_right ||
(s->flags & SEQ_SPEED_BLEND) == 0) {
if ((s->flags & SEQ_SPEED_BLEND) == 0) {
test_and_auto_discard_ibuf(se);
cfra_left = rint(f_cfra_left);
if (se->ibuf == NULL) {
se1 = do_build_seq_recursively_impl(
seq->seq1, cfra_left, render_size, FALSE);
@ -2217,26 +2221,85 @@ static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra,
}
if (se->ibuf == NULL) {
int bl_frames = s->blendFrames;
int diff = rint(fabs(f_cfra_right - f_cfra_left)) + 1;
int i;
float fac;
if (bl_frames > diff) {
bl_frames = diff;
}
if (bl_frames < 2) {
bl_frames = 0;
} else {
bl_frames -= 2;
}
if (bl_frames == 0) {
cfra_left = (int) floor(f_cfra_left);
cfra_right = (int) ceil(f_cfra_left);
fac = f_cfra_left - (float) cfra_left;
} else {
cfra_left = (int) rint(f_cfra_left);
cfra_right = (int) rint(f_cfra_right);
}
se1 = do_build_seq_recursively_impl(
seq->seq1, cfra_left, render_size, FALSE);
se2 = do_build_seq_recursively_impl(
seq->seq1, cfra_right, render_size, FALSE);
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 {
if (se->ibuf) {
sh = get_sequence_effect(seq);
for (i = 0; i < bl_frames; i++) {
int bl_cfra = rint(
cfra_left
+ ((float) i + 1.0) /
((float) bl_frames + 1.0) *
(cfra_right - cfra_left));
se2 = do_build_seq_recursively_impl(
seq->seq1, bl_cfra,
render_size, FALSE);
fac = 1.0 / ((float) i + 2.0);
sh.execute(seq, cfra,
f_cfra - (float) cfra_left,
f_cfra - (float) cfra_left,
fac,
fac,
se->ibuf->x, se->ibuf->y,
se1->ibuf, se2->ibuf, 0, se->ibuf);
se1 ? se1->ibuf : se->ibuf,
se2->ibuf, 0,
se->ibuf);
if (se1 && se1->ibuf) {
IMB_cache_limiter_unref(
se1->ibuf);
se1 = 0;
}
if (se2 && se2->ibuf)
IMB_cache_limiter_unref(
se2->ibuf);
}
if (bl_frames != 0) {
fac = 1.0 / ((float) bl_frames + 2.0);
}
se2 = do_build_seq_recursively_impl(
seq->seq1, cfra_right,
render_size, FALSE);
sh.execute(seq, cfra,
fac,
fac,
se->ibuf->x, se->ibuf->y,
se1 ? se1->ibuf : se->ibuf,
se2->ibuf, 0,
se->ibuf);
}
}