Changeset View
Changeset View
Standalone View
Standalone View
source/blender/sequencer/intern/effects.c
| Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "RE_pipeline.h" | #include "RE_pipeline.h" | ||||
| #include "SEQ_effects.h" | #include "SEQ_effects.h" | ||||
| #include "SEQ_proxy.h" | #include "SEQ_proxy.h" | ||||
| #include "SEQ_render.h" | #include "SEQ_render.h" | ||||
| #include "SEQ_time.h" | |||||
| #include "SEQ_utils.h" | #include "SEQ_utils.h" | ||||
| #include "BLF_api.h" | #include "BLF_api.h" | ||||
| #include "effects.h" | #include "effects.h" | ||||
| #include "render.h" | #include "render.h" | ||||
| #include "strip_time.h" | #include "strip_time.h" | ||||
| #include "utils.h" | #include "utils.h" | ||||
| ▲ Show 20 Lines • Show All 3,054 Lines • ▼ Show 20 Lines | static void copy_speed_effect(Sequence *dst, Sequence *src, const int UNUSED(flag)) | ||||
| v->length = 0; | v->length = 0; | ||||
| } | } | ||||
| static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1)) | static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1)) | ||||
| { | { | ||||
| return EARLY_DO_EFFECT; | return EARLY_DO_EFFECT; | ||||
| } | } | ||||
| static void store_icu_yrange_speed(Sequence *seq, short UNUSED(adrcode), float *ymin, float *ymax) | static void store_icu_yrange_speed( | ||||
| const Scene *scene, Sequence *seq, short UNUSED(adrcode), float *ymin, float *ymax) | |||||
| { | { | ||||
| SpeedControlVars *v = (SpeedControlVars *)seq->effectdata; | SpeedControlVars *v = (SpeedControlVars *)seq->effectdata; | ||||
| /* if not already done, load / initialize data */ | /* if not already done, load / initialize data */ | ||||
| SEQ_effect_handle_get(seq); | SEQ_effect_handle_get(seq); | ||||
| if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) { | if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) { | ||||
| *ymin = -100.0; | *ymin = -100.0; | ||||
| *ymax = 100.0; | *ymax = 100.0; | ||||
| } | } | ||||
| else { | else { | ||||
| if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) { | if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) { | ||||
| *ymin = 0.0; | *ymin = 0.0; | ||||
| *ymax = 1.0; | *ymax = 1.0; | ||||
| } | } | ||||
| else { | else { | ||||
| *ymin = 0.0; | *ymin = 0.0; | ||||
| *ymax = seq->len; | *ymax = SEQ_time_strip_length_get(scene, seq); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * Generator strips with zero inputs have their length set to 1 permanently. In some cases it is | * Generator strips with zero inputs have their length set to 1 permanently. In some cases it is | ||||
| * useful to use speed effect on these strips because they can be animated. This can be done by | * useful to use speed effect on these strips because they can be animated. This can be done by | ||||
| * using their length as is on timeline as content length. See T82698. | * using their length as is on timeline as content length. See T82698. | ||||
| */ | */ | ||||
| static int seq_effect_speed_get_strip_content_length(const Sequence *seq) | static int seq_effect_speed_get_strip_content_length(Scene *scene, const Sequence *seq) | ||||
| { | { | ||||
| if ((seq->type & SEQ_TYPE_EFFECT) != 0 && SEQ_effect_get_num_inputs(seq->type) == 0) { | if ((seq->type & SEQ_TYPE_EFFECT) != 0 && SEQ_effect_get_num_inputs(seq->type) == 0) { | ||||
| return seq->enddisp - seq->startdisp; | return seq->enddisp - seq->startdisp; | ||||
| } | } | ||||
| return seq->len; | return SEQ_time_strip_length_get(scene, seq); | ||||
| } | } | ||||
| void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq, bool force) | void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq, bool force) | ||||
| { | { | ||||
| int timeline_frame; | int timeline_frame; | ||||
| float fallback_fac = 1.0f; | float fallback_fac = 1.0f; | ||||
| SpeedControlVars *v = (SpeedControlVars *)seq->effectdata; | SpeedControlVars *v = (SpeedControlVars *)seq->effectdata; | ||||
| FCurve *fcu = NULL; | FCurve *fcu = NULL; | ||||
| int flags = v->flags; | int flags = v->flags; | ||||
| /* if not already done, load / initialize data */ | /* if not already done, load / initialize data */ | ||||
| SEQ_effect_handle_get(seq); | SEQ_effect_handle_get(seq); | ||||
| if ((force == false) && (seq->len == v->length) && (v->frameMap != NULL)) { | if ((force == false) && (SEQ_time_strip_length_get(scene, seq) == v->length) && | ||||
| (v->frameMap != NULL)) { | |||||
| return; | return; | ||||
| } | } | ||||
| if ((seq->seq1 == NULL) || (seq->len < 1)) { | if ((seq->seq1 == NULL) || (seq->len < 1)) { | ||||
| /* make coverity happy and check for (CID 598) input strip ... */ | /* make coverity happy and check for (CID 598) input strip ... */ | ||||
| return; | return; | ||||
| } | } | ||||
| /* XXX - new in 2.5x. should we use the animation system this way? | /* XXX - new in 2.5x. should we use the animation system this way? | ||||
| * The fcurve is needed because many frames need evaluating at once - campbell */ | * The fcurve is needed because many frames need evaluating at once - campbell */ | ||||
| fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL); | fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL); | ||||
| if (!v->frameMap || v->length != seq->len) { | if (!v->frameMap || v->length != SEQ_time_strip_length_get(scene, seq)) { | ||||
| if (v->frameMap) { | if (v->frameMap) { | ||||
| MEM_freeN(v->frameMap); | MEM_freeN(v->frameMap); | ||||
| } | } | ||||
| v->length = seq->len; | v->length = SEQ_time_strip_length_get(scene, seq); | ||||
| v->frameMap = MEM_callocN(sizeof(float) * v->length, "speedcontrol frameMap"); | v->frameMap = MEM_callocN(sizeof(float) * v->length, "speedcontrol frameMap"); | ||||
| } | } | ||||
| fallback_fac = 1.0; | fallback_fac = 1.0; | ||||
| const int target_strip_length = seq_effect_speed_get_strip_content_length(seq->seq1); | const int target_strip_length = seq_effect_speed_get_strip_content_length(scene, seq->seq1); | ||||
| if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) { | if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) { | ||||
| if ((seq->seq1->enddisp != seq->seq1->start) && (target_strip_length != 0)) { | if ((seq->seq1->enddisp != seq->seq1->start) && (target_strip_length != 0)) { | ||||
| fallback_fac = (float)target_strip_length / (float)(seq->seq1->enddisp - seq->seq1->start); | fallback_fac = (float)target_strip_length / (float)(seq->seq1->enddisp - seq->seq1->start); | ||||
| flags = SEQ_SPEED_INTEGRATE; | flags = SEQ_SPEED_INTEGRATE; | ||||
| fcu = NULL; | fcu = NULL; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /* Override timeline_frame when rendering speed effect input. */ | /* Override timeline_frame when rendering speed effect input. */ | ||||
| float seq_speed_effect_target_frame_get(const SeqRenderData *context, | float seq_speed_effect_target_frame_get(const SeqRenderData *context, | ||||
| Sequence *seq, | Sequence *seq, | ||||
| float timeline_frame, | float timeline_frame, | ||||
| int input) | int input) | ||||
| { | { | ||||
| int frame_index = seq_give_frame_index(seq, timeline_frame); | int frame_index = seq_give_frame_index(context->scene, seq, timeline_frame); | ||||
| SpeedControlVars *s = (SpeedControlVars *)seq->effectdata; | SpeedControlVars *s = (SpeedControlVars *)seq->effectdata; | ||||
| seq_effect_speed_rebuild_map(context->scene, seq, false); | seq_effect_speed_rebuild_map(context->scene, seq, false); | ||||
| /* No interpolation. */ | /* No interpolation. */ | ||||
| if ((s->flags & SEQ_SPEED_USE_INTERPOLATION) == 0) { | if ((s->flags & SEQ_SPEED_USE_INTERPOLATION) == 0) { | ||||
| return seq->start + s->frameMap[frame_index]; | return seq->start + s->frameMap[frame_index]; | ||||
| } | } | ||||
| /* We need to provide current and next image for interpolation. */ | /* We need to provide current and next image for interpolation. */ | ||||
| if (input == 0) { /* Current frame. */ | if (input == 0) { /* Current frame. */ | ||||
| return floor(seq->start + s->frameMap[frame_index]); | return floor(seq->start + s->frameMap[frame_index]); | ||||
| } | } | ||||
| /* Next frame. */ | /* Next frame. */ | ||||
| return ceil(seq->start + s->frameMap[frame_index]); | return ceil(seq->start + s->frameMap[frame_index]); | ||||
| } | } | ||||
| static float speed_effect_interpolation_ratio_get(SpeedControlVars *s, | static float speed_effect_interpolation_ratio_get(SpeedControlVars *s, | ||||
| Sequence *seq, | Sequence *seq, | ||||
| float timeline_frame) | int frame_index) | ||||
| { | { | ||||
| int frame_index = seq_give_frame_index(seq, timeline_frame); | |||||
| return s->frameMap[frame_index] - floor(s->frameMap[frame_index]); | return s->frameMap[frame_index] - floor(s->frameMap[frame_index]); | ||||
| } | } | ||||
| static ImBuf *do_speed_effect(const SeqRenderData *context, | static ImBuf *do_speed_effect(const SeqRenderData *context, | ||||
| Sequence *seq, | Sequence *seq, | ||||
| float timeline_frame, | float timeline_frame, | ||||
| float facf0, | float facf0, | ||||
| float facf1, | float facf1, | ||||
| ImBuf *ibuf1, | ImBuf *ibuf1, | ||||
| ImBuf *ibuf2, | ImBuf *ibuf2, | ||||
| ImBuf *ibuf3) | ImBuf *ibuf3) | ||||
| { | { | ||||
| SpeedControlVars *s = (SpeedControlVars *)seq->effectdata; | SpeedControlVars *s = (SpeedControlVars *)seq->effectdata; | ||||
| struct SeqEffectHandle cross_effect = get_sequence_effect_impl(SEQ_TYPE_CROSS); | struct SeqEffectHandle cross_effect = get_sequence_effect_impl(SEQ_TYPE_CROSS); | ||||
| ImBuf *out; | ImBuf *out; | ||||
| if (s->flags & SEQ_SPEED_USE_INTERPOLATION) { | if (s->flags & SEQ_SPEED_USE_INTERPOLATION) { | ||||
| out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); | out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); | ||||
| facf0 = facf1 = speed_effect_interpolation_ratio_get(s, seq, timeline_frame); | int frame_index = seq_give_frame_index(context->scene, seq, timeline_frame); | ||||
| facf0 = facf1 = speed_effect_interpolation_ratio_get(s, seq, frame_index); | |||||
| /* Current frame is ibuf1, next frame is ibuf2. */ | /* Current frame is ibuf1, next frame is ibuf2. */ | ||||
| out = seq_render_effect_execute_threaded( | out = seq_render_effect_execute_threaded( | ||||
| &cross_effect, context, NULL, timeline_frame, facf0, facf1, ibuf1, ibuf2, ibuf3); | &cross_effect, context, NULL, timeline_frame, facf0, facf1, ibuf1, ibuf2, ibuf3); | ||||
| return out; | return out; | ||||
| } | } | ||||
| /* No interpolation. */ | /* No interpolation. */ | ||||
| return IMB_dupImBuf(ibuf1); | return IMB_dupImBuf(ibuf1); | ||||
| ▲ Show 20 Lines • Show All 746 Lines • ▼ Show 20 Lines | |||||
| static int early_out_mul_input2(Sequence *UNUSED(seq), float facf0, float facf1) | static int early_out_mul_input2(Sequence *UNUSED(seq), float facf0, float facf1) | ||||
| { | { | ||||
| if (facf0 == 0.0f && facf1 == 0.0f) { | if (facf0 == 0.0f && facf1 == 0.0f) { | ||||
| return EARLY_USE_INPUT_1; | return EARLY_USE_INPUT_1; | ||||
| } | } | ||||
| return EARLY_DO_EFFECT; | return EARLY_DO_EFFECT; | ||||
| } | } | ||||
| static void store_icu_yrange_noop(Sequence *UNUSED(seq), | static void store_icu_yrange_noop(const Scene *UNUSED(scene), | ||||
| Sequence *UNUSED(seq), | |||||
| short UNUSED(adrcode), | short UNUSED(adrcode), | ||||
| float *UNUSED(ymin), | float *UNUSED(ymin), | ||||
| float *UNUSED(ymax)) | float *UNUSED(ymax)) | ||||
| { | { | ||||
| /* defaults are fine */ | /* defaults are fine */ | ||||
| } | } | ||||
| static void get_default_fac_noop(Sequence *UNUSED(seq), | static void get_default_fac_noop(const Scene *scene, | ||||
| Sequence *UNUSED(seq), | |||||
| float UNUSED(timeline_frame), | float UNUSED(timeline_frame), | ||||
| float *facf0, | float *facf0, | ||||
| float *facf1) | float *facf1) | ||||
| { | { | ||||
| *facf0 = *facf1 = 1.0; | *facf0 = *facf1 = 1.0; | ||||
| } | } | ||||
| static void get_default_fac_fade(Sequence *seq, float timeline_frame, float *facf0, float *facf1) | static void get_default_fac_fade( | ||||
| const Scene *scene, Sequence *seq, float timeline_frame, float *facf0, float *facf1) | |||||
| { | { | ||||
| *facf0 = (float)(timeline_frame - seq->startdisp); | *facf0 = (float)(timeline_frame - seq->startdisp); | ||||
| *facf1 = (float)(*facf0 + 0.5f); | *facf1 = (float)(*facf0 + 0.5f); | ||||
| *facf0 /= seq->len; | *facf0 /= SEQ_time_strip_length_get(scene, seq); | ||||
| *facf1 /= seq->len; | *facf1 /= SEQ_time_strip_length_get(scene, seq); | ||||
| } | } | ||||
| static struct ImBuf *init_execution(const SeqRenderData *context, | static struct ImBuf *init_execution(const SeqRenderData *context, | ||||
| ImBuf *ibuf1, | ImBuf *ibuf1, | ||||
| ImBuf *ibuf2, | ImBuf *ibuf2, | ||||
| ImBuf *ibuf3) | ImBuf *ibuf3) | ||||
| { | { | ||||
| ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); | ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); | ||||
| ▲ Show 20 Lines • Show All 221 Lines • Show Last 20 Lines | |||||