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
This commit is contained in:
Richard Antalik 2022-06-02 01:39:40 +02:00
parent 604409b8c7
commit 7afcfe111a
Notes: blender-bot 2023-11-02 15:26:17 +01:00
Referenced by commit 62e32e7c2e, Fix VSE: Effect strip flickers when moving left handle
Referenced by commit 5925b1821a, Fix T102328: Incorrect strip state after copying
Referenced by commit 17a773cdce, Fix T99216: RNA startdisp and enddisp return unreliable values
Referenced by commit 06780aa4e6, Fix T98797: VSE Slip Strip Contents doesn't work properly
Referenced by commit 9c029a3eb0, Fix T98621: Image does not update when tweaking strip properties
Referenced by issue #99494, Regression: Wipe Transition not working
Referenced by issue #99216, VSE: invalid sequence.frame_final_end
Referenced by issue #99133, Regression: VSE Speed control - animating multiply factor on video strips crashe blender
Referenced by issue #98797, Regression: VSE Slip Strip Contents doesn't work properly
Referenced by issue #98621, Video Sequencer: Video does not update while being transformed until frame is changed.
Referenced by issue #114252, Regression: VSE: Splitting a meta-strip adds weird "tail," to video clip
36 changed files with 642 additions and 801 deletions

View File

@ -136,7 +136,7 @@ void BKE_sound_remove_scene_sound(struct Scene *scene, void *handle);
void BKE_sound_mute_scene_sound(void *handle, char mute);
void BKE_sound_move_scene_sound(struct Scene *scene,
void BKE_sound_move_scene_sound(const struct Scene *scene,
void *handle,
int startframe,
int endframe,

View File

@ -54,6 +54,7 @@
#include "SEQ_sequencer.h"
#include "SEQ_sound.h"
#include "SEQ_time.h"
static void sound_free_audio(bSound *sound);
@ -719,8 +720,8 @@ void *BKE_sound_scene_add_scene_sound_defaults(Scene *scene, Sequence *sequence)
{
return BKE_sound_scene_add_scene_sound(scene,
sequence,
sequence->startdisp,
sequence->enddisp,
SEQ_time_left_handle_frame_get(sequence),
SEQ_time_right_handle_frame_get(sequence),
sequence->startofs + sequence->anim_startofs);
}
@ -745,8 +746,8 @@ void *BKE_sound_add_scene_sound_defaults(Scene *scene, Sequence *sequence)
{
return BKE_sound_add_scene_sound(scene,
sequence,
sequence->startdisp,
sequence->enddisp,
SEQ_time_left_handle_frame_get(sequence),
SEQ_time_right_handle_frame_get(sequence),
sequence->startofs + sequence->anim_startofs);
}
@ -760,8 +761,12 @@ void BKE_sound_mute_scene_sound(void *handle, char mute)
AUD_SequenceEntry_setMuted(handle, mute);
}
void BKE_sound_move_scene_sound(
Scene *scene, void *handle, int startframe, int endframe, int frameskip, double audio_offset)
void BKE_sound_move_scene_sound(const Scene *scene,
void *handle,
int startframe,
int endframe,
int frameskip,
double audio_offset)
{
sound_verify_evaluated_id(&scene->id);
const double fps = FPS;
@ -774,8 +779,8 @@ void BKE_sound_move_scene_sound_defaults(Scene *scene, Sequence *sequence)
if (sequence->scene_sound) {
BKE_sound_move_scene_sound(scene,
sequence->scene_sound,
sequence->startdisp,
sequence->enddisp,
SEQ_time_left_handle_frame_get(sequence),
SEQ_time_right_handle_frame_get(sequence),
sequence->startofs + sequence->anim_startofs,
0.0);
}
@ -1344,7 +1349,7 @@ void BKE_sound_remove_scene_sound(Scene *UNUSED(scene), void *UNUSED(handle))
void BKE_sound_mute_scene_sound(void *UNUSED(handle), char UNUSED(mute))
{
}
void BKE_sound_move_scene_sound(Scene *UNUSED(scene),
void BKE_sound_move_scene_sound(const Scene *UNUSED(scene),
void *UNUSED(handle),
int UNUSED(startframe),
int UNUSED(endframe),

View File

@ -347,8 +347,9 @@ static void seq_convert_transform_crop_lb_2(const Scene *scene,
}
}
static void seq_update_meta_disp_range(Editing *ed)
static void seq_update_meta_disp_range(Scene *scene)
{
Editing *ed = SEQ_editing_get(scene);
if (ed == NULL) {
return;
}
@ -356,21 +357,14 @@ static void seq_update_meta_disp_range(Editing *ed)
LISTBASE_FOREACH_BACKWARD (MetaStack *, ms, &ed->metastack) {
/* Update ms->disp_range from meta. */
if (ms->disp_range[0] == ms->disp_range[1]) {
copy_v2_v2_int(ms->disp_range, &ms->parseq->startdisp);
ms->disp_range[0] = SEQ_time_left_handle_frame_get(ms->parseq);
ms->disp_range[1] = SEQ_time_right_handle_frame_get(ms->parseq);
}
/* Update meta strip endpoints. */
SEQ_time_left_handle_frame_set(ms->parseq, ms->disp_range[0]);
SEQ_time_right_handle_frame_set(ms->parseq, ms->disp_range[1]);
SEQ_transform_fix_single_image_seq_offsets(ms->parseq);
/* Recalculate effects using meta strip. */
LISTBASE_FOREACH (Sequence *, seq, ms->oldbasep) {
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);
}
}
SEQ_time_left_handle_frame_set(scene, ms->parseq, ms->disp_range[0]);
SEQ_time_right_handle_frame_set(scene, ms->parseq, ms->disp_range[1]);
SEQ_transform_fix_single_image_seq_offsets(scene, ms->parseq);
/* Ensure that active seqbase points to active meta strip seqbase. */
MetaStack *active_ms = SEQ_meta_stack_active_get(ed);
@ -647,7 +641,7 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
if (!MAIN_VERSION_ATLEAST(bmain, 293, 16)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
seq_update_meta_disp_range(SEQ_editing_get(scene));
seq_update_meta_disp_range(scene);
}
/* Add a separate socket for Grid node X and Y size. */

View File

@ -405,7 +405,9 @@ static void do_versions_sequencer_speed_effect_recursive(Scene *scene, const Lis
v->speed_control_type = SEQ_SPEED_MULTIPLY;
v->speed_fader = globalSpeed *
((float)seq->seq1->len /
max_ff((float)(seq->seq1->enddisp - seq->seq1->start), 1.0f));
max_ff((float)(SEQ_time_right_handle_frame_get(seq->seq1) -
seq->seq1->start),
1.0f));
}
}
else if (v->flags & SEQ_SPEED_INTEGRATE) {

View File

@ -191,10 +191,11 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type)
}
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if ((ELEM(type, -1, seq->type)) && (seq->enddisp < timeline_frame) &&
(timeline_frame - seq->enddisp < proximity)) {
const int strip_end = SEQ_time_right_handle_frame_get(seq);
if ((ELEM(type, -1, seq->type)) && (strip_end < timeline_frame) &&
(timeline_frame - strip_end < proximity)) {
tgt = seq;
proximity = timeline_frame - seq->enddisp;
proximity = timeline_frame - strip_end;
}
}
@ -793,9 +794,8 @@ static void sequencer_add_movie_clamp_sound_strip_length(Scene *scene,
return;
}
SEQ_time_right_handle_frame_set(seq_sound, SEQ_time_right_handle_frame_get(seq_movie));
SEQ_time_left_handle_frame_set(seq_sound, SEQ_time_left_handle_frame_get(seq_movie));
SEQ_time_update_sequence(scene, seqbase, seq_sound);
SEQ_time_right_handle_frame_set(scene, seq_sound, SEQ_time_right_handle_frame_get(seq_movie));
SEQ_time_left_handle_frame_set(scene, seq_sound, SEQ_time_left_handle_frame_get(seq_movie));
}
static void sequencer_add_movie_multiple_strips(bContext *C,
@ -842,7 +842,8 @@ static void sequencer_add_movie_multiple_strips(bContext *C,
}
}
load_data->start_frame += seq_movie->enddisp - seq_movie->startdisp;
load_data->start_frame += SEQ_time_right_handle_frame_get(seq_movie) -
SEQ_time_left_handle_frame_get(seq_movie);
if (overlap_shuffle_override) {
has_seq_overlap |= seq_load_apply_generic_options_only_test_overlap(
C, op, seq_sound, strip_col);
@ -1073,7 +1074,8 @@ static void sequencer_add_sound_multiple_strips(bContext *C,
}
else {
seq_load_apply_generic_options(C, op, seq);
load_data->start_frame += seq->enddisp - seq->startdisp;
load_data->start_frame += SEQ_time_right_handle_frame_get(seq) -
SEQ_time_left_handle_frame_get(seq);
}
}
RNA_END;
@ -1300,8 +1302,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
/* Adjust length. */
if (load_data.image.len == 1) {
SEQ_time_right_handle_frame_set(seq, load_data.image.end_frame);
SEQ_time_update_sequence(scene, SEQ_active_seqbase_get(ed), seq);
SEQ_time_right_handle_frame_set(scene, seq, load_data.image.end_frame);
}
seq_load_apply_generic_options(C, op, seq);

View File

