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>2020-12-15 23:42:06 +0300
committerRichard Antalik <richardantalik@gmail.com>2020-12-15 23:49:15 +0300
commit9e4a4c2e996c3741c2beaf5ed5aadc8cb8801ac3 (patch)
tree87e2a0d3abe242a80e93b0c3507c46dfb70540ae /source/blender/sequencer
parent7e8f6985d89866197be8465a8aec57f9b4ef7b51 (diff)
VSE: Move remove gaps operator logic to module code
Logic was broken into finding gaps and ofsetting strips. Functions were modified so they work on explicitly defined seqbase, so they can be used as python API functions. Functional changes: - Improve performance by calculating gap length and offseting strips at once. Previously strips were offset by one frame. - Calculate gap from start frame. Previously gap was considered only inbetween strips. Reviewed By: sergey Differential Revision: https://developer.blender.org/D9730
Diffstat (limited to 'source/blender/sequencer')
-rw-r--r--source/blender/sequencer/SEQ_sequencer.h29
-rw-r--r--source/blender/sequencer/intern/render.c17
-rw-r--r--source/blender/sequencer/intern/strip_edit.c35
-rw-r--r--source/blender/sequencer/intern/strip_time.c84
-rw-r--r--source/blender/sequencer/intern/strip_time.h12
-rw-r--r--source/blender/sequencer/intern/strip_transform.c30
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;
+ }
+ }
+ }
+}