Fix T103531: Hold split not working correctly

Incorrect offset was calculated when strip was implicitly retimed (movie
FPS does not match scene FPS). This is because strip playback rate was
not used for offset calculation at all.

Since hold offset is specifying numbers of frames to skip, but at frame
rate of the source, this could result in gap when splitting the strip.
If that occurs, gap is compensated by moving handle to frame where strip
is split.
This commit is contained in:
Richard Antalik 2023-01-09 17:55:02 +01:00
parent 891fe70d7f
commit ec2046c38d
Notes: blender-bot 2023-02-14 04:46:12 +01:00
Referenced by issue #103531, VSE HOLD SPLIT BROKEN
3 changed files with 32 additions and 21 deletions

View File

@ -258,7 +258,10 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene,
return true;
}
static void seq_split_set_right_hold_offset(Scene *scene, Sequence *seq, int timeline_frame)
static void seq_split_set_right_hold_offset(Main *bmain,
Scene *scene,
Sequence *seq,
int timeline_frame)
{
const float content_start = SEQ_time_start_frame_get(seq);
const float content_end = SEQ_time_content_end_frame_get(scene, seq);
@ -268,31 +271,35 @@ static void seq_split_set_right_hold_offset(Scene *scene, Sequence *seq, int tim
const float offset = content_start + 1 - timeline_frame;
seq->start -= offset;
seq->startofs += offset;
SEQ_time_right_handle_frame_set(scene, seq, timeline_frame);
}
/* Adjust within range of strip contents. */
else if ((timeline_frame >= content_start) && (timeline_frame <= content_end)) {
seq->endofs = 0;
seq->anim_endofs += (content_end - timeline_frame) * seq->speed_factor;
}
/* Adjust within range of extended still-frames after strip. */
else if (timeline_frame > content_end) {
SEQ_time_right_handle_frame_set(scene, seq, timeline_frame);
float speed_factor = (seq->type == SEQ_TYPE_SOUND_RAM) ?
seq_time_media_playback_rate_factor_get(scene, seq) :
seq_time_playback_rate_factor_get(scene, seq);
seq->anim_endofs += round_fl_to_int((content_end - timeline_frame) * speed_factor);
}
/* Needed only to set `seq->len`. */
SEQ_add_reload_new_file(bmain, scene, seq, false);
SEQ_time_right_handle_frame_set(scene, seq, timeline_frame);
}
static void seq_split_set_left_hold_offset(Scene *scene, Sequence *seq, int timeline_frame)
static void seq_split_set_left_hold_offset(Main *bmain,
Scene *scene,
Sequence *seq,
int timeline_frame)
{
const float content_start = SEQ_time_start_frame_get(seq);
const float content_end = SEQ_time_content_end_frame_get(scene, seq);
/* Adjust within range of extended still-frames before strip. */
if (timeline_frame < content_start) {
SEQ_time_left_handle_frame_set(scene, seq, timeline_frame);
}
/* Adjust within range of strip contents. */
else if ((timeline_frame >= content_start) && (timeline_frame <= content_end)) {
seq->anim_startofs += (timeline_frame - content_start) * seq->speed_factor;
if ((timeline_frame >= content_start) && (timeline_frame <= content_end)) {
float speed_factor = (seq->type == SEQ_TYPE_SOUND_RAM) ?
seq_time_media_playback_rate_factor_get(scene, seq) :
seq_time_playback_rate_factor_get(scene, seq);
seq->anim_startofs += round_fl_to_int((timeline_frame - content_start) * speed_factor);
seq->start = timeline_frame;
seq->startofs = 0;
}
@ -301,8 +308,11 @@ static void seq_split_set_left_hold_offset(Scene *scene, Sequence *seq, int time
const float offset = timeline_frame - content_end + 1;
seq->start += offset;
seq->endofs += offset;
SEQ_time_left_handle_frame_set(scene, seq, timeline_frame);
}
/* Needed only to set `seq->len`. */
SEQ_add_reload_new_file(bmain, scene, seq, false);
SEQ_time_left_handle_frame_set(scene, seq, timeline_frame);
}
static bool seq_edit_split_effect_intersect_check(const Scene *scene,
@ -326,8 +336,7 @@ static void seq_edit_split_handle_strip_offsets(Main *bmain,
SEQ_time_left_handle_frame_set(scene, right_seq, timeline_frame);
break;
case SEQ_SPLIT_HARD:
seq_split_set_left_hold_offset(scene, right_seq, timeline_frame);
SEQ_add_reload_new_file(bmain, scene, right_seq, false);
seq_split_set_left_hold_offset(bmain, scene, right_seq, timeline_frame);
break;
}
}
@ -338,8 +347,7 @@ static void seq_edit_split_handle_strip_offsets(Main *bmain,
SEQ_time_right_handle_frame_set(scene, left_seq, timeline_frame);
break;
case SEQ_SPLIT_HARD:
seq_split_set_right_hold_offset(scene, left_seq, timeline_frame);
SEQ_add_reload_new_file(bmain, scene, left_seq, false);
seq_split_set_right_hold_offset(bmain, scene, left_seq, timeline_frame);
break;
}
}

View File

@ -31,7 +31,7 @@
#include "strip_time.h"
#include "utils.h"
static float seq_time_media_playback_rate_factor_get(const Scene *scene, const Sequence *seq)
float seq_time_media_playback_rate_factor_get(const Scene *scene, const Sequence *seq)
{
if ((seq->flag & SEQ_AUTO_PLAYBACK_RATE) == 0) {
return 1.0f;
@ -44,7 +44,7 @@ static float seq_time_media_playback_rate_factor_get(const Scene *scene, const S
return seq->media_playback_rate / scene_playback_rate;
}
static float seq_time_playback_rate_factor_get(const Scene *scene, const Sequence *seq)
float seq_time_playback_rate_factor_get(const Scene *scene, const Sequence *seq)
{
return seq_time_media_playback_rate_factor_get(scene, seq) * seq->speed_factor;
}

View File

@ -41,6 +41,9 @@ void seq_time_gap_info_get(const struct Scene *scene,
void seq_time_effect_range_set(const struct Scene *scene, Sequence *seq);
void seq_time_update_effects_strip_range(const struct Scene *scene, struct SeqCollection *effects);
void seq_time_translate_handles(const struct Scene *scene, struct Sequence *seq, const int offset);
float seq_time_media_playback_rate_factor_get(const struct Scene *scene,
const struct Sequence *seq);
float seq_time_playback_rate_factor_get(const struct Scene *scene, const struct Sequence *seq);
#ifdef __cplusplus
}