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-02 02:39:40 +0300
committerRichard Antalik <richardantalik@gmail.com>2022-06-02 04:16:20 +0300
commit7afcfe111aacc8bc3f456a3287d3cc34765b798a (patch)
treea67d26f084938bf9f05289e756654a7b5387d9d1 /source/blender/sequencer
parent604409b8c7071920e6cc7a672571449070375919 (diff)
VSE: Make time operations self-contained
This patch makes it possible to manipulate strips without need to use update functions to recalculate effect and meta strips. Prior to this change function `SEQ_time_update_sequence` had to be used to update mainly effects and meta strips. This was implemented in a way that relied on sorted list of strips, which can't always be done and in rare cases this approach failed. In case of meta strips, `seqbase` had to be passed and compared with "active" one to determine whether meta strip should be updated or not. This is especially weak system that is prone to bugs when functions are used by python API functions. Finally, other strip types had startdisp` and `enddisp` fields updated by this function and a lot of code relied on these fields even if strip start, length and offsets are available. This is completely unnecessary. Implemented changes: All effects and meta strips are updated when strip handles are moved or strip is translated, without need to call any update function. Function `SEQ_time_update_sequence` has been split to `SEQ_time_update_meta_strip_range` and `seq_time_update_effects_strip_range`. These functions should be only used within sequencer module code. Meta update is used for versioning, which is only reason for it not being declared internally. Sequence fields `startdisp` and `enddisp` are now only used for effects to store strip start and end points. These fields should be used only internally within sequencer module code. Use function `SEQ_time_*_handle_frame_get` to get strip start and end points. To update effects and meta strips with reasonable performance, cache for "parent" meta strip and attached effects is added to `SequenceLookup` cache, so it shares invalidation mechanisms. All caches are populated during single iteration. There should be no functional changes. Differential Revision: https://developer.blender.org/D14990
Diffstat (limited to 'source/blender/sequencer')
-rw-r--r--source/blender/sequencer/SEQ_add.h3
-rw-r--r--source/blender/sequencer/SEQ_sequencer.h3
-rw-r--r--source/blender/sequencer/SEQ_time.h13
-rw-r--r--source/blender/sequencer/SEQ_transform.h7
-rw-r--r--source/blender/sequencer/SEQ_utils.h10
-rw-r--r--source/blender/sequencer/intern/disk_cache.c5
-rw-r--r--source/blender/sequencer/intern/effects.c21
-rw-r--r--source/blender/sequencer/intern/image_cache.c19
-rw-r--r--source/blender/sequencer/intern/proxy.c8
-rw-r--r--source/blender/sequencer/intern/render.c22
-rw-r--r--source/blender/sequencer/intern/sequence_lookup.c94
-rw-r--r--source/blender/sequencer/intern/sequencer.h26
-rw-r--r--source/blender/sequencer/intern/sound.c10
-rw-r--r--source/blender/sequencer/intern/strip_add.c25
-rw-r--r--source/blender/sequencer/intern/strip_edit.c69
-rw-r--r--source/blender/sequencer/intern/strip_relations.c9
-rw-r--r--source/blender/sequencer/intern/strip_time.c217
-rw-r--r--source/blender/sequencer/intern/strip_time.h5
-rw-r--r--source/blender/sequencer/intern/strip_transform.c150
-rw-r--r--source/blender/sequencer/intern/utils.c68
20 files changed, 378 insertions, 406 deletions
diff --git a/source/blender/sequencer/SEQ_add.h b/source/blender/sequencer/SEQ_add.h
index c195165a792..dea5151598c 100644
--- a/source/blender/sequencer/SEQ_add.h
+++ b/source/blender/sequencer/SEQ_add.h
@@ -183,9 +183,6 @@ void SEQ_add_image_load_file(struct Sequence *seq, size_t strip_frame, char *fil
* \param seq: image strip to be changed
*/
void SEQ_add_image_init_alpha_mode(struct Sequence *seq);
-/**
- * \note caller should run `SEQ_time_update_sequence(scene, seq)` after..
- */
void SEQ_add_reload_new_file(struct Main *bmain,
struct Scene *scene,
struct Sequence *seq,
diff --git a/source/blender/sequencer/SEQ_sequencer.h b/source/blender/sequencer/SEQ_sequencer.h
index 8ded6d99a8d..70cba58007f 100644
--- a/source/blender/sequencer/SEQ_sequencer.h
+++ b/source/blender/sequencer/SEQ_sequencer.h
@@ -143,7 +143,8 @@ typedef enum eSequenceLookupTag {
*
* \return pointer to Sequence
*/
-struct Sequence *SEQ_sequence_lookup_by_name(const struct Scene *scene, const char *key);
+struct Sequence *SEQ_sequence_lookup_seq_by_name(const struct Scene *scene, const char *key);
+
/**
* Free lookup hash data.
*
diff --git a/source/blender/sequencer/SEQ_time.h b/source/blender/sequencer/SEQ_time.h
index 1da6efb1d04..eab10f2e852 100644
--- a/source/blender/sequencer/SEQ_time.h
+++ b/source/blender/sequencer/SEQ_time.h
@@ -47,8 +47,6 @@ int SEQ_time_find_next_prev_edit(struct Scene *scene,
bool do_skip_mute,
bool do_center,
bool do_unselected);
-void SEQ_time_update_sequence(struct Scene *scene, struct ListBase *seqbase, struct Sequence *seq);
-void SEQ_time_update_recursive(struct Scene *scene, struct Sequence *changed_seq);
/**
* Test if strip intersects with timeline frame.
* \note This checks if strip would be rendered at this frame. For rendering it is assumed, that
@@ -59,14 +57,15 @@ void SEQ_time_update_recursive(struct Scene *scene, struct Sequence *changed_seq
* \return true if strip intersects with timeline frame.
*/
bool SEQ_time_strip_intersects_frame(const struct Sequence *seq, int timeline_frame);
-void SEQ_time_update_meta_strip_range(struct Scene *scene, struct Sequence *seq_meta);
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);
-int SEQ_time_left_handle_frame_get(struct Sequence *seq);
-int SEQ_time_right_handle_frame_get(struct Sequence *seq);
-void SEQ_time_left_handle_frame_set(struct Sequence *seq, int val);
-void SEQ_time_right_handle_frame_set(struct Sequence *seq, int val);
+
+int SEQ_time_left_handle_frame_get(const struct Sequence *seq);
+int SEQ_time_right_handle_frame_get(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);
+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 bd4258bfdb1..93ce6873d3b 100644
--- a/source/blender/sequencer/SEQ_transform.h
+++ b/source/blender/sequencer/SEQ_transform.h
@@ -21,14 +21,17 @@ 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(struct Sequence *seq, int leftflag, int rightflag);
+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
* since they work a bit differently to normal image seq's (during transform).
*/
bool SEQ_transform_single_image_check(struct Sequence *seq);
-void SEQ_transform_fix_single_image_seq_offsets(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);
void SEQ_transform_translate_sequence(struct Scene *scene, struct Sequence *seq, int delta);
diff --git a/source/blender/sequencer/SEQ_utils.h b/source/blender/sequencer/SEQ_utils.h
index ce3c81606ea..24ca7559166 100644
--- a/source/blender/sequencer/SEQ_utils.h
+++ b/source/blender/sequencer/SEQ_utils.h
@@ -20,14 +20,6 @@ struct SeqRenderData;
struct Sequence;
struct StripElem;
-/**
- * Sort strips in provided seqbase. Effect strips are trailing the list and they are sorted by
- * channel position as well.
- * This is important for SEQ_time_update_sequence to work properly
- *
- * \param seqbase: ListBase with strips
- */
-void SEQ_sort(struct ListBase *seqbase);
void SEQ_sequence_base_unique_name_recursive(struct Scene *scene,
struct ListBase *seqbasep,
struct Sequence *seq);
@@ -39,7 +31,7 @@ const struct Sequence *SEQ_get_topmost_sequence(const struct Scene *scene, int f
/**
* In cases where we don't know the sequence's listbase.
*/
-struct ListBase *SEQ_get_seqbase_by_seq(struct ListBase *seqbase, struct Sequence *seq);
+struct ListBase *SEQ_get_seqbase_by_seq(const struct Scene *scene, struct Sequence *seq);
/**
* Only use as last resort when the StripElem is available but no the Sequence.
* (needed for RNA)
diff --git a/source/blender/sequencer/intern/disk_cache.c b/source/blender/sequencer/intern/disk_cache.c
index f8e8fc32a5d..cc34066c432 100644
--- a/source/blender/sequencer/intern/disk_cache.c
+++ b/source/blender/sequencer/intern/disk_cache.c
@@ -37,6 +37,7 @@
#include "SEQ_relations.h"
#include "SEQ_render.h"
#include "SEQ_sequencer.h"
+#include "SEQ_time.h"
#include "disk_cache.h"
#include "image_cache.h"
@@ -411,8 +412,8 @@ void seq_disk_cache_invalidate(SeqDiskCache *disk_cache,
BLI_mutex_lock(&disk_cache->read_write_mutex);
- start = seq_changed->startdisp - DCACHE_IMAGES_PER_FILE;
- end = seq_changed->enddisp;
+ start = SEQ_time_left_handle_frame_get(seq_changed) - DCACHE_IMAGES_PER_FILE;
+ end = SEQ_time_right_handle_frame_get(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 d9d21ee3b05..0e5e56908b0 100644
--- a/source/blender/sequencer/intern/effects.c
+++ b/source/blender/sequencer/intern/effects.c
@@ -49,6 +49,7 @@
#include "SEQ_proxy.h"
#include "SEQ_relations.h"
#include "SEQ_render.h"
+#include "SEQ_time.h"
#include "SEQ_utils.h"
#include "BLF_api.h"
@@ -2431,7 +2432,7 @@ static ImBuf *do_multicam(const SeqRenderData *context,
if (!ed) {
return NULL;
}
- ListBase *seqbasep = SEQ_get_seqbase_by_seq(&ed->seqbase, seq);
+ ListBase *seqbasep = SEQ_get_seqbase_by_seq(context->scene, seq);
ListBase *channels = SEQ_get_channels_by_seq(&ed->seqbase, &ed->channels, seq);
if (!seqbasep) {
return NULL;
@@ -2467,13 +2468,15 @@ static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, fl
ed = context->scene->ed;
- ListBase *seqbasep = SEQ_get_seqbase_by_seq(&ed->seqbase, seq);
+ ListBase *seqbasep = SEQ_get_seqbase_by_seq(context->scene, seq);
ListBase *channels = SEQ_get_channels_by_seq(&ed->seqbase, &ed->channels, seq);
/* Clamp timeline_frame to strip range so it behaves as if it had "still frame" offset (last
* 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->startdisp, seq->enddisp - 1);
+ timeline_frame = clamp_i(timeline_frame,
+ SEQ_time_left_handle_frame_get(seq),
+ SEQ_time_right_handle_frame_get(seq) - 1);
if (seq->machine > 1) {
i = seq_render_give_ibuf_seqbase(
@@ -2583,7 +2586,7 @@ static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(fac))
static int seq_effect_speed_get_strip_content_length(const Sequence *seq)
{
if ((seq->type & SEQ_TYPE_EFFECT) != 0 && SEQ_effect_get_num_inputs(seq->type) == 0) {
- return seq->enddisp - seq->startdisp;
+ return SEQ_time_right_handle_frame_get(seq) - SEQ_time_left_handle_frame_get(seq);
}
return seq->len;
@@ -2610,13 +2613,14 @@ void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq)
MEM_freeN(v->frameMap);
}
- const int effect_strip_length = seq->enddisp - seq->startdisp;
+ const int effect_strip_length = SEQ_time_right_handle_frame_get(seq) -
+ SEQ_time_left_handle_frame_get(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->startdisp + frame_index);
+ target_frame += evaluate_fcurve(fcu, SEQ_time_left_handle_frame_get(seq) + frame_index);
CLAMP(target_frame, 0, seq->seq1->len);
v->frameMap[frame_index] = target_frame;
}
@@ -2652,7 +2656,8 @@ float seq_speed_effect_target_frame_get(Scene *scene,
/* Only right handle controls effect speed! */
const float target_content_length = seq_effect_speed_get_strip_content_length(source) -
source->startofs;
- const float speed_effetct_length = seq_speed->enddisp - seq_speed->startdisp;
+ const float speed_effetct_length = SEQ_time_right_handle_frame_get(seq_speed) -
+ SEQ_time_left_handle_frame_get(seq_speed);
const float ratio = frame_index / speed_effetct_length;
target_frame = target_content_length * ratio;
break;
@@ -3509,7 +3514,7 @@ static void get_default_fac_noop(Sequence *UNUSED(seq), float UNUSED(timeline_fr
static void get_default_fac_fade(Sequence *seq, float timeline_frame, float *fac)
{
- *fac = (float)(timeline_frame - seq->startdisp);
+ *fac = (float)(timeline_frame - SEQ_time_left_handle_frame_get(seq));
*fac /= seq->len;
}
diff --git a/source/blender/sequencer/intern/image_cache.c b/source/blender/sequencer/intern/image_cache.c
index e1ff0ff64b3..59de24930d6 100644
--- a/source/blender/sequencer/intern/image_cache.c
+++ b/source/blender/sequencer/intern/image_cache.c
@@ -36,6 +36,7 @@
#include "SEQ_prefetch.h"
#include "SEQ_relations.h"
#include "SEQ_sequencer.h"
+#include "SEQ_time.h"
#include "disk_cache.h"
#include "image_cache.h"
@@ -558,8 +559,9 @@ void seq_cache_free_temp_cache(Scene *scene, short id, int timeline_frame)
/* 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);
- if (frame_index != key->frame_index || timeline_frame > key->seq->enddisp ||
- timeline_frame < key->seq->startdisp) {
+ 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)) {
BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree);
}
}
@@ -634,8 +636,8 @@ void seq_cache_cleanup_sequence(Scene *scene,
seq_cache_lock(scene);
- int range_start = seq_changed->startdisp;
- int range_end = seq_changed->enddisp;
+ int range_start = SEQ_time_left_handle_frame_get(seq_changed);
+ int range_end = SEQ_time_right_handle_frame_get(seq_changed);
if (!force_seq_changed_range) {
if (seq->startdisp > range_start) {
@@ -668,8 +670,8 @@ void seq_cache_cleanup_sequence(Scene *scene,
}
if (key->type & invalidate_source && key->seq == seq &&
- key->timeline_frame >= seq_changed->startdisp &&
- key->timeline_frame <= seq_changed->enddisp) {
+ key->timeline_frame >= SEQ_time_left_handle_frame_get(seq_changed) &&
+ key->timeline_frame <= SEQ_time_right_handle_frame_get(seq_changed)) {
if (key->link_next || key->link_prev) {
seq_cache_relink_keys(key->link_next, key->link_prev);
}
@@ -700,11 +702,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 - key->seq->startdisp;
+ 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 relative_base_frame = round_fl_to_int((frame_index / (float)frame_step)) *
frame_step;
- const int nearest_guaranted_absolute_frame = relative_base_frame + key->seq->startdisp;
+ const int nearest_guaranted_absolute_frame = relative_base_frame +
+ SEQ_time_left_handle_frame_get(key->seq);
if (nearest_guaranted_absolute_frame == key->timeline_frame) {
continue;
diff --git a/source/blender/sequencer/intern/proxy.c b/source/blender/sequencer/intern/proxy.c
index 59b4c6de1ef..464580f5bed 100644
--- a/source/blender/sequencer/intern/proxy.c
+++ b/source/blender/sequencer/intern/proxy.c
@@ -43,6 +43,7 @@
#include "SEQ_relations.h"
#include "SEQ_render.h"
#include "SEQ_sequencer.h"
+#include "SEQ_time.h"
#include "multiview.h"
#include "proxy.h"
@@ -523,7 +524,9 @@ void SEQ_proxy_rebuild(SeqIndexBuildContext *context,
SeqRenderState state;
seq_render_state_init(&state);
- for (timeline_frame = seq->startdisp; timeline_frame < seq->enddisp; timeline_frame++) {
+ for (timeline_frame = SEQ_time_left_handle_frame_get(seq);
+ timeline_frame < SEQ_time_right_handle_frame_get(seq);
+ timeline_frame++) {
if (context->size_flags & IMB_PROXY_25) {
seq_proxy_build_frame(&render_context, &state, seq, timeline_frame, 25, overwrite);
}
@@ -537,7 +540,8 @@ void SEQ_proxy_rebuild(SeqIndexBuildContext *context,
seq_proxy_build_frame(&render_context, &state, seq, timeline_frame, 100, overwrite);
}
- *progress = (float)(timeline_frame - seq->startdisp) / (seq->enddisp - seq->startdisp);
+ *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));
*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 b0898be3765..e7a1bbeb9d0 100644
--- a/source/blender/sequencer/intern/render.c
+++ b/source/blender/sequencer/intern/render.c
@@ -1994,11 +1994,12 @@ ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context,
float SEQ_render_thumbnail_first_frame_get(Sequence *seq, float frame_step, rctf *view_area)
{
- int first_drawable_frame = max_iii(seq->startdisp, seq->start, view_area->xmin);
+ int first_drawable_frame = max_iii(
+ SEQ_time_left_handle_frame_get(seq), seq->start, view_area->xmin);
/* First frame should correspond to handle position. */
- if (first_drawable_frame == seq->startdisp) {
- return seq->startdisp;
+ if (first_drawable_frame == SEQ_time_left_handle_frame_get(seq)) {
+ return SEQ_time_left_handle_frame_get(seq);
}
float aligned_frame_offset = (int)((first_drawable_frame - seq->start) / frame_step) *
@@ -2011,7 +2012,7 @@ float SEQ_render_thumbnail_next_frame_get(Sequence *seq, float last_frame, float
float next_frame = last_frame + frame_step;
/* If handle position was displayed, align next frame with `seq->start`. */
- if (last_frame == seq->startdisp) {
+ if (last_frame == SEQ_time_left_handle_frame_get(seq)) {
next_frame = seq->start + ((int)((last_frame - seq->start) / frame_step) + 1) * frame_step;
}
@@ -2088,8 +2089,9 @@ void SEQ_render_thumbnails(const SeqRenderData *context,
/* 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) ? (seq->start + seq->len) :
- seq->enddisp;
+ float upper_thumb_bound = SEQ_time_has_right_still_frames(seq) ?
+ (seq->start + seq->len) :
+ SEQ_time_right_handle_frame_get(seq);
upper_thumb_bound = (upper_thumb_bound > view_area->xmax) ? view_area->xmax + frame_step :
upper_thumb_bound;
@@ -2122,8 +2124,8 @@ void SEQ_render_thumbnails(const SeqRenderData *context,
int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const Sequence *seq)
{
- const int content_start = max_ii(seq->startdisp, seq->start);
- const int content_end = min_ii(seq->enddisp, seq->start + seq->len);
+ 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_len = content_end - content_start;
/* Arbitrary, but due to performance reasons should be as low as possible. */
@@ -2143,10 +2145,10 @@ void SEQ_render_thumbnails_base_set(const SeqRenderData *context,
SeqRenderState state;
seq_render_state_init(&state);
- int timeline_frame = seq->startdisp;
+ int timeline_frame = SEQ_time_left_handle_frame_get(seq);
const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(seq);
- while (timeline_frame < seq->enddisp && !*stop) {
+ while (timeline_frame < SEQ_time_right_handle_frame_get(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/sequence_lookup.c b/source/blender/sequencer/intern/sequence_lookup.c
index 2a2626d8abf..22c1ce39f4f 100644
--- a/source/blender/sequencer/intern/sequence_lookup.c
+++ b/source/blender/sequencer/intern/sequence_lookup.c
@@ -6,6 +6,7 @@
*/
#include "SEQ_sequencer.h"
+#include "sequencer.h"
#include "DNA_listBase.h"
#include "DNA_scene_types.h"
@@ -14,6 +15,7 @@
#include "SEQ_iterator.h"
#include "BLI_ghash.h"
+#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_sys_types.h"
#include "BLI_threads.h"
@@ -24,24 +26,66 @@
static ThreadMutex lookup_lock = BLI_MUTEX_INITIALIZER;
typedef struct SequenceLookup {
- GHash *by_name;
+ GHash *seq_by_name;
+ GHash *meta_by_seq;
+ GHash *effects_by_seq;
eSequenceLookupTag tag;
} SequenceLookup;
static void seq_sequence_lookup_init(struct SequenceLookup *lookup)
{
- lookup->by_name = BLI_ghash_str_new(__func__);
+ lookup->seq_by_name = BLI_ghash_str_new(__func__);
+ lookup->meta_by_seq = BLI_ghash_ptr_new(__func__);
+ lookup->effects_by_seq = BLI_ghash_ptr_new(__func__);
lookup->tag |= SEQ_LOOKUP_TAG_INVALID;
}
-static void seq_sequence_lookup_build(const struct Scene *scene, struct SequenceLookup *lookup)
+static void seq_sequence_lookup_append_effect(Sequence *input,
+ Sequence *effect,
+ struct SequenceLookup *lookup)
+{
+ if (input == NULL) {
+ return;
+ }
+
+ SeqCollection *effects = BLI_ghash_lookup(lookup->effects_by_seq, input);
+ if (effects == NULL) {
+ effects = SEQ_collection_create(__func__);
+ BLI_ghash_insert(lookup->effects_by_seq, input, effects);
+ }
+
+ SEQ_collection_append_strip(effect, effects);
+}
+
+static void seq_sequence_lookup_build_effect(Sequence *seq, struct SequenceLookup *lookup)
{
- SeqCollection *all_strips = SEQ_query_all_strips_recursive(&scene->ed->seqbase);
- Sequence *seq;
- SEQ_ITERATOR_FOREACH (seq, all_strips) {
- BLI_ghash_insert(lookup->by_name, seq->name + 2, seq);
+ if ((seq->type & SEQ_TYPE_EFFECT) == 0) {
+ return;
}
- SEQ_collection_free(all_strips);
+
+ seq_sequence_lookup_append_effect(seq->seq1, seq, lookup);
+ seq_sequence_lookup_append_effect(seq->seq2, seq, lookup);
+}
+
+static void seq_sequence_lookup_build_from_seqbase(Sequence *parent_meta,
+ const ListBase *seqbase,
+ struct SequenceLookup *lookup)
+{
+ LISTBASE_FOREACH (Sequence *, seq, seqbase) {
+ BLI_ghash_insert(lookup->seq_by_name, seq->name + 2, seq);
+ BLI_ghash_insert(lookup->meta_by_seq, seq, parent_meta);
+ seq_sequence_lookup_build_effect(seq, lookup);
+
+ if (seq->type == SEQ_TYPE_META) {
+ seq_sequence_lookup_build_from_seqbase(seq, &seq->seqbase, lookup);
+ }
+ }
+}
+
+static void seq_sequence_lookup_build(const struct Scene *scene, struct SequenceLookup *lookup)
+{
+ Editing *ed = SEQ_editing_get(scene);
+ seq_sequence_lookup_build_from_seqbase(NULL, &ed->seqbase, lookup);
lookup->tag &= ~SEQ_LOOKUP_TAG_INVALID;
}
@@ -58,8 +102,12 @@ static void seq_sequence_lookup_free(struct SequenceLookup **lookup)
return;
}
- BLI_ghash_free((*lookup)->by_name, NULL, NULL);
- (*lookup)->by_name = NULL;
+ BLI_ghash_free((*lookup)->seq_by_name, NULL, NULL);
+ BLI_ghash_free((*lookup)->meta_by_seq, NULL, NULL);
+ BLI_ghash_free((*lookup)->effects_by_seq, NULL, SEQ_collection_free);
+ (*lookup)->seq_by_name = NULL;
+ (*lookup)->meta_by_seq = NULL;
+ (*lookup)->effects_by_seq = NULL;
MEM_freeN(*lookup);
*lookup = NULL;
}
@@ -98,17 +146,39 @@ void SEQ_sequence_lookup_free(const Scene *scene)
BLI_mutex_unlock(&lookup_lock);
}
-Sequence *SEQ_sequence_lookup_by_name(const Scene *scene, const char *key)
+Sequence *SEQ_sequence_lookup_seq_by_name(const Scene *scene, const char *key)
+{
+ BLI_assert(scene->ed);
+ BLI_mutex_lock(&lookup_lock);
+ seq_sequence_lookup_update_if_needed(scene, &scene->ed->runtime.sequence_lookup);
+ SequenceLookup *lookup = scene->ed->runtime.sequence_lookup;
+ Sequence *seq = BLI_ghash_lookup(lookup->seq_by_name, key);
+ BLI_mutex_unlock(&lookup_lock);
+ return seq;
+}
+
+Sequence *seq_sequence_lookup_meta_by_seq(const Scene *scene, const Sequence *key)
{
BLI_assert(scene->ed);
BLI_mutex_lock(&lookup_lock);
seq_sequence_lookup_update_if_needed(scene, &scene->ed->runtime.sequence_lookup);
SequenceLookup *lookup = scene->ed->runtime.sequence_lookup;
- Sequence *seq = BLI_ghash_lookup(lookup->by_name, key);
+ Sequence *seq = BLI_ghash_lookup(lookup->meta_by_seq, key);
BLI_mutex_unlock(&lookup_lock);
return seq;
}
+SeqCollection *seq_sequence_lookup_effects_by_seq(const Scene *scene, const Sequence *key)
+{
+ BLI_assert(scene->ed);
+ BLI_mutex_lock(&lookup_lock);
+ seq_sequence_lookup_update_if_needed(scene, &scene->ed->runtime.sequence_lookup);
+ SequenceLookup *lookup = scene->ed->runtime.sequence_lookup;
+ SeqCollection *effects = BLI_ghash_lookup(lookup->effects_by_seq, key);
+ BLI_mutex_unlock(&lookup_lock);
+ return effects;
+}
+
void SEQ_sequence_lookup_tag(const Scene *scene, eSequenceLookupTag tag)
{
if (!scene->ed) {
diff --git a/source/blender/sequencer/intern/sequencer.h b/source/blender/sequencer/intern/sequencer.h
index 9f5bdf672c0..5e78c8c6f96 100644
--- a/source/blender/sequencer/intern/sequencer.h
+++ b/source/blender/sequencer/intern/sequencer.h
@@ -14,13 +14,37 @@ extern "C" {
struct Scene;
struct Sequence;
struct StripProxy;
+struct SeqCollection;
/**
* Cache must be freed before calling this function
* since it leaves the seqbase in an invalid state.
*/
void seq_free_sequence_recurse(struct Scene *scene, struct Sequence *seq, bool do_id_user);
struct StripProxy *seq_strip_proxy_alloc(void);
-
+/**
+ * Find meta strip, that contains strip `key`.
+ * If lookup hash doesn't exist, it will be created. If hash is tagged as invalid, it will be
+ * rebuilt.
+ *
+ * \param scene: scene that owns lookup hash
+ * \param key: pointer to Sequence inside of meta strip
+ *
+ * \return pointer to meta strip
+ */
+struct Sequence *seq_sequence_lookup_meta_by_seq(const struct Scene *scene,
+ const struct Sequence *key);
+/**
+ * Find effect strips, that use strip `seq` as one of inputs.
+ * If lookup hash doesn't exist, it will be created. If hash is tagged as invalid, it will be
+ * rebuilt.
+ *
+ * \param scene: scene that owns lookup hash
+ * \param key: pointer to Sequence inside of meta strip
+ *
+ * \return collection of effect strips
+ */
+struct SeqCollection *seq_sequence_lookup_effects_by_seq(const struct Scene *scene,
+ const struct Sequence *key);
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/sequencer/intern/sound.c b/source/blender/sequencer/intern/sound.c
index 8076c600560..50c8b76a9a0 100644
--- a/source/blender/sequencer/intern/sound.c
+++ b/source/blender/sequencer/intern/sound.c
@@ -35,7 +35,6 @@ static bool sequencer_refresh_sound_length_recursive(Main *bmain, Scene *scene,
for (seq = seqbase->first; seq; seq = seq->next) {
if (seq->type == SEQ_TYPE_META) {
if (sequencer_refresh_sound_length_recursive(bmain, scene, &seq->seqbase)) {
- SEQ_time_update_sequence(scene, seqbase, seq);
changed = true;
}
}
@@ -55,7 +54,6 @@ static bool sequencer_refresh_sound_length_recursive(Main *bmain, Scene *scene,
seq->endofs *= fac;
seq->start += (old - seq->startofs); /* So that visual/"real" start frame does not change! */
- SEQ_time_update_sequence(scene, seqbase, seq);
changed = true;
}
}
@@ -99,8 +97,12 @@ void SEQ_sound_update_bounds(Scene *scene, Sequence *seq)
/* We have to take into account start frame of the sequence's scene! */
int startofs = seq->startofs + seq->anim_startofs + seq->scene->r.sfra;
- BKE_sound_move_scene_sound(
- scene, seq->scene_sound, seq->startdisp, seq->enddisp, startofs, 0.0);
+ BKE_sound_move_scene_sound(scene,
+ seq->scene_sound,
+ SEQ_time_left_handle_frame_get(seq),
+ SEQ_time_right_handle_frame_get(seq),
+ startofs,
+ 0.0);
}
}
else {
diff --git a/source/blender/sequencer/intern/strip_add.c b/source/blender/sequencer/intern/strip_add.c
index 77b0fc946d9..bb812302464 100644
--- a/source/blender/sequencer/intern/strip_add.c
+++ b/source/blender/sequencer/intern/strip_add.c
@@ -51,6 +51,8 @@
#include "multiview.h"
#include "proxy.h"
+#include "sequencer.h"
+#include "strip_time.h"
#include "utils.h"
void SEQ_add_load_data_init(SeqLoadData *load_data,
@@ -73,9 +75,9 @@ void SEQ_add_load_data_init(SeqLoadData *load_data,
static void seq_add_generic_update(Scene *scene, ListBase *seqbase, Sequence *seq)
{
SEQ_sequence_base_unique_name_recursive(scene, &scene->ed->seqbase, seq);
- SEQ_time_update_sequence(scene, seqbase, seq);
- SEQ_sort(seqbase);
SEQ_relations_invalidate_cache_composite(scene, seq);
+ SEQ_sequence_lookup_tag(scene, SEQ_LOOKUP_TAG_INVALID);
+ SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq));
}
static void seq_add_set_name(Scene *scene, Sequence *seq, SeqLoadData *load_data)
@@ -174,11 +176,12 @@ Sequence *SEQ_add_effect_strip(Scene *scene, ListBase *seqbase, struct SeqLoadDa
if (!load_data->effect.seq1) {
seq->len = 1; /* Effect is generator, set non zero length. */
- SEQ_time_right_handle_frame_set(seq, load_data->effect.end_frame);
+ SEQ_time_right_handle_frame_set(scene, seq, load_data->effect.end_frame);
}
seq_add_set_name(scene, seq, load_data);
seq_add_generic_update(scene, seqbase, seq);
+ seq_time_effect_range_set(seq);
return seq;
}
@@ -362,7 +365,6 @@ Sequence *SEQ_add_meta_strip(Scene *scene, ListBase *seqbase, SeqLoadData *load_
/* Set frames start and length. */
seqm->start = load_data->start_frame;
seqm->len = 1;
- SEQ_time_update_sequence(scene, seqbase, seqm);
return seqm;
}
@@ -509,11 +511,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) */
- Editing *ed = SEQ_editing_get(scene);
- ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq);
- SEQ_time_update_sequence(scene, seqbase, seq);
- prev_startdisp = seq->startdisp;
- prev_enddisp = seq->enddisp;
+ prev_startdisp = SEQ_time_left_handle_frame_get(seq);
+ prev_enddisp = SEQ_time_right_handle_frame_get(seq);
}
switch (seq->type) {
@@ -656,13 +655,11 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo
free_proxy_seq(seq);
if (lock_range) {
- SEQ_time_left_handle_frame_set(seq, prev_startdisp);
- SEQ_time_right_handle_frame_set(seq, prev_enddisp);
- SEQ_transform_fix_single_image_seq_offsets(seq);
+ SEQ_time_left_handle_frame_set(scene, seq, prev_startdisp);
+ SEQ_time_right_handle_frame_set(scene, seq, prev_enddisp);
+ SEQ_transform_fix_single_image_seq_offsets(scene, seq);
}
- ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
- SEQ_time_update_sequence(scene, seqbase, seq);
SEQ_relations_invalidate_cache_raw(scene, seq);
}
diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c
index 96bfce8f740..7965615e188 100644
--- a/source/blender/sequencer/intern/strip_edit.c
+++ b/source/blender/sequencer/intern/strip_edit.c
@@ -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);
- SWAP(int, seq_a->startdisp, seq_b->startdisp);
- SWAP(int, seq_a->enddisp, seq_b->enddisp);
+ seq_time_effect_range_set(seq_a);
+ seq_time_effect_range_set(seq_b);
return 1;
}
@@ -230,7 +230,7 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene,
{
/* Find the appropriate seqbase */
Editing *ed = SEQ_editing_get(scene);
- ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, src_seq);
+ ListBase *seqbase = SEQ_get_seqbase_by_seq(scene, src_seq);
if (dst_seqm->type != SEQ_TYPE_META) {
*error_str = N_("Can not move strip to non-meta strip");
@@ -272,11 +272,11 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene,
return true;
}
-static void seq_split_set_left_hold_offset(Sequence *seq, int timeline_frame)
+static void seq_split_set_left_hold_offset(const 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(seq, timeline_frame);
+ 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))) {
@@ -290,19 +290,19 @@ static void seq_split_set_left_hold_offset(Sequence *seq, int timeline_frame)
seq->start += timeline_frame - seq->start;
seq->anim_startofs += seq->len - 1;
seq->len = 1;
- SEQ_time_left_handle_frame_set(seq, timeline_frame);
- SEQ_time_right_handle_frame_set(seq, right_handle_backup);
+ 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(Sequence *seq, int timeline_frame)
+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(seq, left_handle_backup);
- SEQ_time_right_handle_frame_set(seq, timeline_frame);
+ SEQ_time_left_handle_frame_set(scene, seq, left_handle_backup);
+ SEQ_time_right_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))) {
@@ -311,11 +311,11 @@ static void seq_split_set_right_hold_offset(Sequence *seq, int timeline_frame)
}
/* Adjust within range of extended stillframes after strip. */
else if ((seq->start + seq->len) < timeline_frame) {
- SEQ_time_right_handle_frame_set(seq, timeline_frame);
+ SEQ_time_right_handle_frame_set(scene, seq, timeline_frame);
}
}
-static void seq_split_set_right_offset(Sequence *seq, int timeline_frame)
+static void seq_split_set_right_offset(const Scene *scene, Sequence *seq, int timeline_frame)
{
/* Adjust within range of extended stillframes before strip. */
if (timeline_frame < seq->start) {
@@ -324,10 +324,10 @@ static void seq_split_set_right_offset(Sequence *seq, int timeline_frame)
seq->startofs += content_offset;
}
- SEQ_time_right_handle_frame_set(seq, timeline_frame);
+ SEQ_time_right_handle_frame_set(scene, seq, timeline_frame);
}
-static void seq_split_set_left_offset(Sequence *seq, int 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) {
@@ -336,12 +336,13 @@ static void seq_split_set_left_offset(Sequence *seq, int timeline_frame)
seq->endofs += content_offset;
}
- SEQ_time_left_handle_frame_set(seq, timeline_frame);
+ 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)
{
- return timeline_frame > seq->startdisp && timeline_frame < seq->enddisp;
+ return timeline_frame > SEQ_time_left_handle_frame_get(seq) &&
+ timeline_frame < SEQ_time_right_handle_frame_get(seq);
}
static void seq_edit_split_handle_strip_offsets(Main *bmain,
@@ -355,27 +356,25 @@ static void seq_edit_split_handle_strip_offsets(Main *bmain,
if (seq_edit_split_effect_intersect_check(right_seq, timeline_frame)) {
switch (method) {
case SEQ_SPLIT_SOFT:
- seq_split_set_left_offset(right_seq, timeline_frame);
+ seq_split_set_left_offset(scene, right_seq, timeline_frame);
break;
case SEQ_SPLIT_HARD:
- seq_split_set_left_hold_offset(right_seq, timeline_frame);
+ seq_split_set_left_hold_offset(scene, right_seq, timeline_frame);
SEQ_add_reload_new_file(bmain, scene, right_seq, false);
break;
}
- SEQ_time_update_sequence(scene, seqbase, right_seq);
}
if (seq_edit_split_effect_intersect_check(left_seq, timeline_frame)) {
switch (method) {
case SEQ_SPLIT_SOFT:
- seq_split_set_right_offset(left_seq, timeline_frame);
+ seq_split_set_right_offset(scene, left_seq, timeline_frame);
break;
case SEQ_SPLIT_HARD:
- seq_split_set_right_hold_offset(left_seq, timeline_frame);
+ seq_split_set_right_hold_offset(scene, left_seq, timeline_frame);
SEQ_add_reload_new_file(bmain, scene, left_seq, false);
break;
}
- SEQ_time_update_sequence(scene, seqbase, left_seq);
}
}
@@ -468,10 +467,6 @@ Sequence *SEQ_edit_strip_split(Main *bmain,
SEQ_collection_free(collection);
- /* Sort list, so that no strip can depend on next strip in list.
- * This is important for SEQ_time_update_sequence functionality. */
- SEQ_sort(&left_strips);
-
/* Duplicate ListBase. */
ListBase right_strips = {NULL, NULL};
SEQ_sequence_base_dupli_recursive(scene, scene, &right_strips, &left_strips, SEQ_DUPE_ALL, 0);
@@ -480,18 +475,23 @@ Sequence *SEQ_edit_strip_split(Main *bmain,
Sequence *right_seq = right_strips.first;
Sequence *return_seq = NULL;
- /* Move strips from detached `ListBase`, otherwise they can't be flagged for removal,
- * SEQ_time_update_sequence can fail to update meta strips and they can't be renamed.
- * This is because these functions check all strips in `Editing` to manage relationships. */
+ /* Move strips from detached `ListBase`, otherwise they can't be flagged for removal. */
BLI_movelisttolist(seqbase, &left_strips);
BLI_movelisttolist(seqbase, &right_strips);
+ /* Rename duplicated strips. This has to be done immediately after adding
+ * strips to seqbase, for lookup cache to work correctly. */
+ Sequence *seq_rename = right_seq;
+ for (; seq_rename; seq_rename = seq_rename->next) {
+ SEQ_ensure_unique_name(seq_rename, scene);
+ }
+
/* Split strips. */
while (left_seq && right_seq) {
- if (left_seq->startdisp >= timeline_frame) {
+ if (SEQ_time_left_handle_frame_get(left_seq) >= timeline_frame) {
SEQ_edit_flag_for_removal(scene, seqbase, left_seq);
}
- if (right_seq->enddisp <= timeline_frame) {
+ else if (SEQ_time_right_handle_frame_get(right_seq) <= timeline_frame) {
SEQ_edit_flag_for_removal(scene, seqbase, right_seq);
}
else if (return_seq == NULL) {
@@ -506,13 +506,6 @@ Sequence *SEQ_edit_strip_split(Main *bmain,
}
SEQ_edit_remove_flagged_sequences(scene, seqbase);
-
- /* Rename duplicated strips. */
- Sequence *seq_rename = return_seq;
- for (; seq_rename; seq_rename = seq_rename->next) {
- SEQ_ensure_unique_name(seq_rename, scene);
- }
-
SEQ_animation_restore_original(scene, &fcurves_original_backup);
return return_seq;
diff --git a/source/blender/sequencer/intern/strip_relations.c b/source/blender/sequencer/intern/strip_relations.c
index 1899cc99263..4acf2763ce5 100644
--- a/source/blender/sequencer/intern/strip_relations.c
+++ b/source/blender/sequencer/intern/strip_relations.c
@@ -47,7 +47,8 @@ static bool seq_relations_check_depend(Sequence *seq, Sequence *cur)
}
/* sequences are not intersecting in time, assume no dependency exists between them */
- if (cur->enddisp < seq->startdisp || cur->startdisp > seq->enddisp) {
+ 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)) {
return false;
}
@@ -290,8 +291,8 @@ 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->startdisp);
- meta_range[1] = min_ii(frame_range[1], seq->enddisp);
+ 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));
}
sequencer_all_free_anim_ibufs(ed, &seq->seqbase, timeline_frame, meta_range);
@@ -345,7 +346,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,
- recursive_seq->startdisp);
+ SEQ_time_left_handle_frame_get(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 e4f7a5e87e8..25d4f08be82 100644
--- a/source/blender/sequencer/intern/strip_time.c
+++ b/source/blender/sequencer/intern/strip_time.c
@@ -27,6 +27,7 @@
#include "SEQ_time.h"
#include "SEQ_transform.h"
+#include "sequencer.h"
#include "strip_time.h"
#include "utils.h"
@@ -37,7 +38,7 @@ float seq_give_frame_index(Sequence *seq, float timeline_frame)
int end = seq->start + seq->len - 1;
if (seq->type & SEQ_TYPE_EFFECT) {
- end = seq->enddisp;
+ end = SEQ_time_right_handle_frame_get(seq);
}
if (end < sta) {
@@ -89,7 +90,7 @@ static int metaseq_end(Sequence *metaseq)
return metaseq->start + metaseq->len - metaseq->endofs;
}
-static void seq_update_sound_bounds_recursive_impl(Scene *scene,
+static void seq_update_sound_bounds_recursive_impl(const Scene *scene,
Sequence *metaseq,
int start,
int end)
@@ -131,33 +132,31 @@ static void seq_update_sound_bounds_recursive_impl(Scene *scene,
}
}
-void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
+void seq_update_sound_bounds_recursive(const Scene *scene, Sequence *metaseq)
{
seq_update_sound_bounds_recursive_impl(
scene, metaseq, metaseq_start(metaseq), metaseq_end(metaseq));
}
-static void seq_time_update_sequence_bounds(Scene *scene, Sequence *seq)
+/* Update meta strip content start and end, update sound playback range. */
+void SEQ_time_update_meta_strip_range(const Scene *scene, Sequence *seq_meta)
{
- seq->startdisp = seq->start + seq->startofs;
- seq->enddisp = seq->start + seq->len - seq->endofs;
-
- if (seq->type == SEQ_TYPE_META) {
- seq_update_sound_bounds_recursive(scene, seq);
+ if (seq_meta == NULL) {
+ return;
}
-}
-static void seq_time_update_meta_strip(Scene *scene, Sequence *seq_meta)
-{
if (BLI_listbase_is_empty(&seq_meta->seqbase)) {
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);
+
int min = MAXFRAME * 2;
int max = -MAXFRAME * 2;
LISTBASE_FOREACH (Sequence *, seq, &seq_meta->seqbase) {
- min = min_ii(seq->startdisp, min);
- max = max_ii(seq->enddisp, max);
+ min = min_ii(SEQ_time_left_handle_frame_get(seq), min);
+ max = max_ii(SEQ_time_right_handle_frame_get(seq), max);
}
seq_meta->start = min + seq_meta->anim_startofs;
@@ -166,144 +165,54 @@ static void seq_time_update_meta_strip(Scene *scene, Sequence *seq_meta)
seq_meta->len -= seq_meta->anim_endofs;
seq_update_sound_bounds_recursive(scene, seq_meta);
-}
-
-void SEQ_time_update_meta_strip_range(Scene *scene, Sequence *seq_meta)
-{
- if (seq_meta == NULL) {
- return;
- }
-
- seq_time_update_meta_strip(scene, seq_meta);
/* Prevent meta-strip to move in timeline. */
- SEQ_time_left_handle_frame_set(seq_meta, seq_meta->startdisp);
- SEQ_time_right_handle_frame_set(seq_meta, seq_meta->enddisp);
+ SEQ_time_left_handle_frame_set(scene, seq_meta, strip_start);
+ SEQ_time_right_handle_frame_set(scene, seq_meta, strip_end);
}
-void SEQ_time_update_sequence(Scene *scene, ListBase *seqbase, Sequence *seq)
+void seq_time_effect_range_set(Sequence *seq)
{
- Sequence *seqm;
-
- /* Check all meta-strips recursively. */
- seqm = seq->seqbase.first;
- while (seqm) {
- if (seqm->seqbase.first) {
- SEQ_time_update_sequence(scene, &seqm->seqbase, seqm);
- }
- seqm = seqm->next;
+ 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));
}
-
- /* effects and meta: automatic start and end */
- if (seq->type & SEQ_TYPE_EFFECT) {
- if (seq->seq1) {
- seq->startofs = seq->endofs = 0;
- if (seq->seq3) {
- seq->start = seq->startdisp = max_iii(
- seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
- seq->enddisp = min_iii(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
- }
- else if (seq->seq2) {
- seq->start = seq->startdisp = max_ii(seq->seq1->startdisp, seq->seq2->startdisp);
- seq->enddisp = min_ii(seq->seq1->enddisp, seq->seq2->enddisp);
- }
- else {
- seq->start = seq->startdisp = seq->seq1->startdisp;
- seq->enddisp = seq->seq1->enddisp;
- }
- /* we can't help if strips don't overlap, it won't give useful results.
- * but at least ensure 'len' is never negative which causes bad bugs elsewhere. */
- if (seq->enddisp < seq->startdisp) {
- /* simple start/end swap */
- seq->start = seq->enddisp;
- seq->enddisp = seq->startdisp;
- seq->startdisp = seq->start;
- seq->flag |= SEQ_INVALID_EFFECT;
- }
- else {
- seq->flag &= ~SEQ_INVALID_EFFECT;
- }
-
- seq->len = seq->enddisp - seq->startdisp;
- }
- else {
- seq_time_update_sequence_bounds(scene, seq);
- }
+ 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);
}
- else if (seq->type == SEQ_TYPE_META) {
- seq_time_update_meta_strip(scene, seq);
+ 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);
}
- else {
- seq_time_update_sequence_bounds(scene, seq);
- }
-
- Editing *ed = SEQ_editing_get(scene);
- /* Strip is inside meta strip */
- if (seqbase != &ed->seqbase) {
- Sequence *meta = SEQ_get_meta_by_seqbase(&ed->seqbase, seqbase);
- SEQ_time_update_meta_strip_range(scene, meta);
+ if (seq->startdisp > seq->enddisp) {
+ SWAP(int, seq->startdisp, seq->enddisp);
}
- seq_time_update_sequence_bounds(scene, seq);
+ /* Values unusable for effects, these should be always 0. */
+ seq->startofs = seq->endofs = seq->anim_startofs = seq->anim_endofs = 0;
}
-static bool update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq)
+/* Update strip startdisp and enddisp (n-input effects have no len to calculate these). */
+void seq_time_update_effects_strip_range(const Scene *scene, SeqCollection *effects)
{
- Sequence *subseq;
- bool do_update = false;
-
- /* recurse downwards to see if this seq depends on the changed seq */
-
- if (seq == NULL) {
- return false;
- }
-
- if (seq == changed_seq) {
- do_update = true;
- }
-
- for (subseq = seq->seqbase.first; subseq; subseq = subseq->next) {
- if (update_changed_seq_recurs(scene, subseq, changed_seq)) {
- do_update = true;
- }
- }
-
- if (seq->seq1) {
- if (update_changed_seq_recurs(scene, seq->seq1, changed_seq)) {
- do_update = true;
- }
- }
- if (seq->seq2 && (seq->seq2 != seq->seq1)) {
- if (update_changed_seq_recurs(scene, seq->seq2, changed_seq)) {
- do_update = true;
- }
- }
- if (seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2)) {
- if (update_changed_seq_recurs(scene, seq->seq3, changed_seq)) {
- do_update = true;
- }
- }
-
- if (do_update) {
- ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
- SEQ_time_update_sequence(scene, seqbase, seq);
+ if (effects == NULL) {
+ return;
}
- return do_update;
-}
-
-void SEQ_time_update_recursive(Scene *scene, Sequence *changed_seq)
-{
- Editing *ed = SEQ_editing_get(scene);
Sequence *seq;
-
- if (ed == NULL) {
- return;
+ /* First pass: Update length of immediate effects. */
+ SEQ_ITERATOR_FOREACH (seq, effects) {
+ seq_time_effect_range_set(seq);
}
- for (seq = ed->seqbase.first; seq; seq = seq->next) {
- update_changed_seq_recurs(scene, seq, changed_seq);
+ /* Second pass: Recursive call to update effects in chain and in order, so they inherit length
+ * correctly. */
+ SEQ_ITERATOR_FOREACH (seq, effects) {
+ seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq));
}
}
@@ -342,12 +251,14 @@ int SEQ_time_find_next_prev_edit(Scene *scene,
}
if (do_center) {
- seq_frames[0] = (seq->startdisp + seq->enddisp) / 2;
+ seq_frames[0] = (SEQ_time_left_handle_frame_get(seq) +
+ SEQ_time_right_handle_frame_get(seq)) /
+ 2;
seq_frames_tot = 1;
}
else {
- seq_frames[0] = seq->startdisp;
- seq_frames[1] = seq->enddisp;
+ seq_frames[0] = SEQ_time_left_handle_frame_get(seq);
+ seq_frames[1] = SEQ_time_right_handle_frame_get(seq);
seq_frames_tot = 2;
}
@@ -431,11 +342,11 @@ void SEQ_timeline_expand_boundbox(const ListBase *seqbase, rctf *rect)
}
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
- if (rect->xmin > seq->startdisp - 1) {
- rect->xmin = seq->startdisp - 1;
+ if (rect->xmin > SEQ_time_left_handle_frame_get(seq) - 1) {
+ rect->xmin = SEQ_time_left_handle_frame_get(seq) - 1;
}
- if (rect->xmax < seq->enddisp + 1) {
- rect->xmax = seq->enddisp + 1;
+ if (rect->xmax < SEQ_time_right_handle_frame_get(seq) + 1) {
+ rect->xmax = SEQ_time_right_handle_frame_get(seq) + 1;
}
if (rect->ymax < seq->machine) {
rect->ymax = seq->machine;
@@ -507,7 +418,8 @@ void seq_time_gap_info_get(const Scene *scene,
bool SEQ_time_strip_intersects_frame(const Sequence *seq, const int timeline_frame)
{
- return (seq->startdisp <= timeline_frame) && (seq->enddisp > timeline_frame);
+ return (SEQ_time_left_handle_frame_get(seq) <= timeline_frame) &&
+ (SEQ_time_right_handle_frame_get(seq) > timeline_frame);
}
bool SEQ_time_has_left_still_frames(const Sequence *seq)
@@ -525,21 +437,36 @@ bool SEQ_time_has_still_frames(const Sequence *seq)
return SEQ_time_has_right_still_frames(seq) || SEQ_time_has_left_still_frames(seq);
}
-int SEQ_time_left_handle_frame_get(Sequence *seq)
+int SEQ_time_left_handle_frame_get(const Sequence *seq)
{
+ if (seq->seq1 || seq->seq2) {
+ return seq->startdisp;
+ }
+
return seq->start + seq->startofs;
}
-int SEQ_time_right_handle_frame_get(Sequence *seq)
+
+int SEQ_time_right_handle_frame_get(const Sequence *seq)
{
+ if (seq->seq1 || seq->seq2) {
+ return seq->enddisp;
+ }
+
return seq->start + seq->len - seq->endofs;
}
-void SEQ_time_left_handle_frame_set(Sequence *seq, int val)
+void SEQ_time_left_handle_frame_set(const Scene *scene, Sequence *seq, int val)
{
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(Sequence *seq, int val)
+void SEQ_time_right_handle_frame_set(const Scene *scene, Sequence *seq, int val)
{
seq->endofs = seq->start + seq->len - 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 c96a016e646..7a75aeac1a6 100644
--- a/source/blender/sequencer/intern/strip_time.h
+++ b/source/blender/sequencer/intern/strip_time.h
@@ -14,9 +14,10 @@ extern "C" {
struct ListBase;
struct Scene;
struct Sequence;
+struct SeqCollection;
float seq_give_frame_index(struct Sequence *seq, float timeline_frame);
-void seq_update_sound_bounds_recursive(struct Scene *scene, struct Sequence *metaseq);
+void seq_update_sound_bounds_recursive(const struct Scene *scene, struct Sequence *metaseq);
/* Describes gap between strips in timeline. */
typedef struct GapInfo {
@@ -37,6 +38,8 @@ 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_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 8ff577240d6..051dc3961ba 100644
--- a/source/blender/sequencer/intern/strip_transform.c
+++ b/source/blender/sequencer/intern/strip_transform.c
@@ -25,6 +25,9 @@
#include "SEQ_time.h"
#include "SEQ_transform.h"
+#include "strip_time.h"
+#include "sequencer.h"
+
#include "CLG_log.h"
static CLG_LogRef LOG = {"seq.strip_transform"};
@@ -86,16 +89,16 @@ bool SEQ_transform_seqbase_isolated_sel_check(ListBase *seqbase)
return true;
}
-void SEQ_transform_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
+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(seq, SEQ_time_right_handle_frame_get(seq) - 1);
+ 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(seq, seq_tx_get_end(seq) - 1);
+ SEQ_time_left_handle_frame_set(scene, seq, seq_tx_get_end(seq) - 1);
}
/* TODO: This doesn't work at the moment. */
@@ -112,12 +115,12 @@ void SEQ_transform_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
if (rightflag) {
if (SEQ_time_right_handle_frame_get(seq) <= SEQ_time_left_handle_frame_get(seq)) {
- SEQ_time_right_handle_frame_set(seq, SEQ_time_left_handle_frame_get(seq) + 1);
+ 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(seq, seq_tx_get_start(seq) + 1);
+ SEQ_time_right_handle_frame_set(scene, seq, seq_tx_get_start(seq) + 1);
}
}
}
@@ -129,7 +132,7 @@ void SEQ_transform_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
}
}
-void SEQ_transform_fix_single_image_seq_offsets(Sequence *seq)
+void SEQ_transform_fix_single_image_seq_offsets(const Scene *scene, Sequence *seq)
{
int left, start, offset;
if (!SEQ_transform_single_image_check(seq)) {
@@ -142,8 +145,8 @@ void SEQ_transform_fix_single_image_seq_offsets(Sequence *seq)
start = seq->start;
if (start != left) {
offset = left - start;
- SEQ_time_left_handle_frame_set(seq, SEQ_time_left_handle_frame_get(seq) - offset);
- SEQ_time_right_handle_frame_set(seq, SEQ_time_right_handle_frame_get(seq) - offset);
+ 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->start += offset;
}
}
@@ -156,7 +159,8 @@ bool SEQ_transform_sequence_can_be_translated(Sequence *seq)
bool SEQ_transform_test_overlap_seq_seq(Sequence *seq1, Sequence *seq2)
{
return (seq1 != seq2 && seq1->machine == seq2->machine &&
- ((seq1->enddisp <= seq2->startdisp) || (seq1->startdisp >= seq2->enddisp)) == 0);
+ ((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);
}
bool SEQ_transform_test_overlap(ListBase *seqbasep, Sequence *test)
@@ -180,9 +184,6 @@ void SEQ_transform_translate_sequence(Scene *evil_scene, Sequence *seq, int delt
return;
}
- SEQ_offset_animdata(evil_scene, seq, delta);
- seq->start += delta;
-
/* Meta strips requires special handling: their content is to be translated, and then frame range
* of the meta is to be updated for the updated content. */
if (seq->type == SEQ_TYPE_META) {
@@ -190,16 +191,21 @@ void SEQ_transform_translate_sequence(Scene *evil_scene, Sequence *seq, int delt
for (seq_child = seq->seqbase.first; seq_child; seq_child = seq_child->next) {
SEQ_transform_translate_sequence(evil_scene, seq_child, delta);
}
- /* Ensure that meta bounds are updated, but this function prevents resets seq->start and
- * start/end point in timeline. */
- SEQ_time_update_meta_strip_range(evil_scene, seq);
/* Move meta start/end points. */
- SEQ_time_left_handle_frame_set(seq, seq->startdisp + delta);
- SEQ_time_right_handle_frame_set(seq, seq->enddisp + delta);
+ 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);
+ }
+ 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);
}
- ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(evil_scene));
- SEQ_time_update_sequence(evil_scene, seqbase, seq);
+ SEQ_offset_animdata(evil_scene, seq, delta);
+ SEQ_time_update_meta_strip_range(evil_scene, seq_sequence_lookup_meta_by_seq(evil_scene, seq));
+ seq_time_update_effects_strip_range(evil_scene,
+ seq_sequence_lookup_effects_by_seq(evil_scene, seq));
}
bool SEQ_transform_seqbase_shuffle_ex(ListBase *seqbasep,
@@ -211,16 +217,12 @@ bool SEQ_transform_seqbase_shuffle_ex(ListBase *seqbasep,
BLI_assert(ELEM(channel_delta, -1, 1));
test->machine += channel_delta;
- SEQ_time_update_sequence(evil_scene, seqbasep, test);
while (SEQ_transform_test_overlap(seqbasep, test)) {
if ((channel_delta > 0) ? (test->machine >= MAXSEQ) : (test->machine < 1)) {
break;
}
test->machine += channel_delta;
-
- /* XXX: I don't think this is needed since were only moving vertically, Campbell. */
- SEQ_time_update_sequence(evil_scene, seqbasep, test);
}
if (!SEQ_valid_strip_channel(test)) {
@@ -228,19 +230,18 @@ bool SEQ_transform_seqbase_shuffle_ex(ListBase *seqbasep,
* nicer to move it to the end */
Sequence *seq;
- int new_frame = test->enddisp;
+ int new_frame = SEQ_time_right_handle_frame_get(test);
for (seq = seqbasep->first; seq; seq = seq->next) {
if (seq->machine == orig_machine) {
- new_frame = max_ii(new_frame, seq->enddisp);
+ new_frame = max_ii(new_frame, SEQ_time_right_handle_frame_get(seq));
}
}
test->machine = orig_machine;
- new_frame = new_frame + (test->start - test->startdisp); /* adjust by the startdisp */
+ new_frame = new_frame +
+ (test->start - SEQ_time_left_handle_frame_get(test)); /* adjust by the startdisp */
SEQ_transform_translate_sequence(evil_scene, test, new_frame - test->start);
-
- SEQ_time_update_sequence(evil_scene, seqbasep, test);
return false;
}
@@ -252,61 +253,57 @@ bool SEQ_transform_seqbase_shuffle(ListBase *seqbasep, Sequence *test, Scene *ev
return SEQ_transform_seqbase_shuffle_ex(seqbasep, test, evil_scene, 1);
}
-static int shuffle_seq_time_offset_test(SeqCollection *strips_to_shuffle,
- ListBase *seqbasep,
- char dir)
+static bool shuffle_seq_test_overlap(const Sequence *seq1, const Sequence *seq2, const int offset)
{
- int offset = 0;
- Sequence *seq;
-
- SEQ_ITERATOR_FOREACH (seq, strips_to_shuffle) {
- LISTBASE_FOREACH (Sequence *, seq_other, seqbasep) {
- if (!SEQ_transform_test_overlap_seq_seq(seq, seq_other)) {
- continue;
- }
- if (SEQ_relation_is_effect_of_strip(seq_other, seq)) {
- continue;
- }
- if (UNLIKELY(SEQ_collection_has_strip(seq_other, strips_to_shuffle))) {
- CLOG_WARN(&LOG,
- "Strip overlaps with itself or another strip, that is to be shuffled. "
- "This should never happen.");
- continue;
- }
- if (dir == 'L') {
- offset = min_ii(offset, seq_other->startdisp - seq->enddisp);
- }
- else {
- offset = max_ii(offset, seq_other->enddisp - seq->startdisp);
- }
- }
- }
- return 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);
}
-static int shuffle_seq_time_offset(SeqCollection *strips_to_shuffle,
- ListBase *seqbasep,
- Scene *scene,
- char dir)
+static int shuffle_seq_time_offset_get(SeqCollection *strips_to_shuffle,
+ ListBase *seqbasep,
+ char dir)
{
- int ofs = 0;
- int tot_ofs = 0;
+ int offset = 0;
Sequence *seq;
- while ((ofs = shuffle_seq_time_offset_test(strips_to_shuffle, seqbasep, dir))) {
+ bool all_conflicts_resolved = false;
+
+ while (!all_conflicts_resolved) {
+ all_conflicts_resolved = true;
SEQ_ITERATOR_FOREACH (seq, strips_to_shuffle) {
- /* seq_test_overlap only tests display values */
- seq->startdisp += ofs;
- seq->enddisp += ofs;
- }
+ LISTBASE_FOREACH (Sequence *, seq_other, seqbasep) {
+ if (!shuffle_seq_test_overlap(seq, seq_other, offset)) {
+ continue;
+ }
+ if (SEQ_relation_is_effect_of_strip(seq_other, seq)) {
+ continue;
+ }
+ if (UNLIKELY(SEQ_collection_has_strip(seq_other, strips_to_shuffle))) {
+ CLOG_WARN(&LOG,
+ "Strip overlaps with itself or another strip, that is to be shuffled. "
+ "This should never happen.");
+ continue;
+ }
- tot_ofs += ofs;
- }
+ all_conflicts_resolved = false;
- SEQ_ITERATOR_FOREACH (seq, strips_to_shuffle) {
- SEQ_time_update_sequence(scene, seqbasep, seq); /* corrects dummy startdisp/enddisp values */
+ if (dir == 'L') {
+ offset = min_ii(offset,
+ SEQ_time_left_handle_frame_get(seq_other) -
+ SEQ_time_right_handle_frame_get(seq));
+ }
+ else {
+ offset = max_ii(offset,
+ SEQ_time_right_handle_frame_get(seq_other) -
+ SEQ_time_left_handle_frame_get(seq));
+ }
+ }
+ }
}
- return tot_ofs;
+ return offset;
}
bool SEQ_transform_seqbase_shuffle_time(SeqCollection *strips_to_shuffle,
@@ -315,8 +312,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(strips_to_shuffle, seqbasep, evil_scene, 'L');
- int offset_r = shuffle_seq_time_offset(strips_to_shuffle, seqbasep, evil_scene, 'R');
+ 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 = (-offset_l < offset_r) ? offset_l : offset_r;
if (offset) {
@@ -346,9 +343,8 @@ void SEQ_transform_offset_after_frame(Scene *scene,
const int timeline_frame)
{
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
- if (seq->startdisp >= timeline_frame) {
+ if (SEQ_time_left_handle_frame_get(seq) >= timeline_frame) {
SEQ_transform_translate_sequence(scene, seq, delta);
- SEQ_time_update_sequence(scene, seqbase, seq);
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
}
}
diff --git a/source/blender/sequencer/intern/utils.c b/source/blender/sequencer/intern/utils.c
index 0cf47420d8f..260f82310fb 100644
--- a/source/blender/sequencer/intern/utils.c
+++ b/source/blender/sequencer/intern/utils.c
@@ -39,55 +39,9 @@
#include "multiview.h"
#include "proxy.h"
+#include "sequencer.h"
#include "utils.h"
-void SEQ_sort(ListBase *seqbase)
-{
- if (seqbase == NULL) {
- return;
- }
-
- /* all strips together per kind, and in order of y location ("machine") */
- ListBase inputbase, effbase;
- Sequence *seq, *seqt;
-
- BLI_listbase_clear(&inputbase);
- BLI_listbase_clear(&effbase);
-
- while ((seq = BLI_pophead(seqbase))) {
-
- if (seq->type & SEQ_TYPE_EFFECT) {
- seqt = effbase.first;
- while (seqt) {
- if (seqt->machine >= seq->machine) {
- BLI_insertlinkbefore(&effbase, seqt, seq);
- break;
- }
- seqt = seqt->next;
- }
- if (seqt == NULL) {
- BLI_addtail(&effbase, seq);
- }
- }
- else {
- seqt = inputbase.first;
- while (seqt) {
- if (seqt->machine >= seq->machine) {
- BLI_insertlinkbefore(&inputbase, seqt, seq);
- break;
- }
- seqt = seqt->next;
- }
- if (seqt == NULL) {
- BLI_addtail(&inputbase, seq);
- }
- }
- }
-
- BLI_movelisttolist(seqbase, &inputbase);
- BLI_movelisttolist(seqbase, &effbase);
-}
-
typedef struct SeqUniqueInfo {
Sequence *seq;
char name_src[SEQ_NAME_MAXSTR];
@@ -414,20 +368,18 @@ const Sequence *SEQ_get_topmost_sequence(const Scene *scene, int frame)
return best_seq;
}
-ListBase *SEQ_get_seqbase_by_seq(ListBase *seqbase, Sequence *seq)
+ListBase *SEQ_get_seqbase_by_seq(const Scene *scene, Sequence *seq)
{
- Sequence *iseq;
- ListBase *lb = NULL;
+ Editing *ed = SEQ_editing_get(scene);
+ ListBase *main_seqbase = &ed->seqbase;
+ Sequence *seq_meta = seq_sequence_lookup_meta_by_seq(scene, seq);
- for (iseq = seqbase->first; iseq; iseq = iseq->next) {
- if (seq == iseq) {
- return seqbase;
- }
- if (iseq->seqbase.first && (lb = SEQ_get_seqbase_by_seq(&iseq->seqbase, seq))) {
- return lb;
- }
+ if (seq_meta != NULL) {
+ return &seq_meta->seqbase;
+ }
+ if (BLI_findindex(main_seqbase, seq) >= 0) {
+ return main_seqbase;
}
-
return NULL;
}