Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Antalik <richardantalik@gmail.com>2022-06-29 13:45:59 +0300
committerRichard Antalik <richardantalik@gmail.com>2022-06-29 13:48:34 +0300
commit302b04a5a3fc0e767ac784424f78ce2edf5d2844 (patch)
treedef4de621fbb0a194b350da781f054c6aefbab35 /source/blender/editors/space_sequencer/sequencer_edit.c
parentc51b8ec86364585c4088837c603b39752065bc34 (diff)
VSE: Improved Retiming system
Patch implements better way to control playback speed than it is possible to do with speed effect. Speed factor property can be set in Time panel. There are 2 layers of control: Option to retime movie to match scene FPS rate. Custom speed factor to control playback rate. Since playback rate is strip property, it is now possible to manipulate strip as normal one even if it is retimed. To facilitate manipulation, some functions need to consider speed factor and apply necessary corrections to strip offset or strip start. These corrections may need to be float numbers, so start and offsets must be float as well. Sound strips now use speed factor instead of pitch. This means, that strips will change length to match usable length. In addition, it is possible to group movie and sound strip and change speed of meta strip.
Diffstat (limited to 'source/blender/editors/space_sequencer/sequencer_edit.c')
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c130
1 files changed, 70 insertions, 60 deletions
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 76dd43586d1..d507c9ae6bc 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -81,6 +81,7 @@ typedef struct TransSeq {
int anim_startofs, anim_endofs;
/* int final_left, final_right; */ /* UNUSED */
int len;
+ float content_start;
} TransSeq;
/** \} */
@@ -369,8 +370,6 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
else { /* SEQ_RIGHTSEL */
SEQ_time_right_handle_frame_set(scene, seq, snap_frame);
}
- SEQ_transform_handle_xlimits(
- scene, seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL);
SEQ_transform_fix_single_image_seq_offsets(scene, seq);
}
}
@@ -380,7 +379,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if (seq->flag & SELECT && !SEQ_transform_is_locked(channels, seq)) {
seq->flag &= ~SEQ_OVERLAP;
- if (SEQ_transform_test_overlap(ed->seqbasep, seq)) {
+ if (SEQ_transform_test_overlap(scene, ed->seqbasep, seq)) {
SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene);
}
}
@@ -393,17 +392,20 @@ 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_time_left_handle_frame_get(seq)));
+ SEQ_offset_animdata(
+ scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(scene, seq)));
}
}
else if (seq->seq2 && (seq->seq2->flag & SELECT)) {
if (!either_handle_selected) {
- SEQ_offset_animdata(scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(seq)));
+ SEQ_offset_animdata(
+ scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(scene, seq)));
}
}
else if (seq->seq3 && (seq->seq3->flag & SELECT)) {
if (!either_handle_selected) {
- SEQ_offset_animdata(scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(seq)));
+ SEQ_offset_animdata(
+ scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(scene, seq)));
}
}
}
@@ -473,6 +475,7 @@ typedef struct SlipData {
static void transseq_backup(TransSeq *ts, Sequence *seq)
{
+ ts->content_start = SEQ_time_start_frame_get(seq);
ts->start = seq->start;
ts->machine = seq->machine;
ts->startofs = seq->startofs;
@@ -603,7 +606,7 @@ static void sequencer_slip_recursively(Scene *scene, SlipData *data, int offset)
}
/* Make sure, that each strip contains at least 1 frame of content. */
-static void sequencer_slip_apply_limits(SlipData *data, int *offset)
+static void sequencer_slip_apply_limits(const Scene *scene, SlipData *data, int *offset)
{
for (int i = 0; i < data->num_seq; i++) {
if (data->trim[i]) {
@@ -612,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_time_right_handle_frame_get(seq)) {
- diff = SEQ_time_right_handle_frame_get(seq) - seq_content_start - 1;
+ if (seq_content_start >= SEQ_time_right_handle_frame_get(scene, seq)) {
+ diff = SEQ_time_right_handle_frame_get(scene, seq) - seq_content_start - 1;
}
- if (seq_content_end <= SEQ_time_left_handle_frame_get(seq)) {
- diff = SEQ_time_left_handle_frame_get(seq) - seq_content_end + 1;
+ if (seq_content_end <= SEQ_time_left_handle_frame_get(scene, seq)) {
+ diff = SEQ_time_left_handle_frame_get(scene, seq) - seq_content_end + 1;
}
*offset += diff;
}
@@ -649,7 +652,7 @@ static int sequencer_slip_exec(bContext *C, wmOperator *op)
transseq_backup(data->ts + i, data->seq_array[i]);
}
- sequencer_slip_apply_limits(data, &offset);
+ sequencer_slip_apply_limits(scene, data, &offset);
sequencer_slip_recursively(scene, data, offset);
MEM_freeN(data->seq_array);
@@ -695,7 +698,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
applyNumInput(&data->num_input, &offset_fl);
int offset = round_fl_to_int(offset_fl);
- sequencer_slip_apply_limits(data, &offset);
+ sequencer_slip_apply_limits(scene, data, &offset);
sequencer_slip_update_header(scene, area, data, offset);
RNA_int_set(op->ptr, "offset", offset);
@@ -727,7 +730,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
UI_view2d_region_to_view(v2d, mouse_x, 0, &mouseloc[0], &mouseloc[1]);
offset = mouseloc[0] - data->init_mouseloc[0];
- sequencer_slip_apply_limits(data, &offset);
+ sequencer_slip_apply_limits(scene, data, &offset);
sequencer_slip_update_header(scene, area, data, offset);
RNA_int_set(op->ptr, "offset", offset);
@@ -804,7 +807,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
applyNumInput(&data->num_input, &offset_fl);
int offset = round_fl_to_int(offset_fl);
- sequencer_slip_apply_limits(data, &offset);
+ sequencer_slip_apply_limits(scene, data, &offset);
sequencer_slip_update_header(scene, area, data, offset);
RNA_int_set(op->ptr, "offset", offset);
@@ -1052,7 +1055,7 @@ static int sequencer_reload_exec(bContext *C, wmOperator *op)
SEQ_add_reload_new_file(bmain, scene, seq, !adjust_length);
if (adjust_length) {
- if (SEQ_transform_test_overlap(ed->seqbasep, seq)) {
+ if (SEQ_transform_test_overlap(scene, ed->seqbasep, seq)) {
SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene);
}
}
@@ -1415,14 +1418,14 @@ 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_time_right_handle_frame_get(seq) == split_frame &&
+ if (SEQ_time_right_handle_frame_get(scene, 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_time_left_handle_frame_get(seq) == split_frame &&
+ if (SEQ_time_left_handle_frame_get(scene, seq) == split_frame &&
seq->machine == split_channel) {
seq->flag &= ~SEQ_ALLSEL;
}
@@ -1434,12 +1437,12 @@ 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_time_left_handle_frame_get(seq) >= split_frame) {
+ if (SEQ_time_left_handle_frame_get(scene, seq) >= split_frame) {
seq->flag &= ~SEQ_ALLSEL;
}
}
else {
- if (SEQ_time_right_handle_frame_get(seq) <= split_frame) {
+ if (SEQ_time_right_handle_frame_get(scene, seq) <= split_frame) {
seq->flag &= ~SEQ_ALLSEL;
}
}
@@ -1766,7 +1769,7 @@ static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op))
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) {
- if (SEQ_transform_test_overlap(ed->seqbasep, seq)) {
+ if (SEQ_transform_test_overlap(scene, ed->seqbasep, seq)) {
SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene);
}
}
@@ -1825,12 +1828,12 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
/* TODO: remove f-curve and assign to split image strips.
* The old animation system would remove the user of `seq->ipo`. */
- start_ofs = timeline_frame = SEQ_time_left_handle_frame_get(seq);
- frame_end = SEQ_time_right_handle_frame_get(seq);
+ start_ofs = timeline_frame = SEQ_time_left_handle_frame_get(scene, seq);
+ frame_end = SEQ_time_right_handle_frame_get(scene, seq);
while (timeline_frame < frame_end) {
/* New seq. */
- se = SEQ_render_give_stripelem(seq, timeline_frame);
+ se = SEQ_render_give_stripelem(scene, seq, timeline_frame);
seq_new = SEQ_sequence_dupli_recursive(scene, scene, seqbase, seq, SEQ_DUPE_UNIQUE_NAME);
@@ -1852,7 +1855,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
if (step > 1) {
seq_new->flag &= ~SEQ_OVERLAP;
- if (SEQ_transform_test_overlap(seqbase, seq_new)) {
+ if (SEQ_transform_test_overlap(scene, seqbase, seq_new)) {
SEQ_transform_seqbase_shuffle(seqbase, seq_new, scene);
}
}
@@ -1978,8 +1981,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_time_left_handle_frame_get(seq), meta_start_frame);
- meta_end_frame = max_ii(SEQ_time_right_handle_frame_get(seq), meta_end_frame);
+ meta_start_frame = min_ii(SEQ_time_left_handle_frame_get(scene, seq), meta_start_frame);
+ meta_end_frame = max_ii(SEQ_time_right_handle_frame_get(scene, seq), meta_end_frame);
}
}
@@ -1989,7 +1992,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
seqm->start = meta_start_frame;
seqm->len = meta_end_frame - meta_start_frame;
SEQ_select_active_set(scene, seqm);
- if (SEQ_transform_test_overlap(active_seqbase, seqm)) {
+ if (SEQ_transform_test_overlap(scene, active_seqbase, seqm)) {
SEQ_transform_seqbase_shuffle(active_seqbase, seqm, scene);
}
@@ -2049,7 +2052,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
LISTBASE_FOREACH (Sequence *, seq, active_seqbase) {
if (seq->flag & SELECT) {
seq->flag &= ~SEQ_OVERLAP;
- if (SEQ_transform_test_overlap(active_seqbase, seq)) {
+ if (SEQ_transform_test_overlap(scene, active_seqbase, seq)) {
SEQ_transform_seqbase_shuffle(active_seqbase, seq, scene);
}
}
@@ -2160,17 +2163,18 @@ static const EnumPropertyItem prop_side_lr_types[] = {
static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb)
{
- int gap = SEQ_time_left_handle_frame_get(seqb) - SEQ_time_right_handle_frame_get(seqa);
+ int gap = SEQ_time_left_handle_frame_get(scene, seqb) -
+ SEQ_time_right_handle_frame_get(scene, seqa);
int seq_a_start;
int seq_b_start;
- seq_b_start = (seqb->start - SEQ_time_left_handle_frame_get(seqb)) +
- SEQ_time_left_handle_frame_get(seqa);
+ seq_b_start = (seqb->start - SEQ_time_left_handle_frame_get(scene, seqb)) +
+ SEQ_time_left_handle_frame_get(scene, seqa);
SEQ_transform_translate_sequence(scene, seqb, seq_b_start - seqb->start);
SEQ_relations_invalidate_cache_preprocessed(scene, seqb);
- seq_a_start = (seqa->start - SEQ_time_left_handle_frame_get(seqa)) +
- SEQ_time_right_handle_frame_get(seqb) + gap;
+ seq_a_start = (seqa->start - SEQ_time_left_handle_frame_get(scene, seqa)) +
+ SEQ_time_right_handle_frame_get(scene, seqb) + gap;
SEQ_transform_translate_sequence(scene, seqa, seq_a_start - seqa->start);
SEQ_relations_invalidate_cache_preprocessed(scene, seqa);
}
@@ -2196,13 +2200,17 @@ static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, i
switch (lr) {
case SEQ_SIDE_LEFT:
- 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);
+ if (SEQ_time_right_handle_frame_get(scene, seq) <=
+ SEQ_time_left_handle_frame_get(scene, test)) {
+ dist = SEQ_time_right_handle_frame_get(scene, test) -
+ SEQ_time_left_handle_frame_get(scene, seq);
}
break;
case SEQ_SIDE_RIGHT:
- 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);
+ if (SEQ_time_left_handle_frame_get(scene, seq) >=
+ SEQ_time_right_handle_frame_get(scene, test)) {
+ dist = SEQ_time_left_handle_frame_get(scene, seq) -
+ SEQ_time_right_handle_frame_get(scene, test);
}
break;
}
@@ -2267,7 +2275,7 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op)
if ((iseq->type & SEQ_TYPE_EFFECT) &&
(seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) {
/* This may now overlap. */
- if (SEQ_transform_test_overlap(seqbase, iseq)) {
+ if (SEQ_transform_test_overlap(scene, seqbase, iseq)) {
SEQ_transform_seqbase_shuffle(seqbase, iseq, scene);
}
}
@@ -2317,7 +2325,7 @@ static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op))
switch (active_seq->type) {
case SEQ_TYPE_IMAGE:
- se = SEQ_render_give_stripelem(active_seq, scene->r.cfra);
+ se = SEQ_render_give_stripelem(scene, active_seq, scene->r.cfra);
break;
case SEQ_TYPE_MOVIE:
se = active_seq->strip->stripdata;
@@ -2528,8 +2536,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_time_left_handle_frame_get(seq) < min_seq_startdisp) {
- min_seq_startdisp = SEQ_time_left_handle_frame_get(seq);
+ if (SEQ_time_left_handle_frame_get(scene, seq) < min_seq_startdisp) {
+ min_seq_startdisp = SEQ_time_left_handle_frame_get(scene, seq);
}
}
/* Paste strips relative to the current-frame. */
@@ -2575,7 +2583,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
* strip. */
SEQ_transform_translate_sequence(scene, iseq, ofs);
/* Ensure, that pasted strips don't overlap. */
- if (SEQ_transform_test_overlap(ed->seqbasep, iseq)) {
+ if (SEQ_transform_test_overlap(scene, ed->seqbasep, iseq)) {
SEQ_transform_seqbase_shuffle(ed->seqbasep, iseq, scene);
}
}
@@ -2632,7 +2640,7 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- if (SEQ_edit_sequence_swap(seq_act, seq_other, &error_msg) == 0) {
+ if (SEQ_edit_sequence_swap(scene, seq_act, seq_other, &error_msg) == 0) {
BKE_report(op->reports, RPT_ERROR, error_msg);
return OPERATOR_CANCELLED;
}
@@ -3057,15 +3065,16 @@ void SEQUENCER_OT_change_scene(struct wmOperatorType *ot)
* \{ */
/** Comparison function suitable to be used with BLI_listbase_sort(). */
-static int seq_cmp_time_startdisp_channel(const void *a, const void *b)
+static int seq_cmp_time_startdisp_channel(void *thunk, const void *a, const void *b)
{
+ const Scene *scene = thunk;
Sequence *seq_a = (Sequence *)a;
Sequence *seq_b = (Sequence *)b;
- int seq_a_start = SEQ_time_left_handle_frame_get(seq_a);
- int seq_b_start = SEQ_time_left_handle_frame_get(seq_b);
+ int seq_a_start = SEQ_time_left_handle_frame_get(scene, seq_a);
+ int seq_b_start = SEQ_time_left_handle_frame_get(scene, seq_b);
- /* If strips have the same start frame favor the one with a higher channel. */
+ /* If strips have the same start frame favor the one with a higher channel.*/
if (seq_a_start == seq_b_start) {
return seq_a->machine > seq_b->machine;
}
@@ -3109,7 +3118,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_time_right_handle_frame_get(seq) > cd->scene->r.sfra)) {
+ (SEQ_time_right_handle_frame_get(cd->scene, seq) > cd->scene->r.sfra)) {
BLI_addtail(cd->text_seq, MEM_dupallocN(seq));
}
return true;
@@ -3156,7 +3165,7 @@ static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BLI_listbase_sort(&text_seq, seq_cmp_time_startdisp_channel);
+ BLI_listbase_sort_r(&text_seq, seq_cmp_time_startdisp_channel, scene);
/* Open and write file. */
file = BLI_fopen(filepath, "w");
@@ -3171,15 +3180,16 @@ static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op)
timecode_str_start,
sizeof(timecode_str_start),
-2,
- FRA2TIME(max_ii(SEQ_time_left_handle_frame_get(seq) - scene->r.sfra, 0)),
+ FRA2TIME(max_ii(SEQ_time_left_handle_frame_get(scene, seq) - scene->r.sfra, 0)),
+ FPS,
+ USER_TIMECODE_SUBRIP);
+ BLI_timecode_string_from_time(
+ timecode_str_end,
+ sizeof(timecode_str_end),
+ -2,
+ FRA2TIME(SEQ_time_right_handle_frame_get(scene, seq) - scene->r.sfra),
FPS,
USER_TIMECODE_SUBRIP);
- BLI_timecode_string_from_time(timecode_str_end,
- sizeof(timecode_str_end),
- -2,
- FRA2TIME(SEQ_time_right_handle_frame_get(seq) - scene->r.sfra),
- FPS,
- USER_TIMECODE_SUBRIP);
fprintf(
file, "%d\n%s --> %s\n%s\n\n", iter++, timecode_str_start, timecode_str_end, data->text);
@@ -3245,8 +3255,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_time_left_handle_frame_get(seq));
- efra = max_ii(efra, SEQ_time_right_handle_frame_get(seq) - 1);
+ sfra = min_ii(sfra, SEQ_time_left_handle_frame_get(scene, seq));
+ efra = max_ii(efra, SEQ_time_right_handle_frame_get(scene, seq) - 1);
}
}
@@ -3399,7 +3409,7 @@ static int sequencer_strip_transform_fit_exec(bContext *C, wmOperator *op)
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if (seq->flag & SELECT && seq->type != SEQ_TYPE_SOUND_RAM) {
const int timeline_frame = CFRA;
- StripElem *strip_elem = SEQ_render_give_stripelem(seq, timeline_frame);
+ StripElem *strip_elem = SEQ_render_give_stripelem(scene, seq, timeline_frame);
if (strip_elem == NULL) {
continue;