diff options
Diffstat (limited to 'source/blender/sequencer/intern/strip_time.c')
-rw-r--r-- | source/blender/sequencer/intern/strip_time.c | 79 |
1 files changed, 74 insertions, 5 deletions
diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c index 21dc9aa2cdd..b8b6f62c7aa 100644 --- a/source/blender/sequencer/intern/strip_time.c +++ b/source/blender/sequencer/intern/strip_time.c @@ -36,9 +36,11 @@ #include "IMB_imbuf.h" +#include "SEQ_iterator.h" #include "SEQ_render.h" #include "SEQ_sequencer.h" #include "SEQ_time.h" +#include "SEQ_transform.h" #include "strip_time.h" #include "utils.h" @@ -161,11 +163,41 @@ void SEQ_time_update_sequence_bounds(Scene *scene, Sequence *seq) } } +static void seq_time_update_meta_strip(Scene *scene, Sequence *seq_meta) +{ + if (BLI_listbase_is_empty(&seq_meta->seqbase)) { + return; + } + + 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); + } + + seq_meta->start = min + seq_meta->anim_startofs; + seq_meta->len = max - min; + seq_meta->len -= seq_meta->anim_startofs; + seq_meta->len -= seq_meta->anim_endofs; + + seq_update_sound_bounds_recursive(scene, seq_meta); +} + +static void seq_time_update_meta_strip_range(Scene *scene, Sequence *seq_meta) +{ + seq_time_update_meta_strip(scene, seq_meta); + + /* Prevent meta-strip to move in timeline. */ + SEQ_transform_set_left_handle_frame(seq_meta, seq_meta->startdisp); + SEQ_transform_set_right_handle_frame(seq_meta, seq_meta->enddisp); +} + void SEQ_time_update_sequence(Scene *scene, Sequence *seq) { Sequence *seqm; - /* check all metas recursively */ + /* Check all meta-strips recursively. */ seqm = seq->seqbase.first; while (seqm) { if (seqm->seqbase.first) { @@ -211,6 +243,16 @@ void SEQ_time_update_sequence(Scene *scene, Sequence *seq) } } else { + if (seq->type == SEQ_TYPE_META) { + seq_time_update_meta_strip(scene, seq); + } + + Editing *ed = SEQ_editing_get(scene, false); + MetaStack *ms = SEQ_meta_stack_active_get(ed); + if (ms != NULL) { + seq_time_update_meta_strip_range(scene, ms->parseq); + } + SEQ_time_update_sequence_bounds(scene, seq); } } @@ -363,6 +405,17 @@ void SEQ_timeline_boundbox(const Scene *scene, const ListBase *seqbase, rctf *re } } +static bool strip_exists_at_frame(SeqCollection *all_strips, const int timeline_frame) +{ + Sequence *seq; + SEQ_ITERATOR_FOREACH (seq, all_strips) { + if (SEQ_time_strip_intersects_frame(seq, timeline_frame)) { + return true; + } + } + return false; +} + /** * Find first gap between strips after initial_frame and describe it by filling data of r_gap_info * @@ -384,10 +437,12 @@ void seq_time_gap_info_get(const Scene *scene, int timeline_frame = initial_frame; r_gap_info->gap_exists = false; - if (SEQ_render_evaluate_frame(seqbase, initial_frame) == 0) { + SeqCollection *collection = SEQ_query_all_strips(seqbase); + + if (!strip_exists_at_frame(collection, initial_frame)) { /* Search backward for gap_start_frame. */ for (; timeline_frame >= sfra; timeline_frame--) { - if (SEQ_render_evaluate_frame(seqbase, timeline_frame) != 0) { + if (strip_exists_at_frame(collection, timeline_frame)) { break; } } @@ -397,7 +452,7 @@ void seq_time_gap_info_get(const Scene *scene, else { /* Search forward for gap_start_frame. */ for (; timeline_frame <= efra; timeline_frame++) { - if (SEQ_render_evaluate_frame(seqbase, timeline_frame) == 0) { + if (!strip_exists_at_frame(collection, timeline_frame)) { r_gap_info->gap_start_frame = timeline_frame; break; } @@ -405,7 +460,7 @@ void seq_time_gap_info_get(const Scene *scene, } /* Search forward for gap_end_frame. */ for (; timeline_frame <= efra; timeline_frame++) { - if (SEQ_render_evaluate_frame(seqbase, timeline_frame) != 0) { + if (strip_exists_at_frame(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; @@ -413,3 +468,17 @@ void seq_time_gap_info_get(const Scene *scene, } } } + +/** + * Test if strip intersects with timeline frame. + * Note: This checks if strip would be rendered at this frame. For rendering it is assumed, that + * timeline frame has width of 1 frame and therefore ends at timeline_frame + 1 + * + * \param seq: Sequence to be checked + * \param timeline_frame: absolute frame position + * \return true if strip intersects with timeline frame. + */ +bool SEQ_time_strip_intersects_frame(const Sequence *seq, const int timeline_frame) +{ + return (seq->startdisp <= timeline_frame) && (seq->enddisp > timeline_frame); +} |