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:
authorRichard Antalik <richardantalik@gmail.com>2022-06-29 13:45:59 +0300
committerRichard Antalik <richardantalik@gmail.com>2022-06-29 13:48:34 +0300
commit302b04a5a3fc0e767ac784424f78ce2edf5d2844 (patch)
treedef4de621fbb0a194b350da781f054c6aefbab35 /source/blender/sequencer
parentc51b8ec86364585c4088837c603b39752065bc34 (diff)
VSE: Improved Retiming system
Patch implements better way to control playback speed than it is possible to do with speed effect. Speed factor property can be set in Time panel. There are 2 layers of control: Option to retime movie to match scene FPS rate. Custom speed factor to control playback rate. Since playback rate is strip property, it is now possible to manipulate strip as normal one even if it is retimed. To facilitate manipulation, some functions need to consider speed factor and apply necessary corrections to strip offset or strip start. These corrections may need to be float numbers, so start and offsets must be float as well. Sound strips now use speed factor instead of pitch. This means, that strips will change length to match usable length. In addition, it is possible to group movie and sound strip and change speed of meta strip.
Diffstat (limited to 'source/blender/sequencer')
-rw-r--r--source/blender/sequencer/SEQ_add.h6
-rw-r--r--source/blender/sequencer/SEQ_edit.h5
-rw-r--r--source/blender/sequencer/SEQ_effects.h5
-rw-r--r--source/blender/sequencer/SEQ_iterator.h16
-rw-r--r--source/blender/sequencer/SEQ_render.h13
-rw-r--r--source/blender/sequencer/SEQ_sound.h1
-rw-r--r--source/blender/sequencer/SEQ_time.h24
-rw-r--r--source/blender/sequencer/SEQ_transform.h16
-rw-r--r--source/blender/sequencer/intern/disk_cache.c4
-rw-r--r--source/blender/sequencer/intern/effects.c44
-rw-r--r--source/blender/sequencer/intern/image_cache.c38
-rw-r--r--source/blender/sequencer/intern/iterator.c37
-rw-r--r--source/blender/sequencer/intern/prefetch.c2
-rw-r--r--source/blender/sequencer/intern/proxy.c29
-rw-r--r--source/blender/sequencer/intern/render.c65
-rw-r--r--source/blender/sequencer/intern/render.h3
-rw-r--r--source/blender/sequencer/intern/sequencer.c12
-rw-r--r--source/blender/sequencer/intern/sound.c14
-rw-r--r--source/blender/sequencer/intern/strip_add.c21
-rw-r--r--source/blender/sequencer/intern/strip_edit.c140
-rw-r--r--source/blender/sequencer/intern/strip_relations.c26
-rw-r--r--source/blender/sequencer/intern/strip_time.c193
-rw-r--r--source/blender/sequencer/intern/strip_time.h4
-rw-r--r--source/blender/sequencer/intern/strip_transform.c188
-rw-r--r--source/blender/sequencer/intern/utils.c5
25 files changed, 513 insertions, 398 deletions
diff --git a/source/blender/sequencer/SEQ_add.h b/source/blender/sequencer/SEQ_add.h
index dea5151598c..7c2d50a815e 100644
--- a/source/blender/sequencer/SEQ_add.h
+++ b/source/blender/sequencer/SEQ_add.h
@@ -50,6 +50,7 @@ typedef struct SeqLoadData {
struct Stereo3dFormat *stereo3d_format;
bool allow_invalid_file; /* Used by RNA API to create placeholder strips. */
double r_video_stream_start; /* For AV synchronization. Set by `SEQ_add_movie_strip`. */
+ bool adjust_playback_rate;
} SeqLoadData;
/**
@@ -176,7 +177,10 @@ void SEQ_add_image_set_directory(struct Sequence *seq, char *path);
* \param strip_frame: frame index of strip to be changed
* \param filename: image filename (only filename, not complete path)
*/
-void SEQ_add_image_load_file(struct Sequence *seq, size_t strip_frame, char *filename);
+void SEQ_add_image_load_file(struct Scene *scene,
+ struct Sequence *seq,
+ size_t strip_frame,
+ char *filename);
/**
* Set image strip alpha mode
*
diff --git a/source/blender/sequencer/SEQ_edit.h b/source/blender/sequencer/SEQ_edit.h
index 2f07d5ae940..ff9c387e527 100644
--- a/source/blender/sequencer/SEQ_edit.h
+++ b/source/blender/sequencer/SEQ_edit.h
@@ -16,7 +16,10 @@ struct Main;
struct Scene;
struct Sequence;
-int SEQ_edit_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str);
+int SEQ_edit_sequence_swap(struct Scene *scene,
+ struct Sequence *seq_a,
+ struct Sequence *seq_b,
+ const char **error_str);
/**
* Move sequence to seqbase.
*
diff --git a/source/blender/sequencer/SEQ_effects.h b/source/blender/sequencer/SEQ_effects.h
index e5af6f963e2..fa5d6d18736 100644
--- a/source/blender/sequencer/SEQ_effects.h
+++ b/source/blender/sequencer/SEQ_effects.h
@@ -55,7 +55,10 @@ struct SeqEffectHandle {
int (*early_out)(struct Sequence *seq, float fac);
/* sets the default `fac` value */
- void (*get_default_fac)(struct Sequence *seq, float timeline_frame, float *fac);
+ void (*get_default_fac)(const struct Scene *scene,
+ struct Sequence *seq,
+ float timeline_frame,
+ float *fac);
/* execute the effect
* sequence effects are only required to either support
diff --git a/source/blender/sequencer/SEQ_iterator.h b/source/blender/sequencer/SEQ_iterator.h
index 1f94574513c..e5adb2a33b1 100644
--- a/source/blender/sequencer/SEQ_iterator.h
+++ b/source/blender/sequencer/SEQ_iterator.h
@@ -157,9 +157,11 @@ void SEQ_collection_exclude(SeqCollection *collection, SeqCollection *exclude_el
* \param collection: SeqCollection to be expanded
* \param seq_query_func: query function callback
*/
-void SEQ_collection_expand(struct ListBase *seqbase,
+void SEQ_collection_expand(const struct Scene *scene,
+ struct ListBase *seqbase,
SeqCollection *collection,
- void seq_query_func(struct Sequence *seq_reference,
+ void seq_query_func(const struct Scene *scene,
+ struct Sequence *seq_reference,
struct ListBase *seqbase,
SeqCollection *collection));
/**
@@ -171,8 +173,10 @@ void SEQ_collection_expand(struct ListBase *seqbase,
* \return strip collection
*/
SeqCollection *SEQ_query_by_reference(struct Sequence *seq_reference,
+ const struct Scene *scene,
struct ListBase *seqbase,
- void seq_query_func(struct Sequence *seq_reference,
+ void seq_query_func(const struct Scene *scene,
+ struct Sequence *seq_reference,
struct ListBase *seqbase,
SeqCollection *collection));
/**
@@ -211,7 +215,8 @@ SeqCollection *SEQ_query_all_strips_recursive(ListBase *seqbase);
* \param displayed_channel: viewed channel. when set to 0, no channel filter is applied
* \return strip collection
*/
-SeqCollection *SEQ_query_rendered_strips(ListBase *channels,
+SeqCollection *SEQ_query_rendered_strips(const struct Scene *scene,
+ ListBase *channels,
ListBase *seqbase,
int timeline_frame,
int displayed_channel);
@@ -224,7 +229,8 @@ SeqCollection *SEQ_query_rendered_strips(ListBase *channels,
* \param seqbase: ListBase in which strips are queried
* \param collection: collection to be filled
*/
-void SEQ_query_strip_effect_chain(struct Sequence *seq_reference,
+void SEQ_query_strip_effect_chain(const struct Scene *scene,
+ struct Sequence *seq_reference,
struct ListBase *seqbase,
SeqCollection *collection);
void SEQ_filter_selected_strips(SeqCollection *collection);
diff --git a/source/blender/sequencer/SEQ_render.h b/source/blender/sequencer/SEQ_render.h
index a74eba5fc6f..9c163de4230 100644
--- a/source/blender/sequencer/SEQ_render.h
+++ b/source/blender/sequencer/SEQ_render.h
@@ -79,20 +79,23 @@ struct ImBuf *SEQ_get_thumbnail(const struct SeqRenderData *context,
/**
* Get frame for first thumbnail.
*/
-float SEQ_render_thumbnail_first_frame_get(struct Sequence *seq,
+float SEQ_render_thumbnail_first_frame_get(const struct Scene *scene,
+ struct Sequence *seq,
float frame_step,
struct rctf *view_area);
/**
* Get frame for first thumbnail.
*/
-float SEQ_render_thumbnail_next_frame_get(struct Sequence *seq,
+float SEQ_render_thumbnail_next_frame_get(const struct Scene *scene,
+ struct Sequence *seq,
float last_frame,
float frame_step);
/**
* Get frame step for equally spaced thumbnails. These thumbnails should always be present in
* memory, so they can be used when zooming.
*/
-int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const struct Sequence *seq);
+int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const struct Scene *scene,
+ const struct Sequence *seq);
/**
* Render set of evenly spaced thumbnails that are drawn when zooming..
*/
@@ -112,7 +115,9 @@ void SEQ_render_new_render_data(struct Main *bmain,
int for_render,
SeqRenderData *r_context);
int SEQ_render_evaluate_frame(struct ListBase *seqbase, int timeline_frame);
-struct StripElem *SEQ_render_give_stripelem(struct Sequence *seq, int timeline_frame);
+struct StripElem *SEQ_render_give_stripelem(const struct Scene *scene,
+ struct Sequence *seq,
+ int timeline_frame);
void SEQ_render_imbuf_from_sequencer_space(struct Scene *scene, struct ImBuf *ibuf);
void SEQ_render_pixel_from_sequencer_space_v4(struct Scene *scene, float pixel[4]);
diff --git a/source/blender/sequencer/SEQ_sound.h b/source/blender/sequencer/SEQ_sound.h
index 52bdb68a554..e49f081109f 100644
--- a/source/blender/sequencer/SEQ_sound.h
+++ b/source/blender/sequencer/SEQ_sound.h
@@ -20,6 +20,7 @@ void SEQ_sound_update_bounds_all(struct Scene *scene);
void SEQ_sound_update_bounds(struct Scene *scene, struct Sequence *seq);
void SEQ_sound_update(struct Scene *scene, struct bSound *sound);
void SEQ_sound_update_length(struct Main *bmain, struct Scene *scene);
+float SEQ_sound_pitch_get(const struct Scene *scene, const struct Sequence *seq);
#ifdef __cplusplus
}
diff --git a/source/blender/sequencer/SEQ_time.h b/source/blender/sequencer/SEQ_time.h
index eab10f2e852..69dc20d39ca 100644
--- a/source/blender/sequencer/SEQ_time.h
+++ b/source/blender/sequencer/SEQ_time.h
@@ -29,7 +29,9 @@ void SEQ_timeline_init_boundbox(const struct Scene *scene, struct rctf *rect);
* \param seqbase: ListBase in which strips are located
* \param rect: output parameter to be filled with strips' boundaries
*/
-void SEQ_timeline_expand_boundbox(const struct ListBase *seqbase, struct rctf *rect);
+void SEQ_timeline_expand_boundbox(const struct Scene *scene,
+ const struct ListBase *seqbase,
+ struct rctf *rect);
/**
* Define boundary rectangle of sequencer timeline and fill in rect data
*
@@ -56,15 +58,23 @@ int SEQ_time_find_next_prev_edit(struct Scene *scene,
* \param timeline_frame: absolute frame position
* \return true if strip intersects with timeline frame.
*/
-bool SEQ_time_strip_intersects_frame(const struct Sequence *seq, int timeline_frame);
-bool SEQ_time_has_still_frames(const struct Sequence *seq);
-bool SEQ_time_has_left_still_frames(const struct Sequence *seq);
-bool SEQ_time_has_right_still_frames(const struct Sequence *seq);
+bool SEQ_time_strip_intersects_frame(const struct Scene *scene,
+ const struct Sequence *seq,
+ int timeline_frame);
+bool SEQ_time_has_still_frames(const struct Scene *scene, const struct Sequence *seq);
+bool SEQ_time_has_left_still_frames(const struct Scene *scene, const struct Sequence *seq);
+bool SEQ_time_has_right_still_frames(const struct Scene *scene, const struct Sequence *seq);
-int SEQ_time_left_handle_frame_get(const struct Sequence *seq);
-int SEQ_time_right_handle_frame_get(const struct Sequence *seq);
+int SEQ_time_left_handle_frame_get(const struct Scene *scene, const struct Sequence *seq);
+int SEQ_time_right_handle_frame_get(const struct Scene *scene, const struct Sequence *seq);
void SEQ_time_left_handle_frame_set(const struct Scene *scene, struct Sequence *seq, int val);
void SEQ_time_right_handle_frame_set(const struct Scene *scene, struct Sequence *seq, int val);
+int SEQ_time_strip_length_get(const struct Scene *scene, const struct Sequence *seq);
+void SEQ_time_speed_factor_set(const struct Scene *scene,
+ struct Sequence *seq,
+ const float speed_factor);
+float SEQ_time_start_frame_get(const struct Sequence *seq);
+void SEQ_time_start_frame_set(const struct Scene *scene, struct Sequence *seq, int timeline_frame);
void SEQ_time_update_meta_strip_range(const struct Scene *scene, struct Sequence *seq_meta);
#ifdef __cplusplus
diff --git a/source/blender/sequencer/SEQ_transform.h b/source/blender/sequencer/SEQ_transform.h
index 31a7399f844..8bc7733861c 100644
--- a/source/blender/sequencer/SEQ_transform.h
+++ b/source/blender/sequencer/SEQ_transform.h
@@ -17,14 +17,6 @@ struct Scene;
struct SeqCollection;
struct Sequence;
-/**
- * Use to impose limits when dragging/extending - so impossible situations don't happen.
- * Can't use the #SEQ_LEFTSEL and #SEQ_LEFTSEL directly because the strip may be in a meta-strip.
- */
-void SEQ_transform_handle_xlimits(const struct Scene *scene,
- struct Sequence *seq,
- int leftflag,
- int rightflag);
bool SEQ_transform_sequence_can_be_translated(struct Sequence *seq);
/**
* Used so we can do a quick check for single image seq
@@ -32,8 +24,12 @@ bool SEQ_transform_sequence_can_be_translated(struct Sequence *seq);
*/
bool SEQ_transform_single_image_check(struct Sequence *seq);
void SEQ_transform_fix_single_image_seq_offsets(const struct Scene *scene, struct Sequence *seq);
-bool SEQ_transform_test_overlap(struct ListBase *seqbasep, struct Sequence *test);
-bool SEQ_transform_test_overlap_seq_seq(struct Sequence *seq1, struct Sequence *seq2);
+bool SEQ_transform_test_overlap(const struct Scene *scene,
+ struct ListBase *seqbasep,
+ struct Sequence *test);
+bool SEQ_transform_test_overlap_seq_seq(const struct Scene *scene,
+ struct Sequence *seq1,
+ struct Sequence *seq2);
void SEQ_transform_translate_sequence(struct Scene *scene, struct Sequence *seq, int delta);
/**
* \return 0 if there weren't enough space.
diff --git a/source/blender/sequencer/intern/disk_cache.c b/source/blender/sequencer/intern/disk_cache.c
index cc34066c432..37830205588 100644
--- a/source/blender/sequencer/intern/disk_cache.c
+++ b/source/blender/sequencer/intern/disk_cache.c
@@ -412,8 +412,8 @@ void seq_disk_cache_invalidate(SeqDiskCache *disk_cache,
BLI_mutex_lock(&disk_cache->read_write_mutex);
- start = SEQ_time_left_handle_frame_get(seq_changed) - DCACHE_IMAGES_PER_FILE;
- end = SEQ_time_right_handle_frame_get(seq_changed);
+ start = SEQ_time_left_handle_frame_get(scene, seq_changed) - DCACHE_IMAGES_PER_FILE;
+ end = SEQ_time_right_handle_frame_get(scene, seq_changed);
seq_disk_cache_delete_invalid_files(disk_cache, scene, seq, invalidate_types, start, end);
diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c
index 0e5e56908b0..368c00534be 100644
--- a/source/blender/sequencer/intern/effects.c
+++ b/source/blender/sequencer/intern/effects.c
@@ -2475,8 +2475,8 @@ static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, fl
* frame is static after end of strip). This is how most strips behave. This way transition
* effects that doesn't overlap or speed effect can't fail rendering outside of strip range. */
timeline_frame = clamp_i(timeline_frame,
- SEQ_time_left_handle_frame_get(seq),
- SEQ_time_right_handle_frame_get(seq) - 1);
+ SEQ_time_left_handle_frame_get(context->scene, seq),
+ SEQ_time_right_handle_frame_get(context->scene, seq) - 1);
if (seq->machine > 1) {
i = seq_render_give_ibuf_seqbase(
@@ -2583,13 +2583,14 @@ static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(fac))
* 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.
*/
-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) {
- return SEQ_time_right_handle_frame_get(seq) - SEQ_time_left_handle_frame_get(seq);
+ return SEQ_time_right_handle_frame_get(scene, seq) -
+ SEQ_time_left_handle_frame_get(scene, seq);
}
- return seq->len;
+ return SEQ_time_strip_length_get(scene, seq);
}
static FCurve *seq_effect_speed_speed_factor_curve_get(Scene *scene, Sequence *seq)
@@ -2613,14 +2614,14 @@ void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq)
MEM_freeN(v->frameMap);
}
- const int effect_strip_length = SEQ_time_right_handle_frame_get(seq) -
- SEQ_time_left_handle_frame_get(seq);
+ const int effect_strip_length = SEQ_time_right_handle_frame_get(scene, seq) -
+ SEQ_time_left_handle_frame_get(scene, seq);
v->frameMap = MEM_mallocN(sizeof(float) * effect_strip_length, __func__);
v->frameMap[0] = 0.0f;
float target_frame = 0;
for (int frame_index = 1; frame_index < effect_strip_length; frame_index++) {
- target_frame += evaluate_fcurve(fcu, SEQ_time_left_handle_frame_get(seq) + frame_index);
+ target_frame += evaluate_fcurve(fcu, SEQ_time_left_handle_frame_get(scene, seq) + frame_index);
CLAMP(target_frame, 0, seq->seq1->len);
v->frameMap[frame_index] = target_frame;
}
@@ -2646,7 +2647,7 @@ float seq_speed_effect_target_frame_get(Scene *scene,
}
SEQ_effect_handle_get(seq_speed); /* Ensure, that data are initialized. */
- int frame_index = seq_give_frame_index(seq_speed, timeline_frame);
+ int frame_index = seq_give_frame_index(scene, seq_speed, timeline_frame);
SpeedControlVars *s = (SpeedControlVars *)seq_speed->effectdata;
const Sequence *source = seq_speed->seq1;
@@ -2654,10 +2655,11 @@ float seq_speed_effect_target_frame_get(Scene *scene,
switch (s->speed_control_type) {
case SEQ_SPEED_STRETCH: {
/* Only right handle controls effect speed! */
- const float target_content_length = seq_effect_speed_get_strip_content_length(source) -
+ const float target_content_length = seq_effect_speed_get_strip_content_length(scene,
+ source) -
source->startofs;
- const float speed_effetct_length = SEQ_time_right_handle_frame_get(seq_speed) -
- SEQ_time_left_handle_frame_get(seq_speed);
+ const float speed_effetct_length = SEQ_time_right_handle_frame_get(scene, seq_speed) -
+ SEQ_time_left_handle_frame_get(scene, seq_speed);
const float ratio = frame_index / speed_effetct_length;
target_frame = target_content_length * ratio;
break;
@@ -2674,7 +2676,7 @@ float seq_speed_effect_target_frame_get(Scene *scene,
break;
}
case SEQ_SPEED_LENGTH:
- target_frame = seq_effect_speed_get_strip_content_length(source) *
+ target_frame = seq_effect_speed_get_strip_content_length(scene, source) *
(s->speed_fader_length / 100.0f);
break;
case SEQ_SPEED_FRAME_NUMBER:
@@ -2682,7 +2684,7 @@ float seq_speed_effect_target_frame_get(Scene *scene,
break;
}
- CLAMP(target_frame, 0, seq_effect_speed_get_strip_content_length(source));
+ CLAMP(target_frame, 0, seq_effect_speed_get_strip_content_length(scene, source));
target_frame += seq_speed->start;
/* No interpolation. */
@@ -3507,15 +3509,21 @@ static int early_out_mul_input1(Sequence *UNUSED(seq), float fac)
return EARLY_DO_EFFECT;
}
-static void get_default_fac_noop(Sequence *UNUSED(seq), float UNUSED(timeline_frame), float *fac)
+static void get_default_fac_noop(const Scene *UNUSED(scene),
+ Sequence *UNUSED(seq),
+ float UNUSED(timeline_frame),
+ float *fac)
{
*fac = 1.0f;
}
-static void get_default_fac_fade(Sequence *seq, float timeline_frame, float *fac)
+static void get_default_fac_fade(const Scene *scene,
+ Sequence *seq,
+ float timeline_frame,
+ float *fac)
{
- *fac = (float)(timeline_frame - SEQ_time_left_handle_frame_get(seq));
- *fac /= seq->len;
+ *fac = (float)(timeline_frame - SEQ_time_left_handle_frame_get(scene, seq));
+ *fac /= SEQ_time_strip_length_get(scene, seq);
}
static struct ImBuf *init_execution(const SeqRenderData *context,
diff --git a/source/blender/sequencer/intern/image_cache.c b/source/blender/sequencer/intern/image_cache.c
index 47306dbbc6c..53f076c9681 100644
--- a/source/blender/sequencer/intern/image_cache.c
+++ b/source/blender/sequencer/intern/image_cache.c
@@ -133,21 +133,24 @@ static bool seq_cache_hashcmp(const void *a_, const void *b_)
seq_cmp_render_data(&a->context, &b->context));
}
-static float seq_cache_timeline_frame_to_frame_index(Sequence *seq, float timeline_frame, int type)
+static float seq_cache_timeline_frame_to_frame_index(Scene *scene,
+ Sequence *seq,
+ float timeline_frame,
+ int type)
{
/* With raw images, map timeline_frame to strip input media frame range. This means that static
* images or extended frame range of movies will only generate one cache entry. No special
* treatment in converting frame index to timeline_frame is needed. */
if (ELEM(type, SEQ_CACHE_STORE_RAW, SEQ_CACHE_STORE_THUMBNAIL)) {
- return seq_give_frame_index(seq, timeline_frame);
+ return seq_give_frame_index(scene, seq, timeline_frame);
}
- return timeline_frame - seq->start;
+ return timeline_frame - SEQ_time_start_frame_get(seq);
}
float seq_cache_frame_index_to_timeline_frame(Sequence *seq, float frame_index)
{
- return frame_index + seq->start;
+ return frame_index + SEQ_time_start_frame_get(seq);
}
static SeqCache *seq_cache_get_from_scene(Scene *scene)
@@ -518,7 +521,8 @@ static void seq_cache_populate_key(SeqCacheKey *key,
key->cache_owner = seq_cache_get_from_scene(context->scene);
key->seq = seq;
key->context = *context;
- key->frame_index = seq_cache_timeline_frame_to_frame_index(seq, timeline_frame, type);
+ key->frame_index = seq_cache_timeline_frame_to_frame_index(
+ context->scene, seq, timeline_frame, type);
key->timeline_frame = timeline_frame;
key->type = type;
key->link_prev = NULL;
@@ -558,10 +562,10 @@ void seq_cache_free_temp_cache(Scene *scene, short id, int timeline_frame)
if (key->is_temp_cache && key->task_id == id && key->type != SEQ_CACHE_STORE_THUMBNAIL) {
/* Use frame_index here to avoid freeing raw images if they are used for multiple frames. */
float frame_index = seq_cache_timeline_frame_to_frame_index(
- key->seq, timeline_frame, key->type);
+ scene, key->seq, timeline_frame, key->type);
if (frame_index != key->frame_index ||
- timeline_frame > SEQ_time_right_handle_frame_get(key->seq) ||
- timeline_frame < SEQ_time_left_handle_frame_get(key->seq)) {
+ timeline_frame > SEQ_time_right_handle_frame_get(scene, key->seq) ||
+ timeline_frame < SEQ_time_left_handle_frame_get(scene, key->seq)) {
BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree);
}
}
@@ -636,12 +640,12 @@ void seq_cache_cleanup_sequence(Scene *scene,
seq_cache_lock(scene);
- int range_start = SEQ_time_left_handle_frame_get(seq_changed);
- int range_end = SEQ_time_right_handle_frame_get(seq_changed);
+ int range_start = SEQ_time_left_handle_frame_get(scene, seq_changed);
+ int range_end = SEQ_time_right_handle_frame_get(scene, seq_changed);
if (!force_seq_changed_range) {
- range_start = max_ii(range_start, SEQ_time_left_handle_frame_get(seq));
- range_end = min_ii(range_end, SEQ_time_right_handle_frame_get(seq));
+ range_start = max_ii(range_start, SEQ_time_left_handle_frame_get(scene, seq));
+ range_end = min_ii(range_end, SEQ_time_right_handle_frame_get(scene, seq));
}
int invalidate_composite = invalidate_types & SEQ_CACHE_STORE_FINAL_OUT;
@@ -665,8 +669,8 @@ void seq_cache_cleanup_sequence(Scene *scene,
}
if (key->type & invalidate_source && key->seq == seq &&
- key->timeline_frame >= SEQ_time_left_handle_frame_get(seq_changed) &&
- key->timeline_frame <= SEQ_time_right_handle_frame_get(seq_changed)) {
+ key->timeline_frame >= SEQ_time_left_handle_frame_get(scene, seq_changed) &&
+ key->timeline_frame <= SEQ_time_right_handle_frame_get(scene, seq_changed)) {
if (key->link_next || key->link_prev) {
seq_cache_relink_keys(key->link_next, key->link_prev);
}
@@ -697,12 +701,12 @@ void seq_cache_thumbnail_cleanup(Scene *scene, rctf *view_area_safe)
SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
BLI_ghashIterator_step(&gh_iter);
- const int frame_index = key->timeline_frame - SEQ_time_left_handle_frame_get(key->seq);
- const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(key->seq);
+ const int frame_index = key->timeline_frame - SEQ_time_left_handle_frame_get(scene, key->seq);
+ const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(scene, key->seq);
const int relative_base_frame = round_fl_to_int((frame_index / (float)frame_step)) *
frame_step;
const int nearest_guaranted_absolute_frame = relative_base_frame +
- SEQ_time_left_handle_frame_get(key->seq);
+ SEQ_time_left_handle_frame_get(scene, key->seq);
if (nearest_guaranted_absolute_frame == key->timeline_frame) {
continue;
diff --git a/source/blender/sequencer/intern/iterator.c b/source/blender/sequencer/intern/iterator.c
index 2710edd6e80..acf6776c4ed 100644
--- a/source/blender/sequencer/intern/iterator.c
+++ b/source/blender/sequencer/intern/iterator.c
@@ -103,13 +103,15 @@ bool SEQ_collection_has_strip(const Sequence *seq, const SeqCollection *collecti
}
SeqCollection *SEQ_query_by_reference(Sequence *seq_reference,
+ const Scene *scene,
ListBase *seqbase,
- void seq_query_func(Sequence *seq_reference,
+ void seq_query_func(const Scene *scene,
+ Sequence *seq_reference,
ListBase *seqbase,
SeqCollection *collection))
{
SeqCollection *collection = SEQ_collection_create(__func__);
- seq_query_func(seq_reference, seqbase, collection);
+ seq_query_func(scene, seq_reference, seqbase, collection);
return collection;
}
bool SEQ_collection_append_strip(Sequence *seq, SeqCollection *collection)
@@ -146,9 +148,11 @@ void SEQ_collection_exclude(SeqCollection *collection, SeqCollection *exclude_el
SEQ_collection_free(exclude_elements);
}
-void SEQ_collection_expand(ListBase *seqbase,
+void SEQ_collection_expand(const Scene *scene,
+ ListBase *seqbase,
SeqCollection *collection,
- void seq_query_func(Sequence *seq_reference,
+ void seq_query_func(const Scene *scene,
+ Sequence *seq_reference,
ListBase *seqbase,
SeqCollection *collection))
{
@@ -157,7 +161,8 @@ void SEQ_collection_expand(ListBase *seqbase,
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, collection) {
- SEQ_collection_merge(query_matches, SEQ_query_by_reference(seq, seqbase, seq_query_func));
+ SEQ_collection_merge(query_matches,
+ SEQ_query_by_reference(seq, scene, seqbase, seq_query_func));
}
/* Merge all expanded results in provided SeqIteratorCollection. */
@@ -219,12 +224,14 @@ SeqCollection *SEQ_query_selected_strips(ListBase *seqbase)
return collection;
}
-static SeqCollection *query_strips_at_frame(ListBase *seqbase, const int timeline_frame)
+static SeqCollection *query_strips_at_frame(const Scene *scene,
+ ListBase *seqbase,
+ const int timeline_frame)
{
SeqCollection *collection = SEQ_collection_create(__func__);
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
- if (SEQ_time_strip_intersects_frame(seq, timeline_frame)) {
+ if (SEQ_time_strip_intersects_frame(scene, seq, timeline_frame)) {
SEQ_collection_append_strip(seq, collection);
}
}
@@ -299,12 +306,13 @@ static void collection_filter_rendered_strips(ListBase *channels, SeqCollection
}
}
-SeqCollection *SEQ_query_rendered_strips(ListBase *channels,
+SeqCollection *SEQ_query_rendered_strips(const Scene *scene,
+ ListBase *channels,
ListBase *seqbase,
const int timeline_frame,
const int displayed_channel)
{
- SeqCollection *collection = query_strips_at_frame(seqbase, timeline_frame);
+ SeqCollection *collection = query_strips_at_frame(scene, seqbase, timeline_frame);
if (displayed_channel != 0) {
collection_filter_channel_up_to_incl(collection, displayed_channel);
}
@@ -324,7 +332,8 @@ SeqCollection *SEQ_query_unselected_strips(ListBase *seqbase)
return collection;
}
-void SEQ_query_strip_effect_chain(Sequence *seq_reference,
+void SEQ_query_strip_effect_chain(const Scene *scene,
+ Sequence *seq_reference,
ListBase *seqbase,
SeqCollection *collection)
{
@@ -335,13 +344,13 @@ void SEQ_query_strip_effect_chain(Sequence *seq_reference,
/* Find all strips that seq_reference is connected to. */
if (seq_reference->type & SEQ_TYPE_EFFECT) {
if (seq_reference->seq1) {
- SEQ_query_strip_effect_chain(seq_reference->seq1, seqbase, collection);
+ SEQ_query_strip_effect_chain(scene, seq_reference->seq1, seqbase, collection);
}
if (seq_reference->seq2) {
- SEQ_query_strip_effect_chain(seq_reference->seq2, seqbase, collection);
+ SEQ_query_strip_effect_chain(scene, seq_reference->seq2, seqbase, collection);
}
if (seq_reference->seq3) {
- SEQ_query_strip_effect_chain(seq_reference->seq3, seqbase, collection);
+ SEQ_query_strip_effect_chain(scene, seq_reference->seq3, seqbase, collection);
}
}
@@ -349,7 +358,7 @@ void SEQ_query_strip_effect_chain(Sequence *seq_reference,
LISTBASE_FOREACH (Sequence *, seq_test, seqbase) {
if (seq_test->seq1 == seq_reference || seq_test->seq2 == seq_reference ||
seq_test->seq3 == seq_reference) {
- SEQ_query_strip_effect_chain(seq_test, seqbase, collection);
+ SEQ_query_strip_effect_chain(scene, seq_test, seqbase, collection);
}
}
}
diff --git a/source/blender/sequencer/intern/prefetch.c b/source/blender/sequencer/intern/prefetch.c
index 01f581bc6c1..2a9f7f52779 100644
--- a/source/blender/sequencer/intern/prefetch.c
+++ b/source/blender/sequencer/intern/prefetch.c
@@ -395,7 +395,7 @@ static bool seq_prefetch_scene_strip_is_rendered(PrefetchJob *pfjob,
{
float cfra = seq_prefetch_cfra(pfjob);
Sequence *seq_arr[MAXSEQ + 1];
- int count = seq_get_shown_sequences(channels, seqbase, cfra, 0, seq_arr);
+ int count = seq_get_shown_sequences(pfjob->scene_eval, channels, seqbase, cfra, 0, seq_arr);
/* Iterate over rendered strips. */
for (int i = 0; i < count; i++) {
diff --git a/source/blender/sequencer/intern/proxy.c b/source/blender/sequencer/intern/proxy.c
index 464580f5bed..522c64f7791 100644
--- a/source/blender/sequencer/intern/proxy.c
+++ b/source/blender/sequencer/intern/proxy.c
@@ -123,7 +123,7 @@ bool seq_proxy_get_custom_file_fname(Sequence *seq, char *name, const int view_i
return true;
}
-static bool seq_proxy_get_fname(Editing *ed,
+static bool seq_proxy_get_fname(Scene *scene,
Sequence *seq,
int timeline_frame,
eSpaceSeq_Proxy_RenderSize render_size,
@@ -132,6 +132,7 @@ static bool seq_proxy_get_fname(Editing *ed,
{
char dir[PROXY_MAXFILE];
char suffix[24] = {'\0'};
+ Editing *ed = SEQ_editing_get(scene);
StripProxy *proxy = seq->strip->proxy;
if (proxy == NULL) {
@@ -179,7 +180,7 @@ static bool seq_proxy_get_fname(Editing *ed,
"%s/images/%d/%s_proxy%s",
dir,
proxy_size_number,
- SEQ_render_give_stripelem(seq, timeline_frame)->name,
+ SEQ_render_give_stripelem(scene, seq, timeline_frame)->name,
suffix);
BLI_path_abs(name, BKE_main_blendfile_path_from_global());
strcat(name, ".jpg");
@@ -202,7 +203,6 @@ ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int timeline
char name[PROXY_MAXFILE];
StripProxy *proxy = seq->strip->proxy;
const eSpaceSeq_Proxy_RenderSize psize = context->preview_render_size;
- Editing *ed = context->scene->ed;
StripAnim *sanim;
/* only use proxies, if they are enabled (even if present!) */
@@ -211,9 +211,11 @@ ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int timeline
}
if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) {
- int frameno = (int)seq_give_frame_index(seq, timeline_frame) + seq->anim_startofs;
+ int frameno = (int)seq_give_frame_index(context->scene, seq, timeline_frame) +
+ seq->anim_startofs;
if (proxy->anim == NULL) {
- if (seq_proxy_get_fname(ed, seq, timeline_frame, psize, name, context->view_id) == 0) {
+ if (seq_proxy_get_fname(
+ context->scene, seq, timeline_frame, psize, name, context->view_id) == 0) {
return NULL;
}
@@ -232,7 +234,8 @@ ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int timeline
return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE);
}
- if (seq_proxy_get_fname(ed, seq, timeline_frame, psize, name, context->view_id) == 0) {
+ if (seq_proxy_get_fname(context->scene, seq, timeline_frame, psize, name, context->view_id) ==
+ 0) {
return NULL;
}
@@ -260,9 +263,10 @@ static void seq_proxy_build_frame(const SeqRenderData *context,
int quality;
int rectx, recty;
ImBuf *ibuf_tmp, *ibuf;
- Editing *ed = context->scene->ed;
+ Scene *scene = context->scene;
- if (!seq_proxy_get_fname(ed, seq, timeline_frame, proxy_render_size, name, context->view_id)) {
+ if (!seq_proxy_get_fname(
+ scene, seq, timeline_frame, proxy_render_size, name, context->view_id)) {
return;
}
@@ -524,8 +528,8 @@ void SEQ_proxy_rebuild(SeqIndexBuildContext *context,
SeqRenderState state;
seq_render_state_init(&state);
- for (timeline_frame = SEQ_time_left_handle_frame_get(seq);
- timeline_frame < SEQ_time_right_handle_frame_get(seq);
+ for (timeline_frame = SEQ_time_left_handle_frame_get(scene, seq);
+ timeline_frame < SEQ_time_right_handle_frame_get(scene, seq);
timeline_frame++) {
if (context->size_flags & IMB_PROXY_25) {
seq_proxy_build_frame(&render_context, &state, seq, timeline_frame, 25, overwrite);
@@ -540,8 +544,9 @@ void SEQ_proxy_rebuild(SeqIndexBuildContext *context,
seq_proxy_build_frame(&render_context, &state, seq, timeline_frame, 100, overwrite);
}
- *progress = (float)(timeline_frame - SEQ_time_left_handle_frame_get(seq)) /
- (SEQ_time_right_handle_frame_get(seq) - SEQ_time_left_handle_frame_get(seq));
+ *progress = (float)(timeline_frame - SEQ_time_left_handle_frame_get(scene, seq)) /
+ (SEQ_time_right_handle_frame_get(scene, seq) -
+ SEQ_time_left_handle_frame_get(scene, seq));
*do_update = true;
if (*stop || G.is_break) {
diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c
index e7a1bbeb9d0..15487a597d1 100644
--- a/source/blender/sequencer/intern/render.c
+++ b/source/blender/sequencer/intern/render.c
@@ -233,7 +233,7 @@ void seq_render_state_init(SeqRenderState *state)
state->scene_parents = NULL;
}
-StripElem *SEQ_render_give_stripelem(Sequence *seq, int timeline_frame)
+StripElem *SEQ_render_give_stripelem(const Scene *scene, Sequence *seq, int timeline_frame)
{
StripElem *se = seq->strip->stripdata;
@@ -242,7 +242,7 @@ StripElem *SEQ_render_give_stripelem(Sequence *seq, int timeline_frame)
* all other strips don't use this...
*/
- int frame_index = (int)seq_give_frame_index(seq, timeline_frame);
+ int frame_index = (int)seq_give_frame_index(scene, seq, timeline_frame);
if (frame_index == -1 || se == NULL) {
return NULL;
@@ -258,14 +258,15 @@ static int seq_channel_cmp_fn(const void *a, const void *b)
return (*(Sequence **)a)->machine - (*(Sequence **)b)->machine;
}
-int seq_get_shown_sequences(ListBase *channels,
+int seq_get_shown_sequences(const Scene *scene,
+ ListBase *channels,
ListBase *seqbase,
const int timeline_frame,
const int chanshown,
Sequence **r_seq_arr)
{
SeqCollection *collection = SEQ_query_rendered_strips(
- channels, seqbase, timeline_frame, chanshown);
+ scene, channels, seqbase, timeline_frame, chanshown);
const int strip_count = BLI_gset_len(collection->set);
if (strip_count > MAXSEQ) {
@@ -795,7 +796,7 @@ static ImBuf *seq_render_effect_strip_impl(const SeqRenderData *context,
}
if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
- sh.get_default_fac(seq, timeline_frame, &fac);
+ sh.get_default_fac(scene, seq, timeline_frame, &fac);
}
else {
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "effect_fader", 0, NULL);
@@ -936,7 +937,7 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context,
char prefix[FILE_MAX];
ImBuf *ibuf = NULL;
- StripElem *s_elem = SEQ_render_give_stripelem(seq, timeline_frame);
+ StripElem *s_elem = SEQ_render_give_stripelem(context->scene, seq, timeline_frame);
if (s_elem == NULL) {
return NULL;
}
@@ -1024,7 +1025,8 @@ static ImBuf *seq_render_movie_strip_custom_file_proxy(const SeqRenderData *cont
}
}
- int frameno = (int)seq_give_frame_index(seq, timeline_frame) + seq->anim_startofs;
+ int frameno = (int)seq_give_frame_index(context->scene, seq, timeline_frame) +
+ seq->anim_startofs;
return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE);
}
@@ -1622,7 +1624,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context,
bool *r_is_proxy_image)
{
ImBuf *ibuf = NULL;
- float frame_index = seq_give_frame_index(seq, timeline_frame);
+ float frame_index = seq_give_frame_index(context->scene, seq, timeline_frame);
int type = (seq->type & SEQ_TYPE_EFFECT) ? SEQ_TYPE_EFFECT : seq->type;
switch (type) {
case SEQ_TYPE_META: {
@@ -1826,7 +1828,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
ImBuf *out = NULL;
count = seq_get_shown_sequences(
- channels, seqbasep, timeline_frame, chanshown, (Sequence **)&seq_arr);
+ context->scene, channels, seqbasep, timeline_frame, chanshown, (Sequence **)&seq_arr);
if (count == 0) {
return NULL;
@@ -1940,7 +1942,7 @@ ImBuf *SEQ_render_give_ibuf(const SeqRenderData *context, float timeline_frame,
Sequence *seq_arr[MAXSEQ + 1];
int count;
- count = seq_get_shown_sequences(channels, seqbasep, timeline_frame, chanshown, seq_arr);
+ count = seq_get_shown_sequences(scene, channels, seqbasep, timeline_frame, chanshown, seq_arr);
if (count) {
out = seq_cache_get(context, seq_arr[count - 1], timeline_frame, SEQ_CACHE_STORE_FINAL_OUT);
@@ -1992,14 +1994,17 @@ ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context,
return ibuf;
}
-float SEQ_render_thumbnail_first_frame_get(Sequence *seq, float frame_step, rctf *view_area)
+float SEQ_render_thumbnail_first_frame_get(const Scene *scene,
+ Sequence *seq,
+ float frame_step,
+ rctf *view_area)
{
int first_drawable_frame = max_iii(
- SEQ_time_left_handle_frame_get(seq), seq->start, view_area->xmin);
+ SEQ_time_left_handle_frame_get(scene, seq), seq->start, view_area->xmin);
/* First frame should correspond to handle position. */
- if (first_drawable_frame == SEQ_time_left_handle_frame_get(seq)) {
- return SEQ_time_left_handle_frame_get(seq);
+ if (first_drawable_frame == SEQ_time_left_handle_frame_get(scene, seq)) {
+ return SEQ_time_left_handle_frame_get(scene, seq);
}
float aligned_frame_offset = (int)((first_drawable_frame - seq->start) / frame_step) *
@@ -2007,12 +2012,15 @@ float SEQ_render_thumbnail_first_frame_get(Sequence *seq, float frame_step, rctf
return seq->start + aligned_frame_offset;
}
-float SEQ_render_thumbnail_next_frame_get(Sequence *seq, float last_frame, float frame_step)
+float SEQ_render_thumbnail_next_frame_get(const Scene *scene,
+ Sequence *seq,
+ float last_frame,
+ float frame_step)
{
float next_frame = last_frame + frame_step;
/* If handle position was displayed, align next frame with `seq->start`. */
- if (last_frame == SEQ_time_left_handle_frame_get(seq)) {
+ if (last_frame == SEQ_time_left_handle_frame_get(scene, seq)) {
next_frame = seq->start + ((int)((last_frame - seq->start) / frame_step) + 1) * frame_step;
}
@@ -2086,22 +2094,23 @@ void SEQ_render_thumbnails(const SeqRenderData *context,
{
SeqRenderState state;
seq_render_state_init(&state);
+ const Scene *scene = context->scene;
/* Adding the hold offset value (seq->anim_startofs) to the start frame. Position of image not
* affected, but frame loaded affected. */
- float upper_thumb_bound = SEQ_time_has_right_still_frames(seq) ?
+ float upper_thumb_bound = SEQ_time_has_right_still_frames(scene, seq) ?
(seq->start + seq->len) :
- SEQ_time_right_handle_frame_get(seq);
+ SEQ_time_right_handle_frame_get(scene, seq);
upper_thumb_bound = (upper_thumb_bound > view_area->xmax) ? view_area->xmax + frame_step :
upper_thumb_bound;
- float timeline_frame = SEQ_render_thumbnail_first_frame_get(seq, frame_step, view_area);
+ float timeline_frame = SEQ_render_thumbnail_first_frame_get(scene, seq, frame_step, view_area);
while ((timeline_frame < upper_thumb_bound) & !*stop) {
ImBuf *ibuf = seq_cache_get(
context, seq_orig, round_fl_to_int(timeline_frame), SEQ_CACHE_STORE_THUMBNAIL);
if (ibuf) {
IMB_freeImBuf(ibuf);
- timeline_frame = SEQ_render_thumbnail_next_frame_get(seq, timeline_frame, frame_step);
+ timeline_frame = SEQ_render_thumbnail_next_frame_get(scene, seq, timeline_frame, frame_step);
continue;
}
@@ -2118,14 +2127,15 @@ void SEQ_render_thumbnails(const SeqRenderData *context,
return;
}
- timeline_frame = SEQ_render_thumbnail_next_frame_get(seq, timeline_frame, frame_step);
+ timeline_frame = SEQ_render_thumbnail_next_frame_get(scene, seq, timeline_frame, frame_step);
}
}
-int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const Sequence *seq)
+int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const Scene *scene, const Sequence *seq)
{
- const int content_start = max_ii(SEQ_time_left_handle_frame_get(seq), seq->start);
- const int content_end = min_ii(SEQ_time_right_handle_frame_get(seq), seq->start + seq->len);
+ const int content_start = max_ii(SEQ_time_left_handle_frame_get(scene, seq), seq->start);
+ const int content_end = min_ii(SEQ_time_right_handle_frame_get(scene, seq),
+ seq->start + seq->len);
const int content_len = content_end - content_start;
/* Arbitrary, but due to performance reasons should be as low as possible. */
@@ -2144,11 +2154,12 @@ void SEQ_render_thumbnails_base_set(const SeqRenderData *context,
{
SeqRenderState state;
seq_render_state_init(&state);
+ const Scene *scene = context->scene;
- int timeline_frame = SEQ_time_left_handle_frame_get(seq);
- const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(seq);
+ int timeline_frame = SEQ_time_left_handle_frame_get(scene, seq);
+ const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(scene, seq);
- while (timeline_frame < SEQ_time_right_handle_frame_get(seq) && !*stop) {
+ while (timeline_frame < SEQ_time_right_handle_frame_get(scene, seq) && !*stop) {
ImBuf *ibuf = seq_cache_get(
context, seq_orig, roundf(timeline_frame), SEQ_CACHE_STORE_THUMBNAIL);
if (ibuf) {
diff --git a/source/blender/sequencer/intern/render.h b/source/blender/sequencer/intern/render.h
index d41a0e3f86f..3690eb71ac4 100644
--- a/source/blender/sequencer/intern/render.h
+++ b/source/blender/sequencer/intern/render.h
@@ -44,7 +44,8 @@ struct ImBuf *seq_render_effect_execute_threaded(struct SeqEffectHandle *sh,
struct ImBuf *ibuf2,
struct ImBuf *ibuf3);
void seq_imbuf_to_sequencer_space(struct Scene *scene, struct ImBuf *ibuf, bool make_float);
-int seq_get_shown_sequences(struct ListBase *channels,
+int seq_get_shown_sequences(const struct Scene *scene,
+ struct ListBase *channels,
struct ListBase *seqbase,
int timeline_frame,
int chanshown,
diff --git a/source/blender/sequencer/intern/sequencer.c b/source/blender/sequencer/intern/sequencer.c
index 3f48e6dafdd..a184f727b9e 100644
--- a/source/blender/sequencer/intern/sequencer.c
+++ b/source/blender/sequencer/intern/sequencer.c
@@ -127,9 +127,10 @@ Sequence *SEQ_sequence_alloc(ListBase *lb, int timeline_frame, int machine, int
seq->mul = 1.0;
seq->blend_opacity = 100.0;
seq->volume = 1.0f;
- seq->pitch = 1.0f;
seq->scene_sound = NULL;
seq->type = type;
+ seq->media_playback_rate = 0.0f;
+ seq->speed_factor = 1.0f;
if (seq->type == SEQ_TYPE_ADJUSTMENT) {
seq->blend_mode = SEQ_TYPE_CROSS;
@@ -411,8 +412,8 @@ static MetaStack *seq_meta_stack_alloc(const Scene *scene, Sequence *seq_meta)
ms->oldbasep = higher_level_meta ? &higher_level_meta->seqbase : &ed->seqbase;
ms->old_channels = higher_level_meta ? &higher_level_meta->channels : &ed->channels;
- ms->disp_range[0] = SEQ_time_left_handle_frame_get(ms->parseq);
- ms->disp_range[1] = SEQ_time_right_handle_frame_get(ms->parseq);
+ ms->disp_range[0] = SEQ_time_left_handle_frame_get(scene, ms->parseq);
+ ms->disp_range[1] = SEQ_time_right_handle_frame_get(scene, ms->parseq);
return ms;
}
@@ -965,8 +966,9 @@ static bool seq_update_seq_cb(Sequence *seq, void *user_data)
}
BKE_sound_set_scene_sound_volume(
seq->scene_sound, seq->volume, (seq->flag & SEQ_AUDIO_VOLUME_ANIMATED) != 0);
- BKE_sound_set_scene_sound_pitch(
- seq->scene_sound, seq->pitch, (seq->flag & SEQ_AUDIO_PITCH_ANIMATED) != 0);
+ BKE_sound_set_scene_sound_pitch(seq->scene_sound,
+ SEQ_sound_pitch_get(scene, seq),
+ (seq->flag & SEQ_AUDIO_PITCH_ANIMATED) != 0);
BKE_sound_set_scene_sound_pan(
seq->scene_sound, seq->pan, (seq->flag & SEQ_AUDIO_PAN_ANIMATED) != 0);
}
diff --git a/source/blender/sequencer/intern/sound.c b/source/blender/sequencer/intern/sound.c
index 50c8b76a9a0..c4992848cb5 100644
--- a/source/blender/sequencer/intern/sound.c
+++ b/source/blender/sequencer/intern/sound.c
@@ -23,6 +23,7 @@
#include "SEQ_sound.h"
#include "SEQ_time.h"
+#include "sequencer.h"
#include "strip_time.h"
/* Unlike _update_sound_ funcs, these ones take info from audaspace to update sequence length! */
@@ -99,8 +100,8 @@ void SEQ_sound_update_bounds(Scene *scene, Sequence *seq)
BKE_sound_move_scene_sound(scene,
seq->scene_sound,
- SEQ_time_left_handle_frame_get(seq),
- SEQ_time_right_handle_frame_get(seq),
+ SEQ_time_left_handle_frame_get(scene, seq),
+ SEQ_time_right_handle_frame_get(scene, seq),
startofs,
0.0);
}
@@ -133,3 +134,12 @@ void SEQ_sound_update(Scene *scene, bSound *sound)
seq_update_sound_recursive(scene, &scene->ed->seqbase, sound);
}
}
+
+float SEQ_sound_pitch_get(const Scene *scene, const Sequence *seq)
+{
+ Sequence *meta_parent = seq_sequence_lookup_meta_by_seq(scene, seq);
+ if (meta_parent != NULL) {
+ return seq->speed_factor * SEQ_sound_pitch_get(scene, meta_parent);
+ }
+ return seq->speed_factor;
+}
diff --git a/source/blender/sequencer/intern/strip_add.c b/source/blender/sequencer/intern/strip_add.c
index 4f0b2e38f56..753a6ee39e0 100644
--- a/source/blender/sequencer/intern/strip_add.c
+++ b/source/blender/sequencer/intern/strip_add.c
@@ -181,7 +181,7 @@ Sequence *SEQ_add_effect_strip(Scene *scene, ListBase *seqbase, struct SeqLoadDa
seq_add_set_name(scene, seq, load_data);
seq_add_generic_update(scene, seq);
- seq_time_effect_range_set(seq);
+ seq_time_effect_range_set(scene, seq);
return seq;
}
@@ -191,9 +191,10 @@ void SEQ_add_image_set_directory(Sequence *seq, char *path)
BLI_strncpy(seq->strip->dir, path, sizeof(seq->strip->dir));
}
-void SEQ_add_image_load_file(Sequence *seq, size_t strip_frame, char *filename)
+void SEQ_add_image_load_file(Scene *scene, Sequence *seq, size_t strip_frame, char *filename)
{
- StripElem *se = SEQ_render_give_stripelem(seq, seq->start + strip_frame);
+ StripElem *se = SEQ_render_give_stripelem(
+ scene, seq, SEQ_time_start_frame_get(seq) + strip_frame);
BLI_strncpy(se->name, filename, sizeof(se->name));
}
@@ -468,9 +469,19 @@ Sequence *SEQ_add_movie_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL
orig_height = IMB_anim_get_image_height(anim_arr[0]);
SEQ_set_scale_to_fit(
seq, orig_width, orig_height, scene->r.xsch, scene->r.ysch, load_data->fit_method);
+
+ short frs_sec;
+ float frs_sec_base;
+ if (IMB_anim_get_fps(anim_arr[0], &frs_sec, &frs_sec_base, true)) {
+ seq->media_playback_rate = (float)frs_sec / frs_sec_base;
+ }
}
seq->len = MAX2(1, seq->len);
+ if (load_data->adjust_playback_rate) {
+ seq->flag |= SEQ_AUTO_PLAYBACK_RATE;
+ }
+
BLI_strncpy(seq->strip->colorspace_settings.name,
colorspace,
sizeof(seq->strip->colorspace_settings.name));
@@ -511,8 +522,8 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo
if (lock_range) {
/* keep so we don't have to move the actual start and end points (only the data) */
- prev_startdisp = SEQ_time_left_handle_frame_get(seq);
- prev_enddisp = SEQ_time_right_handle_frame_get(seq);
+ prev_startdisp = SEQ_time_left_handle_frame_get(scene, seq);
+ prev_enddisp = SEQ_time_right_handle_frame_get(scene, seq);
}
switch (seq->type) {
diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c
index 4a88eab0fe2..deab43affee 100644
--- a/source/blender/sequencer/intern/strip_edit.c
+++ b/source/blender/sequencer/intern/strip_edit.c
@@ -37,11 +37,11 @@
#include "SEQ_transform.h"
#include "SEQ_utils.h"
-int SEQ_edit_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str)
+int SEQ_edit_sequence_swap(Scene *scene, Sequence *seq_a, Sequence *seq_b, const char **error_str)
{
char name[sizeof(seq_a->name)];
- if (seq_a->len != seq_b->len) {
+ if (SEQ_time_strip_length_get(scene, seq_a) != SEQ_time_strip_length_get(scene, seq_b)) {
*error_str = N_("Strips must be the same length");
return 0;
}
@@ -84,8 +84,8 @@ int SEQ_edit_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_
SWAP(int, seq_a->startofs, seq_b->startofs);
SWAP(int, seq_a->endofs, seq_b->endofs);
SWAP(int, seq_a->machine, seq_b->machine);
- seq_time_effect_range_set(seq_a);
- seq_time_effect_range_set(seq_b);
+ seq_time_effect_range_set(scene, seq_a);
+ seq_time_effect_range_set(scene, seq_b);
return 1;
}
@@ -203,7 +203,7 @@ bool SEQ_edit_move_strip_to_seqbase(Scene *scene,
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
/* Update meta. */
- if (SEQ_transform_test_overlap(dst_seqbase, seq)) {
+ if (SEQ_transform_test_overlap(scene, dst_seqbase, seq)) {
SEQ_transform_seqbase_shuffle(dst_seqbase, seq, scene);
}
@@ -246,7 +246,7 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene,
SeqCollection *collection = SEQ_collection_create(__func__);
SEQ_collection_append_strip(src_seq, collection);
- SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain);
+ SEQ_collection_expand(scene, seqbase, collection, SEQ_query_strip_effect_chain);
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, collection) {
@@ -259,77 +259,58 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene,
return true;
}
-static void seq_split_set_left_hold_offset(const Scene *scene, Sequence *seq, int timeline_frame)
+static void seq_split_set_left_hold_offset(Scene *scene, Sequence *seq, int timeline_frame)
{
/* Adjust within range of extended stillframes before strip. */
if (timeline_frame < seq->start) {
- SEQ_time_left_handle_frame_set(scene, seq, timeline_frame);
- }
- /* Adjust within range of strip contents. */
- else if ((timeline_frame >= seq->start) && (timeline_frame <= (seq->start + seq->len))) {
- seq->anim_startofs += timeline_frame - seq->start;
- seq->start = timeline_frame;
- seq->startofs = 0;
- }
- /* Adjust within range of extended stillframes after strip. */
- else if ((seq->start + seq->len) < timeline_frame) {
- const int right_handle_backup = SEQ_time_right_handle_frame_get(seq);
- seq->start += timeline_frame - seq->start;
- seq->anim_startofs += seq->len - 1;
- seq->len = 1;
- SEQ_time_left_handle_frame_set(scene, seq, timeline_frame);
- SEQ_time_right_handle_frame_set(scene, seq, right_handle_backup);
- }
-}
-
-static void seq_split_set_right_hold_offset(const Scene *scene, Sequence *seq, int timeline_frame)
-{
- /* Adjust within range of extended stillframes before strip. */
- if (timeline_frame < seq->start) {
- const int left_handle_backup = SEQ_time_left_handle_frame_get(seq);
seq->start = timeline_frame - 1;
- SEQ_time_left_handle_frame_set(scene, seq, left_handle_backup);
- SEQ_time_right_handle_frame_set(scene, seq, timeline_frame);
+ seq->anim_endofs += SEQ_time_strip_length_get(scene, seq) - 1;
+ seq->startstill = timeline_frame - seq->startdisp - 1;
+ seq->endstill = 0;
}
/* Adjust within range of strip contents. */
- else if ((timeline_frame >= seq->start) && (timeline_frame <= (seq->start + seq->len))) {
- seq->anim_endofs += seq->start + seq->len - timeline_frame;
+ else if ((timeline_frame >= seq->start) &&
+ (timeline_frame <= (seq->start + SEQ_time_strip_length_get(scene, seq)))) {
seq->endofs = 0;
+ seq->endstill = 0;
+ seq->anim_endofs += (seq->start + SEQ_time_strip_length_get(scene, seq)) - timeline_frame;
}
/* Adjust within range of extended stillframes after strip. */
- else if ((seq->start + seq->len) < timeline_frame) {
- SEQ_time_right_handle_frame_set(scene, seq, timeline_frame);
+ else if ((seq->start + SEQ_time_strip_length_get(scene, seq)) < timeline_frame) {
+ seq->endstill = timeline_frame - seq->start - SEQ_time_strip_length_get(scene, seq);
}
}
-static void seq_split_set_right_offset(const Scene *scene, Sequence *seq, int timeline_frame)
+static void seq_split_set_right_hold_offset(Scene *scene, Sequence *seq, int timeline_frame)
{
/* Adjust within range of extended stillframes before strip. */
if (timeline_frame < seq->start) {
- const int content_offset = seq->start - timeline_frame + 1;
- seq->start = timeline_frame - 1;
- seq->startofs += content_offset;
+ seq->startstill = seq->start - timeline_frame;
+ }
+ /* Adjust within range of strip contents. */
+ else if ((timeline_frame >= seq->start) &&
+ (timeline_frame <= (seq->start + SEQ_time_strip_length_get(scene, seq)))) {
+ seq->anim_startofs += timeline_frame - seq->start;
+ seq->start = timeline_frame;
+ seq->startstill = 0;
+ seq->startofs = 0;
}
-
- SEQ_time_right_handle_frame_set(scene, seq, timeline_frame);
-}
-
-static void seq_split_set_left_offset(const Scene *scene, Sequence *seq, int timeline_frame)
-{
/* Adjust within range of extended stillframes after strip. */
- if (timeline_frame > seq->start + seq->len) {
- const int content_offset = timeline_frame - (seq->start + seq->len) + 1;
- seq->start += content_offset;
- seq->endofs += content_offset;
+ else if ((seq->start + SEQ_time_strip_length_get(scene, seq)) < timeline_frame) {
+ seq->start = timeline_frame;
+ seq->startofs = 0;
+ seq->anim_startofs += SEQ_time_strip_length_get(scene, seq) - 1;
+ seq->endstill = seq->enddisp - timeline_frame - 1;
+ seq->startstill = 0;
}
-
- SEQ_time_left_handle_frame_set(scene, seq, timeline_frame);
}
-static bool seq_edit_split_effect_intersect_check(const Sequence *seq, const int timeline_frame)
+static bool seq_edit_split_effect_intersect_check(const Scene *scene,
+ const Sequence *seq,
+ const int timeline_frame)
{
- return timeline_frame > SEQ_time_left_handle_frame_get(seq) &&
- timeline_frame < SEQ_time_right_handle_frame_get(seq);
+ return timeline_frame > SEQ_time_left_handle_frame_get(scene, seq) &&
+ timeline_frame < SEQ_time_right_handle_frame_get(scene, seq);
}
static void seq_edit_split_handle_strip_offsets(Main *bmain,
@@ -339,10 +320,10 @@ static void seq_edit_split_handle_strip_offsets(Main *bmain,
const int timeline_frame,
const eSeqSplitMethod method)
{
- if (seq_edit_split_effect_intersect_check(right_seq, timeline_frame)) {
+ if (seq_edit_split_effect_intersect_check(scene, right_seq, timeline_frame)) {
switch (method) {
case SEQ_SPLIT_SOFT:
- seq_split_set_left_offset(scene, right_seq, timeline_frame);
+ SEQ_time_left_handle_frame_set(scene, right_seq, timeline_frame);
break;
case SEQ_SPLIT_HARD:
seq_split_set_left_hold_offset(scene, right_seq, timeline_frame);
@@ -351,10 +332,10 @@ static void seq_edit_split_handle_strip_offsets(Main *bmain,
}
}
- if (seq_edit_split_effect_intersect_check(left_seq, timeline_frame)) {
+ if (seq_edit_split_effect_intersect_check(scene, left_seq, timeline_frame)) {
switch (method) {
case SEQ_SPLIT_SOFT:
- seq_split_set_right_offset(scene, left_seq, timeline_frame);
+ SEQ_time_right_handle_frame_set(scene, left_seq, timeline_frame);
break;
case SEQ_SPLIT_HARD:
seq_split_set_right_hold_offset(scene, left_seq, timeline_frame);
@@ -364,31 +345,40 @@ static void seq_edit_split_handle_strip_offsets(Main *bmain,
}
}
-static bool seq_edit_split_effect_inputs_intersect(const Sequence *seq, const int timeline_frame)
+static bool seq_edit_split_effect_inputs_intersect(const Scene *scene,
+ const Sequence *seq,
+ const int timeline_frame)
{
bool input_does_intersect = false;
if (seq->seq1) {
- input_does_intersect |= seq_edit_split_effect_intersect_check(seq->seq1, timeline_frame);
+ input_does_intersect |= seq_edit_split_effect_intersect_check(
+ scene, seq->seq1, timeline_frame);
if ((seq->seq1->type & SEQ_TYPE_EFFECT) != 0) {
- input_does_intersect |= seq_edit_split_effect_inputs_intersect(seq->seq1, timeline_frame);
+ input_does_intersect |= seq_edit_split_effect_inputs_intersect(
+ scene, seq->seq1, timeline_frame);
}
}
if (seq->seq2) {
- input_does_intersect |= seq_edit_split_effect_intersect_check(seq->seq2, timeline_frame);
+ input_does_intersect |= seq_edit_split_effect_intersect_check(
+ scene, seq->seq2, timeline_frame);
if ((seq->seq1->type & SEQ_TYPE_EFFECT) != 0) {
- input_does_intersect |= seq_edit_split_effect_inputs_intersect(seq->seq2, timeline_frame);
+ input_does_intersect |= seq_edit_split_effect_inputs_intersect(
+ scene, seq->seq2, timeline_frame);
}
}
if (seq->seq3) {
- input_does_intersect |= seq_edit_split_effect_intersect_check(seq->seq3, timeline_frame);
+ input_does_intersect |= seq_edit_split_effect_intersect_check(
+ scene, seq->seq3, timeline_frame);
if ((seq->seq1->type & SEQ_TYPE_EFFECT) != 0) {
- input_does_intersect |= seq_edit_split_effect_inputs_intersect(seq->seq3, timeline_frame);
+ input_does_intersect |= seq_edit_split_effect_inputs_intersect(
+ scene, seq->seq3, timeline_frame);
}
}
return input_does_intersect;
}
-static bool seq_edit_split_operation_permitted_check(SeqCollection *strips,
+static bool seq_edit_split_operation_permitted_check(const Scene *scene,
+ SeqCollection *strips,
const int timeline_frame,
const char **r_error)
{
@@ -397,7 +387,7 @@ static bool seq_edit_split_operation_permitted_check(SeqCollection *strips,
if ((seq->type & SEQ_TYPE_EFFECT) == 0) {
continue;
}
- if (!seq_edit_split_effect_intersect_check(seq, timeline_frame)) {
+ if (!seq_edit_split_effect_intersect_check(scene, seq, timeline_frame)) {
continue;
}
if (SEQ_effect_get_num_inputs(seq->type) <= 1) {
@@ -407,7 +397,7 @@ static bool seq_edit_split_operation_permitted_check(SeqCollection *strips,
*r_error = "Splitting transition effect is not permitted.";
return false;
}
- if (!seq_edit_split_effect_inputs_intersect(seq, timeline_frame)) {
+ if (!seq_edit_split_effect_inputs_intersect(scene, seq, timeline_frame)) {
*r_error = "Effect inputs don't overlap. Can not split such effect.";
return false;
}
@@ -423,16 +413,16 @@ Sequence *SEQ_edit_strip_split(Main *bmain,
const eSeqSplitMethod method,
const char **r_error)
{
- if (!seq_edit_split_effect_intersect_check(seq, timeline_frame)) {
+ if (!seq_edit_split_effect_intersect_check(scene, seq, timeline_frame)) {
return NULL;
}
/* Whole strip chain must be duplicated in order to preserve relationships. */
SeqCollection *collection = SEQ_collection_create(__func__);
SEQ_collection_append_strip(seq, collection);
- SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain);
+ SEQ_collection_expand(scene, seqbase, collection, SEQ_query_strip_effect_chain);
- if (!seq_edit_split_operation_permitted_check(collection, timeline_frame, r_error)) {
+ if (!seq_edit_split_operation_permitted_check(scene, collection, timeline_frame, r_error)) {
SEQ_collection_free(collection);
return NULL;
}
@@ -474,10 +464,10 @@ Sequence *SEQ_edit_strip_split(Main *bmain,
/* Split strips. */
while (left_seq && right_seq) {
- if (SEQ_time_left_handle_frame_get(left_seq) >= timeline_frame) {
+ if (SEQ_time_left_handle_frame_get(scene, left_seq) >= timeline_frame) {
SEQ_edit_flag_for_removal(scene, seqbase, left_seq);
}
- else if (SEQ_time_right_handle_frame_get(right_seq) <= timeline_frame) {
+ else if (SEQ_time_right_handle_frame_get(scene, right_seq) <= timeline_frame) {
SEQ_edit_flag_for_removal(scene, seqbase, right_seq);
}
else if (return_seq == NULL) {
diff --git a/source/blender/sequencer/intern/strip_relations.c b/source/blender/sequencer/intern/strip_relations.c
index a123212cb6e..1132c4dd69d 100644
--- a/source/blender/sequencer/intern/strip_relations.c
+++ b/source/blender/sequencer/intern/strip_relations.c
@@ -29,6 +29,7 @@
#include "SEQ_relations.h"
#include "SEQ_sequencer.h"
#include "SEQ_time.h"
+#include "SEQ_transform.h"
#include "effects.h"
#include "image_cache.h"
@@ -40,15 +41,15 @@ bool SEQ_relation_is_effect_of_strip(const Sequence *effect, const Sequence *inp
}
/* check whether sequence cur depends on seq */
-static bool seq_relations_check_depend(Sequence *seq, Sequence *cur)
+static bool seq_relations_check_depend(const Scene *scene, Sequence *seq, Sequence *cur)
{
if (SEQ_relation_is_effect_of_strip(cur, seq)) {
return true;
}
/* sequences are not intersecting in time, assume no dependency exists between them */
- if (SEQ_time_right_handle_frame_get(cur) < SEQ_time_left_handle_frame_get(seq) ||
- SEQ_time_left_handle_frame_get(cur) > SEQ_time_right_handle_frame_get(seq)) {
+ if (SEQ_time_right_handle_frame_get(scene, cur) < SEQ_time_left_handle_frame_get(scene, seq) ||
+ SEQ_time_left_handle_frame_get(scene, cur) > SEQ_time_right_handle_frame_get(scene, seq)) {
return false;
}
@@ -78,7 +79,7 @@ static void sequence_do_invalidate_dependent(Scene *scene, Sequence *seq, ListBa
continue;
}
- if (seq_relations_check_depend(seq, cur)) {
+ if (seq_relations_check_depend(scene, seq, cur)) {
/* Effect must be invalidated completely if they depend on invalidated seq. */
if ((cur->type & SEQ_TYPE_EFFECT) != 0) {
seq_cache_cleanup_sequence(scene, cur, seq, SEQ_CACHE_ALL_TYPES, false);
@@ -249,7 +250,7 @@ void SEQ_relations_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render)
SEQ_prefetch_stop(scene);
for (seq = seqbase->first; seq; seq = seq->next) {
- if (for_render && SEQ_time_strip_intersects_frame(seq, CFRA)) {
+ if (for_render && SEQ_time_strip_intersects_frame(scene, seq, CFRA)) {
continue;
}
@@ -271,13 +272,14 @@ void SEQ_relations_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render)
}
}
-static void sequencer_all_free_anim_ibufs(Editing *ed,
+static void sequencer_all_free_anim_ibufs(const Scene *scene,
ListBase *seqbase,
int timeline_frame,
const int frame_range[2])
{
+ Editing *ed = SEQ_editing_get(scene);
for (Sequence *seq = seqbase->first; seq != NULL; seq = seq->next) {
- if (!SEQ_time_strip_intersects_frame(seq, timeline_frame) ||
+ if (!SEQ_time_strip_intersects_frame(scene, seq, timeline_frame) ||
!((frame_range[0] <= timeline_frame) && (frame_range[1] > timeline_frame))) {
SEQ_relations_sequence_free_anim(seq);
}
@@ -291,11 +293,11 @@ static void sequencer_all_free_anim_ibufs(Editing *ed,
}
else {
/* Limit frame range to meta strip. */
- meta_range[0] = max_ii(frame_range[0], SEQ_time_left_handle_frame_get(seq));
- meta_range[1] = min_ii(frame_range[1], SEQ_time_right_handle_frame_get(seq));
+ meta_range[0] = max_ii(frame_range[0], SEQ_time_left_handle_frame_get(scene, seq));
+ meta_range[1] = min_ii(frame_range[1], SEQ_time_right_handle_frame_get(scene, seq));
}
- sequencer_all_free_anim_ibufs(ed, &seq->seqbase, timeline_frame, meta_range);
+ sequencer_all_free_anim_ibufs(scene, &seq->seqbase, timeline_frame, meta_range);
}
}
}
@@ -308,7 +310,7 @@ void SEQ_relations_free_all_anim_ibufs(Scene *scene, int timeline_frame)
}
const int frame_range[2] = {-MAXFRAME, MAXFRAME};
- sequencer_all_free_anim_ibufs(ed, &ed->seqbase, timeline_frame, frame_range);
+ sequencer_all_free_anim_ibufs(scene, &ed->seqbase, timeline_frame, frame_range);
}
static Sequence *sequencer_check_scene_recursion(Scene *scene, ListBase *seqbase)
@@ -346,7 +348,7 @@ bool SEQ_relations_check_scene_recursion(Scene *scene, ReportList *reports)
RPT_WARNING,
"Recursion detected in video sequencer. Strip %s at frame %d will not be rendered",
recursive_seq->name + 2,
- SEQ_time_left_handle_frame_get(recursive_seq));
+ SEQ_time_left_handle_frame_get(scene, recursive_seq));
LISTBASE_FOREACH (Sequence *, seq, &ed->seqbase) {
if (seq->type != SEQ_TYPE_SCENE && sequencer_seq_generates_image(seq)) {
diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c
index 4d6efb1639b..d4357fe28b6 100644
--- a/source/blender/sequencer/intern/strip_time.c
+++ b/source/blender/sequencer/intern/strip_time.c
@@ -31,14 +31,32 @@
#include "strip_time.h"
#include "utils.h"
-float seq_give_frame_index(Sequence *seq, float timeline_frame)
+static float seq_time_media_playback_rate_factor_get(const Scene *scene, const Sequence *seq)
+{
+ if ((seq->flag & SEQ_AUTO_PLAYBACK_RATE) == 0) {
+ return 1.0f;
+ }
+ if (seq->media_playback_rate == 0.0f) {
+ return 1.0f;
+ }
+
+ float scene_playback_rate = (float)scene->r.frs_sec / scene->r.frs_sec_base;
+ return seq->media_playback_rate / scene_playback_rate;
+}
+
+static float seq_time_playback_rate_factor_get(const Scene *scene, const Sequence *seq)
+{
+ return seq_time_media_playback_rate_factor_get(scene, seq) * seq->speed_factor;
+}
+
+float seq_give_frame_index(const Scene *scene, Sequence *seq, float timeline_frame)
{
float frame_index;
- int sta = seq->start;
- int end = seq->start + seq->len - 1;
+ float sta = SEQ_time_start_frame_get(seq);
+ float end = SEQ_time_start_frame_get(seq) + SEQ_time_strip_length_get(scene, seq) - 1;
if (seq->type & SEQ_TYPE_EFFECT) {
- end = SEQ_time_right_handle_frame_get(seq);
+ end = SEQ_time_right_handle_frame_get(scene, seq);
}
if (end < sta) {
@@ -46,29 +64,16 @@ float seq_give_frame_index(Sequence *seq, float timeline_frame)
}
if (seq->flag & SEQ_REVERSE_FRAMES) {
- /* Reverse frame in this sequence. */
- if (timeline_frame <= sta) {
- frame_index = end - sta;
- }
- else if (timeline_frame >= end) {
- frame_index = 0;
- }
- else {
- frame_index = end - timeline_frame;
- }
+ frame_index = end - timeline_frame;
}
else {
- if (timeline_frame <= sta) {
- frame_index = 0;
- }
- else if (timeline_frame >= end) {
- frame_index = end - sta;
- }
- else {
- frame_index = timeline_frame - sta;
- }
+ frame_index = timeline_frame - sta;
}
+ /* Clamp frame index to strip frame range. */
+ frame_index = clamp_f(frame_index, 0, end - sta);
+ frame_index *= seq_time_playback_rate_factor_get(scene, seq);
+
if (seq->strobe < 1.0f) {
seq->strobe = 1.0f;
}
@@ -149,14 +154,14 @@ void SEQ_time_update_meta_strip_range(const Scene *scene, Sequence *seq_meta)
return;
}
- const int strip_start = SEQ_time_left_handle_frame_get(seq_meta);
- const int strip_end = SEQ_time_right_handle_frame_get(seq_meta);
+ const int strip_start = SEQ_time_left_handle_frame_get(scene, seq_meta);
+ const int strip_end = SEQ_time_right_handle_frame_get(scene, seq_meta);
int min = MAXFRAME * 2;
int max = -MAXFRAME * 2;
LISTBASE_FOREACH (Sequence *, seq, &seq_meta->seqbase) {
- min = min_ii(SEQ_time_left_handle_frame_get(seq), min);
- max = max_ii(SEQ_time_right_handle_frame_get(seq), max);
+ min = min_ii(SEQ_time_left_handle_frame_get(scene, seq), min);
+ max = max_ii(SEQ_time_right_handle_frame_get(scene, seq), max);
}
seq_meta->start = min + seq_meta->anim_startofs;
@@ -171,25 +176,25 @@ void SEQ_time_update_meta_strip_range(const Scene *scene, Sequence *seq_meta)
SEQ_time_right_handle_frame_set(scene, seq_meta, strip_end);
}
-void seq_time_effect_range_set(Sequence *seq)
+void seq_time_effect_range_set(const Scene *scene, Sequence *seq)
{
if (seq->seq1 == NULL && seq->seq2 == NULL) {
return;
}
if (seq->seq1 && seq->seq2) { /* 2 - input effect. */
- seq->startdisp = max_ii(SEQ_time_left_handle_frame_get(seq->seq1),
- SEQ_time_left_handle_frame_get(seq->seq2));
- seq->enddisp = min_ii(SEQ_time_right_handle_frame_get(seq->seq1),
- SEQ_time_right_handle_frame_get(seq->seq2));
+ seq->startdisp = max_ii(SEQ_time_left_handle_frame_get(scene, seq->seq1),
+ SEQ_time_left_handle_frame_get(scene, seq->seq2));
+ seq->enddisp = min_ii(SEQ_time_right_handle_frame_get(scene, seq->seq1),
+ SEQ_time_right_handle_frame_get(scene, seq->seq2));
}
else if (seq->seq1) { /* Single input effect. */
- seq->startdisp = SEQ_time_right_handle_frame_get(seq->seq1);
- seq->enddisp = SEQ_time_left_handle_frame_get(seq->seq1);
+ seq->startdisp = SEQ_time_right_handle_frame_get(scene, seq->seq1);
+ seq->enddisp = SEQ_time_left_handle_frame_get(scene, seq->seq1);
}
else if (seq->seq2) { /* Strip may be missing one of inputs. */
- seq->startdisp = SEQ_time_right_handle_frame_get(seq->seq2);
- seq->enddisp = SEQ_time_left_handle_frame_get(seq->seq2);
+ seq->startdisp = SEQ_time_right_handle_frame_get(scene, seq->seq2);
+ seq->enddisp = SEQ_time_left_handle_frame_get(scene, seq->seq2);
}
if (seq->startdisp > seq->enddisp) {
@@ -210,7 +215,7 @@ void seq_time_update_effects_strip_range(const Scene *scene, SeqCollection *effe
Sequence *seq;
/* First pass: Update length of immediate effects. */
SEQ_ITERATOR_FOREACH (seq, effects) {
- seq_time_effect_range_set(seq);
+ seq_time_effect_range_set(scene, seq);
}
/* Second pass: Recursive call to update effects in chain and in order, so they inherit length
@@ -255,14 +260,14 @@ int SEQ_time_find_next_prev_edit(Scene *scene,
}
if (do_center) {
- seq_frames[0] = (SEQ_time_left_handle_frame_get(seq) +
- SEQ_time_right_handle_frame_get(seq)) /
+ seq_frames[0] = (SEQ_time_left_handle_frame_get(scene, seq) +
+ SEQ_time_right_handle_frame_get(scene, seq)) /
2;
seq_frames_tot = 1;
}
else {
- seq_frames[0] = SEQ_time_left_handle_frame_get(seq);
- seq_frames[1] = SEQ_time_right_handle_frame_get(seq);
+ seq_frames[0] = SEQ_time_left_handle_frame_get(scene, seq);
+ seq_frames[1] = SEQ_time_right_handle_frame_get(scene, seq);
seq_frames_tot = 2;
}
@@ -339,18 +344,18 @@ void SEQ_timeline_init_boundbox(const Scene *scene, rctf *rect)
rect->ymax = 8.0f;
}
-void SEQ_timeline_expand_boundbox(const ListBase *seqbase, rctf *rect)
+void SEQ_timeline_expand_boundbox(const Scene *scene, const ListBase *seqbase, rctf *rect)
{
if (seqbase == NULL) {
return;
}
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
- if (rect->xmin > SEQ_time_left_handle_frame_get(seq) - 1) {
- rect->xmin = SEQ_time_left_handle_frame_get(seq) - 1;
+ if (rect->xmin > SEQ_time_left_handle_frame_get(scene, seq) - 1) {
+ rect->xmin = SEQ_time_left_handle_frame_get(scene, seq) - 1;
}
- if (rect->xmax < SEQ_time_right_handle_frame_get(seq) + 1) {
- rect->xmax = SEQ_time_right_handle_frame_get(seq) + 1;
+ if (rect->xmax < SEQ_time_right_handle_frame_get(scene, seq) + 1) {
+ rect->xmax = SEQ_time_right_handle_frame_get(scene, seq) + 1;
}
if (rect->ymax < seq->machine) {
rect->ymax = seq->machine;
@@ -361,14 +366,16 @@ void SEQ_timeline_expand_boundbox(const ListBase *seqbase, rctf *rect)
void SEQ_timeline_boundbox(const Scene *scene, const ListBase *seqbase, rctf *rect)
{
SEQ_timeline_init_boundbox(scene, rect);
- SEQ_timeline_expand_boundbox(seqbase, rect);
+ SEQ_timeline_expand_boundbox(scene, seqbase, rect);
}
-static bool strip_exists_at_frame(SeqCollection *all_strips, const int timeline_frame)
+static bool strip_exists_at_frame(const Scene *scene,
+ SeqCollection *all_strips,
+ const int timeline_frame)
{
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, all_strips) {
- if (SEQ_time_strip_intersects_frame(seq, timeline_frame)) {
+ if (SEQ_time_strip_intersects_frame(scene, seq, timeline_frame)) {
return true;
}
}
@@ -390,10 +397,10 @@ void seq_time_gap_info_get(const Scene *scene,
SeqCollection *collection = SEQ_query_all_strips(seqbase);
- if (!strip_exists_at_frame(collection, initial_frame)) {
+ if (!strip_exists_at_frame(scene, collection, initial_frame)) {
/* Search backward for gap_start_frame. */
for (; timeline_frame >= sfra; timeline_frame--) {
- if (strip_exists_at_frame(collection, timeline_frame)) {
+ if (strip_exists_at_frame(scene, collection, timeline_frame)) {
break;
}
}
@@ -403,7 +410,7 @@ void seq_time_gap_info_get(const Scene *scene,
else {
/* Search forward for gap_start_frame. */
for (; timeline_frame <= efra; timeline_frame++) {
- if (!strip_exists_at_frame(collection, timeline_frame)) {
+ if (!strip_exists_at_frame(scene, collection, timeline_frame)) {
r_gap_info->gap_start_frame = timeline_frame;
break;
}
@@ -411,7 +418,7 @@ void seq_time_gap_info_get(const Scene *scene,
}
/* Search forward for gap_end_frame. */
for (; timeline_frame <= efra; timeline_frame++) {
- if (strip_exists_at_frame(collection, timeline_frame)) {
+ if (strip_exists_at_frame(scene, collection, timeline_frame)) {
const int gap_end_frame = timeline_frame;
r_gap_info->gap_length = gap_end_frame - r_gap_info->gap_start_frame;
r_gap_info->gap_exists = true;
@@ -420,28 +427,67 @@ void seq_time_gap_info_get(const Scene *scene,
}
}
-bool SEQ_time_strip_intersects_frame(const Sequence *seq, const int timeline_frame)
+bool SEQ_time_strip_intersects_frame(const Scene *scene,
+ const Sequence *seq,
+ const int timeline_frame)
+{
+ return (SEQ_time_left_handle_frame_get(scene, seq) <= timeline_frame) &&
+ (SEQ_time_right_handle_frame_get(scene, seq) > timeline_frame);
+}
+
+void SEQ_time_speed_factor_set(const Scene *scene, Sequence *seq, const float speed_factor)
+{
+ const float left_handle_frame = SEQ_time_left_handle_frame_get(scene, seq);
+ const float unity_start_offset = seq->startofs * seq->speed_factor;
+ const float unity_end_offset = seq->endofs * seq->speed_factor;
+
+ /* Left handle is pivot point for content scaling - it must always show same frame. */
+ seq->speed_factor = speed_factor;
+ seq->startofs = unity_start_offset / speed_factor;
+ seq->start = left_handle_frame - seq->startofs;
+ seq->endofs = unity_end_offset / speed_factor;
+
+ SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq));
+ seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq));
+}
+
+bool SEQ_time_has_left_still_frames(const Scene *scene, const Sequence *seq)
+{
+ return SEQ_time_left_handle_frame_get(scene, seq) < SEQ_time_start_frame_get(seq);
+}
+
+bool SEQ_time_has_right_still_frames(const Scene *scene, const Sequence *seq)
+{
+ return SEQ_time_right_handle_frame_get(scene, seq) >
+ SEQ_time_start_frame_get(seq) + SEQ_time_strip_length_get(scene, seq);
+}
+
+bool SEQ_time_has_still_frames(const Scene *scene, const Sequence *seq)
{
- return (SEQ_time_left_handle_frame_get(seq) <= timeline_frame) &&
- (SEQ_time_right_handle_frame_get(seq) > timeline_frame);
+ return SEQ_time_has_right_still_frames(scene, seq) || SEQ_time_has_left_still_frames(scene, seq);
}
-bool SEQ_time_has_left_still_frames(const Sequence *seq)
+/* Length of strip content in frames. This is number of original frames adjusted by playback rate
+ * factor */
+int SEQ_time_strip_length_get(const Scene *scene, const Sequence *seq)
{
- return seq->startofs < 0;
+ return seq->len / seq_time_playback_rate_factor_get(scene, seq);
}
-bool SEQ_time_has_right_still_frames(const Sequence *seq)
+/* Return timeline frame, where strip content starts. */
+float SEQ_time_start_frame_get(const Sequence *seq)
{
- return seq->endofs < 0;
+ return seq->start;
}
-bool SEQ_time_has_still_frames(const Sequence *seq)
+void SEQ_time_start_frame_set(const Scene *scene, Sequence *seq, int timeline_frame)
{
- return SEQ_time_has_right_still_frames(seq) || SEQ_time_has_left_still_frames(seq);
+ seq->start = timeline_frame;
+ SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq));
+ seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq));
}
-int SEQ_time_left_handle_frame_get(const Sequence *seq)
+int SEQ_time_left_handle_frame_get(const Scene *UNUSED(scene), const Sequence *seq)
{
if (seq->seq1 || seq->seq2) {
return seq->startdisp;
@@ -450,27 +496,42 @@ int SEQ_time_left_handle_frame_get(const Sequence *seq)
return seq->start + seq->startofs;
}
-int SEQ_time_right_handle_frame_get(const Sequence *seq)
+int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
{
if (seq->seq1 || seq->seq2) {
return seq->enddisp;
}
- return seq->start + seq->len - seq->endofs;
+ return seq->start + SEQ_time_strip_length_get(scene, seq) - seq->endofs;
}
void SEQ_time_left_handle_frame_set(const Scene *scene, Sequence *seq, int val)
{
+ const float right_handle_orig_frame = SEQ_time_right_handle_frame_get(scene, seq);
+
+ if (val >= right_handle_orig_frame) {
+ val = right_handle_orig_frame - 1;
+ }
+
seq->startofs = val - seq->start;
seq->startdisp = val; /* Only to make files usable in older versions. */
+
SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq));
seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq));
}
void SEQ_time_right_handle_frame_set(const Scene *scene, Sequence *seq, int val)
{
- seq->endofs = seq->start + seq->len - val;
+ const float strip_content_end_frame = seq->start + SEQ_time_strip_length_get(scene, seq);
+ const float left_handle_orig_frame = SEQ_time_left_handle_frame_get(scene, seq);
+
+ if (val <= left_handle_orig_frame) {
+ val = left_handle_orig_frame + 1;
+ }
+
+ seq->endofs = strip_content_end_frame - val;
seq->enddisp = val; /* Only to make files usable in older versions. */
+
SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq));
seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq));
}
diff --git a/source/blender/sequencer/intern/strip_time.h b/source/blender/sequencer/intern/strip_time.h
index 7a75aeac1a6..db581649f8a 100644
--- a/source/blender/sequencer/intern/strip_time.h
+++ b/source/blender/sequencer/intern/strip_time.h
@@ -16,7 +16,7 @@ struct Scene;
struct Sequence;
struct SeqCollection;
-float seq_give_frame_index(struct Sequence *seq, float timeline_frame);
+float seq_give_frame_index(const struct Scene *scene, struct Sequence *seq, float timeline_frame);
void seq_update_sound_bounds_recursive(const struct Scene *scene, struct Sequence *metaseq);
/* Describes gap between strips in timeline. */
@@ -38,7 +38,7 @@ void seq_time_gap_info_get(const struct Scene *scene,
struct ListBase *seqbase,
int initial_frame,
struct GapInfo *r_gap_info);
-void seq_time_effect_range_set(Sequence *seq);
+void seq_time_effect_range_set(const struct Scene *scene, Sequence *seq);
void seq_time_update_effects_strip_range(const struct Scene *scene, struct SeqCollection *effects);
#ifdef __cplusplus
diff --git a/source/blender/sequencer/intern/strip_transform.c b/source/blender/sequencer/intern/strip_transform.c
index 19caf12ff2a..68b30c9ce19 100644
--- a/source/blender/sequencer/intern/strip_transform.c
+++ b/source/blender/sequencer/intern/strip_transform.c
@@ -34,15 +34,6 @@
static CLG_LogRef LOG = {"seq.strip_transform"};
-static int seq_tx_get_start(Sequence *seq)
-{
- return seq->start;
-}
-static int seq_tx_get_end(Sequence *seq)
-{
- return seq->start + seq->len;
-}
-
bool SEQ_transform_single_image_check(Sequence *seq)
{
return ((seq->len == 1) &&
@@ -91,49 +82,6 @@ bool SEQ_transform_seqbase_isolated_sel_check(ListBase *seqbase)
return true;
}
-void SEQ_transform_handle_xlimits(const Scene *scene, Sequence *seq, int leftflag, int rightflag)
-{
- if (leftflag) {
- if (SEQ_time_left_handle_frame_get(seq) >= SEQ_time_right_handle_frame_get(seq)) {
- SEQ_time_left_handle_frame_set(scene, seq, SEQ_time_right_handle_frame_get(seq) - 1);
- }
-
- if (SEQ_transform_single_image_check(seq) == 0) {
- if (SEQ_time_left_handle_frame_get(seq) >= seq_tx_get_end(seq)) {
- SEQ_time_left_handle_frame_set(scene, seq, seq_tx_get_end(seq) - 1);
- }
-
- /* TODO: This doesn't work at the moment. */
-#if 0
- if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq, 0)) {
- int ofs;
- ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq, 0);
- seq->start -= ofs;
- seq_tx_set_final_left(seq, seq_tx_get_final_left(seq, 0) + ofs);
- }
-#endif
- }
- }
-
- if (rightflag) {
- if (SEQ_time_right_handle_frame_get(seq) <= SEQ_time_left_handle_frame_get(seq)) {
- SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(seq) + 1);
- }
-
- if (SEQ_transform_single_image_check(seq) == 0) {
- if (SEQ_time_right_handle_frame_get(seq) <= seq_tx_get_start(seq)) {
- SEQ_time_right_handle_frame_set(scene, seq, seq_tx_get_start(seq) + 1);
- }
- }
- }
-
- /* sounds cannot be extended past their endpoints */
- if (seq->type == SEQ_TYPE_SOUND_RAM) {
- CLAMP(seq->startofs, 0, MAXFRAME);
- CLAMP(seq->endofs, 0, MAXFRAME);
- }
-}
-
void SEQ_transform_fix_single_image_seq_offsets(const Scene *scene, Sequence *seq)
{
int left, start, offset;
@@ -143,12 +91,14 @@ void SEQ_transform_fix_single_image_seq_offsets(const Scene *scene, Sequence *se
/* make sure the image is always at the start since there is only one,
* adjusting its start should be ok */
- left = SEQ_time_left_handle_frame_get(seq);
+ left = SEQ_time_left_handle_frame_get(scene, seq);
start = seq->start;
if (start != left) {
offset = left - start;
- SEQ_time_left_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(seq) - offset);
- SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_right_handle_frame_get(seq) - offset);
+ SEQ_time_left_handle_frame_set(
+ scene, seq, SEQ_time_left_handle_frame_get(scene, seq) - offset);
+ SEQ_time_right_handle_frame_set(
+ scene, seq, SEQ_time_right_handle_frame_get(scene, seq) - offset);
seq->start += offset;
}
}
@@ -158,20 +108,22 @@ bool SEQ_transform_sequence_can_be_translated(Sequence *seq)
return !(seq->type & SEQ_TYPE_EFFECT) || (SEQ_effect_get_num_inputs(seq->type) == 0);
}
-bool SEQ_transform_test_overlap_seq_seq(Sequence *seq1, Sequence *seq2)
+bool SEQ_transform_test_overlap_seq_seq(const Scene *scene, Sequence *seq1, Sequence *seq2)
{
return (seq1 != seq2 && seq1->machine == seq2->machine &&
- ((SEQ_time_right_handle_frame_get(seq1) <= SEQ_time_left_handle_frame_get(seq2)) ||
- (SEQ_time_left_handle_frame_get(seq1) >= SEQ_time_right_handle_frame_get(seq2))) == 0);
+ ((SEQ_time_right_handle_frame_get(scene, seq1) <=
+ SEQ_time_left_handle_frame_get(scene, seq2)) ||
+ (SEQ_time_left_handle_frame_get(scene, seq1) >=
+ SEQ_time_right_handle_frame_get(scene, seq2))) == 0);
}
-bool SEQ_transform_test_overlap(ListBase *seqbasep, Sequence *test)
+bool SEQ_transform_test_overlap(const Scene *scene, ListBase *seqbasep, Sequence *test)
{
Sequence *seq;
seq = seqbasep->first;
while (seq) {
- if (SEQ_transform_test_overlap_seq_seq(test, seq)) {
+ if (SEQ_transform_test_overlap_seq_seq(scene, test, seq)) {
return true;
}
@@ -194,14 +146,16 @@ void SEQ_transform_translate_sequence(Scene *evil_scene, Sequence *seq, int delt
SEQ_transform_translate_sequence(evil_scene, seq_child, delta);
}
/* Move meta start/end points. */
- SEQ_time_left_handle_frame_set(evil_scene, seq, SEQ_time_left_handle_frame_get(seq) + delta);
- SEQ_time_right_handle_frame_set(evil_scene, seq, SEQ_time_right_handle_frame_get(seq) + delta);
+ SEQ_time_left_handle_frame_set(
+ evil_scene, seq, SEQ_time_left_handle_frame_get(evil_scene, seq) + delta);
+ SEQ_time_right_handle_frame_set(
+ evil_scene, seq, SEQ_time_right_handle_frame_get(evil_scene, seq) + delta);
}
else { /* All other strip types. */
seq->start += delta;
/* Only to make files usable in older versions. */
- seq->startdisp = SEQ_time_left_handle_frame_get(seq);
- seq->enddisp = SEQ_time_right_handle_frame_get(seq);
+ seq->startdisp = SEQ_time_left_handle_frame_get(evil_scene, seq);
+ seq->enddisp = SEQ_time_right_handle_frame_get(evil_scene, seq);
}
SEQ_offset_animdata(evil_scene, seq, delta);
@@ -219,7 +173,7 @@ bool SEQ_transform_seqbase_shuffle_ex(ListBase *seqbasep,
BLI_assert(ELEM(channel_delta, -1, 1));
test->machine += channel_delta;
- while (SEQ_transform_test_overlap(seqbasep, test)) {
+ while (SEQ_transform_test_overlap(evil_scene, seqbasep, test)) {
if ((channel_delta > 0) ? (test->machine >= MAXSEQ) : (test->machine < 1)) {
break;
}
@@ -232,17 +186,17 @@ bool SEQ_transform_seqbase_shuffle_ex(ListBase *seqbasep,
* nicer to move it to the end */
Sequence *seq;
- int new_frame = SEQ_time_right_handle_frame_get(test);
+ int new_frame = SEQ_time_right_handle_frame_get(evil_scene, test);
for (seq = seqbasep->first; seq; seq = seq->next) {
if (seq->machine == orig_machine) {
- new_frame = max_ii(new_frame, SEQ_time_right_handle_frame_get(seq));
+ new_frame = max_ii(new_frame, SEQ_time_right_handle_frame_get(evil_scene, seq));
}
}
test->machine = orig_machine;
- new_frame = new_frame +
- (test->start - SEQ_time_left_handle_frame_get(test)); /* adjust by the startdisp */
+ new_frame = new_frame + (test->start - SEQ_time_left_handle_frame_get(
+ evil_scene, test)); /* adjust by the startdisp */
SEQ_transform_translate_sequence(evil_scene, test, new_frame - test->start);
return false;
}
@@ -255,16 +209,20 @@ bool SEQ_transform_seqbase_shuffle(ListBase *seqbasep, Sequence *test, Scene *ev
return SEQ_transform_seqbase_shuffle_ex(seqbasep, test, evil_scene, 1);
}
-static bool shuffle_seq_test_overlap(const Sequence *seq1, const Sequence *seq2, const int offset)
+static bool shuffle_seq_test_overlap(const Scene *scene,
+ const Sequence *seq1,
+ const Sequence *seq2,
+ const int offset)
{
- return (
- seq1 != seq2 && seq1->machine == seq2->machine &&
- ((SEQ_time_right_handle_frame_get(seq1) + offset <= SEQ_time_left_handle_frame_get(seq2)) ||
- (SEQ_time_left_handle_frame_get(seq1) + offset >= SEQ_time_right_handle_frame_get(seq2))) ==
- 0);
+ return (seq1 != seq2 && seq1->machine == seq2->machine &&
+ ((SEQ_time_right_handle_frame_get(scene, seq1) + offset <=
+ SEQ_time_left_handle_frame_get(scene, seq2)) ||
+ (SEQ_time_left_handle_frame_get(scene, seq1) + offset >=
+ SEQ_time_right_handle_frame_get(scene, seq2))) == 0);
}
-static int shuffle_seq_time_offset_get(SeqCollection *strips_to_shuffle,
+static int shuffle_seq_time_offset_get(const Scene *scene,
+ SeqCollection *strips_to_shuffle,
ListBase *seqbasep,
char dir)
{
@@ -276,7 +234,7 @@ static int shuffle_seq_time_offset_get(SeqCollection *strips_to_shuffle,
all_conflicts_resolved = true;
SEQ_ITERATOR_FOREACH (seq, strips_to_shuffle) {
LISTBASE_FOREACH (Sequence *, seq_other, seqbasep) {
- if (!shuffle_seq_test_overlap(seq, seq_other, offset)) {
+ if (!shuffle_seq_test_overlap(scene, seq, seq_other, offset)) {
continue;
}
if (SEQ_relation_is_effect_of_strip(seq_other, seq)) {
@@ -293,13 +251,13 @@ static int shuffle_seq_time_offset_get(SeqCollection *strips_to_shuffle,
if (dir == 'L') {
offset = min_ii(offset,
- SEQ_time_left_handle_frame_get(seq_other) -
- SEQ_time_right_handle_frame_get(seq));
+ SEQ_time_left_handle_frame_get(scene, seq_other) -
+ SEQ_time_right_handle_frame_get(scene, seq));
}
else {
offset = max_ii(offset,
- SEQ_time_right_handle_frame_get(seq_other) -
- SEQ_time_left_handle_frame_get(seq));
+ SEQ_time_right_handle_frame_get(scene, seq_other) -
+ SEQ_time_left_handle_frame_get(scene, seq));
}
}
}
@@ -315,8 +273,8 @@ bool SEQ_transform_seqbase_shuffle_time(SeqCollection *strips_to_shuffle,
ListBase *markers,
const bool use_sync_markers)
{
- int offset_l = shuffle_seq_time_offset_get(strips_to_shuffle, seqbasep, 'L');
- int offset_r = shuffle_seq_time_offset_get(strips_to_shuffle, seqbasep, 'R');
+ int offset_l = shuffle_seq_time_offset_get(evil_scene, strips_to_shuffle, seqbasep, 'L');
+ int offset_r = shuffle_seq_time_offset_get(evil_scene, strips_to_shuffle, seqbasep, 'R');
int offset = (-offset_l < offset_r) ? offset_l : offset_r;
if (offset) {
@@ -359,7 +317,8 @@ static SeqCollection *extract_standalone_strips(SeqCollection *transformed_strip
}
/* Query strips positioned after left edge of transformed strips bound-box. */
-static SeqCollection *query_right_side_strips(ListBase *seqbase,
+static SeqCollection *query_right_side_strips(const Scene *scene,
+ ListBase *seqbase,
SeqCollection *transformed_strips,
SeqCollection *time_dependent_strips)
{
@@ -367,7 +326,7 @@ static SeqCollection *query_right_side_strips(ListBase *seqbase,
{
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, transformed_strips) {
- minframe = min_ii(minframe, SEQ_time_left_handle_frame_get(seq));
+ minframe = min_ii(minframe, SEQ_time_left_handle_frame_get(scene, seq));
}
}
@@ -380,7 +339,7 @@ static SeqCollection *query_right_side_strips(ListBase *seqbase,
continue;
}
- if ((seq->flag & SELECT) == 0 && SEQ_time_left_handle_frame_get(seq) >= minframe) {
+ if ((seq->flag & SELECT) == 0 && SEQ_time_left_handle_frame_get(scene, seq) >= minframe) {
SEQ_collection_append_strip(seq, collection);
}
}
@@ -398,7 +357,7 @@ static void seq_transform_handle_expand_to_fit(Scene *scene,
ListBase *markers = &scene->markers;
SeqCollection *right_side_strips = query_right_side_strips(
- seqbasep, transformed_strips, time_dependent_strips);
+ scene, seqbasep, transformed_strips, time_dependent_strips);
/* Temporarily move right side strips beyond timeline boundary. */
Sequence *seq;
@@ -424,7 +383,8 @@ static void seq_transform_handle_expand_to_fit(Scene *scene,
SEQ_collection_free(right_side_strips);
}
-static SeqCollection *query_overwrite_targets(ListBase *seqbasep,
+static SeqCollection *query_overwrite_targets(const Scene *scene,
+ ListBase *seqbasep,
SeqCollection *transformed_strips)
{
SeqCollection *collection = SEQ_query_unselected_strips(seqbasep);
@@ -438,7 +398,7 @@ static SeqCollection *query_overwrite_targets(ListBase *seqbasep,
if (seq == seq_transformed) {
SEQ_collection_remove_strip(seq, collection);
}
- if (SEQ_transform_test_overlap_seq_seq(seq, seq_transformed)) {
+ if (SEQ_transform_test_overlap_seq_seq(scene, seq, seq_transformed)) {
does_overlap = true;
}
}
@@ -463,23 +423,32 @@ typedef enum eOvelapDescrition {
STRIP_OVERLAP_RIGHT_SIDE,
} eOvelapDescrition;
-static eOvelapDescrition overlap_description_get(const Sequence *transformed,
+static eOvelapDescrition overlap_description_get(const Scene *scene,
+ const Sequence *transformed,
const Sequence *target)
{
- if (SEQ_time_left_handle_frame_get(transformed) <= SEQ_time_left_handle_frame_get(target) &&
- SEQ_time_right_handle_frame_get(transformed) >= SEQ_time_right_handle_frame_get(target)) {
+ if (SEQ_time_left_handle_frame_get(scene, transformed) <=
+ SEQ_time_left_handle_frame_get(scene, target) &&
+ SEQ_time_right_handle_frame_get(scene, transformed) >=
+ SEQ_time_right_handle_frame_get(scene, target)) {
return STRIP_OVERLAP_IS_FULL;
}
- if (SEQ_time_left_handle_frame_get(transformed) > SEQ_time_left_handle_frame_get(target) &&
- SEQ_time_right_handle_frame_get(transformed) < SEQ_time_right_handle_frame_get(target)) {
+ if (SEQ_time_left_handle_frame_get(scene, transformed) >
+ SEQ_time_left_handle_frame_get(scene, target) &&
+ SEQ_time_right_handle_frame_get(scene, transformed) <
+ SEQ_time_right_handle_frame_get(scene, target)) {
return STRIP_OVERLAP_IS_INSIDE;
}
- if (SEQ_time_left_handle_frame_get(transformed) <= SEQ_time_left_handle_frame_get(target) &&
- SEQ_time_left_handle_frame_get(target) <= SEQ_time_right_handle_frame_get(transformed)) {
+ if (SEQ_time_left_handle_frame_get(scene, transformed) <=
+ SEQ_time_left_handle_frame_get(scene, target) &&
+ SEQ_time_left_handle_frame_get(scene, target) <=
+ SEQ_time_right_handle_frame_get(scene, transformed)) {
return STRIP_OVERLAP_LEFT_SIDE;
}
- if (SEQ_time_left_handle_frame_get(transformed) <= SEQ_time_right_handle_frame_get(target) &&
- SEQ_time_right_handle_frame_get(target) <= SEQ_time_right_handle_frame_get(transformed)) {
+ if (SEQ_time_left_handle_frame_get(scene, transformed) <=
+ SEQ_time_right_handle_frame_get(scene, target) &&
+ SEQ_time_right_handle_frame_get(scene, target) <=
+ SEQ_time_right_handle_frame_get(scene, transformed)) {
return STRIP_OVERLAP_RIGHT_SIDE;
}
return STRIP_OVERLAP_NONE;
@@ -499,14 +468,14 @@ static void seq_transform_handle_overwrite_split(Scene *scene,
scene,
seqbasep,
target,
- SEQ_time_left_handle_frame_get(transformed),
+ SEQ_time_left_handle_frame_get(scene, transformed),
SEQ_SPLIT_SOFT,
NULL);
SEQ_edit_strip_split(bmain,
scene,
seqbasep,
split_strip,
- SEQ_time_right_handle_frame_get(transformed),
+ SEQ_time_right_handle_frame_get(scene, transformed),
SEQ_SPLIT_SOFT,
NULL);
SEQ_edit_flag_for_removal(scene, seqbasep, split_strip);
@@ -521,11 +490,12 @@ static void seq_transform_handle_overwrite_trim(Scene *scene,
Sequence *target,
const eOvelapDescrition overlap)
{
- SeqCollection *targets = SEQ_query_by_reference(target, seqbasep, SEQ_query_strip_effect_chain);
+ SeqCollection *targets = SEQ_query_by_reference(
+ target, scene, seqbasep, SEQ_query_strip_effect_chain);
/* Expand collection by adding all target's children, effects and their children. */
if ((target->type & SEQ_TYPE_EFFECT) != 0) {
- SEQ_collection_expand(seqbasep, targets, SEQ_query_strip_effect_chain);
+ SEQ_collection_expand(scene, seqbasep, targets, SEQ_query_strip_effect_chain);
}
/* Trim all non effects, that have influence on effect length which is overlapping. */
@@ -535,11 +505,13 @@ static void seq_transform_handle_overwrite_trim(Scene *scene,
continue;
}
if (overlap == STRIP_OVERLAP_LEFT_SIDE) {
- SEQ_time_left_handle_frame_set(scene, seq, SEQ_time_right_handle_frame_get(transformed));
+ SEQ_time_left_handle_frame_set(
+ scene, seq, SEQ_time_right_handle_frame_get(scene, transformed));
}
else {
BLI_assert(overlap == STRIP_OVERLAP_RIGHT_SIDE);
- SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(transformed));
+ SEQ_time_right_handle_frame_set(
+ scene, seq, SEQ_time_left_handle_frame_get(scene, transformed));
}
}
SEQ_collection_free(targets);
@@ -549,7 +521,7 @@ static void seq_transform_handle_overwrite(Scene *scene,
ListBase *seqbasep,
SeqCollection *transformed_strips)
{
- SeqCollection *targets = query_overwrite_targets(seqbasep, transformed_strips);
+ SeqCollection *targets = query_overwrite_targets(scene, seqbasep, transformed_strips);
SeqCollection *strips_to_delete = SEQ_collection_create(__func__);
Sequence *target;
@@ -560,7 +532,7 @@ static void seq_transform_handle_overwrite(Scene *scene,
continue;
}
- const eOvelapDescrition overlap = overlap_description_get(transformed, target);
+ const eOvelapDescrition overlap = overlap_description_get(scene, transformed, target);
if (overlap == STRIP_OVERLAP_IS_FULL) {
SEQ_collection_append_strip(target, strips_to_delete);
@@ -629,7 +601,7 @@ void SEQ_transform_handle_overlap(Scene *scene,
* In some cases other strips can be overlapping still, see T90646. */
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, transformed_strips) {
- if (SEQ_transform_test_overlap(seqbasep, seq)) {
+ if (SEQ_transform_test_overlap(scene, seqbasep, seq)) {
SEQ_transform_seqbase_shuffle(seqbasep, seq, scene);
}
seq->flag &= ~SEQ_OVERLAP;
@@ -642,7 +614,7 @@ void SEQ_transform_offset_after_frame(Scene *scene,
const int timeline_frame)
{
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
- if (SEQ_time_left_handle_frame_get(seq) >= timeline_frame) {
+ if (SEQ_time_left_handle_frame_get(scene, seq) >= timeline_frame) {
SEQ_transform_translate_sequence(scene, seq, delta);
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
}
diff --git a/source/blender/sequencer/intern/utils.c b/source/blender/sequencer/intern/utils.c
index 3cfe63e284f..2026e322763 100644
--- a/source/blender/sequencer/intern/utils.c
+++ b/source/blender/sequencer/intern/utils.c
@@ -187,7 +187,7 @@ ListBase *SEQ_get_seqbase_from_sequence(Sequence *seq, ListBase **r_channels, in
case SEQ_TYPE_META: {
seqbase = &seq->seqbase;
*r_channels = &seq->channels;
- *r_offset = seq->start;
+ *r_offset = SEQ_time_start_frame_get(seq);
break;
}
case SEQ_TYPE_SCENE: {
@@ -347,7 +347,8 @@ const Sequence *SEQ_get_topmost_sequence(const Scene *scene, int frame)
}
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- if (SEQ_render_is_muted(channels, seq) || !SEQ_time_strip_intersects_frame(seq, frame)) {
+ if (SEQ_render_is_muted(channels, seq) ||
+ !SEQ_time_strip_intersects_frame(scene, seq, frame)) {
continue;
}
/* Only use strips that generate an image, not ones that combine