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:
authorHans Goudey <h.goudey@me.com>2021-08-25 01:40:18 +0300
committerHans Goudey <h.goudey@me.com>2021-08-25 01:40:18 +0300
commit137a5e162c2435662dbb299ff49771e7d2e7598f (patch)
treea40ebf526c1a320c7a9fa0c8456dfe2ffd4db6a6 /source/blender/sequencer/intern/effects.c
parentaad18a005026cfaa19c45f2477318c6e06303eae (diff)
parent5ef3afd87c54b47614254d95c9b2e9a17c60f76e (diff)
Merge branch 'master' into refactor-idprop-ui-data
Diffstat (limited to 'source/blender/sequencer/intern/effects.c')
-rw-r--r--source/blender/sequencer/intern/effects.c212
1 files changed, 79 insertions, 133 deletions
diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c
index 3ca0555d9a5..d4adad9a34d 100644
--- a/source/blender/sequencer/intern/effects.c
+++ b/source/blender/sequencer/intern/effects.c
@@ -61,6 +61,7 @@
#include "SEQ_effects.h"
#include "SEQ_proxy.h"
+#include "SEQ_relations.h"
#include "SEQ_render.h"
#include "SEQ_utils.h"
@@ -3023,7 +3024,7 @@ static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, fl
if (!i) {
Sequence *meta;
- meta = seq_find_metastrip_by_sequence(&ed->seqbase, NULL, seq);
+ meta = SEQ_find_metastrip_by_sequence(&ed->seqbase, NULL, seq);
if (meta) {
i = do_adjustment_impl(context, meta, timeline_frame);
@@ -3069,8 +3070,6 @@ static void init_speed_effect(Sequence *seq)
seq->effectdata = MEM_callocN(sizeof(SpeedControlVars), "speedcontrolvars");
v = (SpeedControlVars *)seq->effectdata;
- v->frameMap = NULL;
- v->length = 0;
v->speed_control_type = SEQ_SPEED_STRETCH;
v->speed_fader = 1.0f;
v->speed_fader_length = 0.0f;
@@ -3080,9 +3079,7 @@ static void init_speed_effect(Sequence *seq)
static void load_speed_effect(Sequence *seq)
{
SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
-
v->frameMap = NULL;
- v->length = 0;
}
static int num_inputs_speed(void)
@@ -3105,7 +3102,6 @@ static void copy_speed_effect(Sequence *dst, Sequence *src, const int UNUSED(fla
dst->effectdata = MEM_dupallocN(src->effectdata);
v = (SpeedControlVars *)dst->effectdata;
v->frameMap = NULL;
- v->length = 0;
}
static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
@@ -3127,164 +3123,114 @@ static int seq_effect_speed_get_strip_content_length(const Sequence *seq)
return seq->len;
}
-void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq, bool force)
+static FCurve *seq_effect_speed_speed_factor_curve_get(Scene *scene, Sequence *seq)
{
- int timeline_frame;
- float fallback_fac = 1.0f;
- SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
- FCurve *fcu = NULL;
-
- /* if not already done, load / initialize data */
- SEQ_effect_handle_get(seq);
+ return id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
+}
- if ((force == false) && (seq->len == v->length) && (v->frameMap != NULL)) {
- return;
- }
+/* Build frame map when speed in mode #SEQ_SPEED_MULTIPLY is animated.
+ * This is, because `target_frame` value is integrated over time. */
+void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq)
+{
if ((seq->seq1 == NULL) || (seq->len < 1)) {
- /* make coverity happy and check for (CID 598) input strip ... */
- return;
+ return; /* Make coverity happy and check for (CID 598) input strip... */
}
- /* XXX(campbell): new in 2.5x. should we use the animation system this way?
- * The fcurve is needed because many frames need evaluating at once. */
- switch (v->speed_control_type) {
- case SEQ_SPEED_MULTIPLY: {
- fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
- break;
- }
- case SEQ_SPEED_FRAME_NUMBER: {
- fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_frame_number", 0, NULL);
- break;
- }
- case SEQ_SPEED_LENGTH: {
- fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_length", 0, NULL);
- break;
- }
+ FCurve *fcu = seq_effect_speed_speed_factor_curve_get(scene, seq);
+ if (fcu == NULL) {
+ 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");
+ SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
+ if (v->frameMap) {
+ MEM_freeN(v->frameMap);
}
- fallback_fac = 1.0;
+ const int effect_strip_length = seq->enddisp - seq->startdisp;
+ v->frameMap = MEM_mallocN(sizeof(float) * effect_strip_length, __func__);
+ v->frameMap[0] = 0.0f;
- const int target_strip_length = seq_effect_speed_get_strip_content_length(seq->seq1);
-
- if (v->speed_control_type == SEQ_SPEED_STRETCH) {
- if ((seq->seq1->enddisp != seq->seq1->start) && (target_strip_length != 0)) {
- fallback_fac = (float)target_strip_length / (float)(seq->seq1->enddisp - seq->seq1->start);
- fcu = NULL;
- }
- }
- else {
- /* if there is no fcurve, use value as simple multiplier */
- if (!fcu) {
- switch (v->speed_control_type) {
- case SEQ_SPEED_MULTIPLY: {
- fallback_fac = v->speed_fader;
- break;
- }
- case SEQ_SPEED_FRAME_NUMBER: {
- fallback_fac = v->speed_fader_frame_number;
- break;
- }
- case SEQ_SPEED_LENGTH: {
- fallback_fac = v->speed_fader_length;
- break;
- }
- }
- }
+ float target_frame = 0;
+ for (int frame_index = 1; frame_index < effect_strip_length; frame_index++) {
+ target_frame += evaluate_fcurve(fcu, seq->startdisp + frame_index);
+ v->frameMap[frame_index] = target_frame;
}
+}
- if (ELEM(v->speed_control_type, SEQ_SPEED_MULTIPLY, SEQ_SPEED_STRETCH)) {
- float cursor = 0;
- float facf;
-
- v->frameMap[0] = 0;
- v->lastValidFrame = 0;
-
- for (timeline_frame = 1; timeline_frame < v->length; timeline_frame++) {
- if (fcu) {
- facf = evaluate_fcurve(fcu, seq->startdisp + timeline_frame);
- }
- else {
- facf = fallback_fac;
- }
-
- cursor += facf;
-
- if (cursor >= target_strip_length) {
- v->frameMap[timeline_frame] = target_strip_length - 1;
- }
- else {
- v->frameMap[timeline_frame] = cursor;
- v->lastValidFrame = timeline_frame;
- }
- }
+static void seq_effect_speed_frame_map_ensure(Scene *scene, Sequence *seq)
+{
+ SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
+ if (v->frameMap != NULL) {
+ return;
}
- else {
- float facf;
- v->lastValidFrame = 0;
- for (timeline_frame = 0; timeline_frame < v->length; timeline_frame++) {
+ seq_effect_speed_rebuild_map(scene, seq);
+}
- if (fcu) {
- facf = evaluate_fcurve(fcu, seq->startdisp + timeline_frame);
- }
- else {
- facf = fallback_fac;
- }
+/* Override timeline_frame when rendering speed effect input. */
+float seq_speed_effect_target_frame_get(Scene *scene,
+ Sequence *seq_speed,
+ float timeline_frame,
+ int input)
+{
+ if (seq_speed->seq1 == NULL) {
+ return 0.0f;
+ }
- if (v->speed_control_type == SEQ_SPEED_LENGTH) {
- facf *= target_strip_length;
- facf /= 100.0f;
- }
+ SEQ_effect_handle_get(seq_speed); /* Ensure, that data are initialized. */
+ int frame_index = seq_give_frame_index(seq_speed, timeline_frame);
+ SpeedControlVars *s = (SpeedControlVars *)seq_speed->effectdata;
+ const Sequence *source = seq_speed->seq1;
- if (facf >= target_strip_length) {
- facf = target_strip_length - 1;
+ float target_frame = 0.0f;
+ switch (s->speed_control_type) {
+ case SEQ_SPEED_STRETCH: {
+ const float target_content_length = seq_effect_speed_get_strip_content_length(source);
+ const float target_strip_length = source->enddisp - source->startdisp;
+ const float ratio = target_content_length / target_strip_length;
+ target_frame = frame_index * ratio;
+ break;
+ }
+ case SEQ_SPEED_MULTIPLY: {
+ FCurve *fcu = seq_effect_speed_speed_factor_curve_get(scene, seq_speed);
+ if (fcu != NULL) {
+ seq_effect_speed_frame_map_ensure(scene, seq_speed);
+ target_frame = s->frameMap[frame_index];
}
else {
- v->lastValidFrame = timeline_frame;
+ target_frame = frame_index * s->speed_fader;
}
- v->frameMap[timeline_frame] = facf;
+ break;
}
+ case SEQ_SPEED_LENGTH:
+ target_frame = seq_effect_speed_get_strip_content_length(source) *
+ (s->speed_fader_length / 100.0f);
+ break;
+ case SEQ_SPEED_FRAME_NUMBER:
+ target_frame = s->speed_fader_frame_number;
+ break;
}
-}
-/* Override timeline_frame when rendering speed effect input. */
-float seq_speed_effect_target_frame_get(const SeqRenderData *context,
- Sequence *seq,
- float timeline_frame,
- int input)
-{
- int frame_index = seq_give_frame_index(seq, timeline_frame);
- SpeedControlVars *s = (SpeedControlVars *)seq->effectdata;
- seq_effect_speed_rebuild_map(context->scene, seq, false);
+ CLAMP(target_frame, 0, seq_effect_speed_get_strip_content_length(source));
+ target_frame += seq_speed->start;
/* No interpolation. */
if ((s->flags & SEQ_SPEED_USE_INTERPOLATION) == 0) {
- return seq->start + s->frameMap[frame_index];
+ return target_frame;
}
- /* We need to provide current and next image for interpolation. */
- if (input == 0) { /* Current frame. */
- return floor(seq->start + s->frameMap[frame_index]);
- }
- /* Next frame. */
- return ceil(seq->start + s->frameMap[frame_index]);
+ /* Interpolation is used, switch between current and next frame based on which input is
+ * requested. */
+ return input == 0 ? target_frame : ceil(target_frame);
}
-static float speed_effect_interpolation_ratio_get(SpeedControlVars *s,
- Sequence *seq,
+static float speed_effect_interpolation_ratio_get(Scene *scene,
+ Sequence *seq_speed,
float timeline_frame)
{
- int frame_index = seq_give_frame_index(seq, timeline_frame);
- return s->frameMap[frame_index] - floor(s->frameMap[frame_index]);
+ const float target_frame = seq_speed_effect_target_frame_get(
+ scene, seq_speed, timeline_frame, 0);
+ return target_frame - floor(target_frame);
}
static ImBuf *do_speed_effect(const SeqRenderData *context,
@@ -3302,7 +3248,7 @@ static ImBuf *do_speed_effect(const SeqRenderData *context,
if (s->flags & SEQ_SPEED_USE_INTERPOLATION) {
out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
- facf0 = facf1 = speed_effect_interpolation_ratio_get(s, seq, timeline_frame);
+ facf0 = facf1 = speed_effect_interpolation_ratio_get(context->scene, seq, timeline_frame);
/* Current frame is ibuf1, next frame is ibuf2. */
out = seq_render_effect_execute_threaded(
&cross_effect, context, NULL, timeline_frame, facf0, facf1, ibuf1, ibuf2, ibuf3);