WIP: VSE: Use seconds for strip length and position #105620
|
@ -27,7 +27,7 @@ extern "C" {
|
|||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 7
|
||||
#define BLENDER_FILE_SUBVERSION 8
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and show a warning if the file
|
||||
|
|
|
@ -776,12 +776,15 @@ void BKE_sound_move_scene_sound_defaults(Scene *scene, Sequence *sequence)
|
|||
{
|
||||
sound_verify_evaluated_id(&scene->id);
|
||||
if (sequence->scene_sound) {
|
||||
BKE_sound_move_scene_sound(scene,
|
||||
sequence->scene_sound,
|
||||
SEQ_time_left_handle_frame_get(scene, sequence),
|
||||
SEQ_time_right_handle_frame_get(scene, sequence),
|
||||
sequence->startofs + sequence->anim_startofs,
|
||||
0.0);
|
||||
BKE_sound_move_scene_sound(
|
||||
scene,
|
||||
sequence->scene_sound,
|
||||
SEQ_time_left_handle_frame_get(scene, sequence),
|
||||
SEQ_time_right_handle_frame_get(scene, sequence),
|
||||
SEQ_time_seconds_to_frames(
|
||||
scene,
|
||||
sequence->startofs + sequence->anim_startofs), // XXX don't use the function here!
|
||||
0.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -670,7 +670,7 @@ static bool do_versions_sequencer_init_retiming_tool_data(Sequence *seq, void *u
|
|||
|
||||
const int content_length = SEQ_time_strip_length_get(scene, seq);
|
||||
|
||||
SEQ_retiming_data_ensure(seq);
|
||||
SEQ_retiming_data_ensure(scene, seq);
|
||||
|
||||
SeqRetimingHandle *handle = &seq->retiming_handles[seq->retiming_handle_num - 1];
|
||||
handle->strip_frame_index = round_fl_to_int(content_length / seq->speed_factor);
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
|
||||
#include "BLO_readfile.h"
|
||||
|
||||
#include "SEQ_sequencer.h"
|
||||
#include "SEQ_iterator.h"
|
||||
|
||||
#include "readfile.h"
|
||||
|
||||
#include "versioning_common.h"
|
||||
|
@ -200,6 +203,23 @@ static void versioning_remove_microfacet_sharp_distribution(bNodeTree *ntree)
|
|||
}
|
||||
}
|
||||
|
||||
static bool version_seq_convert_frames_to_seconds(Sequence *seq, void *user_data)
|
||||
{
|
||||
if (seq->seq1 != nullptr || seq->seq2 != nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const Scene *scene = static_cast<Scene *>(user_data);
|
||||
double scene_playback_rate = (float)scene->r.frs_sec / scene->r.frs_sec_base;
|
||||
|
||||
seq->start /= scene_playback_rate;
|
||||
seq->len /= scene_playback_rate;
|
||||
seq->startofs /= scene_playback_rate;
|
||||
seq->endofs /= scene_playback_rate;
|
||||
// XXX anim offsets
|
||||
return true;
|
||||
}
|
||||
|
||||
void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
|
||||
{
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 400, 1)) {
|
||||
|
@ -257,6 +277,16 @@ void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
|
|||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 400, 8)) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
if (ed != nullptr) {
|
||||
SEQ_for_each_callback(&ed->seqbase, version_seq_convert_frames_to_seconds, scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
|
|
|
@ -546,7 +546,7 @@ static void drawmeta_contents(Scene *scene,
|
|||
ListBase *meta_channels;
|
||||
int offset;
|
||||
|
||||
meta_seqbase = SEQ_get_seqbase_from_sequence(seqm, &meta_channels, &offset);
|
||||
meta_seqbase = SEQ_get_seqbase_from_sequence(scene, seqm, &meta_channels, &offset);
|
||||
|
||||
if (!meta_seqbase || BLI_listbase_is_empty(meta_seqbase)) {
|
||||
return;
|
||||
|
@ -964,7 +964,7 @@ static void draw_sequence_extensions_overlay(
|
|||
col[3] = SEQ_render_is_muted(channels, seq) ? MUTE_ALPHA : 200;
|
||||
UI_GetColorPtrShade3ubv(col, blend_col, 10);
|
||||
|
||||
const float strip_content_start = SEQ_time_start_frame_get(seq);
|
||||
const float strip_content_start = SEQ_time_start_frame_get(scene, seq);
|
||||
const float strip_content_end = SEQ_time_content_end_frame_get(scene, seq);
|
||||
float right_handle_frame = SEQ_time_right_handle_frame_get(scene, seq);
|
||||
float left_handle_frame = SEQ_time_left_handle_frame_get(scene, seq);
|
||||
|
@ -1092,7 +1092,7 @@ static void draw_seq_background(Scene *scene,
|
|||
|
||||
if (SEQ_time_has_left_still_frames(scene, seq)) {
|
||||
float left_handle_frame = SEQ_time_left_handle_frame_get(scene, seq);
|
||||
const float content_start = SEQ_time_start_frame_get(seq);
|
||||
const float content_start = SEQ_time_start_frame_get(scene, seq);
|
||||
immRectf(pos, left_handle_frame, y1, content_start, y2);
|
||||
}
|
||||
if (SEQ_time_has_right_still_frames(scene, seq)) {
|
||||
|
@ -1315,7 +1315,7 @@ static void draw_seq_strip(const bContext *C,
|
|||
SEQ_TIMELINE_SHOW_STRIP_COLOR_TAG);
|
||||
|
||||
/* Draw strip body. */
|
||||
x1 = SEQ_time_has_left_still_frames(scene, seq) ? SEQ_time_start_frame_get(seq) :
|
||||
x1 = SEQ_time_has_left_still_frames(scene, seq) ? SEQ_time_start_frame_get(scene, seq) :
|
||||
SEQ_time_left_handle_frame_get(scene, seq);
|
||||
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
|
||||
x2 = SEQ_time_has_right_still_frames(scene, seq) ? SEQ_time_content_end_frame_get(scene, seq) :
|
||||
|
@ -2280,9 +2280,8 @@ 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_time_left_handle_frame_get(scene, seq), SEQ_time_start_frame_get(seq)) >
|
||||
v2d->cur.xmax)
|
||||
{
|
||||
if (min_ii(SEQ_time_left_handle_frame_get(scene, seq),
|
||||
SEQ_time_start_frame_get(scene, seq)) > v2d->cur.xmax) {
|
||||
continue;
|
||||
}
|
||||
if (max_ii(SEQ_time_right_handle_frame_get(scene, seq),
|
||||
|
|
|
@ -74,22 +74,6 @@
|
|||
/* Own include. */
|
||||
#include "sequencer_intern.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Structs & Enums
|
||||
* \{ */
|
||||
|
||||
struct TransSeq {
|
||||
int start, machine;
|
||||
int startofs, endofs;
|
||||
int anim_startofs, anim_endofs;
|
||||
/* int final_left, final_right; */ /* UNUSED */
|
||||
int len;
|
||||
float content_start;
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public Context Checks
|
||||
* \{ */
|
||||
|
||||
|
@ -376,7 +360,8 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
|
|||
SEQ_transform_sequence_can_be_translated(seq))
|
||||
{
|
||||
if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) {
|
||||
SEQ_transform_translate_sequence(scene, seq, (snap_frame - seq->startofs) - seq->start);
|
||||
const int offset = snap_frame - SEQ_time_left_handle_frame_get(scene, seq);
|
||||
SEQ_transform_translate_sequence(scene, seq, offset);
|
||||
}
|
||||
else {
|
||||
if (seq->flag & SEQ_LEFTSEL) {
|
||||
|
@ -475,7 +460,14 @@ void SEQUENCER_OT_snap(wmOperatorType *ot)
|
|||
/** \name Trim Strips Operator
|
||||
* \{ */
|
||||
|
||||
struct SlipData {
|
||||
typedef struct TransSeq {
|
||||
int start;
|
||||
int left_handle, right_handle;
|
||||
int anim_startofs, anim_endofs;
|
||||
int machine;
|
||||
} TransSeq;
|
||||
|
||||
typedef struct SlipData {
|
||||
int init_mouse[2];
|
||||
float init_mouseloc[2];
|
||||
TransSeq *ts;
|
||||
|
@ -487,27 +479,24 @@ struct SlipData {
|
|||
NumInput num_input;
|
||||
};
|
||||
|
||||
static void transseq_backup(TransSeq *ts, Sequence *seq)
|
||||
static void transseq_backup(TransSeq *ts, const Scene *scene, Sequence *seq)
|
||||
{
|
||||
ts->content_start = SEQ_time_start_frame_get(seq);
|
||||
ts->start = seq->start;
|
||||
ts->machine = seq->machine;
|
||||
ts->startofs = seq->startofs;
|
||||
ts->endofs = seq->endofs;
|
||||
ts->start = SEQ_time_start_frame_get(scene, seq);
|
||||
ts->left_handle = SEQ_time_left_handle_frame_get(scene, seq);
|
||||
ts->right_handle = SEQ_time_right_handle_frame_get(scene, seq);
|
||||
ts->anim_startofs = seq->anim_startofs;
|
||||
ts->anim_endofs = seq->anim_endofs;
|
||||
ts->len = seq->len;
|
||||
ts->machine = seq->machine;
|
||||
}
|
||||
|
||||
static void transseq_restore(TransSeq *ts, Sequence *seq)
|
||||
static void transseq_restore(Scene *scene, TransSeq *ts, Sequence *seq)
|
||||
{
|
||||
seq->start = ts->start;
|
||||
seq->machine = ts->machine;
|
||||
seq->startofs = ts->startofs;
|
||||
seq->endofs = ts->endofs;
|
||||
SEQ_time_start_frame_set(scene, seq, ts->start);
|
||||
SEQ_time_left_handle_frame_set(scene, seq, ts->left_handle);
|
||||
SEQ_time_right_handle_frame_set(scene, seq, ts->right_handle);
|
||||
seq->anim_startofs = ts->anim_startofs;
|
||||
seq->anim_endofs = ts->anim_endofs;
|
||||
seq->len = ts->len;
|
||||
seq->machine = ts->machine;
|
||||
}
|
||||
|
||||
static int slip_add_sequences_recursive(
|
||||
|
@ -582,7 +571,7 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve
|
|||
slip_add_sequences_recursive(ed->seqbasep, data->seq_array, data->trim, 0, true);
|
||||
|
||||
for (int i = 0; i < num_seq; i++) {
|
||||
transseq_backup(data->ts + i, data->seq_array[i]);
|
||||
transseq_backup(data->ts + i, scene, data->seq_array[i]);
|
||||
}
|
||||
|
||||
UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouseloc[0], &mouseloc[1]);
|
||||
|
@ -603,13 +592,14 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve
|
|||
static void sequencer_slip_recursively(Scene *scene, SlipData *data, int offset)
|
||||
{
|
||||
for (int i = data->num_seq - 1; i >= 0; i--) {
|
||||
Sequence *seq = data->seq_array[i];
|
||||
|
||||
seq->start = data->ts[i].start + offset;
|
||||
if (data->trim[i]) {
|
||||
seq->startofs = data->ts[i].startofs - offset;
|
||||
seq->endofs = data->ts[i].endofs + offset;
|
||||
if (!data->trim[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Sequence *seq = data->seq_array[i];
|
||||
SEQ_time_start_frame_set(scene, seq, data->ts[i].start + offset);
|
||||
SEQ_time_left_handle_frame_set(scene, seq, data->ts[i].left_handle);
|
||||
SEQ_time_right_handle_frame_set(scene, seq, data->ts[i].right_handle);
|
||||
}
|
||||
|
||||
for (int i = data->num_seq - 1; i >= 0; i--) {
|
||||
|
@ -625,7 +615,8 @@ static void sequencer_slip_apply_limits(const Scene *scene, SlipData *data, int
|
|||
if (data->trim[i]) {
|
||||
Sequence *seq = data->seq_array[i];
|
||||
int seq_content_start = data->ts[i].start + *offset;
|
||||
int seq_content_end = seq_content_start + seq->len + seq->anim_startofs + seq->anim_endofs;
|
||||
int seq_content_end = seq_content_start + SEQ_time_strip_length_get(scene, seq) +
|
||||
seq->anim_startofs + seq->anim_endofs;
|
||||
int diff = 0;
|
||||
|
||||
if (seq_content_start >= SEQ_time_right_handle_frame_get(scene, seq)) {
|
||||
|
@ -663,7 +654,7 @@ static int sequencer_slip_exec(bContext *C, wmOperator *op)
|
|||
slip_add_sequences_recursive(ed->seqbasep, data->seq_array, data->trim, 0, true);
|
||||
|
||||
for (int i = 0; i < num_seq; i++) {
|
||||
transseq_backup(data->ts + i, data->seq_array[i]);
|
||||
transseq_backup(data->ts + i, scene, data->seq_array[i]);
|
||||
}
|
||||
|
||||
sequencer_slip_apply_limits(scene, data, &offset);
|
||||
|
@ -774,7 +765,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
|
|||
case EVT_ESCKEY:
|
||||
case RIGHTMOUSE: {
|
||||
for (int i = 0; i < data->num_seq; i++) {
|
||||
transseq_restore(data->ts + i, data->seq_array[i]);
|
||||
transseq_restore(scene, data->ts + i, data->seq_array[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < data->num_seq; i++) {
|
||||
|
@ -1272,7 +1263,7 @@ static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op)
|
|||
last_seq->seq2 = seq2;
|
||||
last_seq->seq3 = seq3;
|
||||
|
||||
int old_start = last_seq->start;
|
||||
int old_start = SEQ_time_start_frame_get(scene, last_seq);
|
||||
|
||||
/* Force time position update for reassigned effects.
|
||||
* TODO(Richard): This is because internally startdisp is still used, due to poor performance of
|
||||
|
@ -1281,7 +1272,7 @@ static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op)
|
|||
SEQ_time_left_handle_frame_set(scene, seq1, SEQ_time_left_handle_frame_get(scene, seq1));
|
||||
|
||||
SEQ_relations_invalidate_cache_preprocessed(scene, last_seq);
|
||||
SEQ_offset_animdata(scene, last_seq, (last_seq->start - old_start));
|
||||
SEQ_offset_animdata(scene, last_seq, (SEQ_time_start_frame_get(scene, last_seq) - old_start));
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
||||
|
||||
|
@ -1783,7 +1774,10 @@ static int sequencer_offset_clear_exec(bContext *C, wmOperator * /*op*/)
|
|||
seq = static_cast<Sequence *>(seq->next))
|
||||
{
|
||||
if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) {
|
||||
seq->startofs = seq->endofs = 0;
|
||||
const int start = SEQ_time_start_frame_get(scene, seq);
|
||||
const int end = start + SEQ_time_strip_length_get(scene, seq);
|
||||
SEQ_time_left_handle_frame_set(scene, seq, start);
|
||||
SEQ_time_right_handle_frame_set(scene, seq, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1848,7 +1842,8 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
|
|||
SEQ_prefetch_stop(scene);
|
||||
|
||||
while (seq) {
|
||||
if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) {
|
||||
if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) &&
|
||||
SEQ_transform_single_image_check(seq)) {
|
||||
Sequence *seq_next;
|
||||
|
||||
/* Remove seq so overlap tests don't conflict,
|
||||
|
@ -3623,7 +3618,7 @@ static int sequencer_scene_frame_range_update_exec(bContext *C, wmOperator * /*o
|
|||
|
||||
Scene *target_scene = seq->scene;
|
||||
|
||||
seq->len = target_scene->r.efra - target_scene->r.sfra + 1;
|
||||
SEQ_time_strip_length_set(scene, seq, target_scene->r.efra - target_scene->r.sfra + 1);
|
||||
SEQ_time_left_handle_frame_set(scene, seq, old_start);
|
||||
SEQ_time_right_handle_frame_set(scene, seq, old_end);
|
||||
|
||||
|
|
|
@ -222,8 +222,9 @@ static void gizmo_retime_handle_add_draw(const bContext *C, wmGizmo *gz)
|
|||
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
const Sequence *seq = active_seq_from_context(C);
|
||||
const int frame_index = BKE_scene_frame_get(scene) - SEQ_time_start_frame_get(seq);
|
||||
const SeqRetimingHandle *handle = SEQ_retiming_find_segment_start_handle(seq, frame_index);
|
||||
const int frame_index = BKE_scene_frame_get(scene) - SEQ_time_start_frame_get(scene, seq);
|
||||
const SeqRetimingHandle *handle = SEQ_retiming_find_segment_start_handle(
|
||||
scene, seq, frame_index);
|
||||
|
||||
if (handle != nullptr && (SEQ_retiming_handle_is_transition_type(handle) ||
|
||||
SEQ_retiming_handle_is_freeze_frame(handle)))
|
||||
|
@ -407,7 +408,7 @@ static void gizmo_retime_handle_draw(const bContext *C, wmGizmo *gz)
|
|||
{
|
||||
RetimeHandleMoveGizmo *gizmo = (RetimeHandleMoveGizmo *)gz;
|
||||
const View2D *v2d = UI_view2d_fromcontext(C);
|
||||
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
/* TODO: This is hard-coded behavior, same as pre-select gizmos in 3D view.
|
||||
* Better solution would be to check operator keymap and display this information in status bar
|
||||
* and tool-tip. */
|
||||
|
@ -429,7 +430,7 @@ static void gizmo_retime_handle_draw(const bContext *C, wmGizmo *gz)
|
|||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
|
||||
Sequence *seq = active_seq_from_context(C);
|
||||
SEQ_retiming_data_ensure(seq);
|
||||
SEQ_retiming_data_ensure(scene, seq);
|
||||
MutableSpan handles = SEQ_retiming_handles_get(seq);
|
||||
|
||||
for (const SeqRetimingHandle &handle : handles) {
|
||||
|
@ -454,7 +455,7 @@ static int gizmo_retime_handle_test_select(bContext *C, wmGizmo *gz, const int m
|
|||
gizmo->mouse_over_seq = nullptr;
|
||||
|
||||
Sequence *seq = active_seq_from_context(C);
|
||||
SEQ_retiming_data_ensure(seq);
|
||||
SEQ_retiming_data_ensure(scene, seq);
|
||||
const SeqRetimingHandle *handle = mouse_over_handle_get(
|
||||
scene, seq, UI_view2d_fromcontext(C), mval);
|
||||
const int handle_index = SEQ_retiming_handle_index_get(seq, handle);
|
||||
|
@ -531,7 +532,7 @@ static int gizmo_retime_remove_test_select(bContext *C, wmGizmo *gz, const int m
|
|||
Scene *scene = CTX_data_scene(C);
|
||||
Sequence *seq = active_seq_from_context(C);
|
||||
|
||||
SEQ_retiming_data_ensure(seq);
|
||||
SEQ_retiming_data_ensure(scene, seq);
|
||||
const SeqRetimingHandle *handle = mouse_over_handle_get(
|
||||
scene, seq, UI_view2d_fromcontext(C), mval);
|
||||
const int handle_index = SEQ_retiming_handle_index_get(seq, handle);
|
||||
|
@ -594,22 +595,23 @@ void GIZMO_GT_retime_remove(wmGizmoType *gzt)
|
|||
/** \name Retiming Speed Set Gizmo
|
||||
* \{ */
|
||||
|
||||
static size_t label_str_get(const Sequence *seq,
|
||||
static size_t label_str_get(const Scene *scene,
|
||||
const Sequence *seq,
|
||||
const SeqRetimingHandle *handle,
|
||||
size_t str_len,
|
||||
char *r_label_str)
|
||||
{
|
||||
const SeqRetimingHandle *next_handle = handle + 1;
|
||||
if (SEQ_retiming_handle_is_transition_type(handle)) {
|
||||
const float prev_speed = SEQ_retiming_handle_speed_get(seq, handle - 1);
|
||||
const float next_speed = SEQ_retiming_handle_speed_get(seq, next_handle + 1);
|
||||
const float prev_speed = SEQ_retiming_handle_speed_get(scene, seq, handle - 1);
|
||||
const float next_speed = SEQ_retiming_handle_speed_get(scene, seq, next_handle + 1);
|
||||
return BLI_snprintf_rlen(r_label_str,
|
||||
str_len,
|
||||
"%d%% - %d%%",
|
||||
round_fl_to_int(prev_speed * 100.0f),
|
||||
round_fl_to_int(next_speed * 100.0f));
|
||||
}
|
||||
const float speed = SEQ_retiming_handle_speed_get(seq, next_handle);
|
||||
const float speed = SEQ_retiming_handle_speed_get(scene, seq, next_handle);
|
||||
return BLI_snprintf_rlen(r_label_str, str_len, "%d%%", round_fl_to_int(speed * 100.0f));
|
||||
}
|
||||
|
||||
|
@ -669,7 +671,7 @@ static void retime_speed_text_draw(const bContext *C,
|
|||
|
||||
char label_str[40];
|
||||
rctf label_rect;
|
||||
size_t label_len = label_str_get(seq, handle, sizeof(label_str), label_str);
|
||||
size_t label_len = label_str_get(scene, seq, handle, sizeof(label_str), label_str);
|
||||
|
||||
if (!label_rect_get(C, seq, handle, label_str, label_len, &label_rect)) {
|
||||
return; /* Not enough space to draw label. */
|
||||
|
@ -683,6 +685,7 @@ static void retime_speed_text_draw(const bContext *C,
|
|||
static void gizmo_retime_speed_set_draw(const bContext *C, wmGizmo * /* gz */)
|
||||
{
|
||||
const View2D *v2d = UI_view2d_fromcontext(C);
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
|
||||
wmOrtho2_region_pixelspace(CTX_wm_region(C));
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
@ -690,7 +693,7 @@ static void gizmo_retime_speed_set_draw(const bContext *C, wmGizmo * /* gz */)
|
|||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
|
||||
Sequence *seq = active_seq_from_context(C);
|
||||
SEQ_retiming_data_ensure(seq);
|
||||
SEQ_retiming_data_ensure(scene, seq);
|
||||
MutableSpan handles = SEQ_retiming_handles_get(seq);
|
||||
|
||||
for (const SeqRetimingHandle &handle : handles) {
|
||||
|
@ -711,7 +714,7 @@ static int gizmo_retime_speed_set_test_select(bContext *C, wmGizmo *gz, const in
|
|||
const View2D *v2d = UI_view2d_fromcontext(C);
|
||||
|
||||
Sequence *seq = active_seq_from_context(C);
|
||||
SEQ_retiming_data_ensure(seq);
|
||||
SEQ_retiming_data_ensure(scene, seq);
|
||||
|
||||
for (const SeqRetimingHandle &handle : SEQ_retiming_handles_get(seq)) {
|
||||
if (SEQ_retiming_handle_is_transition_type(&handle)) {
|
||||
|
@ -720,7 +723,7 @@ static int gizmo_retime_speed_set_test_select(bContext *C, wmGizmo *gz, const in
|
|||
|
||||
char label_str[40];
|
||||
rctf label_rect;
|
||||
size_t label_len = label_str_get(seq, &handle, sizeof(label_str), label_str);
|
||||
size_t label_len = label_str_get(scene, seq, &handle, sizeof(label_str), label_str);
|
||||
|
||||
if (!label_rect_get(C, seq, &handle, label_str, label_len, &label_rect)) {
|
||||
continue;
|
||||
|
|
|
@ -325,7 +325,7 @@ static int sequesequencer_retiming_handle_add_exec(bContext *C, wmOperator *op)
|
|||
const Editing *ed = SEQ_editing_get(scene);
|
||||
Sequence *seq = ed->act_seq;
|
||||
|
||||
SEQ_retiming_data_ensure(seq);
|
||||
SEQ_retiming_data_ensure(scene, seq);
|
||||
|
||||
float timeline_frame;
|
||||
if (RNA_struct_property_is_set(op->ptr, "timeline_frame")) {
|
||||
|
@ -335,8 +335,9 @@ static int sequesequencer_retiming_handle_add_exec(bContext *C, wmOperator *op)
|
|||
timeline_frame = BKE_scene_frame_get(scene);
|
||||
}
|
||||
|
||||
const int frame_index = BKE_scene_frame_get(scene) - SEQ_time_start_frame_get(seq);
|
||||
const SeqRetimingHandle *handle = SEQ_retiming_find_segment_start_handle(seq, frame_index);
|
||||
const int frame_index = BKE_scene_frame_get(scene) - SEQ_time_start_frame_get(scene, seq);
|
||||
const SeqRetimingHandle *handle = SEQ_retiming_find_segment_start_handle(
|
||||
scene, seq, frame_index);
|
||||
|
||||
if (SEQ_retiming_handle_is_transition_type(handle)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Can not create handle inside of speed transition");
|
||||
|
@ -509,7 +510,7 @@ static int sequencer_retiming_segment_speed_set_invoke(bContext *C,
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
RNA_float_set(op->ptr, "speed", SEQ_retiming_handle_speed_get(seq, handle) * 100.0f);
|
||||
RNA_float_set(op->ptr, "speed", SEQ_retiming_handle_speed_get(scene, seq, handle) * 100.0f);
|
||||
RNA_int_set(op->ptr, "handle_index", SEQ_retiming_handle_index_get(seq, handle));
|
||||
return WM_operator_props_popup(C, op, event);
|
||||
}
|
||||
|
|
|
@ -75,9 +75,8 @@ static bool check_seq_need_thumbnails(const Scene *scene, Sequence *seq, rctf *v
|
|||
if (!ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE)) {
|
||||
return false;
|
||||
}
|
||||
if (min_ii(SEQ_time_left_handle_frame_get(scene, seq), SEQ_time_start_frame_get(seq)) >
|
||||
view_area->xmax)
|
||||
{
|
||||
if (min_ii(SEQ_time_left_handle_frame_get(scene, seq), SEQ_time_start_frame_get(scene, seq)) >
|
||||
view_area->xmax) {
|
||||
return false;
|
||||
}
|
||||
if (max_ii(SEQ_time_right_handle_frame_get(scene, seq),
|
||||
|
|
|
@ -181,7 +181,8 @@ static TransData *SeqToTransData(Scene *scene,
|
|||
* tdsq->start_offset is used when flushing the tx data back */
|
||||
start_left = SEQ_time_left_handle_frame_get(scene, seq);
|
||||
td2d->loc[0] = start_left;
|
||||
tdsq->start_offset = start_left - seq->start; /* use to apply the original location */
|
||||
tdsq->start_offset = start_left - SEQ_time_start_frame_get(
|
||||
scene, seq); /* use to apply the original location */
|
||||
break;
|
||||
case SEQ_LEFTSEL:
|
||||
start_left = SEQ_time_left_handle_frame_get(scene, seq);
|
||||
|
@ -604,7 +605,7 @@ static void flushTransSeq(TransInfo *t)
|
|||
switch (tdsq->sel_flag) {
|
||||
case SELECT: {
|
||||
if (SEQ_transform_sequence_can_be_translated(seq)) {
|
||||
offset = new_frame - tdsq->start_offset - seq->start;
|
||||
offset = new_frame - tdsq->start_offset - SEQ_time_start_frame_get(scene, seq);
|
||||
SEQ_transform_translate_sequence(scene, seq, offset);
|
||||
if (abs(offset) > abs(max_offset)) {
|
||||
max_offset = offset;
|
||||
|
|
|
@ -205,11 +205,12 @@ static void seq_snap_target_points_build(Scene *scene,
|
|||
|
||||
if (snap_mode & SEQ_SNAP_TO_STRIP_HOLD) {
|
||||
int content_start = min_ii(SEQ_time_left_handle_frame_get(scene, seq),
|
||||
SEQ_time_start_frame_get(seq));
|
||||
SEQ_time_start_frame_get(scene, seq));
|
||||
int content_end = max_ii(SEQ_time_right_handle_frame_get(scene, seq),
|
||||
SEQ_time_content_end_frame_get(scene, seq));
|
||||
/* Effects and single image strips produce incorrect content length. Skip these strips. */
|
||||
if ((seq->type & SEQ_TYPE_EFFECT) != 0 || seq->len == 1) {
|
||||
if ((seq->type & SEQ_TYPE_EFFECT) != 0 ||
|
||||
seq->len == 1) { // XXX - this has to have some flag. it can't rely on precise length.
|
||||
content_start = SEQ_time_left_handle_frame_get(scene, seq);
|
||||
content_end = SEQ_time_right_handle_frame_get(scene, seq);
|
||||
}
|
||||
|
|
|
@ -128,13 +128,13 @@ typedef enum eSeqRetimingHandleFlag {
|
|||
} eSeqRetimingHandleFlag;
|
||||
|
||||
typedef struct SeqRetimingHandle {
|
||||
int strip_frame_index;
|
||||
int flag; /* eSeqRetimingHandleFlag */
|
||||
int _pad0;
|
||||
double strip_frame_index; /* -> strip_position in seconds. */
|
||||
int flag; /* eSeqRetimingHandleFlag */
|
||||
int _pad0[2];
|
||||
float retiming_factor; /* Value between 0-1 mapped to original content range. */
|
||||
|
||||
int original_strip_frame_index; /* Used for transition handles only. */
|
||||
float original_retiming_factor; /* Used for transition handles only. */
|
||||
double original_strip_frame_index; /* Used for transition handles only. */
|
||||
double original_retiming_factor; /* Used for transition handles only. */
|
||||
} SeqRetimingHandle;
|
||||
|
||||
typedef struct SequenceRuntime {
|
||||
|
@ -163,17 +163,17 @@ typedef struct Sequence {
|
|||
/** Flags bitmap (see below) and the type of sequence. */
|
||||
int flag, type;
|
||||
/** The length of the contents of this strip - before handles are applied. */
|
||||
int len;
|
||||
double len;
|
||||
/**
|
||||
* Start frame of contents of strip in absolute frame coordinates.
|
||||
* For meta-strips start of first strip startdisp.
|
||||
*/
|
||||
float start;
|
||||
double start;
|
||||
/**
|
||||
* Frames after the first frame where display starts,
|
||||
* frames before the last frame where display ends.
|
||||
*/
|
||||
float startofs, endofs;
|
||||
double startofs, endofs;
|
||||
/**
|
||||
* Frames that use the first frame before data begins,
|
||||
* frames that use the last frame after data ends.
|
||||
|
|
|
@ -337,7 +337,7 @@ static void rna_Sequence_retiming_handle_remove(ID *id, SeqRetimingHandle *handl
|
|||
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
|
||||
}
|
||||
|
||||
static int rna_Sequence_retiming_handle_frame_get(PointerRNA *ptr)
|
||||
static float rna_Sequence_retiming_handle_frame_get(PointerRNA *ptr)
|
||||
{
|
||||
SeqRetimingHandle *handle = (SeqRetimingHandle *)ptr->data;
|
||||
Scene *scene = (Scene *)ptr->owner_id;
|
||||
|
@ -347,10 +347,10 @@ static int rna_Sequence_retiming_handle_frame_get(PointerRNA *ptr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
return SEQ_time_start_frame_get(seq) + handle->strip_frame_index;
|
||||
return SEQ_time_start_frame_get(scene, seq) + handle->strip_frame_index;
|
||||
}
|
||||
|
||||
static void rna_Sequence_retiming_handle_frame_set(PointerRNA *ptr, int value)
|
||||
static void rna_Sequence_retiming_handle_frame_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
SeqRetimingHandle *handle = (SeqRetimingHandle *)ptr->data;
|
||||
Scene *scene = (Scene *)ptr->owner_id;
|
||||
|
@ -360,7 +360,7 @@ static void rna_Sequence_retiming_handle_frame_set(PointerRNA *ptr, int value)
|
|||
return;
|
||||
}
|
||||
|
||||
const int offset = value - (SEQ_time_start_frame_get(seq) + handle->strip_frame_index);
|
||||
const int offset = value - SEQ_time_start_frame_get(scene, seq) + handle->strip_frame_index;
|
||||
SEQ_retiming_offset_handle(scene, seq, handle, offset);
|
||||
SEQ_relations_invalidate_cache_raw(scene, seq);
|
||||
}
|
||||
|
@ -431,18 +431,39 @@ static void rna_Sequence_start_frame_set(PointerRNA *ptr, float value)
|
|||
Sequence *seq = (Sequence *)ptr->data;
|
||||
Scene *scene = (Scene *)ptr->owner_id;
|
||||
|
||||
SEQ_transform_translate_sequence(scene, seq, value - seq->start);
|
||||
SEQ_transform_translate_sequence(scene, seq, value - SEQ_time_start_frame_get(scene, seq));
|
||||
do_sequence_frame_change_update(scene, seq);
|
||||
SEQ_relations_invalidate_cache_composite(scene, seq);
|
||||
}
|
||||
|
||||
static float rna_Sequence_start_frame_get(PointerRNA *ptr)
|
||||
{
|
||||
Sequence *seq = (Sequence *)ptr->data;
|
||||
Scene *scene = (Scene *)ptr->owner_id;
|
||||
return SEQ_time_start_frame_get(scene, seq);
|
||||
}
|
||||
|
||||
static float rna_Sequence_frame_offset_start_get(PointerRNA *ptr)
|
||||
{
|
||||
Sequence *seq = (Sequence *)ptr->data;
|
||||
Scene *scene = (Scene *)ptr->owner_id;
|
||||
return SEQ_time_seconds_to_frames(scene, seq->startofs);
|
||||
}
|
||||
|
||||
static float rna_Sequence_frame_offset_end_get(PointerRNA *ptr)
|
||||
{
|
||||
Sequence *seq = (Sequence *)ptr->data;
|
||||
Scene *scene = (Scene *)ptr->owner_id;
|
||||
return SEQ_time_seconds_to_frames(scene, seq->endofs);
|
||||
}
|
||||
|
||||
static void rna_Sequence_frame_offset_start_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
Sequence *seq = (Sequence *)ptr->data;
|
||||
Scene *scene = (Scene *)ptr->owner_id;
|
||||
|
||||
SEQ_relations_invalidate_cache_composite(scene, seq);
|
||||
seq->startofs = value;
|
||||
seq->startofs = SEQ_time_frames_to_seconds(scene, value);
|
||||
}
|
||||
|
||||
static void rna_Sequence_frame_offset_end_set(PointerRNA *ptr, float value)
|
||||
|
@ -451,7 +472,7 @@ static void rna_Sequence_frame_offset_end_set(PointerRNA *ptr, float value)
|
|||
Scene *scene = (Scene *)ptr->owner_id;
|
||||
|
||||
SEQ_relations_invalidate_cache_composite(scene, seq);
|
||||
seq->endofs = value;
|
||||
seq->endofs = SEQ_time_frames_to_seconds(scene, value);
|
||||
}
|
||||
|
||||
static void rna_Sequence_anim_startofs_final_set(PointerRNA *ptr, int value)
|
||||
|
@ -498,19 +519,21 @@ static void rna_Sequence_frame_offset_start_range(
|
|||
PointerRNA *ptr, float *min, float *max, float *UNUSED(softmin), float *UNUSED(softmax))
|
||||
{
|
||||
Sequence *seq = (Sequence *)ptr->data;
|
||||
Scene *scene = (Scene *)ptr->owner_id;
|
||||
*min = ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD) ? 0 : INT_MIN;
|
||||
*max = seq->len - seq->endofs - 1;
|
||||
*max = SEQ_time_seconds_to_frames(scene, seq->len - seq->endofs) - 1;
|
||||
}
|
||||
|
||||
static void rna_Sequence_frame_offset_end_range(
|
||||
PointerRNA *ptr, float *min, float *max, float *UNUSED(softmin), float *UNUSED(softmax))
|
||||
{
|
||||
Sequence *seq = (Sequence *)ptr->data;
|
||||
Scene *scene = (Scene *)ptr->owner_id;
|
||||
*min = ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD) ? 0 : INT_MIN;
|
||||
*max = seq->len - seq->startofs - 1;
|
||||
*max = SEQ_time_seconds_to_frames(scene, seq->len - seq->startofs) - 1;
|
||||
}
|
||||
|
||||
static void rna_Sequence_frame_length_set(PointerRNA *ptr, int value)
|
||||
static void rna_Sequence_frame_final_duration_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
Sequence *seq = (Sequence *)ptr->data;
|
||||
Scene *scene = (Scene *)ptr->owner_id;
|
||||
|
@ -520,13 +543,20 @@ static void rna_Sequence_frame_length_set(PointerRNA *ptr, int value)
|
|||
SEQ_relations_invalidate_cache_composite(scene, seq);
|
||||
}
|
||||
|
||||
static int rna_Sequence_frame_length_get(PointerRNA *ptr)
|
||||
static int rna_Sequence_frame_final_duration_get(PointerRNA *ptr)
|
||||
{
|
||||
Sequence *seq = (Sequence *)ptr->data;
|
||||
Scene *scene = (Scene *)ptr->owner_id;
|
||||
return SEQ_time_right_handle_frame_get(scene, seq) - SEQ_time_left_handle_frame_get(scene, seq);
|
||||
}
|
||||
|
||||
static int rna_Sequence_frame_duration_get(PointerRNA *ptr)
|
||||
{
|
||||
Sequence *seq = (Sequence *)ptr->data;
|
||||
Scene *scene = (Scene *)ptr->owner_id;
|
||||
return SEQ_time_strip_length_get(scene, seq);
|
||||
}
|
||||
|
||||
static int rna_Sequence_frame_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
Sequence *seq = (Sequence *)ptr->data;
|
||||
|
@ -1594,12 +1624,12 @@ static void rna_def_retiming_handle(BlenderRNA *brna)
|
|||
"Handle mapped to particular frame that can be moved to change playback speed");
|
||||
RNA_def_struct_sdna(srna, "SeqRetimingHandle");
|
||||
|
||||
prop = RNA_def_property(srna, "timeline_frame", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "strip_frame_index");
|
||||
RNA_def_property_int_funcs(prop,
|
||||
"rna_Sequence_retiming_handle_frame_get",
|
||||
"rna_Sequence_retiming_handle_frame_set",
|
||||
NULL);
|
||||
prop = RNA_def_property(srna, "timeline_frame", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "strip_frame_index");
|
||||
RNA_def_property_float_funcs(prop,
|
||||
"rna_Sequence_retiming_handle_frame_get",
|
||||
"rna_Sequence_retiming_handle_frame_set",
|
||||
NULL);
|
||||
RNA_def_property_ui_text(prop, "Timeline Frame", "Position of retiming handle in timeline");
|
||||
|
||||
FunctionRNA *func = RNA_def_function(srna, "remove", "rna_Sequence_retiming_handle_remove");
|
||||
|
@ -2111,32 +2141,34 @@ static void rna_def_sequence(BlenderRNA *brna)
|
|||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Length", "The length of the contents of this strip after the handles are applied");
|
||||
RNA_def_property_int_funcs(
|
||||
prop, "rna_Sequence_frame_length_get", "rna_Sequence_frame_length_set", NULL);
|
||||
RNA_def_property_int_funcs(prop,
|
||||
"rna_Sequence_frame_final_duration_get",
|
||||
"rna_Sequence_frame_final_duration_set",
|
||||
NULL);
|
||||
RNA_def_property_editable_func(prop, "rna_Sequence_frame_editable");
|
||||
RNA_def_property_update(
|
||||
prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update");
|
||||
|
||||
prop = RNA_def_property(srna, "frame_duration", PROP_INT, PROP_TIME);
|
||||
RNA_def_property_int_sdna(prop, NULL, "len");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE | PROP_ANIMATABLE);
|
||||
RNA_def_property_range(prop, 1, MAXFRAME);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Length", "The length of the contents of this strip before the handles are applied");
|
||||
RNA_def_property_int_funcs(prop, "rna_Sequence_frame_duration_get", NULL, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_TIME);
|
||||
RNA_def_property_float_sdna(prop, NULL, "start");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Start Frame", "X position where the strip begins");
|
||||
RNA_def_property_ui_range(prop, MINFRAME, MAXFRAME, 100.0f, 0);
|
||||
RNA_def_property_float_funcs(
|
||||
prop, NULL, "rna_Sequence_start_frame_set", NULL); /* overlap tests and calc_seq_disp */
|
||||
RNA_def_property_ui_range(prop, MINFRAME, MAXFRAME, 3, 0);
|
||||
RNA_def_property_float_funcs(prop,
|
||||
"rna_Sequence_start_frame_get",
|
||||
"rna_Sequence_start_frame_set",
|
||||
NULL); /* overlap tests and calc_seq_disp */
|
||||
RNA_def_property_editable_func(prop, "rna_Sequence_frame_editable");
|
||||
RNA_def_property_update(
|
||||
prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update");
|
||||
|
||||
prop = RNA_def_property(srna, "frame_final_start", PROP_INT, PROP_TIME);
|
||||
RNA_def_property_int_sdna(prop, NULL, "startdisp");
|
||||
RNA_def_property_int_funcs(
|
||||
prop, "rna_Sequence_frame_final_start_get", "rna_Sequence_start_frame_final_set", NULL);
|
||||
RNA_def_property_editable_func(prop, "rna_Sequence_frame_editable");
|
||||
|
@ -2151,7 +2183,6 @@ static void rna_def_sequence(BlenderRNA *brna)
|
|||
prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update");
|
||||
|
||||
prop = RNA_def_property(srna, "frame_final_end", PROP_INT, PROP_TIME);
|
||||
RNA_def_property_int_sdna(prop, NULL, "enddisp");
|
||||
RNA_def_property_int_funcs(
|
||||
prop, "rna_Sequence_frame_final_end_get", "rna_Sequence_end_frame_final_set", NULL);
|
||||
RNA_def_property_editable_func(prop, "rna_Sequence_frame_editable");
|
||||
|
@ -2164,20 +2195,22 @@ static void rna_def_sequence(BlenderRNA *brna)
|
|||
|
||||
prop = RNA_def_property(srna, "frame_offset_start", PROP_FLOAT, PROP_TIME);
|
||||
RNA_def_property_float_sdna(prop, NULL, "startofs");
|
||||
// RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
|
||||
RNA_def_property_ui_text(prop, "Start Offset", "");
|
||||
RNA_def_property_ui_range(prop, MINFRAME, MAXFRAME, 100.0f, 0);
|
||||
RNA_def_property_float_funcs(
|
||||
prop, NULL, "rna_Sequence_frame_offset_start_set", "rna_Sequence_frame_offset_start_range");
|
||||
RNA_def_property_float_funcs(prop,
|
||||
"rna_Sequence_frame_offset_start_get",
|
||||
"rna_Sequence_frame_offset_start_set",
|
||||
"rna_Sequence_frame_offset_start_range");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_frame_change_update");
|
||||
|
||||
prop = RNA_def_property(srna, "frame_offset_end", PROP_FLOAT, PROP_TIME);
|
||||
RNA_def_property_float_sdna(prop, NULL, "endofs");
|
||||
// RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
|
||||
RNA_def_property_ui_text(prop, "End Offset", "");
|
||||
RNA_def_property_ui_range(prop, MINFRAME, MAXFRAME, 100.0f, 0);
|
||||
RNA_def_property_float_funcs(
|
||||
prop, NULL, "rna_Sequence_frame_offset_end_set", "rna_Sequence_frame_offset_end_range");
|
||||
RNA_def_property_float_funcs(prop,
|
||||
"rna_Sequence_frame_offset_end_get",
|
||||
"rna_Sequence_frame_offset_end_set",
|
||||
"rna_Sequence_frame_offset_end_range");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_frame_change_update");
|
||||
|
||||
prop = RNA_def_property(srna, "channel", PROP_INT, PROP_UNSIGNED);
|
||||
|
|
|
@ -578,9 +578,10 @@ static StripElem *rna_SequenceElements_append(ID *id, Sequence *seq, const char
|
|||
|
||||
seq->strip->stripdata = se = MEM_reallocN(seq->strip->stripdata,
|
||||
sizeof(StripElem) * (seq->len + 1));
|
||||
se += seq->len;
|
||||
STRNCPY(se->filename, filename);
|
||||
seq->len++;
|
||||
|
||||
/* se += seq->len; // XXX get size of se before realloc...
|
||||
BLI_strncpy(se->name, filename, sizeof(se->name));
|
||||
seq->len++;*/
|
||||
|
||||
seq->flag &= ~SEQ_SINGLE_FRAME_CONTENT;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ struct SeqRetimingHandle;
|
|||
|
||||
int SEQ_retiming_handles_count(const struct Sequence *seq);
|
||||
bool SEQ_retiming_is_active(const struct Sequence *seq);
|
||||
void SEQ_retiming_data_ensure(struct Sequence *seq);
|
||||
void SEQ_retiming_data_ensure(const struct Scene *scene, struct Sequence *seq);
|
||||
void SEQ_retiming_data_clear(struct Sequence *seq);
|
||||
bool SEQ_retiming_is_allowed(const struct Sequence *seq);
|
||||
|
||||
|
@ -46,7 +46,8 @@ void SEQ_retiming_offset_handle(const struct Scene *scene,
|
|||
struct Sequence *seq,
|
||||
struct SeqRetimingHandle *handle,
|
||||
const int offset);
|
||||
float SEQ_retiming_handle_speed_get(const struct Sequence *seq,
|
||||
float SEQ_retiming_handle_speed_get(const struct Scene *scene,
|
||||
const struct Sequence *seq,
|
||||
const struct SeqRetimingHandle *handle);
|
||||
void SEQ_retiming_handle_speed_set(const struct Scene *scene,
|
||||
struct Sequence *seq,
|
||||
|
@ -58,7 +59,8 @@ void SEQ_retiming_sound_animation_data_set(const struct Scene *scene, const stru
|
|||
float SEQ_retiming_handle_timeline_frame_get(const struct Scene *scene,
|
||||
const struct Sequence *seq,
|
||||
const struct SeqRetimingHandle *handle);
|
||||
const SeqRetimingHandle *SEQ_retiming_find_segment_start_handle(const struct Sequence *seq,
|
||||
const SeqRetimingHandle *SEQ_retiming_find_segment_start_handle(const struct Scene *scene,
|
||||
const struct Sequence *seq,
|
||||
const int frame_index);
|
||||
bool SEQ_retiming_handle_is_transition_type(const struct SeqRetimingHandle *handle);
|
||||
bool SEQ_retiming_handle_is_freeze_frame(const struct SeqRetimingHandle *handle);
|
||||
|
|
|
@ -67,7 +67,7 @@ struct ListBase *SEQ_active_seqbase_get(const struct Editing *ed);
|
|||
* \param seqbase: ListBase with strips
|
||||
*/
|
||||
void SEQ_seqbase_active_set(struct Editing *ed, struct ListBase *seqbase);
|
||||
struct Sequence *SEQ_sequence_alloc(ListBase *lb, int timeline_frame, int machine, int type);
|
||||
struct Sequence *SEQ_sequence_alloc(ListBase *lb, double start_time, int machine, int type);
|
||||
void SEQ_sequence_free(struct Scene *scene, struct Sequence *seq);
|
||||
/**
|
||||
* Get #MetaStack that corresponds to current level that is being viewed
|
||||
|
|
|
@ -114,6 +114,10 @@ void SEQ_time_right_handle_frame_set(const struct Scene *scene,
|
|||
* This can change depending on scene FPS or strip speed factor.
|
||||
*/
|
||||
int SEQ_time_strip_length_get(const struct Scene *scene, const struct Sequence *seq);
|
||||
void SEQ_time_strip_length_set(const struct Scene *scene,
|
||||
struct Sequence *seq,
|
||||
const double length_in_frames);
|
||||
|
||||
/**
|
||||
* Set strip playback speed.
|
||||
* Strip length is affected by changing speed factor.
|
||||
|
@ -124,7 +128,7 @@ void SEQ_time_speed_factor_set(const struct Scene *scene,
|
|||
/**
|
||||
* Get timeline frame where strip content starts.
|
||||
*/
|
||||
float SEQ_time_start_frame_get(const struct Sequence *seq);
|
||||
float SEQ_time_start_frame_get(const struct Scene *scene, const struct Sequence *seq);
|
||||
/**
|
||||
* Get timeline frame where strip content ends.
|
||||
*/
|
||||
|
@ -141,6 +145,9 @@ void SEQ_time_start_frame_set(const struct Scene *scene, struct Sequence *seq, i
|
|||
* \note this function is currently only used internally and in versioning code.
|
||||
*/
|
||||
void SEQ_time_update_meta_strip_range(const struct Scene *scene, struct Sequence *seq_meta);
|
||||
double SEQ_time_frames_to_seconds(const struct Scene *scene, const double frames);
|
||||
int SEQ_time_seconds_to_frames(const struct Scene *scene, const double seconds);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,8 @@ void SEQ_sequence_base_unique_name_recursive(struct Scene *scene,
|
|||
struct ListBase *seqbasep,
|
||||
struct Sequence *seq);
|
||||
const char *SEQ_sequence_give_name(struct Sequence *seq);
|
||||
struct ListBase *SEQ_get_seqbase_from_sequence(struct Sequence *seq,
|
||||
struct ListBase *SEQ_get_seqbase_from_sequence(const struct Scene *scene,
|
||||
struct Sequence *seq,
|
||||
struct ListBase **channels,
|
||||
int *r_offset);
|
||||
const struct Sequence *SEQ_get_topmost_sequence(const struct Scene *scene, int frame);
|
||||
|
|
|
@ -395,7 +395,7 @@ static void seq_disk_cache_delete_invalid_files(SeqDiskCache *disk_cache,
|
|||
if (cache_file->cache_type & invalidate_types) {
|
||||
if (STREQ(cache_dir, cache_file->dir)) {
|
||||
int timeline_frame_start = seq_cache_frame_index_to_timeline_frame(
|
||||
seq, cache_file->start_frame);
|
||||
scene, seq, cache_file->start_frame);
|
||||
if (timeline_frame_start > range_start && timeline_frame_start <= range_end) {
|
||||
seq_disk_cache_delete_file(disk_cache, cache_file);
|
||||
}
|
||||
|
|
|
@ -146,12 +146,12 @@ static float seq_cache_timeline_frame_to_frame_index(Scene *scene,
|
|||
return SEQ_give_frame_index(scene, seq, timeline_frame);
|
||||
}
|
||||
|
||||
return timeline_frame - SEQ_time_start_frame_get(seq);
|
||||
return timeline_frame - SEQ_time_start_frame_get(scene, seq);
|
||||
}
|
||||
|
||||
float seq_cache_frame_index_to_timeline_frame(Sequence *seq, float frame_index)
|
||||
float seq_cache_frame_index_to_timeline_frame(const Scene *scene, Sequence *seq, float frame_index)
|
||||
{
|
||||
return frame_index + SEQ_time_start_frame_get(seq);
|
||||
return frame_index + SEQ_time_start_frame_get(scene, seq);
|
||||
}
|
||||
|
||||
static SeqCache *seq_cache_get_from_scene(Scene *scene)
|
||||
|
|
|
@ -70,7 +70,9 @@ void seq_cache_cleanup_sequence(struct Scene *scene,
|
|||
bool force_seq_changed_range);
|
||||
void seq_cache_thumbnail_cleanup(Scene *scene, rctf *view_area);
|
||||
bool seq_cache_is_full(void);
|
||||
float seq_cache_frame_index_to_timeline_frame(struct Sequence *seq, float frame_index);
|
||||
float seq_cache_frame_index_to_timeline_frame(const struct Scene *scene,
|
||||
struct Sequence *seq,
|
||||
float frame_index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1646,7 +1646,7 @@ static ImBuf *do_render_strip_seqbase(const SeqRenderData *context,
|
|||
ListBase *channels = NULL;
|
||||
int offset;
|
||||
|
||||
seqbase = SEQ_get_seqbase_from_sequence(seq, &channels, &offset);
|
||||
seqbase = SEQ_get_seqbase_from_sequence(context->scene, seq, &channels, &offset);
|
||||
|
||||
if (seqbase && !BLI_listbase_is_empty(seqbase)) {
|
||||
|
||||
|
@ -2190,7 +2190,7 @@ void SEQ_render_thumbnails(const SeqRenderData *context,
|
|||
int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const Scene *scene, const Sequence *seq)
|
||||
{
|
||||
const int content_start = max_ii(SEQ_time_left_handle_frame_get(scene, seq),
|
||||
SEQ_time_start_frame_get(seq));
|
||||
SEQ_time_start_frame_get(scene, seq));
|
||||
const int content_end = min_ii(SEQ_time_right_handle_frame_get(scene, seq),
|
||||
SEQ_time_content_end_frame_get(scene, seq));
|
||||
const int content_len = content_end - content_start;
|
||||
|
|
|
@ -113,7 +113,7 @@ static void seq_free_strip(Strip *strip)
|
|||
MEM_freeN(strip);
|
||||
}
|
||||
|
||||
Sequence *SEQ_sequence_alloc(ListBase *lb, int timeline_frame, int machine, int type)
|
||||
Sequence *SEQ_sequence_alloc(ListBase *lb, double start_time, int machine, int type)
|
||||
{
|
||||
Sequence *seq;
|
||||
|
||||
|
@ -124,7 +124,7 @@ Sequence *SEQ_sequence_alloc(ListBase *lb, int timeline_frame, int machine, int
|
|||
seq->name[2] = 0;
|
||||
|
||||
seq->flag = SELECT;
|
||||
seq->start = timeline_frame;
|
||||
seq->start = start_time;
|
||||
seq->machine = machine;
|
||||
seq->sat = 1.0;
|
||||
seq->mul = 1.0;
|
||||
|
|
|
@ -47,15 +47,12 @@ static bool sequencer_refresh_sound_length_recursive(Main *bmain, Scene *scene,
|
|||
continue;
|
||||
}
|
||||
|
||||
int old = seq->len;
|
||||
float fac;
|
||||
|
||||
seq->len = MAX2(1, round((info.length - seq->sound->offset_time) * FPS));
|
||||
fac = (float)seq->len / (float)old;
|
||||
old = seq->startofs;
|
||||
seq->startofs *= fac;
|
||||
seq->endofs *= fac;
|
||||
seq->start += (old - seq->startofs); /* So that visual/"real" start frame does not change! */
|
||||
const int left_handle = SEQ_time_left_handle_frame_get(scene, seq);
|
||||
const int right_handle = SEQ_time_right_handle_frame_get(scene, seq);
|
||||
SEQ_time_strip_length_set(
|
||||
scene, seq, MAX2(1, round((info.length - seq->sound->offset_time) * FPS)));
|
||||
SEQ_time_left_handle_frame_set(scene, seq, left_handle);
|
||||
SEQ_time_right_handle_frame_set(scene, seq, right_handle);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
@ -98,7 +95,8 @@ void SEQ_sound_update_bounds(Scene *scene, Sequence *seq)
|
|||
if (seq->type == SEQ_TYPE_SCENE) {
|
||||
if (seq->scene && seq->scene_sound) {
|
||||
/* We have to take into account start frame of the sequence's scene! */
|
||||
int startofs = seq->startofs + seq->anim_startofs + seq->scene->r.sfra;
|
||||
int startofs = SEQ_time_seconds_to_frames(scene, seq->startofs + seq->anim_startofs) +
|
||||
seq->scene->r.sfra;
|
||||
|
||||
BKE_sound_move_scene_sound(scene,
|
||||
seq->scene_sound,
|
||||
|
|
|
@ -128,7 +128,7 @@ Sequence *SEQ_add_scene_strip(Scene *scene, ListBase *seqbase, SeqLoadData *load
|
|||
Sequence *seq = SEQ_sequence_alloc(
|
||||
seqbase, load_data->start_frame, load_data->channel, SEQ_TYPE_SCENE);
|
||||
seq->scene = load_data->scene;
|
||||
seq->len = load_data->scene->r.efra - load_data->scene->r.sfra + 1;
|
||||
SEQ_time_strip_length_set(scene, seq, load_data->scene->r.efra - load_data->scene->r.sfra + 1);
|
||||
id_us_ensure_real((ID *)load_data->scene);
|
||||
seq_add_set_name(scene, seq, load_data);
|
||||
seq_add_generic_update(scene, seq);
|
||||
|
@ -140,7 +140,7 @@ Sequence *SEQ_add_movieclip_strip(Scene *scene, ListBase *seqbase, SeqLoadData *
|
|||
Sequence *seq = SEQ_sequence_alloc(
|
||||
seqbase, load_data->start_frame, load_data->channel, SEQ_TYPE_MOVIECLIP);
|
||||
seq->clip = load_data->clip;
|
||||
seq->len = BKE_movieclip_get_duration(load_data->clip);
|
||||
SEQ_time_strip_length_set(scene, seq, BKE_movieclip_get_duration(load_data->clip));
|
||||
id_us_ensure_real((ID *)load_data->clip);
|
||||
seq_add_set_name(scene, seq, load_data);
|
||||
seq_add_generic_update(scene, seq);
|
||||
|
@ -152,7 +152,7 @@ Sequence *SEQ_add_mask_strip(Scene *scene, ListBase *seqbase, SeqLoadData *load_
|
|||
Sequence *seq = SEQ_sequence_alloc(
|
||||
seqbase, load_data->start_frame, load_data->channel, SEQ_TYPE_MASK);
|
||||
seq->mask = load_data->mask;
|
||||
seq->len = BKE_mask_get_duration(load_data->mask);
|
||||
SEQ_time_strip_length_set(scene, seq, BKE_mask_get_duration(load_data->mask));
|
||||
id_us_ensure_real((ID *)load_data->mask);
|
||||
seq_add_set_name(scene, seq, load_data);
|
||||
seq_add_generic_update(scene, seq);
|
||||
|
@ -161,8 +161,10 @@ Sequence *SEQ_add_mask_strip(Scene *scene, ListBase *seqbase, SeqLoadData *load_
|
|||
|
||||
Sequence *SEQ_add_effect_strip(Scene *scene, ListBase *seqbase, SeqLoadData *load_data)
|
||||
{
|
||||
Sequence *seq = SEQ_sequence_alloc(
|
||||
seqbase, load_data->start_frame, load_data->channel, load_data->effect.type);
|
||||
Sequence *seq = SEQ_sequence_alloc(seqbase,
|
||||
SEQ_time_frames_to_seconds(scene, load_data->start_frame),
|
||||
load_data->channel,
|
||||
load_data->effect.type);
|
||||
|
||||
seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE;
|
||||
struct SeqEffectHandle sh = SEQ_effect_handle_get(seq);
|
||||
|
@ -176,7 +178,7 @@ Sequence *SEQ_add_effect_strip(Scene *scene, ListBase *seqbase, SeqLoadData *loa
|
|||
}
|
||||
|
||||
if (!load_data->effect.seq1) {
|
||||
seq->len = 1; /* Effect is generator, set non zero length. */
|
||||
SEQ_time_strip_length_set(scene, seq, 0);
|
||||
seq->flag |= SEQ_SINGLE_FRAME_CONTENT;
|
||||
SEQ_time_right_handle_frame_set(scene, seq, load_data->effect.end_frame);
|
||||
}
|
||||
|
@ -196,7 +198,7 @@ void SEQ_add_image_set_directory(Sequence *seq, const char *dirpath)
|
|||
void SEQ_add_image_load_file(Scene *scene, Sequence *seq, size_t strip_frame, const char *filename)
|
||||
{
|
||||
StripElem *se = SEQ_render_give_stripelem(
|
||||
scene, seq, SEQ_time_start_frame_get(seq) + strip_frame);
|
||||
scene, seq, SEQ_time_start_frame_get(scene, seq) + strip_frame);
|
||||
STRNCPY(se->filename, filename);
|
||||
}
|
||||
|
||||
|
@ -234,7 +236,7 @@ Sequence *SEQ_add_image_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL
|
|||
{
|
||||
Sequence *seq = SEQ_sequence_alloc(
|
||||
seqbase, load_data->start_frame, load_data->channel, SEQ_TYPE_IMAGE);
|
||||
seq->len = load_data->image.len;
|
||||
SEQ_time_strip_length_set(scene, seq, load_data->image.len);
|
||||
Strip *strip = seq->strip;
|
||||
strip->stripdata = MEM_callocN(load_data->image.len * sizeof(StripElem), "stripelem");
|
||||
|
||||
|
@ -322,7 +324,7 @@ Sequence *SEQ_add_sound_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL
|
|||
* nearest frame as the audio track usually overshoots or undershoots the
|
||||
* end frame of the video by a little bit.
|
||||
* See #47135 for under shoot example. */
|
||||
seq->len = MAX2(1, round((info.length - sound->offset_time) * FPS));
|
||||
SEQ_time_strip_length_set(scene, seq, MAX2(1, round((info.length - sound->offset_time) * FPS)));
|
||||
|
||||
Strip *strip = seq->strip;
|
||||
/* We only need 1 element to store the filename. */
|
||||
|
@ -447,8 +449,10 @@ Sequence *SEQ_add_movie_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL
|
|||
load_data->r_video_stream_start = IMD_anim_get_offset(anim_arr[0]);
|
||||
}
|
||||
|
||||
Sequence *seq = SEQ_sequence_alloc(
|
||||
seqbase, load_data->start_frame, load_data->channel, SEQ_TYPE_MOVIE);
|
||||
Sequence *seq = SEQ_sequence_alloc(seqbase,
|
||||
SEQ_time_frames_to_seconds(scene, load_data->start_frame),
|
||||
load_data->channel,
|
||||
SEQ_TYPE_MOVIE);
|
||||
|
||||
/* Multiview settings. */
|
||||
if (load_data->use_multiview) {
|
||||
|
@ -471,7 +475,7 @@ Sequence *SEQ_add_movie_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL
|
|||
}
|
||||
|
||||
if (anim_arr[0] != NULL) {
|
||||
seq->len = IMB_anim_get_duration(anim_arr[0], IMB_TC_RECORD_RUN);
|
||||
SEQ_time_strip_length_set(scene, seq, IMB_anim_get_duration(anim_arr[0], IMB_TC_RECORD_RUN));
|
||||
|
||||
IMB_anim_load_metadata(anim_arr[0]);
|
||||
|
||||
|
@ -488,7 +492,7 @@ Sequence *SEQ_add_movie_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL
|
|||
}
|
||||
}
|
||||
|
||||
seq->len = MAX2(1, seq->len);
|
||||
seq->len = MAX2(SEQ_time_frames_to_seconds(scene, 1), seq->len); // XXX
|
||||
if (load_data->adjust_playback_rate) {
|
||||
seq->flag |= SEQ_AUTO_PLAYBACK_RATE;
|
||||
}
|
||||
|
@ -536,17 +540,17 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo
|
|||
prev_enddisp = SEQ_time_right_handle_frame_get(scene, seq);
|
||||
}
|
||||
|
||||
int length;
|
||||
switch (seq->type) {
|
||||
case SEQ_TYPE_IMAGE: {
|
||||
/* Hack? */
|
||||
size_t olen = MEM_allocN_len(seq->strip->stripdata) / sizeof(StripElem);
|
||||
|
||||
seq->len = olen;
|
||||
seq->len -= seq->anim_startofs;
|
||||
seq->len -= seq->anim_endofs;
|
||||
if (seq->len < 0) {
|
||||
seq->len = 0;
|
||||
length = olen - seq->anim_startofs - seq->anim_endofs;
|
||||
if (length < 0) {
|
||||
length = 0;
|
||||
}
|
||||
SEQ_time_strip_length_set(scene, seq, length);
|
||||
break;
|
||||
}
|
||||
case SEQ_TYPE_MOVIE: {
|
||||
|
@ -614,14 +618,15 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo
|
|||
|
||||
IMB_anim_load_metadata(sanim->anim);
|
||||
|
||||
seq->len = IMB_anim_get_duration(
|
||||
length = IMB_anim_get_duration(
|
||||
sanim->anim, seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN);
|
||||
|
||||
seq->len -= seq->anim_startofs;
|
||||
seq->len -= seq->anim_endofs;
|
||||
if (seq->len < 0) {
|
||||
seq->len = 0;
|
||||
length -= seq->anim_startofs;
|
||||
length -= seq->anim_endofs;
|
||||
if (length < 0) {
|
||||
length = 0;
|
||||
}
|
||||
SEQ_time_strip_length_set(scene, seq, length);
|
||||
break;
|
||||
}
|
||||
case SEQ_TYPE_MOVIECLIP:
|
||||
|
@ -629,48 +634,52 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo
|
|||
return;
|
||||
}
|
||||
|
||||
seq->len = BKE_movieclip_get_duration(seq->clip);
|
||||
length = BKE_movieclip_get_duration(seq->clip);
|
||||
|
||||
seq->len -= seq->anim_startofs;
|
||||
seq->len -= seq->anim_endofs;
|
||||
if (seq->len < 0) {
|
||||
seq->len = 0;
|
||||
length -= seq->anim_startofs;
|
||||
length -= seq->anim_endofs;
|
||||
if (length < 0) {
|
||||
length = 0;
|
||||
}
|
||||
SEQ_time_strip_length_set(scene, seq, length);
|
||||
break;
|
||||
case SEQ_TYPE_MASK:
|
||||
if (seq->mask == NULL) {
|
||||
return;
|
||||
}
|
||||
seq->len = BKE_mask_get_duration(seq->mask);
|
||||
seq->len -= seq->anim_startofs;
|
||||
seq->len -= seq->anim_endofs;
|
||||
if (seq->len < 0) {
|
||||
seq->len = 0;
|
||||
length = BKE_mask_get_duration(seq->mask);
|
||||
length -= seq->anim_startofs;
|
||||
length -= seq->anim_endofs;
|
||||
if (length < 0) {
|
||||
length = 0;
|
||||
}
|
||||
SEQ_time_strip_length_set(scene, seq, length);
|
||||
break;
|
||||
case SEQ_TYPE_SOUND_RAM:
|
||||
#ifdef WITH_AUDASPACE
|
||||
if (!seq->sound) {
|
||||
return;
|
||||
}
|
||||
seq->len = ceil((double)BKE_sound_get_length(bmain, seq->sound) * FPS);
|
||||
seq->len -= seq->anim_startofs;
|
||||
seq->len -= seq->anim_endofs;
|
||||
if (seq->len < 0) {
|
||||
seq->len = 0;
|
||||
length = ceil((double)BKE_sound_get_length(bmain, seq->sound) * FPS);
|
||||
length -= seq->anim_startofs;
|
||||
length -= seq->anim_endofs;
|
||||
if (length < 0) {
|
||||
length = 0;
|
||||
}
|
||||
SEQ_time_strip_length_set(scene, seq, length);
|
||||
#else
|
||||
UNUSED_VARS(bmain);
|
||||
return;
|
||||
#endif
|
||||
break;
|
||||
case SEQ_TYPE_SCENE: {
|
||||
seq->len = (seq->scene) ? seq->scene->r.efra - seq->scene->r.sfra + 1 : 0;
|
||||
seq->len -= seq->anim_startofs;
|
||||
seq->len -= seq->anim_endofs;
|
||||
if (seq->len < 0) {
|
||||
seq->len = 0;
|
||||
length = (seq->scene) ? seq->scene->r.efra - seq->scene->r.sfra + 1 : 0;
|
||||
length -= seq->anim_startofs;
|
||||
length -= seq->anim_endofs;
|
||||
if (length < 0) {
|
||||
length = 0;
|
||||
}
|
||||
SEQ_time_strip_length_set(scene, seq, length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -264,7 +264,7 @@ static void seq_split_set_right_hold_offset(Main *bmain,
|
|||
Sequence *seq,
|
||||
int timeline_frame)
|
||||
{
|
||||
const float content_start = SEQ_time_start_frame_get(seq);
|
||||
const float content_start = SEQ_time_start_frame_get(scene, seq);
|
||||
const float content_end = SEQ_time_content_end_frame_get(scene, seq);
|
||||
|
||||
/* Adjust within range of extended still-frames before strip. */
|
||||
|
@ -290,7 +290,7 @@ static void seq_split_set_left_hold_offset(Main *bmain,
|
|||
Sequence *seq,
|
||||
int timeline_frame)
|
||||
{
|
||||
const float content_start = SEQ_time_start_frame_get(seq);
|
||||
const float content_start = SEQ_time_start_frame_get(scene, seq);
|
||||
const float content_end = SEQ_time_content_end_frame_get(scene, seq);
|
||||
|
||||
/* Adjust within range of strip contents. */
|
||||
|
|
|
@ -65,7 +65,8 @@ static bool seq_retiming_is_last_handle(const Sequence *seq, const SeqRetimingHa
|
|||
return SEQ_retiming_handle_index_get(seq, handle) == seq->retiming_handle_num - 1;
|
||||
}
|
||||
|
||||
const SeqRetimingHandle *SEQ_retiming_find_segment_start_handle(const Sequence *seq,
|
||||
const SeqRetimingHandle *SEQ_retiming_find_segment_start_handle(const Scene *scene,
|
||||
const Sequence *seq,
|
||||
const int frame_index)
|
||||
{
|
||||
const SeqRetimingHandle *start_handle = nullptr;
|
||||
|
@ -73,7 +74,7 @@ const SeqRetimingHandle *SEQ_retiming_find_segment_start_handle(const Sequence *
|
|||
if (seq_retiming_is_last_handle(seq, &handle)) {
|
||||
break;
|
||||
}
|
||||
if (handle.strip_frame_index > frame_index) {
|
||||
if (handle.strip_frame_index > SEQ_time_frames_to_seconds(scene, frame_index)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -88,7 +89,7 @@ int SEQ_retiming_handles_count(const Sequence *seq)
|
|||
return seq->retiming_handle_num;
|
||||
}
|
||||
|
||||
void SEQ_retiming_data_ensure(Sequence *seq)
|
||||
void SEQ_retiming_data_ensure(const Scene *scene, Sequence *seq)
|
||||
{
|
||||
if (!SEQ_retiming_is_allowed(seq)) {
|
||||
return;
|
||||
|
@ -129,16 +130,19 @@ bool SEQ_retiming_is_allowed(const Sequence *seq)
|
|||
SEQ_TYPE_MASK);
|
||||
}
|
||||
|
||||
static int seq_retiming_segment_length_get(const SeqRetimingHandle *start_handle)
|
||||
static int seq_retiming_segment_length_get(const Scene *scene,
|
||||
const SeqRetimingHandle *start_handle)
|
||||
{
|
||||
const SeqRetimingHandle *end_handle = start_handle + 1;
|
||||
return end_handle->strip_frame_index - start_handle->strip_frame_index;
|
||||
return SEQ_time_seconds_to_frames(
|
||||
scene, end_handle->strip_frame_index - start_handle->strip_frame_index);
|
||||
}
|
||||
|
||||
static float seq_retiming_segment_step_get(const SeqRetimingHandle *start_handle)
|
||||
static float seq_retiming_segment_step_get(const Scene *scene,
|
||||
const SeqRetimingHandle *start_handle)
|
||||
{
|
||||
const SeqRetimingHandle *end_handle = start_handle + 1;
|
||||
const int segment_length = seq_retiming_segment_length_get(start_handle);
|
||||
const int segment_length = seq_retiming_segment_length_get(scene, start_handle);
|
||||
const float segment_fac_diff = end_handle->retiming_factor - start_handle->retiming_factor;
|
||||
return segment_fac_diff / segment_length;
|
||||
}
|
||||
|
@ -199,41 +203,45 @@ bool SEQ_retiming_handle_is_freeze_frame(const SeqRetimingHandle *handle)
|
|||
/* Check colinearity of 2 segments allowing for some imprecision.
|
||||
* `isect_seg_seg_v2_lambda_mu_db()` return value does not work well in this case. */
|
||||
|
||||
static bool seq_retiming_transition_is_linear(const Sequence *seq, const SeqRetimingHandle *handle)
|
||||
static bool seq_retiming_transition_is_linear(const Scene *scene,
|
||||
const Sequence *seq,
|
||||
const SeqRetimingHandle *handle)
|
||||
{
|
||||
const float prev_speed = SEQ_retiming_handle_speed_get(seq, handle - 1);
|
||||
const float next_speed = SEQ_retiming_handle_speed_get(seq, handle + 1);
|
||||
const float prev_speed = SEQ_retiming_handle_speed_get(scene, seq, handle - 1);
|
||||
const float next_speed = SEQ_retiming_handle_speed_get(scene, seq, handle + 1);
|
||||
|
||||
return abs(prev_speed - next_speed) < 0.01f;
|
||||
}
|
||||
|
||||
static float seq_retiming_evaluate_arc_segment(const SeqRetimingHandle *handle,
|
||||
const float frame_index)
|
||||
const float eval_time)
|
||||
{
|
||||
double c[2], r;
|
||||
seq_retiming_line_segments_tangent_circle(handle, c, &r);
|
||||
const int side = c[1] > handle->retiming_factor ? -1 : 1;
|
||||
const float y = c[1] + side * sqrt(pow(r, 2) - pow((frame_index - c[0]), 2));
|
||||
const float y = c[1] + side * sqrt(pow(r, 2) - pow((eval_time - c[0]), 2));
|
||||
return y;
|
||||
}
|
||||
|
||||
float seq_retiming_evaluate(const Sequence *seq, const float frame_index)
|
||||
float seq_retiming_evaluate(const Scene *scene, const Sequence *seq, const float frame_index)
|
||||
{
|
||||
const SeqRetimingHandle *start_handle = SEQ_retiming_find_segment_start_handle(seq, frame_index);
|
||||
const SeqRetimingHandle *start_handle = SEQ_retiming_find_segment_start_handle(
|
||||
scene, seq, frame_index);
|
||||
const double eval_time = SEQ_time_frames_to_seconds(scene, frame_index);
|
||||
|
||||
const int start_handle_index = start_handle - seq->retiming_handles;
|
||||
BLI_assert(start_handle_index < seq->retiming_handle_num);
|
||||
|
||||
const float segment_frame_index = frame_index - start_handle->strip_frame_index;
|
||||
const float segment_eval_time = eval_time - start_handle->strip_frame_index;
|
||||
|
||||
if (!SEQ_retiming_handle_is_transition_type(start_handle)) {
|
||||
const float segment_step = seq_retiming_segment_step_get(start_handle);
|
||||
return start_handle->retiming_factor + segment_step * segment_frame_index;
|
||||
const float segment_step = seq_retiming_segment_step_get(scene, start_handle);
|
||||
return start_handle->retiming_factor + segment_step * segment_eval_time;
|
||||
}
|
||||
|
||||
if (seq_retiming_transition_is_linear(seq, start_handle)) {
|
||||
const float segment_step = seq_retiming_segment_step_get(start_handle - 1);
|
||||
return start_handle->retiming_factor + segment_step * segment_frame_index;
|
||||
if (seq_retiming_transition_is_linear(scene, seq, start_handle)) {
|
||||
const float segment_step = seq_retiming_segment_step_get(scene, start_handle - 1);
|
||||
return start_handle->retiming_factor + segment_step * segment_eval_time;
|
||||
}
|
||||
|
||||
/* Sanity check for transition type. */
|
||||
|
@ -241,18 +249,19 @@ float seq_retiming_evaluate(const Sequence *seq, const float frame_index)
|
|||
BLI_assert(start_handle_index < seq->retiming_handle_num - 1);
|
||||
UNUSED_VARS_NDEBUG(start_handle_index);
|
||||
|
||||
return seq_retiming_evaluate_arc_segment(start_handle, frame_index);
|
||||
return seq_retiming_evaluate_arc_segment(start_handle, eval_time);
|
||||
}
|
||||
|
||||
SeqRetimingHandle *SEQ_retiming_add_handle(const Scene *scene,
|
||||
Sequence *seq,
|
||||
const int timeline_frame)
|
||||
{
|
||||
float frame_index = (timeline_frame - SEQ_time_start_frame_get(seq)) *
|
||||
float frame_index = (timeline_frame - SEQ_time_start_frame_get(scene, seq)) *
|
||||
seq_time_media_playback_rate_factor_get(scene, seq);
|
||||
float value = seq_retiming_evaluate(seq, frame_index);
|
||||
float value = seq_retiming_evaluate(scene, seq, frame_index);
|
||||
|
||||
const SeqRetimingHandle *start_handle = SEQ_retiming_find_segment_start_handle(seq, frame_index);
|
||||
const SeqRetimingHandle *start_handle = SEQ_retiming_find_segment_start_handle(
|
||||
scene, seq, frame_index);
|
||||
if (start_handle->strip_frame_index == frame_index) {
|
||||
return nullptr; /* Retiming handle already exists. */
|
||||
}
|
||||
|
@ -284,7 +293,7 @@ SeqRetimingHandle *SEQ_retiming_add_handle(const Scene *scene,
|
|||
seq->retiming_handle_num++;
|
||||
|
||||
SeqRetimingHandle *added_handle = (new_handles + new_handle_index);
|
||||
added_handle->strip_frame_index = frame_index;
|
||||
added_handle->strip_frame_index = SEQ_time_frames_to_seconds(scene, frame_index);
|
||||
added_handle->retiming_factor = value;
|
||||
|
||||
return added_handle;
|
||||
|
@ -298,7 +307,7 @@ static void seq_retiming_offset_linear_handle(const Scene *scene,
|
|||
MutableSpan handles = SEQ_retiming_handles_get(seq);
|
||||
|
||||
for (SeqRetimingHandle *next_handle = handle; next_handle < handles.end(); next_handle++) {
|
||||
next_handle->strip_frame_index += offset * seq_time_media_playback_rate_factor_get(scene, seq);
|
||||
next_handle->strip_frame_index += SEQ_time_frames_to_seconds(scene, offset);
|
||||
}
|
||||
|
||||
/* Handle affected transitions: remove and re-create transition. This way transition won't change
|
||||
|
@ -310,8 +319,9 @@ static void seq_retiming_offset_linear_handle(const Scene *scene,
|
|||
{
|
||||
SeqRetimingHandle *transition_handle = handle - 2;
|
||||
|
||||
const int transition_offset = transition_handle->strip_frame_index -
|
||||
transition_handle->original_strip_frame_index;
|
||||
const int transition_offset = SEQ_time_seconds_to_frames(
|
||||
scene,
|
||||
transition_handle->strip_frame_index - transition_handle->original_strip_frame_index);
|
||||
|
||||
const int transition_handle_index = SEQ_retiming_handle_index_get(seq, transition_handle);
|
||||
|
||||
|
@ -358,13 +368,15 @@ static void seq_retiming_offset_transition_handle(const Scene *scene,
|
|||
end_frame - SEQ_retiming_handle_timeline_frame_get(scene, seq, next_segment_start) - 1;
|
||||
corrected_offset = max_iii(corrected_offset, offset_min_left, offset_min_right);
|
||||
|
||||
const float prev_segment_step = seq_retiming_segment_step_get(handle_start - 1);
|
||||
const float next_segment_step = seq_retiming_segment_step_get(handle_end);
|
||||
const float prev_segment_step = seq_retiming_segment_step_get(scene, handle_start - 1);
|
||||
const float next_segment_step = seq_retiming_segment_step_get(scene, handle_end);
|
||||
|
||||
handle_start->strip_frame_index += corrected_offset;
|
||||
handle_start->retiming_factor += corrected_offset * prev_segment_step;
|
||||
handle_end->strip_frame_index -= corrected_offset;
|
||||
handle_end->retiming_factor -= corrected_offset * next_segment_step;
|
||||
handle_start->strip_frame_index += SEQ_time_frames_to_seconds(scene, corrected_offset);
|
||||
handle_start->retiming_factor += SEQ_time_frames_to_seconds(scene, corrected_offset) *
|
||||
prev_segment_step;
|
||||
handle_end->strip_frame_index -= SEQ_time_frames_to_seconds(scene, corrected_offset);
|
||||
handle_end->retiming_factor -= SEQ_time_frames_to_seconds(scene, corrected_offset) *
|
||||
next_segment_step;
|
||||
}
|
||||
|
||||
void SEQ_retiming_offset_handle(const Scene *scene,
|
||||
|
@ -441,7 +453,9 @@ static void seq_retiming_remove_transition(const Scene *scene,
|
|||
|
||||
/* Create original linear handle. */
|
||||
SeqRetimingHandle *orig_handle = SEQ_retiming_add_handle(
|
||||
scene, seq, SEQ_time_start_frame_get(seq) + orig_frame_index);
|
||||
scene,
|
||||
seq,
|
||||
SEQ_time_start_frame_get(scene, seq) + SEQ_time_seconds_to_frames(scene, orig_frame_index));
|
||||
orig_handle->retiming_factor = orig_retiming_factor;
|
||||
}
|
||||
|
||||
|
@ -516,7 +530,9 @@ SeqRetimingHandle *SEQ_retiming_add_transition(const Scene *scene,
|
|||
return seq->retiming_handles + orig_handle_index;
|
||||
}
|
||||
|
||||
float SEQ_retiming_handle_speed_get(const Sequence *seq, const SeqRetimingHandle *handle)
|
||||
float SEQ_retiming_handle_speed_get(const Scene *scene,
|
||||
const Sequence *seq,
|
||||
const SeqRetimingHandle *handle)
|
||||
{
|
||||
if (handle->strip_frame_index == 0) {
|
||||
return 1.0f;
|
||||
|
@ -524,7 +540,7 @@ float SEQ_retiming_handle_speed_get(const Sequence *seq, const SeqRetimingHandle
|
|||
|
||||
const SeqRetimingHandle *handle_prev = handle - 1;
|
||||
|
||||
const int frame_index_max = seq->len - 1;
|
||||
const int frame_index_max = SEQ_time_seconds_to_frames(scene, seq->len);
|
||||
const int frame_retimed_prev = round_fl_to_int(handle_prev->retiming_factor * frame_index_max);
|
||||
const int frame_index_prev = handle_prev->strip_frame_index;
|
||||
const int frame_retimed = round_fl_to_int(handle->retiming_factor * frame_index_max);
|
||||
|
@ -580,12 +596,17 @@ class RetimingRange {
|
|||
blender::Vector<float> speed_table;
|
||||
|
||||
eRangeType type;
|
||||
RetimingRange(const Sequence *seq, int start_frame, int end_frame, float speed, eRangeType type)
|
||||
RetimingRange(const Scene *scene,
|
||||
const Sequence *seq,
|
||||
int start_frame,
|
||||
int end_frame,
|
||||
float speed,
|
||||
eRangeType type)
|
||||
: start(start_frame), end(end_frame), speed(speed), type(type)
|
||||
{
|
||||
if (type == TRANSITION) {
|
||||
speed = 1.0f;
|
||||
claculate_speed_table_from_seq(seq);
|
||||
claculate_speed_table_from_seq(scene, seq);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -665,15 +686,15 @@ class RetimingRange {
|
|||
return new_range;
|
||||
}
|
||||
|
||||
void claculate_speed_table_from_seq(const Sequence *seq)
|
||||
void claculate_speed_table_from_seq(const Scene *scene, const Sequence *seq)
|
||||
{
|
||||
for (int frame = start; frame <= end; frame++) {
|
||||
/* We need number actual number of frames here. */
|
||||
const double normal_step = 1 / double(seq->len);
|
||||
|
||||
/* Who needs calculus, when you can have slow code? */
|
||||
const double val_prev = seq_retiming_evaluate(seq, frame - 1);
|
||||
const double val = seq_retiming_evaluate(seq, frame);
|
||||
const double val_prev = seq_retiming_evaluate(scene, seq, frame - 1);
|
||||
const double val = seq_retiming_evaluate(scene, seq, frame);
|
||||
const double speed_at_frame = (val - val_prev) / normal_step;
|
||||
speed_table.append(speed_at_frame);
|
||||
}
|
||||
|
@ -700,7 +721,7 @@ class RetimingRange {
|
|||
class RetimingRangeData {
|
||||
public:
|
||||
blender::Vector<RetimingRange> ranges;
|
||||
RetimingRangeData(const Sequence *seq)
|
||||
RetimingRangeData(const Scene *scene, const Sequence *seq)
|
||||
{
|
||||
MutableSpan handles = SEQ_retiming_handles_get(seq);
|
||||
for (const SeqRetimingHandle &handle : handles) {
|
||||
|
@ -708,12 +729,12 @@ class RetimingRangeData {
|
|||
continue;
|
||||
}
|
||||
const SeqRetimingHandle *handle_prev = &handle - 1;
|
||||
float speed = SEQ_retiming_handle_speed_get(seq, &handle);
|
||||
int frame_start = SEQ_time_start_frame_get(seq) + handle_prev->strip_frame_index;
|
||||
int frame_end = SEQ_time_start_frame_get(seq) + handle.strip_frame_index;
|
||||
float speed = SEQ_retiming_handle_speed_get(scene, seq, &handle);
|
||||
int frame_start = SEQ_retiming_handle_timeline_frame_get(scene, seq, handle_prev);
|
||||
int frame_end = SEQ_retiming_handle_timeline_frame_get(scene, seq, &handle);
|
||||
|
||||
eRangeType type = SEQ_retiming_handle_is_transition_type(handle_prev) ? TRANSITION : LINEAR;
|
||||
RetimingRange range = RetimingRange(seq, frame_start, frame_end, speed, type);
|
||||
RetimingRange range = RetimingRange(scene, seq, frame_start, frame_end, speed, type);
|
||||
ranges.append(range);
|
||||
}
|
||||
}
|
||||
|
@ -765,14 +786,14 @@ class RetimingRangeData {
|
|||
|
||||
static RetimingRangeData seq_retiming_range_data_get(const Scene *scene, const Sequence *seq)
|
||||
{
|
||||
RetimingRangeData strip_retiming_data = RetimingRangeData(seq);
|
||||
RetimingRangeData strip_retiming_data = RetimingRangeData(scene, seq);
|
||||
|
||||
const Sequence *meta_parent = seq_sequence_lookup_meta_by_seq(scene, seq);
|
||||
if (meta_parent == nullptr) {
|
||||
return strip_retiming_data;
|
||||
}
|
||||
|
||||
RetimingRangeData meta_retiming_data = RetimingRangeData(meta_parent);
|
||||
RetimingRangeData meta_retiming_data = RetimingRangeData(scene, meta_parent);
|
||||
strip_retiming_data *= meta_retiming_data;
|
||||
return strip_retiming_data;
|
||||
}
|
||||
|
@ -802,6 +823,6 @@ float SEQ_retiming_handle_timeline_frame_get(const Scene *scene,
|
|||
const Sequence *seq,
|
||||
const SeqRetimingHandle *handle)
|
||||
{
|
||||
return SEQ_time_start_frame_get(seq) +
|
||||
handle->strip_frame_index / seq_time_media_playback_rate_factor_get(scene, seq);
|
||||
return SEQ_time_start_frame_get(scene, seq) +
|
||||
SEQ_time_seconds_to_frames(scene, handle->strip_frame_index);
|
||||
}
|
||||
|
|
|
@ -66,9 +66,10 @@ int seq_time_strip_original_content_length_get(const Scene *scene, const Sequenc
|
|||
float SEQ_give_frame_index(const Scene *scene, Sequence *seq, float timeline_frame)
|
||||
{
|
||||
float frame_index;
|
||||
float sta = SEQ_time_start_frame_get(seq);
|
||||
float sta = SEQ_time_start_frame_get(scene, seq);
|
||||
float end = SEQ_time_content_end_frame_get(scene, seq) - 1;
|
||||
const float length = seq->len;
|
||||
const float length = SEQ_time_seconds_to_frames(scene, seq->len) *
|
||||
seq_time_media_playback_rate_factor_get(scene, seq);
|
||||
|
||||
if (seq->type & SEQ_TYPE_EFFECT) {
|
||||
end = SEQ_time_right_handle_frame_get(scene, seq);
|
||||
|
@ -94,7 +95,7 @@ float SEQ_give_frame_index(const Scene *scene, Sequence *seq, float timeline_fra
|
|||
frame_index *= seq_time_media_playback_rate_factor_get(scene, seq);
|
||||
|
||||
if (SEQ_retiming_is_active(seq)) {
|
||||
const float retiming_factor = seq_retiming_evaluate(seq, frame_index);
|
||||
const float retiming_factor = seq_retiming_evaluate(scene, seq, frame_index);
|
||||
frame_index = retiming_factor * (length);
|
||||
}
|
||||
/* Clamp frame index to strip content frame range. */
|
||||
|
@ -110,17 +111,6 @@ float SEQ_give_frame_index(const Scene *scene, Sequence *seq, float timeline_fra
|
|||
|
||||
return frame_index;
|
||||
}
|
||||
|
||||
static int metaseq_start(Sequence *metaseq)
|
||||
{
|
||||
return metaseq->start + metaseq->startofs;
|
||||
}
|
||||
|
||||
static int metaseq_end(Sequence *metaseq)
|
||||
{
|
||||
return metaseq->start + metaseq->len - metaseq->endofs;
|
||||
}
|
||||
|
||||
static void seq_update_sound_bounds_recursive_impl(const Scene *scene,
|
||||
Sequence *metaseq,
|
||||
int start,
|
||||
|
@ -133,18 +123,23 @@ static void seq_update_sound_bounds_recursive_impl(const Scene *scene,
|
|||
for (seq = metaseq->seqbase.first; seq; seq = seq->next) {
|
||||
if (seq->type == SEQ_TYPE_META) {
|
||||
seq_update_sound_bounds_recursive_impl(
|
||||
scene, seq, max_ii(start, metaseq_start(seq)), min_ii(end, metaseq_end(seq)));
|
||||
scene,
|
||||
seq,
|
||||
max_ii(start, SEQ_time_left_handle_frame_get(scene, seq)),
|
||||
min_ii(end, SEQ_time_right_handle_frame_get(scene, seq)));
|
||||
}
|
||||
else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
|
||||
if (seq->scene_sound) {
|
||||
int startofs = seq->startofs;
|
||||
int endofs = seq->endofs;
|
||||
if (seq->startofs + seq->start < start) {
|
||||
startofs = start - seq->start;
|
||||
int start_frame = SEQ_time_start_frame_get(scene, seq);
|
||||
int length = SEQ_time_strip_length_get(scene, seq);
|
||||
int startofs = SEQ_time_seconds_to_frames(scene, seq->startofs);
|
||||
int endofs = SEQ_time_seconds_to_frames(scene, seq->endofs);
|
||||
if (startofs + start_frame < start) {
|
||||
startofs = start - start_frame;
|
||||
}
|
||||
|
||||
if (seq->start + seq->len - seq->endofs > end) {
|
||||
endofs = seq->start + seq->len - end;
|
||||
if (start_frame + length - endofs > end) {
|
||||
endofs = start_frame + length - end;
|
||||
}
|
||||
|
||||
double offset_time = 0.0f;
|
||||
|
@ -154,8 +149,8 @@ static void seq_update_sound_bounds_recursive_impl(const Scene *scene,
|
|||
|
||||
BKE_sound_move_scene_sound(scene,
|
||||
seq->scene_sound,
|
||||
seq->start + startofs,
|
||||
seq->start + seq->len - endofs,
|
||||
start_frame + startofs,
|
||||
start_frame + length - endofs,
|
||||
startofs + seq->anim_startofs,
|
||||
offset_time);
|
||||
}
|
||||
|
@ -165,8 +160,10 @@ static void seq_update_sound_bounds_recursive_impl(const Scene *scene,
|
|||
|
||||
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));
|
||||
seq_update_sound_bounds_recursive_impl(scene,
|
||||
metaseq,
|
||||
SEQ_time_left_handle_frame_get(scene, metaseq),
|
||||
SEQ_time_right_handle_frame_get(scene, metaseq));
|
||||
}
|
||||
|
||||
void SEQ_time_update_meta_strip_range(const Scene *scene, Sequence *seq_meta)
|
||||
|
@ -233,8 +230,8 @@ void seq_time_effect_range_set(const Scene *scene, Sequence *seq)
|
|||
|
||||
/* Values unusable for effects, these should be always 0. */
|
||||
seq->startofs = seq->endofs = seq->anim_startofs = seq->anim_endofs = 0;
|
||||
seq->start = seq->startdisp;
|
||||
seq->len = seq->enddisp - seq->startdisp;
|
||||
seq->start = SEQ_time_frames_to_seconds(scene, seq->startdisp);
|
||||
seq->len = SEQ_time_frames_to_seconds(scene, seq->enddisp - seq->startdisp);
|
||||
}
|
||||
|
||||
void seq_time_update_effects_strip_range(const Scene *scene, SeqCollection *effects)
|
||||
|
@ -489,7 +486,7 @@ void SEQ_time_speed_factor_set(const Scene *scene, Sequence *seq, const float sp
|
|||
|
||||
bool SEQ_time_has_left_still_frames(const Scene *scene, const Sequence *seq)
|
||||
{
|
||||
return SEQ_time_left_handle_frame_get(scene, seq) < SEQ_time_start_frame_get(seq);
|
||||
return SEQ_time_left_handle_frame_get(scene, seq) < SEQ_time_start_frame_get(scene, seq);
|
||||
}
|
||||
|
||||
bool SEQ_time_has_right_still_frames(const Scene *scene, const Sequence *seq)
|
||||
|
@ -502,42 +499,49 @@ bool SEQ_time_has_still_frames(const Scene *scene, const Sequence *seq)
|
|||
return SEQ_time_has_right_still_frames(scene, seq) || SEQ_time_has_left_still_frames(scene, seq);
|
||||
}
|
||||
|
||||
void SEQ_time_strip_length_set(const Scene *scene, Sequence *seq, double length_in_frames)
|
||||
{
|
||||
seq->len = SEQ_time_frames_to_seconds(scene, length_in_frames);
|
||||
}
|
||||
|
||||
int SEQ_time_strip_length_get(const Scene *scene, const Sequence *seq)
|
||||
{
|
||||
if (SEQ_retiming_is_active(seq)) {
|
||||
SeqRetimingHandle *handle_start = seq->retiming_handles;
|
||||
SeqRetimingHandle *handle_end = seq->retiming_handles + (SEQ_retiming_handles_count(seq) - 1);
|
||||
return handle_end->strip_frame_index / seq_time_media_playback_rate_factor_get(scene, seq) -
|
||||
(handle_start->strip_frame_index) / seq_time_media_playback_rate_factor_get(scene, seq);
|
||||
return SEQ_time_seconds_to_frames(
|
||||
scene, handle_end->strip_frame_index - handle_start->strip_frame_index);
|
||||
}
|
||||
|
||||
return seq->len / seq_time_media_playback_rate_factor_get(scene, seq);
|
||||
/* XXX it was seq->len / seq_time_media_playback_rate_factor_get(scene, seq) but now it doesn't
|
||||
* make sense, because playback rate factor does not influence length. */
|
||||
return SEQ_time_seconds_to_frames(scene, seq->len);
|
||||
}
|
||||
|
||||
float SEQ_time_start_frame_get(const Sequence *seq)
|
||||
float SEQ_time_start_frame_get(const Scene *scene, const Sequence *seq)
|
||||
{
|
||||
return seq->start;
|
||||
return SEQ_time_seconds_to_frames(scene, seq->start);
|
||||
}
|
||||
|
||||
void SEQ_time_start_frame_set(const Scene *scene, Sequence *seq, int timeline_frame)
|
||||
{
|
||||
seq->start = timeline_frame;
|
||||
seq->start = SEQ_time_frames_to_seconds(scene, timeline_frame);
|
||||
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));
|
||||
}
|
||||
|
||||
float SEQ_time_content_end_frame_get(const Scene *scene, const Sequence *seq)
|
||||
{
|
||||
return SEQ_time_start_frame_get(seq) + SEQ_time_strip_length_get(scene, seq);
|
||||
return SEQ_time_start_frame_get(scene, seq) + SEQ_time_strip_length_get(scene, seq);
|
||||
}
|
||||
|
||||
int SEQ_time_left_handle_frame_get(const Scene *UNUSED(scene), const Sequence *seq)
|
||||
int SEQ_time_left_handle_frame_get(const Scene *scene, const Sequence *seq)
|
||||
{
|
||||
if (seq->seq1 || seq->seq2) {
|
||||
return seq->startdisp;
|
||||
}
|
||||
|
||||
return seq->start + seq->startofs;
|
||||
return SEQ_time_start_frame_get(scene, seq) + SEQ_time_seconds_to_frames(scene, seq->startofs);
|
||||
}
|
||||
|
||||
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
|
||||
|
@ -546,7 +550,8 @@ int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
|
|||
return seq->enddisp;
|
||||
}
|
||||
|
||||
return SEQ_time_content_end_frame_get(scene, seq) - seq->endofs;
|
||||
return SEQ_time_content_end_frame_get(scene, seq) -
|
||||
SEQ_time_seconds_to_frames(scene, seq->endofs);
|
||||
}
|
||||
|
||||
void SEQ_time_left_handle_frame_set(const Scene *scene, Sequence *seq, int timeline_frame)
|
||||
|
@ -557,13 +562,13 @@ void SEQ_time_left_handle_frame_set(const Scene *scene, Sequence *seq, int timel
|
|||
timeline_frame = right_handle_orig_frame - 1;
|
||||
}
|
||||
|
||||
float offset = timeline_frame - SEQ_time_start_frame_get(seq);
|
||||
float offset = SEQ_time_frames_to_seconds(scene, timeline_frame) - seq->start;
|
||||
|
||||
if (SEQ_transform_single_image_check(seq)) {
|
||||
/* This strip has only 1 frame of content, that is always stretched to whole strip length.
|
||||
* Therefore, strip start should be moved instead of adjusting offset. */
|
||||
SEQ_time_start_frame_set(scene, seq, timeline_frame);
|
||||
seq->endofs += offset;
|
||||
seq->len -= offset;
|
||||
}
|
||||
else {
|
||||
seq->startofs = offset;
|
||||
|
@ -583,7 +588,15 @@ void SEQ_time_right_handle_frame_set(const Scene *scene, Sequence *seq, int time
|
|||
timeline_frame = left_handle_orig_frame + 1;
|
||||
}
|
||||
|
||||
seq->endofs = SEQ_time_content_end_frame_get(scene, seq) - timeline_frame;
|
||||
if (SEQ_transform_single_image_check(seq)) {
|
||||
double strip_end_time = seq->start + seq->len;
|
||||
double time = SEQ_time_frames_to_seconds(scene, timeline_frame);
|
||||
seq->len += time - strip_end_time;
|
||||
}
|
||||
else {
|
||||
seq->endofs = seq->start + seq->len - SEQ_time_frames_to_seconds(scene, timeline_frame);
|
||||
}
|
||||
|
||||
seq->enddisp = timeline_frame; /* Only to make files usable in older versions. */
|
||||
|
||||
SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq));
|
||||
|
@ -600,3 +613,15 @@ void seq_time_translate_handles(const Scene *scene, Sequence *seq, const int off
|
|||
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));
|
||||
}
|
||||
|
||||
double SEQ_time_frames_to_seconds(const Scene *scene, double frames)
|
||||
{
|
||||
double scene_playback_rate = (float)scene->r.frs_sec / scene->r.frs_sec_base;
|
||||
return frames / scene_playback_rate;
|
||||
}
|
||||
|
||||
int SEQ_time_seconds_to_frames(const Scene *scene, double seconds)
|
||||
{
|
||||
double scene_playback_rate = (float)scene->r.frs_sec / scene->r.frs_sec_base;
|
||||
return round_db_to_int(seconds * scene_playback_rate);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ float seq_time_media_playback_rate_factor_get(const struct Scene *scene,
|
|||
const struct Sequence *seq);
|
||||
int seq_time_strip_original_content_length_get(const struct Scene *scene,
|
||||
const struct Sequence *seq);
|
||||
float seq_retiming_evaluate(const struct Sequence *seq, const float frame_index);
|
||||
float seq_retiming_evaluate(const struct Scene *scene, const struct Sequence *seq, const float frame_index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ void SEQ_transform_translate_sequence(Scene *evil_scene, Sequence *seq, int delt
|
|||
seq_time_translate_handles(evil_scene, seq, delta);
|
||||
}
|
||||
else if (seq->seq1 == NULL && seq->seq2 == NULL) { /* All other strip types. */
|
||||
seq->start += delta;
|
||||
seq->start += SEQ_time_frames_to_seconds(evil_scene, delta);
|
||||
/* Only to make files usable in older versions. */
|
||||
seq->startdisp = SEQ_time_left_handle_frame_get(evil_scene, seq);
|
||||
seq->enddisp = SEQ_time_right_handle_frame_get(evil_scene, seq);
|
||||
|
|
|
@ -176,7 +176,10 @@ const char *SEQ_sequence_give_name(Sequence *seq)
|
|||
return name;
|
||||
}
|
||||
|
||||
ListBase *SEQ_get_seqbase_from_sequence(Sequence *seq, ListBase **r_channels, int *r_offset)
|
||||
ListBase *SEQ_get_seqbase_from_sequence(const Scene *scene,
|
||||
Sequence *seq,
|
||||
ListBase **r_channels,
|
||||
int *r_offset)
|
||||
{
|
||||
ListBase *seqbase = NULL;
|
||||
|
||||
|
@ -184,7 +187,7 @@ ListBase *SEQ_get_seqbase_from_sequence(Sequence *seq, ListBase **r_channels, in
|
|||
case SEQ_TYPE_META: {
|
||||
seqbase = &seq->seqbase;
|
||||
*r_channels = &seq->channels;
|
||||
*r_offset = SEQ_time_start_frame_get(seq);
|
||||
*r_offset = SEQ_time_start_frame_get(scene, seq);
|
||||
break;
|
||||
}
|
||||
case SEQ_TYPE_SCENE: {
|
||||
|
|
Loading…
Reference in New Issue