diff options
Diffstat (limited to 'source/blender/sequencer')
-rw-r--r-- | source/blender/sequencer/SEQ_sequencer.h | 29 | ||||
-rw-r--r-- | source/blender/sequencer/intern/render.c | 17 | ||||
-rw-r--r-- | source/blender/sequencer/intern/strip_edit.c | 35 | ||||
-rw-r--r-- | source/blender/sequencer/intern/strip_time.c | 84 | ||||
-rw-r--r-- | source/blender/sequencer/intern/strip_time.h | 12 | ||||
-rw-r--r-- | source/blender/sequencer/intern/strip_transform.c | 30 |
6 files changed, 198 insertions, 9 deletions
diff --git a/source/blender/sequencer/SEQ_sequencer.h b/source/blender/sequencer/SEQ_sequencer.h index 11e213d842d..a024d5e10d3 100644 --- a/source/blender/sequencer/SEQ_sequencer.h +++ b/source/blender/sequencer/SEQ_sequencer.h @@ -161,7 +161,7 @@ void SEQ_render_new_render_data(struct Main *bmain, int preview_render_size, int for_render, SeqRenderData *r_context); -int SEQ_render_evaluate_frame(struct Scene *scene, int timeline_frame); +int SEQ_render_evaluate_frame(struct ListBase *seqbase, int timeline_frame); struct StripElem *SEQ_render_give_stripelem(struct Sequence *seq, int timeline_frame); /* ********************************************************************** @@ -595,6 +595,33 @@ struct Sequence *SEQ_edit_strip_split(struct Main *bmain, struct Sequence *seq, const int timeline_frame, const eSeqSplitMethod method); +bool SEQ_edit_remove_gaps(struct Scene *scene, + struct ListBase *seqbase, + const int initial_frame, + const bool remove_all_gaps); + +/* ********************************************************************** + * strip_time.c + * + * Editing functions + * ********************************************************************** + */ + +void SEQ_timeline_boundbox(const struct Scene *scene, + const struct ListBase *seqbase, + struct rctf *rect); + +/* ********************************************************************** + * strip_transform.c + * + * Editing functions + * ********************************************************************** + */ + +void SEQ_offset_after_frame(struct Scene *scene, + struct ListBase *seqbase, + const int delta, + const int timeline_frame); #ifdef __cplusplus } diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c index 008ea1cd3a0..155258dc2c3 100644 --- a/source/blender/sequencer/intern/render.c +++ b/source/blender/sequencer/intern/render.c @@ -337,16 +337,17 @@ static int evaluate_seq_frame_gen(Sequence **seq_arr, return totseq; } -int SEQ_render_evaluate_frame(Scene *scene, int timeline_frame) +/** + * Count number of strips in timeline at timeline_frame + * + * \param seqbase: ListBase in which strips are located + * \param timeline_frame: frame on timeline from where gaps are searched for + * \return number of strips + */ +int SEQ_render_evaluate_frame(ListBase *seqbase, int timeline_frame) { - Editing *ed = BKE_sequencer_editing_get(scene, false); Sequence *seq_arr[MAXSEQ + 1]; - - if (ed == NULL) { - return 0; - } - - return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, timeline_frame, 0); + return evaluate_seq_frame_gen(seq_arr, seqbase, timeline_frame, 0); } static bool video_seq_is_rendered(Sequence *seq) diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c index 3137a471470..a29810cc9ee 100644 --- a/source/blender/sequencer/intern/strip_edit.c +++ b/source/blender/sequencer/intern/strip_edit.c @@ -38,6 +38,8 @@ #include "BKE_scene.h" #include "BKE_sound.h" +#include "strip_time.h" + #include "SEQ_sequencer.h" int BKE_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str) @@ -319,3 +321,36 @@ Sequence *SEQ_edit_strip_split(Main *bmain, BKE_sequence_calc(scene, right_seq); return right_seq; } + +/** + * Find gap after initial_frame and move strips on right side to close the gap + * + * \param scene: Scene in which strips are located + * \param seqbase: ListBase in which strips are located + * \param initial_frame: frame on timeline from where gaps are searched for + * \param remove_all_gaps: remove all gaps instead of one gap + * \return true if gap is removed, otherwise false + */ +bool SEQ_edit_remove_gaps(Scene *scene, + ListBase *seqbase, + const int initial_frame, + const bool remove_all_gaps) +{ + GapInfo gap_info = {0}; + seq_time_gap_info_get(scene, seqbase, initial_frame, &gap_info); + + if (!gap_info.gap_exists) { + return false; + } + + if (remove_all_gaps) { + while (gap_info.gap_exists) { + SEQ_offset_after_frame(scene, seqbase, -gap_info.gap_length, gap_info.gap_start_frame); + seq_time_gap_info_get(scene, seqbase, initial_frame, &gap_info); + } + } + else { + SEQ_offset_after_frame(scene, seqbase, -gap_info.gap_length, gap_info.gap_start_frame); + } + return true; +} diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c index a0ae6d6f16d..015d81cc217 100644 --- a/source/blender/sequencer/intern/strip_time.c +++ b/source/blender/sequencer/intern/strip_time.c @@ -351,3 +351,87 @@ float BKE_sequence_get_fps(Scene *scene, Sequence *seq) } return 0.0f; } + +/** + * Define boundary rectangle of sequencer timeline and fill in rect data + * + * \param scene: Scene in which strips are located + * \param seqbase: ListBase in which strips are located + * \param rect: data structure describing rectangle, that will be filled in by this function + */ +void SEQ_timeline_boundbox(const Scene *scene, const ListBase *seqbase, rctf *rect) +{ + float min[2], max[2]; + min[0] = scene->r.sfra; + max[0] = scene->r.efra + 1; + min[1] = 0.0; + max[1] = 8.0; + + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + if (min[0] > seq->startdisp - 1) { + min[0] = seq->startdisp - 1; + } + if (max[0] < seq->enddisp + 1) { + max[0] = seq->enddisp + 1; + } + if (max[1] < seq->machine + 2) { + max[1] = seq->machine + 2; + } + } + + rect->xmin = min[0]; + rect->xmax = max[0]; + rect->ymin = min[1]; + rect->ymax = max[1]; +} + +/** + * Find first gap between strips after initial_frame and describe it by filling data of r_gap_info + * + * \param scene: Scene in which strips are located + * \param seqbase: ListBase in which strips are located + * \param initial_frame: frame on timeline from where gaps are searched for + * \param r_gap_info: data structure describing gap, that will be filled in by this function + */ +void seq_time_gap_info_get(const Scene *scene, + ListBase *seqbase, + const int initial_frame, + GapInfo *r_gap_info) +{ + rctf rectf; + /* Get first and last frame. */ + SEQ_timeline_boundbox(scene, seqbase, &rectf); + const int sfra = (int)rectf.xmin; + const int efra = (int)rectf.xmax; + int timeline_frame = initial_frame; + r_gap_info->gap_exists = false; + + if (SEQ_render_evaluate_frame(seqbase, initial_frame) == 0) { + /* Search backward for gap_start_frame. */ + for (; timeline_frame >= sfra; timeline_frame--) { + if (SEQ_render_evaluate_frame(seqbase, timeline_frame) != 0) { + break; + } + } + r_gap_info->gap_start_frame = timeline_frame + 1; + timeline_frame = initial_frame; + } + else { + /* Search forward for gap_start_frame. */ + for (; timeline_frame <= efra; timeline_frame++) { + if (SEQ_render_evaluate_frame(seqbase, timeline_frame) == 0) { + r_gap_info->gap_start_frame = timeline_frame; + break; + } + } + } + /* Search forward for gap_end_frame. */ + for (; timeline_frame <= efra; timeline_frame++) { + if (SEQ_render_evaluate_frame(seqbase, timeline_frame) != 0) { + 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; + break; + } + } +} diff --git a/source/blender/sequencer/intern/strip_time.h b/source/blender/sequencer/intern/strip_time.h index e4fb7f1d2ec..e435ff1ec5d 100644 --- a/source/blender/sequencer/intern/strip_time.h +++ b/source/blender/sequencer/intern/strip_time.h @@ -29,10 +29,22 @@ extern "C" { struct Scene; struct Sequence; +struct ListBase; float seq_give_frame_index(struct Sequence *seq, float timeline_frame); void seq_update_sound_bounds_recursive(struct Scene *scene, struct Sequence *metaseq); +/* Describes gap between strips in timeline. */ +typedef struct GapInfo { + int gap_start_frame; /* Start frame of the gap. */ + int gap_length; /* Length of the gap. */ + bool gap_exists; /* False if there are no gaps. */ +} GapInfo; +void seq_time_gap_info_get(const struct Scene *scene, + struct ListBase *seqbase, + const int initial_frame, + struct GapInfo *r_gap_info); + #ifdef __cplusplus } #endif diff --git a/source/blender/sequencer/intern/strip_transform.c b/source/blender/sequencer/intern/strip_transform.c index 233f8e5b22e..4aabe87bce1 100644 --- a/source/blender/sequencer/intern/strip_transform.c +++ b/source/blender/sequencer/intern/strip_transform.c @@ -397,3 +397,33 @@ bool BKE_sequence_base_shuffle_time(ListBase *seqbasep, return offset ? false : true; } + +/** + * Move strips and markers (if not locked) that start after timeline_frame by delta frames + * + * \param scene: Scene in which strips are located + * \param seqbase: ListBase in which strips are located + * \param delta: offset in frames to be applied + * \param timeline_frame: frame on timeline from where strips are moved + */ +void SEQ_offset_after_frame(Scene *scene, + ListBase *seqbase, + const int delta, + const int timeline_frame) +{ + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + if (seq->startdisp >= timeline_frame) { + BKE_sequence_translate(scene, seq, delta); + BKE_sequence_calc(scene, seq); + BKE_sequence_invalidate_cache_preprocessed(scene, seq); + } + } + + if (!scene->toolsettings->lock_markers) { + LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) { + if (marker->frame >= timeline_frame) { + marker->frame += delta; + } + } + } +} |