@ -231,9 +231,8 @@ static void update_overlay_strip_poistion_data(bContext *C, const int mval[2])
else {
/* Check if there is a strip that would intersect with the new strip(s). */
coords->is_intersecting = false;
Sequence dummy_seq = {.machine = coords->channel,
.startdisp = coords->start_frame,
.enddisp = coords->start_frame + coords->strip_len};
Sequence dummy_seq = {
.machine = coords->channel, .start = coords->start_frame, .len = coords->strip_len};
Editing *ed = SEQ_editing_get(scene);
for (int i = 0; i < coords->channel_len && !coords->is_intersecting; i++) {

View File

@ -617,8 +617,8 @@ static void drawmeta_contents(Scene *scene,
/* Draw only immediate children (1 level depth). */
for (seq = meta_seqbase->first; seq; seq = seq->next) {
const int startdisp = seq->startdisp + offset;
const int enddisp = seq->enddisp + offset;
const int startdisp = SEQ_time_left_handle_frame_get(seq) + offset;
const int enddisp = SEQ_time_right_handle_frame_get(seq) + offset;
if ((startdisp > x2 || enddisp < x1) == 0) {
float y_chan = (seq->machine - chan_min) / (float)(chan_range)*draw_range;
@ -668,7 +668,7 @@ float sequence_handle_size_get_clamped(Sequence *seq, const float pixelx)
const float maxhandle = (pixelx * SEQ_HANDLE_SIZE) * U.pixelsize;
/* Ensure that handle is not wider, than quarter of strip. */
return min_ff(maxhandle, ((float)(seq->enddisp - seq->startdisp) / 4.0f));
return min_ff(maxhandle, ((float)(SEQ_time_right_handle_frame_get(seq) - SEQ_time_left_handle_frame_get(seq)) / 4.0f));
}
/* Draw a handle, on left or right side of strip. */
@ -686,8 +686,8 @@ static void draw_seq_handle(View2D *v2d,
uint whichsel = 0;
uchar col[4];
x1 = seq->startdisp;
x2 = seq->enddisp;
x1 = SEQ_time_left_handle_frame_get(seq);
x2 = SEQ_time_right_handle_frame_get(seq);
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
y2 = seq->machine + SEQ_STRIP_OFSTOP;
@ -739,7 +739,7 @@ static void draw_seq_handle(View2D *v2d,
BLF_set_default();
/* Calculate if strip is wide enough for showing the labels. */
numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d%d", seq->startdisp, seq->enddisp);
numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d%d", SEQ_time_left_handle_frame_get(seq), SEQ_time_right_handle_frame_get(seq));
float tot_width = BLF_width(fontid, numstr, numstr_len);
if ((x2 - x1) / pixelx > 20 + tot_width) {
@ -747,12 +747,12 @@ static void draw_seq_handle(View2D *v2d,
float text_margin = 1.2f * handsize_clamped;
if (direction == SEQ_LEFTHANDLE) {
numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", seq->startdisp);
numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", SEQ_time_left_handle_frame_get(seq));
x1 += text_margin;
y1 += 0.09f;
}
else {
numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", seq->enddisp - 1);
numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", SEQ_time_right_handle_frame_get(seq) - 1);
x1 = x2 - (text_margin + pixelx * BLF_width(fontid, numstr, numstr_len));
y1 += 0.09f;
}
@ -913,7 +913,7 @@ static size_t draw_seq_text_get_overlay_string(SpaceSeq *sseq,
char strip_duration_text[16];
if (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_DURATION) {
const int strip_duration = seq->enddisp - seq->startdisp;
const int strip_duration = SEQ_time_right_handle_frame_get(seq) - SEQ_time_left_handle_frame_get(seq);
SNPRINTF(strip_duration_text, "%d", strip_duration);
if (i != 0) {
text_array[i++] = text_sep;
@ -980,8 +980,8 @@ static void draw_sequence_extensions_overlay(
float x1, x2, y1, y2;
uchar col[4], blend_col[3];
x1 = seq->startdisp;
x2 = seq->enddisp;
x1 = SEQ_time_left_handle_frame_get(seq);
x2 = SEQ_time_right_handle_frame_get(seq);
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
y2 = seq->machine + SEQ_STRIP_OFSTOP;
@ -1038,15 +1038,15 @@ static void draw_color_strip_band(
immUniformColor4ubv(col);
immRectf(pos, seq->startdisp, y1, seq->enddisp, text_margin_y);
immRectf(pos, SEQ_time_left_handle_frame_get(seq), y1, SEQ_time_right_handle_frame_get(seq), text_margin_y);
/* 1px line to better separate the color band. */
UI_GetColorPtrShade3ubv(col, col, -20);
immUniformColor4ubv(col);
immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, seq->startdisp, text_margin_y);
immVertex2f(pos, seq->enddisp, text_margin_y);
immVertex2f(pos, SEQ_time_left_handle_frame_get(seq), text_margin_y);
immVertex2f(pos, SEQ_time_right_handle_frame_get(seq), text_margin_y);
immEnd();
GPU_blend(GPU_BLEND_NONE);
@ -1111,12 +1111,12 @@ static void draw_seq_background(Scene *scene,
immUniformColor4ubv(col);
if (SEQ_time_has_left_still_frames(seq)) {
const float content_start = min_ff(seq->enddisp, seq->start);
immRectf(pos, seq->startdisp, y1, content_start, y2);
const float content_start = min_ff(SEQ_time_right_handle_frame_get(seq), seq->start);
immRectf(pos, SEQ_time_left_handle_frame_get(seq), y1, content_start, y2);
}
if (SEQ_time_has_right_still_frames(seq)) {
const float content_end = max_ff(seq->startdisp, seq->start + seq->len);
immRectf(pos, content_end, y1, seq->enddisp, y2);
const float content_end = max_ff(SEQ_time_left_handle_frame_get(seq), seq->start + seq->len);
immRectf(pos, content_end, y1, SEQ_time_right_handle_frame_get(seq), y2);
}
}
@ -1333,14 +1333,14 @@ static void draw_seq_strip(const bContext *C,
SEQ_TIMELINE_SHOW_STRIP_COLOR_TAG);
/* Draw strip body. */
x1 = SEQ_time_has_left_still_frames(seq) ? seq->start : seq->startdisp;
x1 = SEQ_time_has_left_still_frames(seq) ? seq->start : SEQ_time_left_handle_frame_get(seq);
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
x2 = SEQ_time_has_right_still_frames(seq) ? (seq->start + seq->len) : seq->enddisp;
x2 = SEQ_time_has_right_still_frames(seq) ? (seq->start + seq->len) : SEQ_time_right_handle_frame_get(seq);
y2 = seq->machine + SEQ_STRIP_OFSTOP;
/* Limit body to strip bounds. Meta strip can end up with content outside of strip range. */
x1 = min_ff(x1, seq->enddisp);
x2 = max_ff(x2, seq->startdisp);
x1 = min_ff(x1, SEQ_time_right_handle_frame_get(seq));
x2 = max_ff(x2, SEQ_time_left_handle_frame_get(seq));
float text_margin_y;
bool y_threshold;
@ -1380,8 +1380,8 @@ static void draw_seq_strip(const bContext *C,
}
immUnbindProgram();
x1 = seq->startdisp;
x2 = seq->enddisp;
x1 = SEQ_time_left_handle_frame_get(seq);
x2 = SEQ_time_right_handle_frame_get(seq);
if ((seq->type == SEQ_TYPE_META) ||
((seq->type == SEQ_TYPE_SCENE) && (seq->flag & SEQ_SCENE_STRIPS))) {
@ -1471,23 +1471,23 @@ static void draw_effect_inputs_highlight(Sequence *seq)
immUniformColor4ub(255, 255, 255, 48);
immRectf(pos,
seq1->startdisp,
SEQ_time_left_handle_frame_get(seq1),
seq1->machine + SEQ_STRIP_OFSBOTTOM,
seq1->enddisp,
SEQ_time_right_handle_frame_get(seq1),
seq1->machine + SEQ_STRIP_OFSTOP);
if (seq2 && seq2 != seq1) {
immRectf(pos,
seq2->startdisp,
SEQ_time_left_handle_frame_get(seq2),
seq2->machine + SEQ_STRIP_OFSBOTTOM,
seq2->enddisp,
SEQ_time_right_handle_frame_get(seq2),
seq2->machine + SEQ_STRIP_OFSTOP);
}
if (seq3 && !ELEM(seq3, seq1, seq2)) {
immRectf(pos,
seq3->startdisp,
SEQ_time_left_handle_frame_get(seq3),
seq3->machine + SEQ_STRIP_OFSBOTTOM,
seq3->enddisp,
SEQ_time_right_handle_frame_get(seq3),
seq3->machine + SEQ_STRIP_OFSTOP);
}
immUnbindProgram();
@ -2081,10 +2081,10 @@ static int sequencer_draw_get_transform_preview_frame(Scene *scene)
int preview_frame;
if (last_seq->flag & SEQ_RIGHTSEL) {
preview_frame = last_seq->enddisp - 1;
preview_frame = SEQ_time_right_handle_frame_get(last_seq) - 1;
}
else {
preview_frame = last_seq->startdisp;
preview_frame = SEQ_time_left_handle_frame_get(last_seq);
}
return preview_frame;
@ -2310,10 +2310,10 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
if (seq == last_seq && (last_seq->flag & SELECT)) {
continue;
}
if (min_ii(seq->startdisp, seq->start) > v2d->cur.xmax) {
if (min_ii(SEQ_time_left_handle_frame_get(seq), seq->start) > v2d->cur.xmax) {
continue;
}
if (max_ii(seq->enddisp, seq->start + seq->len) < v2d->cur.xmin) {
if (max_ii(SEQ_time_right_handle_frame_get(seq), seq->start + seq->len) < v2d->cur.xmin) {
continue;
}
if (seq->machine + 1.0f < v2d->cur.ymin) {
@ -2368,9 +2368,9 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
immUniformColor4ub(255, 255, 255, 48);
immRectf(pos,
seq->startdisp,
SEQ_time_left_handle_frame_get(seq),
seq->machine + SEQ_STRIP_OFSBOTTOM,
seq->enddisp,
SEQ_time_right_handle_frame_get(seq),
seq->machine + SEQ_STRIP_OFSTOP);
immUnbindProgram();
@ -2597,7 +2597,7 @@ static void draw_cache_view(const bContext *C)
continue;
}
if (seq->startdisp > v2d->cur.xmax || seq->enddisp < v2d->cur.xmin) {
if (SEQ_time_left_handle_frame_get(seq) > v2d->cur.xmax || SEQ_time_right_handle_frame_get(seq) < v2d->cur.xmin) {
continue;
}
@ -2607,7 +2607,7 @@ static void draw_cache_view(const bContext *C)
if (scene->ed->cache_flag & SEQ_CACHE_VIEW_RAW) {
const float bg_color[4] = {1.0f, 0.1f, 0.02f, 0.1f};
immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top);
immRectf(pos, SEQ_time_left_handle_frame_get(seq), stripe_bot, SEQ_time_right_handle_frame_get(seq), stripe_top);
}
stripe_bot += stripe_ht + stripe_ofs_y;
@ -2616,7 +2616,7 @@ static void draw_cache_view(const bContext *C)
if (scene->ed->cache_flag & SEQ_CACHE_VIEW_PREPROCESSED) {
const float bg_color[4] = {0.1f, 0.1f, 0.75f, 0.1f};
immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top);
immRectf(pos, SEQ_time_left_handle_frame_get(seq), stripe_bot, SEQ_time_right_handle_frame_get(seq), stripe_top);
}
stripe_top = seq->machine + SEQ_STRIP_OFSTOP - stripe_ofs_y;
@ -2625,7 +2625,7 @@ static void draw_cache_view(const bContext *C)
if (scene->ed->cache_flag & SEQ_CACHE_VIEW_COMPOSITE) {
const float bg_color[4] = {1.0f, 0.6f, 0.0f, 0.1f};
immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top);
immRectf(pos, SEQ_time_left_handle_frame_get(seq), stripe_bot, SEQ_time_right_handle_frame_get(seq), stripe_top);
}
}

View File

@ -77,7 +77,6 @@
typedef struct TransSeq {
int start, machine;
int startdisp, enddisp;
int startofs, endofs;
int anim_startofs, anim_endofs;
/* int final_left, final_right; */ /* UNUSED */
@ -345,7 +344,6 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Editing *ed = SEQ_editing_get(scene);
ListBase *seqbase = SEQ_active_seqbase_get(ed);
ListBase *channels = SEQ_channels_displayed_get(ed);
Sequence *seq;
int snap_frame;
@ -361,15 +359,15 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
}
else {
if (seq->flag & SEQ_LEFTSEL) {
SEQ_time_left_handle_frame_set(seq, snap_frame);
SEQ_time_left_handle_frame_set(scene, seq, snap_frame);
}
else { /* SEQ_RIGHTSEL */
SEQ_time_right_handle_frame_set(seq, snap_frame);
SEQ_time_right_handle_frame_set(scene, seq, snap_frame);
}
SEQ_transform_handle_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL);
SEQ_transform_fix_single_image_seq_offsets(seq);
SEQ_transform_handle_xlimits(
scene, seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL);
SEQ_transform_fix_single_image_seq_offsets(scene, seq);
}
SEQ_time_update_sequence(scene, seqbase, seq);
}
}
@ -390,27 +388,22 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
if (seq->seq1 && (seq->seq1->flag & SELECT)) {
if (!either_handle_selected) {
SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp));
SEQ_offset_animdata(scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(seq)));
}
SEQ_time_update_sequence(scene, seqbase, seq);
}
else if (seq->seq2 && (seq->seq2->flag & SELECT)) {
if (!either_handle_selected) {
SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp));
SEQ_offset_animdata(scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(seq)));
}
SEQ_time_update_sequence(scene, seqbase, seq);
}
else if (seq->seq3 && (seq->seq3->flag & SELECT)) {
if (!either_handle_selected) {
SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp));
SEQ_offset_animdata(scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(seq)));
}
SEQ_time_update_sequence(scene, seqbase, seq);
}
}
}
SEQ_sort(SEQ_active_seqbase_get(ed));
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@ -477,8 +470,6 @@ static void transseq_backup(TransSeq *ts, Sequence *seq)
{
ts->start = seq->start;
ts->machine = seq->machine;
ts->startdisp = seq->startdisp;
ts->enddisp = seq->enddisp;
ts->startofs = seq->startofs;
ts->endofs = seq->endofs;
ts->anim_startofs = seq->anim_startofs;
@ -490,8 +481,6 @@ static void transseq_restore(TransSeq *ts, Sequence *seq)
{
seq->start = ts->start;
seq->machine = ts->machine;
seq->startdisp = ts->startdisp;
seq->enddisp = ts->enddisp;
seq->startofs = ts->startofs;
seq->endofs = ts->endofs;
seq->anim_startofs = ts->anim_startofs;
@ -605,22 +594,8 @@ static void sequencer_slip_recursively(Scene *scene, SlipData *data, int offset)
endframe = seq->start + seq->len;
/* Compute the sequence offsets. */
seq->endofs = endframe - seq->enddisp;
seq->startofs = seq->startdisp - seq->start;
}
else {
/* No transform data (likely effect strip). Only move start and end. */
seq->startdisp = data->ts[i].startdisp + offset;
seq->enddisp = data->ts[i].enddisp + offset;
}
/* Effects are only added if we they are in a meta-strip.
* In this case, dependent strips will just be transformed and
* we can skip calculating for effects.
* This way we can avoid an extra loop just for effects. */
if (!(seq->type & SEQ_TYPE_EFFECT)) {
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
SEQ_time_update_sequence(scene, seqbase, seq);
seq->endofs = endframe - SEQ_time_right_handle_frame_get(seq);
seq->startofs = SEQ_time_left_handle_frame_get(seq) - seq->start;
}
}
@ -640,12 +615,12 @@ static void sequencer_slip_apply_limits(SlipData *data, int *offset)
int seq_content_end = seq_content_start + seq->len + seq->anim_startofs + seq->anim_endofs;
int diff = 0;
if (seq_content_start >= seq->enddisp) {
diff = seq->enddisp - seq_content_start - 1;
if (seq_content_start >= SEQ_time_right_handle_frame_get(seq)) {
diff = SEQ_time_right_handle_frame_get(seq) - seq_content_start - 1;
}
if (seq_content_end <= seq->startdisp) {
diff = seq->startdisp - seq_content_end + 1;
if (seq_content_end <= SEQ_time_left_handle_frame_get(seq)) {
diff = SEQ_time_left_handle_frame_get(seq) - seq_content_end + 1;
}
*offset += diff;
}
@ -791,8 +766,6 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
for (int i = 0; i < data->num_seq; i++) {
Sequence *seq = data->seq_array[i];
SEQ_add_reload_new_file(bmain, scene, seq, false);
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
SEQ_time_update_sequence(scene, seqbase, seq);
}
MEM_freeN(data->seq_array);
@ -1288,7 +1261,6 @@ static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op)
last_seq->seq3 = seq3;
int old_start = last_seq->start;
SEQ_time_update_recursive(scene, last_seq);
SEQ_relations_invalidate_cache_preprocessed(scene, last_seq);
SEQ_offset_animdata(scene, last_seq, (last_seq->start - old_start));
@ -1446,13 +1418,15 @@ static int sequencer_split_exec(bContext *C, wmOperator *op)
if (ignore_selection) {
if (use_cursor_position) {
LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (seq->enddisp == split_frame && seq->machine == split_channel) {
if (SEQ_time_right_handle_frame_get(seq) == split_frame &&
seq->machine == split_channel) {
seq_selected = seq->flag & SEQ_ALLSEL;
}
}
if (!seq_selected) {
LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (seq->startdisp == split_frame && seq->machine == split_channel) {
if (SEQ_time_left_handle_frame_get(seq) == split_frame &&
seq->machine == split_channel) {
seq->flag &= ~SEQ_ALLSEL;
}
}
@ -1463,20 +1437,18 @@ static int sequencer_split_exec(bContext *C, wmOperator *op)
if (split_side != SEQ_SIDE_BOTH) {
LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
if (split_side == SEQ_SIDE_LEFT) {
if (seq->startdisp >= split_frame) {
if (SEQ_time_left_handle_frame_get(seq) >= split_frame) {
seq->flag &= ~SEQ_ALLSEL;
}
}
else {
if (seq->enddisp <= split_frame) {
if (SEQ_time_right_handle_frame_get(seq) <= split_frame) {
seq->flag &= ~SEQ_ALLSEL;
}
}
}
}
}
SEQ_sort(SEQ_active_seqbase_get(ed));
}
if (changed) {
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@ -1791,8 +1763,6 @@ static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op))
/* Update lengths, etc. */
seq = ed->seqbasep->first;
while (seq) {
ListBase *seqbase = SEQ_active_seqbase_get(ed);
SEQ_time_update_sequence(scene, seqbase, seq);
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
seq = seq->next;
}
@ -1883,8 +1853,6 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
BLI_strncpy(se_new->name, se->name, sizeof(se_new->name));
strip_new->stripdata = se_new;
SEQ_time_update_sequence(scene, seqbase, seq_new);
if (step > 1) {
seq_new->flag &= ~SEQ_OVERLAP;
if (SEQ_transform_test_overlap(seqbase, seq_new)) {
@ -1908,9 +1876,6 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
}
SEQ_edit_remove_flagged_sequences(scene, seqbase);
SEQ_sort(seqbase);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@ -2020,8 +1985,8 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
BLI_addtail(&seqm->seqbase, seq);
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
channel_max = max_ii(seq->machine, channel_max);
meta_start_frame = min_ii(seq->startdisp, meta_start_frame);
meta_end_frame = max_ii(seq->enddisp, meta_end_frame);
meta_start_frame = min_ii(SEQ_time_left_handle_frame_get(seq), meta_start_frame);
meta_end_frame = max_ii(SEQ_time_right_handle_frame_get(seq), meta_end_frame);
}
}
@ -2030,7 +1995,6 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
SEQ_sequence_base_unique_name_recursive(scene, &ed->seqbase, seqm);
seqm->start = meta_start_frame;
seqm->len = meta_end_frame - meta_start_frame;
SEQ_time_update_sequence(scene, active_seqbase, seqm);
SEQ_select_active_set(scene, seqm);
if (SEQ_transform_test_overlap(active_seqbase, seqm)) {
SEQ_transform_seqbase_shuffle(active_seqbase, seqm, scene);
@ -2098,7 +2062,6 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
}
}
SEQ_sort(active_seqbase);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@ -2204,19 +2167,18 @@ static const EnumPropertyItem prop_side_lr_types[] = {
static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb)
{
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
int gap = seqb->startdisp - seqa->enddisp;
int gap = SEQ_time_left_handle_frame_get(seqb) - SEQ_time_right_handle_frame_get(seqa);
int seq_a_start;
int seq_b_start;
seq_b_start = (seqb->start - seqb->startdisp) + seqa->startdisp;
seq_b_start = (seqb->start - SEQ_time_left_handle_frame_get(seqb)) +
SEQ_time_left_handle_frame_get(seqa);
SEQ_transform_translate_sequence(scene, seqb, seq_b_start - seqb->start);
SEQ_time_update_sequence(scene, seqbase, seqb);
SEQ_relations_invalidate_cache_preprocessed(scene, seqb);
seq_a_start = (seqa->start - seqa->startdisp) + seqb->enddisp + gap;
seq_a_start = (seqa->start - SEQ_time_left_handle_frame_get(seqa)) +
SEQ_time_right_handle_frame_get(seqb) + gap;
SEQ_transform_translate_sequence(scene, seqa, seq_a_start - seqa->start);
SEQ_time_update_sequence(scene, seqbase, seqa);
SEQ_relations_invalidate_cache_preprocessed(scene, seqa);
}
@ -2241,13 +2203,13 @@ static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, i
switch (lr) {
case SEQ_SIDE_LEFT:
if (seq->enddisp <= test->startdisp) {
dist = test->enddisp - seq->startdisp;
if (SEQ_time_right_handle_frame_get(seq) <= SEQ_time_left_handle_frame_get(test)) {
dist = SEQ_time_right_handle_frame_get(test) - SEQ_time_left_handle_frame_get(seq);
}
break;
case SEQ_SIDE_RIGHT:
if (seq->startdisp >= test->enddisp) {
dist = seq->startdisp - test->enddisp;
if (SEQ_time_left_handle_frame_get(seq) >= SEQ_time_right_handle_frame_get(test)) {
dist = SEQ_time_left_handle_frame_get(seq) - SEQ_time_right_handle_frame_get(test);
}
break;
}
@ -2307,14 +2269,6 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op)
break;
}
/* XXX: Should be a generic function. */
for (iseq = seqbase->first; iseq; iseq = iseq->next) {
if ((iseq->type & SEQ_TYPE_EFFECT) &&
(seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) {
SEQ_time_update_sequence(scene, seqbase, iseq);
}
}
/* Do this in a new loop since both effects need to be calculated first. */
for (iseq = seqbase->first; iseq; iseq = iseq->next) {
if ((iseq->type & SEQ_TYPE_EFFECT) &&
@ -2326,10 +2280,7 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op)
}
}
SEQ_sort(SEQ_active_seqbase_get(ed));
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
}
@ -2576,8 +2527,8 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
else {
int min_seq_startdisp = INT_MAX;
LISTBASE_FOREACH (Sequence *, seq, &seqbase_clipboard) {
if (seq->startdisp < min_seq_startdisp) {
min_seq_startdisp = seq->startdisp;
if (SEQ_time_left_handle_frame_get(seq) < min_seq_startdisp) {
min_seq_startdisp = SEQ_time_left_handle_frame_get(seq);
}
}
/* Paste strips relative to the current-frame. */
@ -2608,13 +2559,17 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
* in the new list. */
BLI_movelisttolist(ed->seqbasep, &nseqbase);
/* Make sure, that pasted strips have unique names. This has to be done immediately after adding
* strips to seqbase, for lookup cache to work correctly. */
for (iseq = iseq_first; iseq; iseq = iseq->next) {
SEQ_ensure_unique_name(iseq, scene);
}
for (iseq = iseq_first; iseq; iseq = iseq->next) {
if (SEQ_clipboard_pasted_seq_was_active(iseq)) {
SEQ_select_active_set(scene, iseq);
}
/* Make sure, that pasted strips have unique names. */
SEQ_ensure_unique_name(iseq, scene);
/* Translate after name has been changed, otherwise this will affect animdata of original
* strip. */
SEQ_transform_translate_sequence(scene, iseq, ofs);
@ -2692,10 +2647,6 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op)
seq_act->scene_sound = NULL;
seq_other->scene_sound = NULL;
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
SEQ_time_update_sequence(scene, seqbase, seq_act);
SEQ_time_update_sequence(scene, seqbase, seq_other);
if (seq_act->sound) {
BKE_sound_add_scene_sound_defaults(scene, seq_act);
}
@ -2938,9 +2889,6 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op)
/* Correct start/end frames so we don't move.
* Important not to set seq->len = len; allow the function to handle it. */
SEQ_add_reload_new_file(bmain, scene, seq, true);
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
SEQ_time_update_sequence(scene, seqbase, seq);
}
else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) {
bSound *sound = seq->sound;
@ -3160,7 +3108,7 @@ static bool seq_get_text_strip_cb(Sequence *seq, void *user_data)
ListBase *channels = SEQ_channels_displayed_get(ed);
/* Only text strips that are not muted and don't end with negative frame. */
if ((seq->type == SEQ_TYPE_TEXT) && !SEQ_render_is_muted(channels, seq) &&
(seq->enddisp > cd->scene->r.sfra)) {
(SEQ_time_right_handle_frame_get(seq) > cd->scene->r.sfra)) {
BLI_addtail(cd->text_seq, MEM_dupallocN(seq));
}
return true;
@ -3218,16 +3166,17 @@ static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op)
char timecode_str_end[32];
/* Write time-code relative to start frame of scene. Don't allow negative time-codes. */
BLI_timecode_string_from_time(timecode_str_start,
sizeof(timecode_str_start),
-2,
FRA2TIME(max_ii(seq->startdisp - scene->r.sfra, 0)),
FPS,
USER_TIMECODE_SUBRIP);
BLI_timecode_string_from_time(
timecode_str_start,
sizeof(timecode_str_start),
-2,
FRA2TIME(max_ii(SEQ_time_left_handle_frame_get(seq) - scene->r.sfra, 0)),
FPS,
USER_TIMECODE_SUBRIP);
BLI_timecode_string_from_time(timecode_str_end,
sizeof(timecode_str_end),
-2,
FRA2TIME(seq->enddisp - scene->r.sfra),
FRA2TIME(SEQ_time_right_handle_frame_get(seq) - scene->r.sfra),
FPS,
USER_TIMECODE_SUBRIP);
@ -3295,8 +3244,8 @@ static int sequencer_set_range_to_strips_exec(bContext *C, wmOperator *op)
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if (seq->flag & SELECT) {
selected = true;
sfra = min_ii(sfra, seq->startdisp);
efra = max_ii(efra, seq->enddisp - 1);
sfra = min_ii(sfra, SEQ_time_left_handle_frame_get(seq));
efra = max_ii(efra, SEQ_time_right_handle_frame_get(seq) - 1);
}
}

View File

@ -116,13 +116,13 @@ static void select_active_side(ListBase *seqbase, int sel_side, int channel, int
if (channel == seq->machine) {
switch (sel_side) {
case SEQ_SIDE_LEFT:
if (frame > (seq->startdisp)) {
if (frame > (SEQ_time_left_handle_frame_get(seq))) {
seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL);
seq->flag |= SELECT;
}
break;
case SEQ_SIDE_RIGHT:
if (frame < (seq->startdisp)) {
if (frame < (SEQ_time_left_handle_frame_get(seq))) {
seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL);
seq->flag |= SELECT;
}
@ -152,13 +152,13 @@ static void select_active_side_range(ListBase *seqbase,
}
switch (sel_side) {
case SEQ_SIDE_LEFT:
if (frame > (seq->startdisp)) {
if (frame > (SEQ_time_left_handle_frame_get(seq))) {
seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL);
seq->flag |= SELECT;
}
break;
case SEQ_SIDE_RIGHT:
if (frame < (seq->startdisp)) {
if (frame < (SEQ_time_left_handle_frame_get(seq))) {
seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL);
seq->flag |= SELECT;
}
@ -179,8 +179,8 @@ static void select_linked_time(ListBase *seqbase, Sequence *seq_link)
for (seq = seqbase->first; seq; seq = seq->next) {
if (seq_link->machine != seq->machine) {
int left_match = (seq->startdisp == seq_link->startdisp) ? 1 : 0;
int right_match = (seq->enddisp == seq_link->enddisp) ? 1 : 0;
int left_match = (SEQ_time_left_handle_frame_get(seq) == seq_link->startdisp) ? 1 : 0;
int right_match = (SEQ_time_right_handle_frame_get(seq) == seq_link->enddisp) ? 1 : 0;
if (left_match && right_match) {
/* Direct match, copy the selection settings. */
@ -247,8 +247,8 @@ void ED_sequencer_select_sequence_single(Scene *scene, Sequence *seq, bool desel
void seq_rectf(Sequence *seq, rctf *rect)
{
rect->xmin = seq->startdisp;
rect->xmax = seq->enddisp;
rect->xmin = SEQ_time_left_handle_frame_get(seq);
rect->xmax = SEQ_time_right_handle_frame_get(seq);
rect->ymin = seq->machine + SEQ_STRIP_OFSBOTTOM;
rect->ymax = seq->machine + SEQ_STRIP_OFSTOP;
}
@ -273,12 +273,12 @@ Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int se
(sel == 0 && (seq->flag & SELECT) == 0))) {
switch (lr) {
case SEQ_SIDE_LEFT:
if (test->startdisp == (seq->enddisp)) {
if (SEQ_time_left_handle_frame_get(test) == (SEQ_time_right_handle_frame_get(seq))) {
return seq;
}
break;
case SEQ_SIDE_RIGHT:
if (test->enddisp == (seq->startdisp)) {
if (SEQ_time_right_handle_frame_get(test) == (SEQ_time_left_handle_frame_get(seq))) {
return seq;
}
break;
@ -311,13 +311,18 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[
while (seq) {
if (seq->machine == (int)y) {
/* Check for both normal strips, and strips that have been flipped horizontally. */
if (((seq->startdisp < seq->enddisp) && (seq->startdisp <= x && seq->enddisp >= x)) ||
((seq->startdisp > seq->enddisp) && (seq->startdisp >= x && seq->enddisp <= x))) {
if (((SEQ_time_left_handle_frame_get(seq) < SEQ_time_right_handle_frame_get(seq)) &&
(SEQ_time_left_handle_frame_get(seq) <= x &&
SEQ_time_right_handle_frame_get(seq) >= x)) ||
((SEQ_time_left_handle_frame_get(seq) > SEQ_time_right_handle_frame_get(seq)) &&
(SEQ_time_left_handle_frame_get(seq) >= x &&
SEQ_time_right_handle_frame_get(seq) <= x))) {
if (SEQ_transform_sequence_can_be_translated(seq)) {
/* Clamp handles to defined size in pixel space. */
handsize = 2.0f * sequence_handle_size_get_clamped(seq, pixelx);
displen = (float)abs(seq->startdisp - seq->enddisp);
displen = (float)abs(SEQ_time_left_handle_frame_get(seq) -
SEQ_time_right_handle_frame_get(seq));
/* Don't even try to grab the handles of small strips. */
if (displen / pixelx > 16) {
@ -332,10 +337,10 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[
CLAMP(handsize, 7 * pixelx, 30 * pixelx);
}
if (handsize + seq->startdisp >= x) {
if (handsize + SEQ_time_left_handle_frame_get(seq) >= x) {
*hand = SEQ_SIDE_LEFT;
}
else if (-handsize + seq->enddisp <= x) {
else if (-handsize + SEQ_time_right_handle_frame_get(seq) <= x) {
*hand = SEQ_SIDE_RIGHT;
}
}
@ -578,8 +583,8 @@ static void sequencer_select_side_of_frame(const bContext *C,
const float x = UI_view2d_region_to_view_x(v2d, mval[0]);
LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(ed)) {
if (((x < CFRA) && (seq_iter->enddisp <= CFRA)) ||
((x >= CFRA) && (seq_iter->startdisp >= CFRA))) {
if (((x < CFRA) && (SEQ_time_right_handle_frame_get(seq_iter) <= CFRA)) ||
((x >= CFRA) && (SEQ_time_left_handle_frame_get(seq_iter) >= CFRA))) {
/* Select left or right. */
seq_iter->flag |= SELECT;
recurs_sel_seq(seq_iter);
@ -634,7 +639,8 @@ static void sequencer_select_linked_handle(const bContext *C,
case SEQ_SIDE_LEFT:
if ((seq->flag & SEQ_LEFTSEL) && (neighbor->flag & SEQ_RIGHTSEL)) {
seq->flag |= SELECT;
select_active_side(ed->seqbasep, SEQ_SIDE_LEFT, seq->machine, seq->startdisp);
select_active_side(
ed->seqbasep, SEQ_SIDE_LEFT, seq->machine, SEQ_time_left_handle_frame_get(seq));
}
else {
seq->flag |= SELECT;
@ -647,7 +653,8 @@ static void sequencer_select_linked_handle(const bContext *C,
case SEQ_SIDE_RIGHT:
if ((seq->flag & SEQ_RIGHTSEL) && (neighbor->flag & SEQ_LEFTSEL)) {
seq->flag |= SELECT;
select_active_side(ed->seqbasep, SEQ_SIDE_RIGHT, seq->machine, seq->startdisp);
select_active_side(
ed->seqbasep, SEQ_SIDE_RIGHT, seq->machine, SEQ_time_left_handle_frame_get(seq));
}
else {
seq->flag |= SELECT;
@ -661,7 +668,8 @@ static void sequencer_select_linked_handle(const bContext *C,
}
else {
select_active_side(ed->seqbasep, sel_side, seq->machine, seq->startdisp);
select_active_side(
ed->seqbasep, sel_side, seq->machine, SEQ_time_left_handle_frame_get(seq));
}
}
}
@ -1428,10 +1436,10 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op)
bool test = false;
switch (side) {
case -1:
test = (timeline_frame >= seq->enddisp);
test = (timeline_frame >= SEQ_time_right_handle_frame_get(seq));
break;
case 1:
test = (timeline_frame <= seq->startdisp);
test = (timeline_frame <= SEQ_time_left_handle_frame_get(seq));
break;
case 2:
test = SEQ_time_strip_intersects_frame(seq, timeline_frame);
@ -1505,10 +1513,10 @@ static int sequencer_select_side_exec(bContext *C, wmOperator *op)
if (seq->flag & SELECT) {
selected = true;
if (sel_side == SEQ_SIDE_LEFT) {
*frame_limit_p = max_ii(*frame_limit_p, seq->startdisp);
*frame_limit_p = max_ii(*frame_limit_p, SEQ_time_left_handle_frame_get(seq));
}
else {
*frame_limit_p = min_ii(*frame_limit_p, seq->startdisp);
*frame_limit_p = min_ii(*frame_limit_p, SEQ_time_left_handle_frame_get(seq));
}
}
}
@ -1648,7 +1656,7 @@ static int sequencer_box_select_exec(bContext *C, wmOperator *op)
float handsize = sequence_handle_size_get_clamped(seq, pixelx);
/* Right handle. */
if (rectf.xmax > (seq->enddisp - handsize)) {
if (rectf.xmax > (SEQ_time_right_handle_frame_get(seq) - handsize)) {
if (select) {
seq->flag |= SELECT | SEQ_RIGHTSEL;
}
@ -1661,7 +1669,7 @@ static int sequencer_box_select_exec(bContext *C, wmOperator *op)
}
}
/* Left handle. */
if (rectf.xmin < (seq->startdisp + handsize)) {
if (rectf.xmin < (SEQ_time_left_handle_frame_get(seq) + handsize)) {
if (select) {
seq->flag |= SELECT | SEQ_LEFTSEL;
}
@ -1953,7 +1961,8 @@ static bool select_grouped_time_overlap(SeqCollection *strips,
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, strips) {
if (seq->startdisp < actseq->enddisp && seq->enddisp > actseq->startdisp) {
if (SEQ_time_left_handle_frame_get(seq) < SEQ_time_right_handle_frame_get(actseq) &&
SEQ_time_right_handle_frame_get(seq) > SEQ_time_left_handle_frame_get(actseq)) {
seq->flag |= SELECT;
changed = true;
}
@ -1971,8 +1980,10 @@ static void query_lower_channel_strips(Sequence *seq_reference,
if (seq_test->machine > seq_reference->machine) {
continue; /* Not lower channel. */
}
if (seq_test->enddisp <= seq_reference->startdisp ||
seq_test->startdisp >= seq_reference->enddisp) {
if (SEQ_time_right_handle_frame_get(seq_test) <=
SEQ_time_left_handle_frame_get(seq_reference) ||
SEQ_time_left_handle_frame_get(seq_test) >=
SEQ_time_right_handle_frame_get(seq_reference)) {
continue; /* Not intersecting in time. */
}
SEQ_collection_append_strip(seq_test, collection);

View File

@ -74,10 +74,10 @@ static bool check_seq_need_thumbnails(Sequence *seq, rctf *view_area)
if (!ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE)) {
return false;
}
if (min_ii(seq->startdisp, seq->start) > view_area->xmax) {
if (min_ii(SEQ_time_left_handle_frame_get(seq), seq->start) > view_area->xmax) {
return false;
}
if (max_ii(seq->enddisp, seq->start + seq->len) < view_area->xmin) {
if (max_ii(SEQ_time_right_handle_frame_get(seq), seq->start + seq->len) < view_area->xmin) {
return false;
}
if (seq->machine + 1.0f < view_area->ymin) {
@ -206,7 +206,7 @@ static GHash *sequencer_thumbnail_ghash_init(const bContext *C, View2D *v2d, Edi
else {
if (val_need_update != NULL) {
val_need_update->seq_dupli->start = seq->start;
val_need_update->seq_dupli->startdisp = seq->startdisp;
val_need_update->seq_dupli->startdisp = SEQ_time_left_handle_frame_get(seq);
}
}
}
@ -363,15 +363,16 @@ static int sequencer_thumbnail_closest_previous_frame_get(int timeline_frame,
static int sequencer_thumbnail_closest_guaranteed_frame_get(Sequence *seq, int timeline_frame)
{
if (timeline_frame <= seq->startdisp) {
return seq->startdisp;
if (timeline_frame <= SEQ_time_left_handle_frame_get(seq)) {
return SEQ_time_left_handle_frame_get(seq);
}
/* Set of "guaranteed" thumbnails. */
const int frame_index = timeline_frame - seq->startdisp;
const int frame_index = timeline_frame - SEQ_time_left_handle_frame_get(seq);
const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(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->startdisp;
const int nearest_guaranted_absolute_frame = relative_base_frame +
SEQ_time_left_handle_frame_get(seq);
return nearest_guaranted_absolute_frame;
}
@ -444,10 +445,11 @@ void draw_seq_strip_thumbnail(View2D *v2d,
float thumb_y_end = y1 + thumb_height;
float cut_off = 0;
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);
if (seq->type == SEQ_TYPE_IMAGE) {
upper_thumb_bound = seq->enddisp;
upper_thumb_bound = SEQ_time_right_handle_frame_get(seq);
}
float timeline_frame = SEQ_render_thumbnail_first_frame_get(seq, thumb_width, &v2d->cur);
@ -473,8 +475,8 @@ void draw_seq_strip_thumbnail(View2D *v2d,
}
/* Set the clipping bound to show the left handle moving over thumbs and not shift thumbs. */
if (IN_RANGE_INCL(seq->startdisp, timeline_frame, thumb_x_end)) {
cut_off = seq->startdisp - timeline_frame;
if (IN_RANGE_INCL(SEQ_time_left_handle_frame_get(seq), timeline_frame, thumb_x_end)) {
cut_off = SEQ_time_left_handle_frame_get(seq) - timeline_frame;
clipped = true;
}

View File

@ -306,8 +306,8 @@ static void seq_view_collection_rect_timeline(Scene *scene, SeqCollection *strip
int xmargin = FPS;
SEQ_ITERATOR_FOREACH (seq, strips) {
xmin = min_ii(xmin, seq->startdisp);
xmax = max_ii(xmax, seq->enddisp);
xmin = min_ii(xmin, SEQ_time_left_handle_frame_get(seq));
xmax = max_ii(xmax, SEQ_time_right_handle_frame_get(seq));
ymin = min_ii(ymin, seq->machine);
ymax = max_ii(ymax, seq->machine);

View File

@ -278,8 +278,6 @@ static void seq_transform_cancel(TransInfo *t, SeqCollection *transformed_strips
if (SEQ_transform_test_overlap(seqbase, seq)) {
SEQ_transform_seqbase_shuffle(seqbase, seq, t->scene);
}
SEQ_time_update_sequence(t->scene, seqbase, seq);
}
}
@ -313,43 +311,19 @@ static SeqCollection *query_right_side_strips(ListBase *seqbase, SeqCollection *
{
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, transformed_strips) {
minframe = min_ii(minframe, seq->startdisp);
minframe = min_ii(minframe, SEQ_time_left_handle_frame_get(seq));
}
}
SeqCollection *collection = SEQ_collection_create(__func__);
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
if ((seq->flag & SELECT) == 0 && seq->startdisp >= minframe) {
if ((seq->flag & SELECT) == 0 && SEQ_time_left_handle_frame_get(seq) >= minframe) {
SEQ_collection_append_strip(seq, collection);
}
}
return collection;
}
static void seq_transform_update_effects(Scene *scene,
ListBase *seqbasep,
SeqCollection *collection)
{
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, collection) {
if ((seq->type & SEQ_TYPE_EFFECT) && (seq->seq1 || seq->seq2 || seq->seq3)) {
SEQ_time_update_sequence(scene, seqbasep, seq);
}
}
}
/* Check if effect strips with input are transformed. */
static bool seq_transform_check_strip_effects(SeqCollection *transformed_strips)
{
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, transformed_strips) {
if ((seq->type & SEQ_TYPE_EFFECT) && (seq->seq1 || seq->seq2 || seq->seq3)) {
return true;
}
}
return false;
}
static ListBase *seqbase_active_get(const TransInfo *t)
{
Editing *ed = SEQ_editing_get(t->scene);
@ -388,7 +362,6 @@ static void seq_transform_handle_expand_to_fit(Scene *scene,
* SEQ_transform_handle_overlap. */
SEQ_transform_seqbase_shuffle_time(
right_side_strips, seqbasep, scene, markers, use_sync_markers);
seq_transform_update_effects(scene, seqbasep, right_side_strips);
SEQ_collection_free(right_side_strips);
}
@ -434,16 +407,20 @@ typedef enum eOvelapDescrition {
static eOvelapDescrition overlap_description_get(const Sequence *transformed,
const Sequence *target)
{
if (transformed->startdisp <= target->startdisp && transformed->enddisp >= target->enddisp) {
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)) {
return STRIP_OVERLAP_IS_FULL;
}
if (transformed->startdisp > target->startdisp && transformed->enddisp < target->enddisp) {
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)) {
return STRIP_OVERLAP_IS_INSIDE;
}
if (transformed->startdisp <= target->startdisp && target->startdisp <= transformed->enddisp) {
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)) {
return STRIP_OVERLAP_LEFT_SIDE;
}
if (transformed->startdisp <= target->enddisp && target->enddisp <= transformed->enddisp) {
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)) {
return STRIP_OVERLAP_RIGHT_SIDE;
}
return STRIP_OVERLAP_NONE;
@ -459,10 +436,20 @@ static void seq_transform_handle_overwrite_split(Scene *scene,
* NULL here. */
Main *bmain = NULL;
Sequence *split_strip = SEQ_edit_strip_split(
bmain, scene, seqbasep, target, transformed->startdisp, SEQ_SPLIT_SOFT, NULL);
SEQ_edit_strip_split(
bmain, scene, seqbasep, split_strip, transformed->enddisp, SEQ_SPLIT_SOFT, NULL);
Sequence *split_strip = SEQ_edit_strip_split(bmain,
scene,
seqbasep,
target,
SEQ_time_left_handle_frame_get(transformed),
SEQ_SPLIT_SOFT,
NULL);
SEQ_edit_strip_split(bmain,
scene,
seqbasep,
split_strip,
SEQ_time_right_handle_frame_get(transformed),
SEQ_SPLIT_SOFT,
NULL);
SEQ_edit_flag_for_removal(scene, seqbasep, split_strip);
SEQ_edit_remove_flagged_sequences(scene, seqbasep);
}
@ -489,14 +476,12 @@ static void seq_transform_handle_overwrite_trim(Scene *scene,
continue;
}
if (overlap == STRIP_OVERLAP_LEFT_SIDE) {
SEQ_time_left_handle_frame_set(seq, transformed->enddisp);
SEQ_time_left_handle_frame_set(scene, seq, SEQ_time_right_handle_frame_get(transformed));
}
else {
BLI_assert(overlap == STRIP_OVERLAP_RIGHT_SIDE);
SEQ_time_right_handle_frame_set(seq, transformed->startdisp);
SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(transformed));
}
SEQ_time_update_sequence(scene, seqbasep, seq);
}
SEQ_collection_free(targets);
}
@ -577,11 +562,6 @@ void SEQ_transform_handle_overlap(Scene *scene,
break;
}
if (seq_transform_check_strip_effects(transformed_strips)) {
/* Update effect strips based on strips just moved in time. */
seq_transform_update_effects(scene, seqbasep, transformed_strips);
}
/* If any effects still overlap, we need to move them up.
* In some cases other strips can be overlapping still, see T90646. */
Sequence *seq;
@ -635,10 +615,7 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c
SEQ_transform_handle_overlap(scene, seqbasep, transformed_strips, use_sync_markers);
}
seq_transform_update_effects(scene, seqbasep, transformed_strips);
SEQ_collection_free(transformed_strips);
SEQ_sort(ed->seqbasep);
DEG_id_tag_update(&t->scene->id, ID_RECALC_SEQUENCER_STRIPS);
free_transform_custom_data(custom_data);
}
@ -662,7 +639,10 @@ typedef enum SeqInputSide {
static Sequence *effect_input_get(Sequence *effect, SeqInputSide side)
{
Sequence *input = effect->seq1;
if (effect->seq2 && (effect->seq2->startdisp - effect->seq1->startdisp) * side > 0) {
if (effect->seq2 && (SEQ_time_left_handle_frame_get(effect->seq2) -
SEQ_time_left_handle_frame_get(effect->seq1)) *
side >
0) {
input = effect->seq2;
}
return input;
@ -825,23 +805,6 @@ void createTransSeqData(TransInfo *t)
/** \name UVs Transform Flush
* \{ */
/* commented _only_ because the meta may have animation data which
* needs moving too T28158. */
BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int sel_flag)
{
/* Calculate this strip and all nested strips.
* Children are ALWAYS transformed first so we don't need to do this in another loop.
*/
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(sce));
SEQ_time_update_sequence(sce, seqbase, seq);
if (sel_flag == SELECT) {
SEQ_offset_animdata(sce, seq, seq->start - old_start);
}
}
static void view2d_edge_pan_loc_compensate(TransInfo *t, float loc_in[2], float r_loc[2])
{
TransSeq *ts = (TransSeq *)TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
@ -914,24 +877,24 @@ static void flushTransSeq(TransInfo *t)
break;
}
case SEQ_LEFTSEL: { /* No vertical transform. */
int old_startdisp = seq->startdisp;
SEQ_time_left_handle_frame_set(seq, new_frame);
SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
SEQ_transform_fix_single_image_seq_offsets(seq);
SEQ_time_update_sequence(t->scene, seqbasep, seq);
if (abs(seq->startdisp - old_startdisp) > abs(max_offset)) {
max_offset = seq->startdisp - old_startdisp;
int old_startdisp = SEQ_time_left_handle_frame_get(seq);
SEQ_time_left_handle_frame_set(t->scene, seq, new_frame);
SEQ_transform_handle_xlimits(
t->scene, seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
SEQ_transform_fix_single_image_seq_offsets(t->scene, seq);
if (abs(SEQ_time_left_handle_frame_get(seq) - old_startdisp) > abs(max_offset)) {
max_offset = SEQ_time_left_handle_frame_get(seq) - old_startdisp;
}
break;
}
case SEQ_RIGHTSEL: { /* No vertical transform. */
int old_enddisp = seq->enddisp;
SEQ_time_right_handle_frame_set(seq, new_frame);
SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
SEQ_transform_fix_single_image_seq_offsets(seq);
SEQ_time_update_sequence(t->scene, seqbasep, seq);
if (abs(seq->enddisp - old_enddisp) > abs(max_offset)) {
max_offset = seq->enddisp - old_enddisp;
int old_enddisp = SEQ_time_right_handle_frame_get(seq);
SEQ_time_right_handle_frame_set(t->scene, seq, new_frame);
SEQ_transform_handle_xlimits(
t->scene, seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
SEQ_transform_fix_single_image_seq_offsets(t->scene, seq);
if (abs(SEQ_time_right_handle_frame_get(seq) - old_enddisp) > abs(max_offset)) {
max_offset = SEQ_time_right_handle_frame_get(seq) - old_enddisp;
}
break;
}
@ -945,15 +908,6 @@ static void flushTransSeq(TransInfo *t)
SEQ_offset_animdata(t->scene, seq, max_offset);
}
/* Update effect length and position. */
if (ELEM(t->mode, TFM_SEQ_SLIDE, TFM_TIME_TRANSLATE)) {
for (seq = seqbasep->first; seq; seq = seq->next) {
if (seq->seq1 || seq->seq2 || seq->seq3) {
SEQ_time_update_sequence(t->scene, seqbasep, seq);
}
}
}
/* need to do the overlap check in a new loop otherwise adjacent strips
* will not be updated and we'll get false positives */
SeqCollection *transformed_strips = seq_transform_collection_from_transdata(tc);

View File

@ -25,6 +25,7 @@
#include "SEQ_relations.h"
#include "SEQ_render.h"
#include "SEQ_sequencer.h"
#include "SEQ_time.h"
#include "transform.h"
#include "transform_snap.h"
@ -65,14 +66,14 @@ static void seq_snap_source_points_build(TransSeqSnapData *snap_data, SeqCollect
SEQ_ITERATOR_FOREACH (seq, snap_sources) {
int left = 0, right = 0;
if (seq->flag & SEQ_LEFTSEL) {
left = right = seq->startdisp;
left = right = SEQ_time_left_handle_frame_get(seq);
}
else if (seq->flag & SEQ_RIGHTSEL) {
left = right = seq->enddisp;
left = right = SEQ_time_right_handle_frame_get(seq);
}
else {
left = seq->startdisp;
right = seq->enddisp;
left = SEQ_time_left_handle_frame_get(seq);
right = SEQ_time_right_handle_frame_get(seq);
}
snap_data->source_snap_points[i] = left;
@ -193,21 +194,24 @@ static void seq_snap_target_points_build(Scene *scene,
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, snap_targets) {
snap_data->target_snap_points[i] = seq->startdisp;
snap_data->target_snap_points[i + 1] = seq->enddisp;
snap_data->target_snap_points[i] = SEQ_time_left_handle_frame_get(seq);
snap_data->target_snap_points[i + 1] = SEQ_time_right_handle_frame_get(seq);
i += 2;
if (snap_mode & SEQ_SNAP_TO_STRIP_HOLD) {
int content_start = min_ii(seq->enddisp, seq->start);
int content_end = max_ii(seq->startdisp, seq->start + seq->len);
int content_start = min_ii(SEQ_time_right_handle_frame_get(seq), seq->start);
int content_end = max_ii(SEQ_time_left_handle_frame_get(seq), seq->start + seq->len);
/* Effects and single image strips produce incorrect content length. Skip these strips. */
if ((seq->type & SEQ_TYPE_EFFECT) != 0 || seq->len == 1) {
content_start = seq->startdisp;
content_end = seq->enddisp;
content_start = SEQ_time_left_handle_frame_get(seq);
content_end = SEQ_time_right_handle_frame_get(seq);
}
CLAMP(content_start, seq->startdisp, seq->enddisp);
CLAMP(content_end, seq->startdisp, seq->enddisp);
CLAMP(content_start,
SEQ_time_left_handle_frame_get(seq),
SEQ_time_right_handle_frame_get(seq));
CLAMP(
content_end, SEQ_time_left_handle_frame_get(seq), SEQ_time_right_handle_frame_get(seq));
snap_data->target_snap_points[i] = content_start;
snap_data->target_snap_points[i + 1] = content_end;

View File

@ -161,11 +161,11 @@ typedef struct Sequence {
* Frames that use the first frame before data begins,
* frames that use the last frame after data ends.
*/
int startstill DNA_DEPRECATED, endstill DNA_DEPRECATED;
int startstill, endstill;
/** Machine: the strip channel */
int machine;
int _pad3;
/** Starting and ending points of the strip in the sequence. */
/** Starting and ending points of the effect strip. Undefined for other strip types. */
int startdisp, enddisp;
float sat;
float mul;

View File

@ -240,7 +240,7 @@ static int rna_SequenceEditor_sequences_all_lookup_string(PointerRNA *ptr,
ID *id = ptr->owner_id;
Scene *scene = (Scene *)id;
Sequence *seq = SEQ_sequence_lookup_by_name(scene, key);
Sequence *seq = SEQ_sequence_lookup_seq_by_name(scene, key);
if (seq) {
RNA_pointer_create(ptr->owner_id, &RNA_Sequence, seq, r_ptr);
return true;
@ -289,26 +289,11 @@ static void rna_Sequence_views_format_update(Main *bmain, Scene *scene, PointerR
static void do_sequence_frame_change_update(Scene *scene, Sequence *seq)
{
Editing *ed = SEQ_editing_get(scene);
ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq);
Sequence *tseq;
SEQ_time_update_sequence(scene, seqbase, seq);
/* ensure effects are always fit in length to their input */
/* TODO(sergey): probably could be optimized.
* in terms skipping update of non-changing strips
*/
for (tseq = seqbase->first; tseq; tseq = tseq->next) {
if (tseq->seq1 || tseq->seq2 || tseq->seq3) {
SEQ_time_update_sequence(scene, seqbase, tseq);
}
}
ListBase *seqbase = SEQ_get_seqbase_by_seq(scene, seq);
if (SEQ_transform_test_overlap(seqbase, seq)) {
SEQ_transform_seqbase_shuffle(seqbase, seq, scene); /* XXX: BROKEN!, uses context seqbasep. */
SEQ_transform_seqbase_shuffle(seqbase, seq, scene);
}
SEQ_sort(seqbase);
if (seq->type == SEQ_TYPE_SOUND_RAM) {
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
@ -341,8 +326,8 @@ static void rna_Sequence_start_frame_final_set(PointerRNA *ptr, int value)
Sequence *seq = (Sequence *)ptr->data;
Scene *scene = (Scene *)ptr->owner_id;
SEQ_time_left_handle_frame_set(seq, value);
SEQ_transform_fix_single_image_seq_offsets(seq);
SEQ_time_left_handle_frame_set(scene, seq, value);
SEQ_transform_fix_single_image_seq_offsets(scene, seq);
do_sequence_frame_change_update(scene, seq);
SEQ_relations_invalidate_cache_composite(scene, seq);
}
@ -352,8 +337,8 @@ static void rna_Sequence_end_frame_final_set(PointerRNA *ptr, int value)
Sequence *seq = (Sequence *)ptr->data;
Scene *scene = (Scene *)ptr->owner_id;
SEQ_time_right_handle_frame_set(seq, value);
SEQ_transform_fix_single_image_seq_offsets(seq);
SEQ_time_right_handle_frame_set(scene, seq, value);
SEQ_transform_fix_single_image_seq_offsets(scene, seq);
do_sequence_frame_change_update(scene, seq);
SEQ_relations_invalidate_cache_composite(scene, seq);
}
@ -437,7 +422,7 @@ static void rna_Sequence_frame_length_set(PointerRNA *ptr, int value)
Sequence *seq = (Sequence *)ptr->data;
Scene *scene = (Scene *)ptr->owner_id;
SEQ_time_right_handle_frame_set(seq, SEQ_time_left_handle_frame_get(seq) + value);
SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(seq) + value);
do_sequence_frame_change_update(scene, seq);
SEQ_relations_invalidate_cache_composite(scene, seq);
}
@ -459,18 +444,15 @@ static void rna_Sequence_channel_set(PointerRNA *ptr, int value)
{
Sequence *seq = (Sequence *)ptr->data;
Scene *scene = (Scene *)ptr->owner_id;
Editing *ed = SEQ_editing_get(scene);
ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq);
ListBase *seqbase = SEQ_get_seqbase_by_seq(scene, seq);
/* check channel increment or decrement */
const int channel_delta = (value >= seq->machine) ? 1 : -1;
seq->machine = value;
if (SEQ_transform_test_overlap(seqbase, seq)) {
/* XXX: BROKEN!, uses context seqbasep. */
SEQ_transform_seqbase_shuffle_ex(seqbase, seq, scene, channel_delta);
}
SEQ_sort(seqbase);
SEQ_relations_invalidate_cache_composite(scene, seq);
}
@ -722,8 +704,6 @@ static IDProperty **rna_Sequence_idprops(PointerRNA *ptr)
static bool rna_MovieSequence_reload_if_needed(ID *scene_id, Sequence *seq, Main *bmain)
{
Scene *scene = (Scene *)scene_id;
Editing *ed = SEQ_editing_get(scene);
ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq);
bool has_reloaded;
bool can_produce_frames;
@ -731,7 +711,6 @@ static bool rna_MovieSequence_reload_if_needed(ID *scene_id, Sequence *seq, Main
SEQ_add_movie_reload_if_needed(bmain, scene, seq, &has_reloaded, &can_produce_frames);
if (has_reloaded && can_produce_frames) {
SEQ_time_update_sequence(scene, seqbase, seq);
SEQ_relations_invalidate_cache_raw(scene, seq);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
@ -919,9 +898,6 @@ static void rna_Sequence_filepath_update(Main *bmain, Scene *UNUSED(scene), Poin
Scene *scene = (Scene *)ptr->owner_id;
Sequence *seq = (Sequence *)(ptr->data);
SEQ_add_reload_new_file(bmain, scene, seq, true);
Editing *ed = SEQ_editing_get(scene);
ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq);
SEQ_time_update_sequence(scene, seqbase, seq);
rna_Sequence_invalidate_raw_update(bmain, scene, ptr);
}
@ -1337,8 +1313,7 @@ static void rna_Sequence_separate(ID *id, Sequence *seqm, Main *bmain)
Scene *scene = (Scene *)id;
/* Find the appropriate seqbase */
Editing *ed = SEQ_editing_get(scene);
ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seqm);
ListBase *seqbase = SEQ_get_seqbase_by_seq(scene, seqm);
LISTBASE_FOREACH_MUTABLE (Sequence *, seq, &seqm->seqbase) {
SEQ_edit_move_strip_to_seqbase(scene, &seqm->seqbase, seq, seqbase);

View File

@ -49,20 +49,6 @@
# include "WM_api.h"
static void rna_Sequence_update_rnafunc(ID *id, Sequence *self, bool do_data)
{
Scene *scene = (Scene *)id;
Editing *ed = SEQ_editing_get(scene);
ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, self);
if (do_data) {
SEQ_time_update_recursive(scene, self);
// new_tstripdata(self); /* need 2.6x version of this. */
}
SEQ_time_update_sequence(scene, seqbase, self);
}
static void rna_Sequence_swap_internal(Sequence *seq_self,
ReportList *reports,
Sequence *seq_other)
@ -96,8 +82,7 @@ static Sequence *rna_Sequence_split(
ID *id, Sequence *seq, Main *bmain, ReportList *reports, int frame, int split_method)
{
Scene *scene = (Scene *)id;
Editing *ed = SEQ_editing_get(scene);
ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq);
ListBase *seqbase = SEQ_get_seqbase_by_seq(scene, seq);
const char *error_msg = NULL;
Sequence *r_seq = SEQ_edit_strip_split(
@ -576,8 +561,6 @@ static void rna_Sequences_meta_remove(
static StripElem *rna_SequenceElements_append(ID *id, Sequence *seq, const char *filename)
{
Scene *scene = (Scene *)id;
Editing *ed = SEQ_editing_get(scene);
ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq);
StripElem *se;
seq->strip->stripdata = se = MEM_reallocN(seq->strip->stripdata,
@ -586,7 +569,6 @@ static StripElem *rna_SequenceElements_append(ID *id, Sequence *seq, const char
BLI_strncpy(se->name, filename, sizeof(se->name));
seq->len++;
SEQ_time_update_sequence(scene, seqbase, seq);
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);
return se;
@ -595,8 +577,6 @@ static StripElem *rna_SequenceElements_append(ID *id, Sequence *seq, const char
static void rna_SequenceElements_pop(ID *id, Sequence *seq, ReportList *reports, int index)
{
Scene *scene = (Scene *)id;
Editing *ed = SEQ_editing_get(scene);
ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq);
StripElem *new_seq, *se;
if (seq->len == 1) {
@ -629,8 +609,6 @@ static void rna_SequenceElements_pop(ID *id, Sequence *seq, ReportList *reports,
MEM_freeN(seq->strip->stripdata);
seq->strip->stripdata = new_seq;
SEQ_time_update_sequence(scene, seqbase, seq);
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);
}
@ -669,11 +647,6 @@ void RNA_api_sequence_strip(StructRNA *srna)
{0, NULL, 0, NULL, NULL},
};
func = RNA_def_function(srna, "update", "rna_Sequence_update_rnafunc");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
RNA_def_function_ui_description(func, "Update the strip dimensions");
parm = RNA_def_boolean(func, "data", false, "Data", "Update strip data");
func = RNA_def_function(srna, "strip_elem_from_frame", "SEQ_render_give_stripelem");
RNA_def_function_ui_description(func, "Return the strip element from a given frame or None");
parm = RNA_def_int(func,

View File

@ -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,

View File

@ -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.
*

View File

@ -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
}

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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) {

View File

@ -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) {

View File

@ -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_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)
{
if ((seq->type & SEQ_TYPE_EFFECT) == 0) {
return;
}
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)
{
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);
}
SEQ_collection_free(all_strips);
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->by_name, key);
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->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) {

View File

@ -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

View File

@ -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 {

View File

@ -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);
}

View File

@ -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;

View File

@ -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)) {

View File

@ -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));
}
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->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);
}
/* 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->type == SEQ_TYPE_META) {
seq_time_update_meta_strip(scene, seq);
}
else {
seq_time_update_sequence_bounds(scene, seq);
if (seq->startdisp > seq->enddisp) {
SWAP(int, seq->startdisp, seq->enddisp);
}
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);
}
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);
}
return do_update;
}
void SEQ_time_update_recursive(Scene *scene, Sequence *changed_seq)
{
Editing *ed = SEQ_editing_get(scene);
Sequence *seq;
if (ed == NULL) {
if (effects == NULL) {
return;
}
for (seq = ed->seqbase.first; seq; seq = seq->next) {
update_changed_seq_recurs(scene, seq, changed_seq);
Sequence *seq;
/* First pass: Update length of immediate effects. */
SEQ_ITERATOR_FOREACH (seq, effects) {
seq_time_effect_range_set(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));
}

View File

@ -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
}

View File

@ -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)
{
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_get(SeqCollection *strips_to_shuffle,
ListBase *seqbasep,
char dir)
{
int offset = 0;
Sequence *seq;
bool all_conflicts_resolved = false;
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;
}
static int shuffle_seq_time_offset(SeqCollection *strips_to_shuffle,
ListBase *seqbasep,
Scene *scene,
char dir)
{
int ofs = 0;
int tot_ofs = 0;
Sequence *seq;
while ((ofs = shuffle_seq_time_offset_test(strips_to_shuffle, seqbasep, dir))) {
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;
}
all_conflicts_resolved = false;
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));
}
}
}
tot_ofs += ofs;
}
SEQ_ITERATOR_FOREACH (seq, strips_to_shuffle) {
SEQ_time_update_sequence(scene, seqbasep, seq); /* corrects dummy startdisp/enddisp values */
}
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);
}
}

View File

@ -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;
}