diff options
Diffstat (limited to 'source/blender')
47 files changed, 1050 insertions, 768 deletions
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 04767a742ce..efe44ec657b 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,7 +25,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 3 +#define BLENDER_FILE_SUBVERSION 5 /* 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 diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 5bafce15b34..343a829cf76 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -720,8 +720,8 @@ void *BKE_sound_scene_add_scene_sound_defaults(Scene *scene, Sequence *sequence) { return BKE_sound_scene_add_scene_sound(scene, sequence, - SEQ_time_left_handle_frame_get(sequence), - SEQ_time_right_handle_frame_get(sequence), + SEQ_time_left_handle_frame_get(scene, sequence), + SEQ_time_right_handle_frame_get(scene, sequence), sequence->startofs + sequence->anim_startofs); } @@ -746,8 +746,8 @@ void *BKE_sound_add_scene_sound_defaults(Scene *scene, Sequence *sequence) { return BKE_sound_add_scene_sound(scene, sequence, - SEQ_time_left_handle_frame_get(sequence), - SEQ_time_right_handle_frame_get(sequence), + SEQ_time_left_handle_frame_get(scene, sequence), + SEQ_time_right_handle_frame_get(scene, sequence), sequence->startofs + sequence->anim_startofs); } @@ -779,8 +779,8 @@ void BKE_sound_move_scene_sound_defaults(Scene *scene, Sequence *sequence) if (sequence->scene_sound) { BKE_sound_move_scene_sound(scene, sequence->scene_sound, - SEQ_time_left_handle_frame_get(sequence), - SEQ_time_right_handle_frame_get(sequence), + SEQ_time_left_handle_frame_get(scene, sequence), + SEQ_time_right_handle_frame_get(scene, sequence), sequence->startofs + sequence->anim_startofs, 0.0); } diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index a15ddc75aa2..47786f55871 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -160,7 +160,7 @@ static void seq_convert_transform_crop(const Scene *scene, const uint32_t use_transform_flag = (1 << 16); const uint32_t use_crop_flag = (1 << 17); - const StripElem *s_elem = SEQ_render_give_stripelem(seq, seq->start); + const StripElem *s_elem = SEQ_render_give_stripelem(scene, seq, seq->start); if (s_elem != NULL) { image_size_x = s_elem->orig_width; image_size_y = s_elem->orig_height; @@ -285,7 +285,7 @@ static void seq_convert_transform_crop_2(const Scene *scene, Sequence *seq, const eSpaceSeq_Proxy_RenderSize render_size) { - const StripElem *s_elem = SEQ_render_give_stripelem(seq, seq->start); + const StripElem *s_elem = SEQ_render_give_stripelem(scene, seq, seq->start); if (s_elem == NULL) { return; } @@ -350,6 +350,7 @@ static void seq_convert_transform_crop_lb_2(const Scene *scene, static void seq_update_meta_disp_range(Scene *scene) { Editing *ed = SEQ_editing_get(scene); + if (ed == NULL) { return; } @@ -357,8 +358,8 @@ static void seq_update_meta_disp_range(Scene *scene) LISTBASE_FOREACH_BACKWARD (MetaStack *, ms, &ed->metastack) { /* Update ms->disp_range from meta. */ if (ms->disp_range[0] == ms->disp_range[1]) { - ms->disp_range[0] = SEQ_time_left_handle_frame_get(ms->parseq); - ms->disp_range[1] = SEQ_time_right_handle_frame_get(ms->parseq); + ms->disp_range[0] = SEQ_time_left_handle_frame_get(scene, ms->parseq); + ms->disp_range[1] = SEQ_time_right_handle_frame_get(scene, ms->parseq); } /* Update meta strip endpoints. */ @@ -366,6 +367,14 @@ static void seq_update_meta_disp_range(Scene *scene) SEQ_time_right_handle_frame_set(scene, ms->parseq, ms->disp_range[1]); SEQ_transform_fix_single_image_seq_offsets(scene, ms->parseq); + /* Recalculate effects using meta strip. */ + LISTBASE_FOREACH (Sequence *, seq, ms->oldbasep) { + if (seq->seq2) { + seq->start = seq->startdisp = max_ii(seq->seq1->startdisp, seq->seq2->startdisp); + seq->enddisp = min_ii(seq->seq1->enddisp, seq->seq2->enddisp); + } + } + /* Ensure that active seqbase points to active meta strip seqbase. */ MetaStack *active_ms = SEQ_meta_stack_active_get(ed); SEQ_seqbase_active_set(ed, &active_ms->parseq->seqbase); diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c index 57fd71f8933..9514f1667b1 100644 --- a/source/blender/blenloader/intern/versioning_300.c +++ b/source/blender/blenloader/intern/versioning_300.c @@ -408,7 +408,7 @@ static void do_versions_sequencer_speed_effect_recursive(Scene *scene, const Lis v->speed_control_type = SEQ_SPEED_MULTIPLY; v->speed_fader = globalSpeed * ((float)seq->seq1->len / - max_ff((float)(SEQ_time_right_handle_frame_get(seq->seq1) - + max_ff((float)(SEQ_time_right_handle_frame_get(scene, seq->seq1) - seq->seq1->start), 1.0f)); } @@ -1235,6 +1235,17 @@ static bool version_merge_still_offsets(Sequence *seq, void *UNUSED(user_data)) return true; } +static bool seq_speed_factor_set(Sequence *seq, void *UNUSED(user_data)) +{ + if (seq->type == SEQ_TYPE_SOUND_RAM) { + seq->speed_factor = seq->pitch; + } + else { + seq->speed_factor = 1.0f; + } + return true; +} + /* Those `version_liboverride_rnacollections_*` functions mimic the old, pre-3.0 code to find * anchor and source items in the given list of modifiers, constraints etc., using only the * `subitem_local` data of the override property operation. @@ -3171,18 +3182,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) } } - /** - * Versioning code until next subversion bump goes here. - * - * \note Be sure to check when bumping the version: - * - "versioning_userdef.c", #blo_do_versions_userdef - * - "versioning_userdef.c", #do_versions_theme - * - * \note Keep this message at the bottom of the function. - */ - { - /* Keep this block, even when empty. */ - + if (!MAIN_VERSION_ATLEAST(bmain, 303, 5)) { /* Fix for T98925 - remove channels region, that was initialized in incorrect editor types. */ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { @@ -3201,5 +3201,25 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + Editing *ed = SEQ_editing_get(scene); + if (ed == NULL) { + continue; + } + SEQ_for_each_callback(&ed->seqbase, seq_speed_factor_set, NULL); + } + } + /** + * Versioning code until next subversion bump goes here. + * + * \note Be sure to check when bumping the version: + * - "versioning_userdef.c", #blo_do_versions_userdef + * - "versioning_userdef.c", #do_versions_theme + * + * \note Keep this message at the bottom of the function. + */ + { + /* Keep this block, even when empty. */ } } diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 84f99ec0ac0..f3972cb45df 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -111,9 +111,9 @@ static int seq_frame_apply_snap(bContext *C, Scene *scene, const int timeline_fr Sequence *seq; SEQ_ITERATOR_FOREACH (seq, strips) { seq_frame_snap_update_best( - SEQ_time_left_handle_frame_get(seq), timeline_frame, &best_frame, &best_distance); + SEQ_time_left_handle_frame_get(scene, seq), timeline_frame, &best_frame, &best_distance); seq_frame_snap_update_best( - SEQ_time_right_handle_frame_get(seq), timeline_frame, &best_frame, &best_distance); + SEQ_time_right_handle_frame_get(scene, seq), timeline_frame, &best_frame, &best_distance); } SEQ_collection_free(strips); diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 647d13a4d56..0f6d6930530 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -85,6 +85,7 @@ typedef struct SequencerAddData { #define SEQPROP_NOCHAN (1 << 3) #define SEQPROP_FIT_METHOD (1 << 4) #define SEQPROP_VIEW_TRANSFORM (1 << 5) +#define SEQPROP_PLAYBACK_RATE (1 << 6) static const EnumPropertyItem scale_fit_methods[] = { {SEQ_SCALE_TO_FIT, "FIT", 0, "Scale to Fit", "Scale image to fit within the canvas"}, @@ -158,6 +159,14 @@ static void sequencer_generic_props__internal(wmOperatorType *ot, int flag) "Set View Transform", "Set appropriate view transform based on media color space"); } + + if (flag & SEQPROP_PLAYBACK_RATE) { + ot->prop = RNA_def_boolean(ot->srna, + "adjust_playback_rate", + true, + "Adjust Playback Rate", + "Play at normal speed regardless of scene FPS"); + } } static void sequencer_generic_invoke_path__internal(bContext *C, @@ -191,7 +200,7 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type) } for (seq = ed->seqbasep->first; seq; seq = seq->next) { - const int strip_end = SEQ_time_right_handle_frame_get(seq); + const int strip_end = SEQ_time_right_handle_frame_get(scene, seq); if ((ELEM(type, -1, seq->type)) && (strip_end < timeline_frame) && (timeline_frame - strip_end < proximity)) { tgt = seq; @@ -250,6 +259,10 @@ static void load_data_init_from_operator(SeqLoadData *load_data, bContext *C, wm SEQ_tool_settings_fit_method_set(CTX_data_scene(C), load_data->fit_method); } + if ((prop = RNA_struct_find_property(op->ptr, "adjust_playback_rate"))) { + load_data->adjust_playback_rate = RNA_boolean_get(op->ptr, "adjust_playback_rate"); + } + if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) { RNA_property_string_get(op->ptr, prop, load_data->path); BLI_strncpy(load_data->name, BLI_path_basename(load_data->path), sizeof(load_data->name)); @@ -327,7 +340,7 @@ static void seq_load_apply_generic_options(bContext *C, wmOperator *op, Sequence } if (RNA_boolean_get(op->ptr, "overlap") == true || - !SEQ_transform_test_overlap(ed->seqbasep, seq)) { + !SEQ_transform_test_overlap(scene, ed->seqbasep, seq)) { /* No overlap should be handled or the strip is not overlapping, exit early. */ return; } @@ -370,7 +383,7 @@ static bool seq_load_apply_generic_options_only_test_overlap(bContext *C, SEQ_collection_append_strip(seq, strip_col); - return SEQ_transform_test_overlap(ed->seqbasep, seq); + return SEQ_transform_test_overlap(scene, ed->seqbasep, seq); } static bool seq_effect_add_properties_poll(const bContext *UNUSED(C), @@ -793,8 +806,10 @@ static void sequencer_add_movie_clamp_sound_strip_length(Scene *scene, return; } - SEQ_time_right_handle_frame_set(scene, seq_sound, SEQ_time_right_handle_frame_get(seq_movie)); - SEQ_time_left_handle_frame_set(scene, seq_sound, SEQ_time_left_handle_frame_get(seq_movie)); + SEQ_time_right_handle_frame_set( + scene, seq_sound, SEQ_time_right_handle_frame_get(scene, seq_movie)); + SEQ_time_left_handle_frame_set( + scene, seq_sound, SEQ_time_left_handle_frame_get(scene, seq_movie)); } static void sequencer_add_movie_multiple_strips(bContext *C, @@ -841,8 +856,8 @@ static void sequencer_add_movie_multiple_strips(bContext *C, } } - load_data->start_frame += SEQ_time_right_handle_frame_get(seq_movie) - - SEQ_time_left_handle_frame_get(seq_movie); + load_data->start_frame += SEQ_time_right_handle_frame_get(scene, seq_movie) - + SEQ_time_left_handle_frame_get(scene, seq_movie); if (overlap_shuffle_override) { has_seq_overlap |= seq_load_apply_generic_options_only_test_overlap( C, op, seq_sound, strip_col); @@ -976,6 +991,7 @@ static int sequencer_add_movie_strip_invoke(bContext *C, sequencer_disable_one_time_properties(C, op); RNA_enum_set(op->ptr, "fit_method", SEQ_tool_settings_fit_method_get(scene)); + RNA_boolean_set(op->ptr, "adjust_playback_rate", true); /* This is for drag and drop. */ if ((RNA_struct_property_is_set(op->ptr, "files") && @@ -1042,8 +1058,9 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot) WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY, FILE_DEFAULTDISPLAY, FILE_SORT_DEFAULT); - sequencer_generic_props__internal( - ot, SEQPROP_STARTFRAME | SEQPROP_FIT_METHOD | SEQPROP_VIEW_TRANSFORM); + sequencer_generic_props__internal(ot, + SEQPROP_STARTFRAME | SEQPROP_FIT_METHOD | + SEQPROP_VIEW_TRANSFORM | SEQPROP_PLAYBACK_RATE); RNA_def_boolean(ot->srna, "sound", true, "Sound", "Load sound with the movie"); RNA_def_boolean(ot->srna, "use_framerate", @@ -1073,8 +1090,8 @@ static void sequencer_add_sound_multiple_strips(bContext *C, } else { seq_load_apply_generic_options(C, op, seq); - load_data->start_frame += SEQ_time_right_handle_frame_get(seq) - - SEQ_time_left_handle_frame_get(seq); + load_data->start_frame += SEQ_time_right_handle_frame_get(scene, seq) - + SEQ_time_left_handle_frame_get(scene, seq); } } RNA_END; @@ -1250,8 +1267,12 @@ static int sequencer_add_image_strip_calculate_length(wmOperator *op, return RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files")); } -static void sequencer_add_image_strip_load_files( - wmOperator *op, Sequence *seq, SeqLoadData *load_data, const int minframe, const int numdigits) +static void sequencer_add_image_strip_load_files(wmOperator *op, + Scene *scene, + Sequence *seq, + SeqLoadData *load_data, + const int minframe, + const int numdigits) { const bool use_placeholders = RNA_boolean_get(op->ptr, "use_placeholders"); /* size of Strip->dir. */ @@ -1267,7 +1288,7 @@ static void sequencer_add_image_strip_load_files( size_t strip_frame = 0; RNA_BEGIN (op->ptr, itemptr, "files") { char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0, NULL); - SEQ_add_image_load_file(seq, strip_frame, filename); + SEQ_add_image_load_file(scene, seq, strip_frame, filename); MEM_freeN(filename); strip_frame++; } @@ -1296,7 +1317,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) } Sequence *seq = SEQ_add_image_strip(CTX_data_main(C), scene, ed->seqbasep, &load_data); - sequencer_add_image_strip_load_files(op, seq, &load_data, minframe, numdigits); + sequencer_add_image_strip_load_files(op, scene, seq, &load_data, minframe, numdigits); SEQ_add_image_init_alpha_mode(seq); /* Adjust length. */ diff --git a/source/blender/editors/space_sequencer/sequencer_channels_draw.c b/source/blender/editors/space_sequencer/sequencer_channels_draw.c index c11388e8555..81fc87598f8 100644 --- a/source/blender/editors/space_sequencer/sequencer_channels_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_channels_draw.c @@ -97,7 +97,7 @@ static void displayed_channel_range_get(const SeqChannelDrawContext *context, rctf strip_boundbox; BLI_rctf_init(&strip_boundbox, 0.0f, 0.0f, 1.0f, r_channel_range[1]); - SEQ_timeline_expand_boundbox(context->seqbase, &strip_boundbox); + SEQ_timeline_expand_boundbox(context->scene, context->seqbase, &strip_boundbox); CLAMP(r_channel_range[0], strip_boundbox.ymin, strip_boundbox.ymax); CLAMP(r_channel_range[1], strip_boundbox.ymin, MAXSEQ); } diff --git a/source/blender/editors/space_sequencer/sequencer_drag_drop.c b/source/blender/editors/space_sequencer/sequencer_drag_drop.c index 8dadb9360e3..586cdad7e74 100644 --- a/source/blender/editors/space_sequencer/sequencer_drag_drop.c +++ b/source/blender/editors/space_sequencer/sequencer_drag_drop.c @@ -167,7 +167,7 @@ static void sequencer_drop_copy(bContext *C, wmDrag *drag, wmDropBox *drop) SpaceSeq *sseq = CTX_wm_space_seq(C); SeqCollection *strips = SEQ_query_rendered_strips( - channels, seqbase, scene->r.cfra, sseq->chanshown); + scene, channels, seqbase, scene->r.cfra, sseq->chanshown); /* Get the top most strip channel that is in view.*/ Sequence *seq; @@ -236,7 +236,7 @@ static void update_overlay_strip_poistion_data(bContext *C, const int mval[2]) Editing *ed = SEQ_editing_get(scene); for (int i = 0; i < coords->channel_len && !coords->is_intersecting; i++) { - coords->is_intersecting = SEQ_transform_test_overlap(ed->seqbasep, &dummy_seq); + coords->is_intersecting = SEQ_transform_test_overlap(scene, ed->seqbasep, &dummy_seq); dummy_seq.machine++; } } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 25701c323b9..4b9ff1e170e 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -617,8 +617,8 @@ static void drawmeta_contents(Scene *scene, /* Draw only immediate children (1 level depth). */ for (seq = meta_seqbase->first; seq; seq = seq->next) { - const int startdisp = SEQ_time_left_handle_frame_get(seq) + offset; - const int enddisp = SEQ_time_right_handle_frame_get(seq) + offset; + const int startdisp = SEQ_time_left_handle_frame_get(scene, seq) + offset; + const int enddisp = SEQ_time_right_handle_frame_get(scene, seq) + offset; if ((startdisp > x2 || enddisp < x1) == 0) { float y_chan = (seq->machine - chan_min) / (float)(chan_range)*draw_range; @@ -663,19 +663,20 @@ static void drawmeta_contents(Scene *scene, GPU_blend(GPU_BLEND_NONE); } -float sequence_handle_size_get_clamped(Sequence *seq, const float pixelx) +float sequence_handle_size_get_clamped(const Scene *scene, Sequence *seq, const float pixelx) { const float maxhandle = (pixelx * SEQ_HANDLE_SIZE) * U.pixelsize; /* Ensure that handle is not wider, than quarter of strip. */ - return min_ff( - maxhandle, - ((float)(SEQ_time_right_handle_frame_get(seq) - SEQ_time_left_handle_frame_get(seq)) / - 4.0f)); + return min_ff(maxhandle, + ((float)(SEQ_time_right_handle_frame_get(scene, seq) - + SEQ_time_left_handle_frame_get(scene, seq)) / + 4.0f)); } /* Draw a handle, on left or right side of strip. */ -static void draw_seq_handle(View2D *v2d, +static void draw_seq_handle(const Scene *scene, + View2D *v2d, Sequence *seq, const float handsize_clamped, const short direction, @@ -689,8 +690,8 @@ static void draw_seq_handle(View2D *v2d, uint whichsel = 0; uchar col[4]; - x1 = SEQ_time_left_handle_frame_get(seq); - x2 = SEQ_time_right_handle_frame_get(seq); + x1 = SEQ_time_left_handle_frame_get(scene, seq); + x2 = SEQ_time_right_handle_frame_get(scene, seq); y1 = seq->machine + SEQ_STRIP_OFSBOTTOM; y2 = seq->machine + SEQ_STRIP_OFSTOP; @@ -745,8 +746,8 @@ static void draw_seq_handle(View2D *v2d, numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d%d", - SEQ_time_left_handle_frame_get(seq), - SEQ_time_right_handle_frame_get(seq)); + SEQ_time_left_handle_frame_get(scene, seq), + SEQ_time_right_handle_frame_get(scene, seq)); float tot_width = BLF_width(fontid, numstr, numstr_len); if ((x2 - x1) / pixelx > 20 + tot_width) { @@ -755,13 +756,13 @@ static void draw_seq_handle(View2D *v2d, if (direction == SEQ_LEFTHANDLE) { numstr_len = BLI_snprintf_rlen( - numstr, sizeof(numstr), "%d", SEQ_time_left_handle_frame_get(seq)); + numstr, sizeof(numstr), "%d", SEQ_time_left_handle_frame_get(scene, seq)); x1 += text_margin; y1 += 0.09f; } else { numstr_len = BLI_snprintf_rlen( - numstr, sizeof(numstr), "%d", SEQ_time_right_handle_frame_get(seq) - 1); + numstr, sizeof(numstr), "%d", SEQ_time_right_handle_frame_get(scene, seq) - 1); x1 = x2 - (text_margin + pixelx * BLF_width(fontid, numstr, numstr_len)); y1 += 0.09f; } @@ -896,7 +897,8 @@ static void draw_seq_text_get_source(Sequence *seq, char *r_source, size_t sourc } } -static size_t draw_seq_text_get_overlay_string(SpaceSeq *sseq, +static size_t draw_seq_text_get_overlay_string(const Scene *scene, + SpaceSeq *sseq, Sequence *seq, char *r_overlay_string, size_t overlay_string_len) @@ -922,8 +924,8 @@ static size_t draw_seq_text_get_overlay_string(SpaceSeq *sseq, char strip_duration_text[16]; if (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_DURATION) { - const int strip_duration = SEQ_time_right_handle_frame_get(seq) - - SEQ_time_left_handle_frame_get(seq); + const int strip_duration = SEQ_time_right_handle_frame_get(scene, seq) - + SEQ_time_left_handle_frame_get(scene, seq); SNPRINTF(strip_duration_text, "%d", strip_duration); if (i != 0) { text_array[i++] = text_sep; @@ -952,7 +954,7 @@ static void draw_seq_text_overlay(Scene *scene, ListBase *channels = SEQ_channels_displayed_get(ed); char overlay_string[FILE_MAX]; size_t overlay_string_len = draw_seq_text_get_overlay_string( - sseq, seq, overlay_string, sizeof(overlay_string)); + scene, sseq, seq, overlay_string, sizeof(overlay_string)); if (overlay_string_len == 0) { return; @@ -990,8 +992,8 @@ static void draw_sequence_extensions_overlay( float x1, x2, y1, y2; uchar col[4], blend_col[3]; - x1 = SEQ_time_left_handle_frame_get(seq); - x2 = SEQ_time_right_handle_frame_get(seq); + x1 = SEQ_time_left_handle_frame_get(scene, seq); + x2 = SEQ_time_right_handle_frame_get(scene, seq); y1 = seq->machine + SEQ_STRIP_OFSBOTTOM; y2 = seq->machine + SEQ_STRIP_OFSTOP; @@ -1005,28 +1007,32 @@ static void draw_sequence_extensions_overlay( col[3] = SEQ_render_is_muted(channels, seq) ? MUTE_ALPHA : 200; UI_GetColorPtrShade3ubv(col, blend_col, 10); - if (seq->startofs) { + const float strip_content_start = SEQ_time_start_frame_get(seq); + const float strip_content_end = SEQ_time_start_frame_get(seq) + + SEQ_time_strip_length_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); + + if (left_handle_frame > strip_content_start) { immUniformColor4ubv(col); - immRectf(pos, (float)(seq->start), y1 - pixely, x1, y1 - SEQ_STRIP_OFSBOTTOM); + immRectf(pos, strip_content_start, y1 - pixely, x1, y1 - SEQ_STRIP_OFSBOTTOM); /* Outline. */ immUniformColor3ubv(blend_col); - imm_draw_box_wire_2d(pos, x1, y1 - pixely, (float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM); + imm_draw_box_wire_2d(pos, x1, y1 - pixely, strip_content_start, y1 - SEQ_STRIP_OFSBOTTOM); } - if (seq->endofs) { + if (right_handle_frame < strip_content_end) { immUniformColor4ubv(col); - immRectf(pos, x2, y2 + pixely, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); + immRectf(pos, x2, y2 + pixely, strip_content_end, y2 + SEQ_STRIP_OFSBOTTOM); - /* Outline. */ - immUniformColor3ubv(blend_col); - imm_draw_box_wire_2d( - pos, x2, y2 + pixely, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); + /* Outline. */ immUniformColor3ubv(blend_col); + imm_draw_box_wire_2d(pos, x2, y2 + pixely, strip_content_end, y2 + SEQ_STRIP_OFSBOTTOM); } GPU_blend(GPU_BLEND_NONE); } static void draw_color_strip_band( - ListBase *channels, Sequence *seq, uint pos, float text_margin_y, float y1) + const Scene *scene, ListBase *channels, Sequence *seq, uint pos, float text_margin_y, float y1) { uchar col[4]; SolidColorVars *colvars = (SolidColorVars *)seq->effectdata; @@ -1049,9 +1055,9 @@ static void draw_color_strip_band( immUniformColor4ubv(col); immRectf(pos, - SEQ_time_left_handle_frame_get(seq), + SEQ_time_left_handle_frame_get(scene, seq), y1, - SEQ_time_right_handle_frame_get(seq), + SEQ_time_right_handle_frame_get(scene, seq), text_margin_y); /* 1px line to better separate the color band. */ @@ -1059,8 +1065,8 @@ static void draw_color_strip_band( immUniformColor4ubv(col); immBegin(GPU_PRIM_LINES, 2); - immVertex2f(pos, SEQ_time_left_handle_frame_get(seq), text_margin_y); - immVertex2f(pos, SEQ_time_right_handle_frame_get(seq), text_margin_y); + immVertex2f(pos, SEQ_time_left_handle_frame_get(scene, seq), text_margin_y); + immVertex2f(pos, SEQ_time_right_handle_frame_get(scene, seq), text_margin_y); immEnd(); GPU_blend(GPU_BLEND_NONE); @@ -1112,25 +1118,31 @@ static void draw_seq_background(Scene *scene, /* Draw the main strip body. */ if (is_single_image) { - immRectf( - pos, SEQ_time_left_handle_frame_get(seq), y1, SEQ_time_right_handle_frame_get(seq), y2); + immRectf(pos, + SEQ_time_left_handle_frame_get(scene, seq), + y1, + SEQ_time_right_handle_frame_get(scene, seq), + y2); } else { immRectf(pos, x1, y1, x2, y2); } /* Draw background for hold still regions. */ - if (!is_single_image && SEQ_time_has_still_frames(seq)) { + if (!is_single_image) { UI_GetColorPtrShade3ubv(col, col, -35); immUniformColor4ubv(col); - if (SEQ_time_has_left_still_frames(seq)) { - const float content_start = min_ff(SEQ_time_right_handle_frame_get(seq), seq->start); - immRectf(pos, SEQ_time_left_handle_frame_get(seq), y1, content_start, y2); + if (SEQ_time_has_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); + immRectf(pos, left_handle_frame, y1, content_start, y2); } - if (SEQ_time_has_right_still_frames(seq)) { - const float content_end = max_ff(SEQ_time_left_handle_frame_get(seq), seq->start + seq->len); - immRectf(pos, content_end, y1, SEQ_time_right_handle_frame_get(seq), y2); + if (SEQ_time_has_right_still_frames(scene, seq)) { + float right_handle_frame = SEQ_time_right_handle_frame_get(scene, seq); + const float content_end = SEQ_time_start_frame_get(seq) + + SEQ_time_strip_length_get(scene, seq); + immRectf(pos, content_end, y1, right_handle_frame, y2); } } @@ -1200,9 +1212,9 @@ static void draw_seq_invalid(float x1, float x2, float y2, float text_margin_y) } static void calculate_seq_text_offsets( - View2D *v2d, Sequence *seq, float *x1, float *x2, float pixelx) + const Scene *scene, View2D *v2d, Sequence *seq, float *x1, float *x2, float pixelx) { - const float handsize_clamped = sequence_handle_size_get_clamped(seq, pixelx); + const float handsize_clamped = sequence_handle_size_get_clamped(scene, seq, pixelx); float text_margin = 2.0f * handsize_clamped; *x1 += text_margin; @@ -1336,7 +1348,7 @@ static void draw_seq_strip(const bContext *C, View2D *v2d = ®ion->v2d; float x1, x2, y1, y2; - const float handsize_clamped = sequence_handle_size_get_clamped(seq, pixelx); + const float handsize_clamped = sequence_handle_size_get_clamped(scene, seq, pixelx); float pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask); /* Check if we are doing "solo preview". */ @@ -1347,15 +1359,17 @@ static void draw_seq_strip(const bContext *C, SEQ_TIMELINE_SHOW_STRIP_COLOR_TAG); /* Draw strip body. */ - x1 = SEQ_time_has_left_still_frames(seq) ? seq->start : SEQ_time_left_handle_frame_get(seq); + x1 = SEQ_time_has_left_still_frames(scene, seq) ? SEQ_time_start_frame_get(seq) : + SEQ_time_left_handle_frame_get(scene, seq); y1 = seq->machine + SEQ_STRIP_OFSBOTTOM; - x2 = SEQ_time_has_right_still_frames(seq) ? (seq->start + seq->len) : - SEQ_time_right_handle_frame_get(seq); + x2 = SEQ_time_has_right_still_frames(scene, seq) ? + SEQ_time_start_frame_get(seq) + SEQ_time_strip_length_get(scene, seq) : + SEQ_time_right_handle_frame_get(scene, seq); y2 = seq->machine + SEQ_STRIP_OFSTOP; /* Limit body to strip bounds. Meta strip can end up with content outside of strip range. */ - x1 = min_ff(x1, SEQ_time_right_handle_frame_get(seq)); - x2 = max_ff(x2, SEQ_time_left_handle_frame_get(seq)); + x1 = min_ff(x1, SEQ_time_right_handle_frame_get(scene, seq)); + x2 = max_ff(x2, SEQ_time_left_handle_frame_get(scene, seq)); float text_margin_y; bool y_threshold; @@ -1381,12 +1395,12 @@ static void draw_seq_strip(const bContext *C, /* Draw a color band inside color strip. */ if (seq->type == SEQ_TYPE_COLOR && y_threshold) { - draw_color_strip_band(channels, seq, pos, text_margin_y, y1); + draw_color_strip_band(scene, channels, seq, pos, text_margin_y, y1); } /* Draw strip offsets when flag is enabled or during "solo preview". */ if (sseq->flag & SEQ_SHOW_OVERLAY) { - if (!is_single_image && (seq->startofs || seq->endofs) && pixely > 0) { + if (!is_single_image && pixely > 0) { if ((sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_OFFSETS) || (seq == special_seq_update)) { draw_sequence_extensions_overlay(scene, seq, pos, pixely, show_strip_color_tag); @@ -1395,8 +1409,8 @@ static void draw_seq_strip(const bContext *C, } immUnbindProgram(); - x1 = SEQ_time_left_handle_frame_get(seq); - x2 = SEQ_time_right_handle_frame_get(seq); + x1 = SEQ_time_left_handle_frame_get(scene, seq); + x2 = SEQ_time_right_handle_frame_get(scene, seq); if ((seq->type == SEQ_TYPE_META) || ((seq->type == SEQ_TYPE_SCENE) && (seq->flag & SEQ_SCENE_STRIPS))) { @@ -1444,16 +1458,16 @@ static void draw_seq_strip(const bContext *C, if (!SEQ_transform_is_locked(channels, seq)) { draw_seq_handle( - v2d, seq, handsize_clamped, SEQ_LEFTHANDLE, pos, seq_active, pixelx, y_threshold); + scene, v2d, seq, handsize_clamped, SEQ_LEFTHANDLE, pos, seq_active, pixelx, y_threshold); draw_seq_handle( - v2d, seq, handsize_clamped, SEQ_RIGHTHANDLE, pos, seq_active, pixelx, y_threshold); + scene, v2d, seq, handsize_clamped, SEQ_RIGHTHANDLE, pos, seq_active, pixelx, y_threshold); } draw_seq_outline(scene, seq, pos, x1, x2, y1, y2, pixelx, pixely, seq_active); immUnbindProgram(); - calculate_seq_text_offsets(v2d, seq, &x1, &x2, pixelx); + calculate_seq_text_offsets(scene, v2d, seq, &x1, &x2, pixelx); /* If a waveform is drawn, avoid drawing text when there is not enough vertical space. */ if (seq->type == SEQ_TYPE_SOUND_RAM) { @@ -1474,7 +1488,7 @@ static void draw_seq_strip(const bContext *C, } } -static void draw_effect_inputs_highlight(Sequence *seq) +static void draw_effect_inputs_highlight(const Scene *scene, Sequence *seq) { Sequence *seq1 = seq->seq1; Sequence *seq2 = seq->seq2; @@ -1486,23 +1500,23 @@ static void draw_effect_inputs_highlight(Sequence *seq) immUniformColor4ub(255, 255, 255, 48); immRectf(pos, - SEQ_time_left_handle_frame_get(seq1), + SEQ_time_left_handle_frame_get(scene, seq1), seq1->machine + SEQ_STRIP_OFSBOTTOM, - SEQ_time_right_handle_frame_get(seq1), + SEQ_time_right_handle_frame_get(scene, seq1), seq1->machine + SEQ_STRIP_OFSTOP); if (seq2 && seq2 != seq1) { immRectf(pos, - SEQ_time_left_handle_frame_get(seq2), + SEQ_time_left_handle_frame_get(scene, seq2), seq2->machine + SEQ_STRIP_OFSBOTTOM, - SEQ_time_right_handle_frame_get(seq2), + SEQ_time_right_handle_frame_get(scene, seq2), seq2->machine + SEQ_STRIP_OFSTOP); } if (seq3 && !ELEM(seq3, seq1, seq2)) { immRectf(pos, - SEQ_time_left_handle_frame_get(seq3), + SEQ_time_left_handle_frame_get(scene, seq3), seq3->machine + SEQ_STRIP_OFSBOTTOM, - SEQ_time_right_handle_frame_get(seq3), + SEQ_time_right_handle_frame_get(scene, seq3), seq3->machine + SEQ_STRIP_OFSTOP); } immUnbindProgram(); @@ -1591,7 +1605,8 @@ ImBuf *sequencer_ibuf_get(struct Main *bmain, } if (viewport) { - /* Follows same logic as wm_draw_window_offscreen to make sure to restore the same viewport. */ + /* Follows same logic as wm_draw_window_offscreen to make sure to restore the same + * viewport. */ int view = (sseq->multiview_eye == STEREO_RIGHT_ID) ? 1 : 0; GPU_viewport_bind(viewport, view, ®ion->winrct); } @@ -2096,10 +2111,10 @@ static int sequencer_draw_get_transform_preview_frame(Scene *scene) int preview_frame; if (last_seq->flag & SEQ_RIGHTSEL) { - preview_frame = SEQ_time_right_handle_frame_get(last_seq) - 1; + preview_frame = SEQ_time_right_handle_frame_get(scene, last_seq) - 1; } else { - preview_frame = SEQ_time_left_handle_frame_get(last_seq); + preview_frame = SEQ_time_left_handle_frame_get(scene, last_seq); } return preview_frame; @@ -2253,7 +2268,7 @@ void sequencer_draw_preview(const bContext *C, Editing *ed = SEQ_editing_get(scene); ListBase *channels = SEQ_channels_displayed_get(ed); SeqCollection *collection = SEQ_query_rendered_strips( - channels, ed->seqbasep, timeline_frame, 0); + scene, channels, ed->seqbasep, timeline_frame, 0); Sequence *seq; Sequence *active_seq = SEQ_select_active_get(scene); SEQ_ITERATOR_FOREACH (seq, collection) { @@ -2325,10 +2340,13 @@ 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(seq), seq->start) > v2d->cur.xmax) { + if (min_ii(SEQ_time_left_handle_frame_get(scene, seq), SEQ_time_start_frame_get(seq)) > + v2d->cur.xmax) { continue; } - if (max_ii(SEQ_time_right_handle_frame_get(seq), seq->start + seq->len) < v2d->cur.xmin) { + if (max_ii(SEQ_time_right_handle_frame_get(scene, seq), + SEQ_time_start_frame_get(seq) + SEQ_time_strip_length_get(scene, seq)) < + v2d->cur.xmin) { continue; } if (seq->machine + 1.0f < v2d->cur.ymin) { @@ -2353,7 +2371,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) /* When active strip is an effect, highlight its inputs. */ if (SEQ_effect_get_num_inputs(last_seq->type) > 0) { - draw_effect_inputs_highlight(last_seq); + draw_effect_inputs_highlight(scene, last_seq); } /* When active is a Multi-cam strip, highlight its source channel. */ else if (last_seq->type == SEQ_TYPE_MULTICAM) { @@ -2383,9 +2401,9 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) immUniformColor4ub(255, 255, 255, 48); immRectf(pos, - SEQ_time_left_handle_frame_get(seq), + SEQ_time_left_handle_frame_get(scene, seq), seq->machine + SEQ_STRIP_OFSBOTTOM, - SEQ_time_right_handle_frame_get(seq), + SEQ_time_right_handle_frame_get(scene, seq), seq->machine + SEQ_STRIP_OFSTOP); immUnbindProgram(); @@ -2612,8 +2630,8 @@ static void draw_cache_view(const bContext *C) continue; } - if (SEQ_time_left_handle_frame_get(seq) > v2d->cur.xmax || - SEQ_time_right_handle_frame_get(seq) < v2d->cur.xmin) { + if (SEQ_time_left_handle_frame_get(scene, seq) > v2d->cur.xmax || + SEQ_time_right_handle_frame_get(scene, seq) < v2d->cur.xmin) { continue; } @@ -2624,9 +2642,9 @@ static void draw_cache_view(const bContext *C) const float bg_color[4] = {1.0f, 0.1f, 0.02f, 0.1f}; immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]); immRectf(pos, - SEQ_time_left_handle_frame_get(seq), + SEQ_time_left_handle_frame_get(scene, seq), stripe_bot, - SEQ_time_right_handle_frame_get(seq), + SEQ_time_right_handle_frame_get(scene, seq), stripe_top); } @@ -2637,9 +2655,9 @@ static void draw_cache_view(const bContext *C) const float bg_color[4] = {0.1f, 0.1f, 0.75f, 0.1f}; immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]); immRectf(pos, - SEQ_time_left_handle_frame_get(seq), + SEQ_time_left_handle_frame_get(scene, seq), stripe_bot, - SEQ_time_right_handle_frame_get(seq), + SEQ_time_right_handle_frame_get(scene, seq), stripe_top); } @@ -2650,9 +2668,9 @@ static void draw_cache_view(const bContext *C) const float bg_color[4] = {1.0f, 0.6f, 0.0f, 0.1f}; immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]); immRectf(pos, - SEQ_time_left_handle_frame_get(seq), + SEQ_time_left_handle_frame_get(scene, seq), stripe_bot, - SEQ_time_right_handle_frame_get(seq), + SEQ_time_right_handle_frame_get(scene, seq), stripe_top); } } 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; diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index 3f91be9e9e8..644e897f631 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -70,7 +70,9 @@ void color3ubv_from_seq(const struct Scene *curscene, void sequencer_special_update_set(Sequence *seq); /* Get handle width in 2d-View space. */ -float sequence_handle_size_get_clamped(struct Sequence *seq, float pixelx); +float sequence_handle_size_get_clamped(const struct Scene *scene, + struct Sequence *seq, + float pixelx); /* UNUSED */ /* void seq_reset_imageofs(struct SpaceSeq *sseq); */ @@ -113,7 +115,7 @@ void channel_draw_context_init(const struct bContext *C, /* sequencer_edit.c */ struct View2D; -void seq_rectf(struct Sequence *seq, struct rctf *rectf); +void seq_rectf(const struct Scene *scene, struct Sequence *seq, struct rctf *rectf); struct Sequence *find_nearest_seq(struct Scene *scene, struct View2D *v2d, int *hand, diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index f237fbc0a12..cfdbeaf0658 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -59,7 +59,7 @@ SeqCollection *all_strips_from_context(bContext *C) const bool is_preview = sequencer_view_has_preview_poll(C); if (is_preview) { - return SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); + return SEQ_query_rendered_strips(scene, channels, seqbase, scene->r.cfra, 0); } return SEQ_query_all_strips(seqbase); @@ -74,7 +74,7 @@ SeqCollection *selected_strips_from_context(bContext *C) const bool is_preview = sequencer_view_has_preview_poll(C); if (is_preview) { - SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); + SeqCollection *strips = SEQ_query_rendered_strips(scene, channels, seqbase, scene->r.cfra, 0); SEQ_filter_selected_strips(strips); return strips; } @@ -108,7 +108,8 @@ static void select_surrounding_handles(Scene *scene, Sequence *test) /* XXX BRIN } /* Used for mouse selection in SEQUENCER_OT_select. */ -static void select_active_side(ListBase *seqbase, int sel_side, int channel, int frame) +static void select_active_side( + const Scene *scene, ListBase *seqbase, int sel_side, int channel, int frame) { Sequence *seq; @@ -116,13 +117,13 @@ static void select_active_side(ListBase *seqbase, int sel_side, int channel, int if (channel == seq->machine) { switch (sel_side) { case SEQ_SIDE_LEFT: - if (frame > (SEQ_time_left_handle_frame_get(seq))) { + if (frame > (SEQ_time_left_handle_frame_get(scene, seq))) { seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); seq->flag |= SELECT; } break; case SEQ_SIDE_RIGHT: - if (frame < (SEQ_time_left_handle_frame_get(seq))) { + if (frame < (SEQ_time_left_handle_frame_get(scene, seq))) { seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); seq->flag |= SELECT; } @@ -137,7 +138,8 @@ static void select_active_side(ListBase *seqbase, int sel_side, int channel, int } /* Used for mouse selection in SEQUENCER_OT_select_side. */ -static void select_active_side_range(ListBase *seqbase, +static void select_active_side_range(const Scene *scene, + ListBase *seqbase, const int sel_side, const int frame_ranges[MAXSEQ], const int frame_ignore) @@ -152,13 +154,13 @@ static void select_active_side_range(ListBase *seqbase, } switch (sel_side) { case SEQ_SIDE_LEFT: - if (frame > (SEQ_time_left_handle_frame_get(seq))) { + if (frame > (SEQ_time_left_handle_frame_get(scene, seq))) { seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); seq->flag |= SELECT; } break; case SEQ_SIDE_RIGHT: - if (frame < (SEQ_time_left_handle_frame_get(seq))) { + if (frame < (SEQ_time_left_handle_frame_get(scene, seq))) { seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); seq->flag |= SELECT; } @@ -173,14 +175,14 @@ static void select_active_side_range(ListBase *seqbase, } /* Used for mouse selection in SEQUENCER_OT_select */ -static void select_linked_time(ListBase *seqbase, Sequence *seq_link) +static void select_linked_time(const Scene *scene, ListBase *seqbase, Sequence *seq_link) { Sequence *seq; for (seq = seqbase->first; seq; seq = seq->next) { if (seq_link->machine != seq->machine) { - int left_match = (SEQ_time_left_handle_frame_get(seq) == seq_link->startdisp) ? 1 : 0; - int right_match = (SEQ_time_right_handle_frame_get(seq) == seq_link->enddisp) ? 1 : 0; + int left_match = (SEQ_time_left_handle_frame_get(scene, seq) == seq_link->startdisp) ? 1 : 0; + int right_match = (SEQ_time_right_handle_frame_get(scene, seq) == seq_link->enddisp) ? 1 : 0; if (left_match && right_match) { /* Direct match, copy the selection settings. */ @@ -245,10 +247,10 @@ void ED_sequencer_select_sequence_single(Scene *scene, Sequence *seq, bool desel recurs_sel_seq(seq); } -void seq_rectf(Sequence *seq, rctf *rect) +void seq_rectf(const Scene *scene, Sequence *seq, rctf *rect) { - rect->xmin = SEQ_time_left_handle_frame_get(seq); - rect->xmax = SEQ_time_right_handle_frame_get(seq); + rect->xmin = SEQ_time_left_handle_frame_get(scene, seq); + rect->xmax = SEQ_time_right_handle_frame_get(scene, seq); rect->ymin = seq->machine + SEQ_STRIP_OFSBOTTOM; rect->ymax = seq->machine + SEQ_STRIP_OFSTOP; } @@ -273,12 +275,14 @@ Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int se (sel == 0 && (seq->flag & SELECT) == 0))) { switch (lr) { case SEQ_SIDE_LEFT: - if (SEQ_time_left_handle_frame_get(test) == (SEQ_time_right_handle_frame_get(seq))) { + if (SEQ_time_left_handle_frame_get(scene, test) == + (SEQ_time_right_handle_frame_get(scene, seq))) { return seq; } break; case SEQ_SIDE_RIGHT: - if (SEQ_time_right_handle_frame_get(test) == (SEQ_time_left_handle_frame_get(seq))) { + if (SEQ_time_right_handle_frame_get(scene, test) == + (SEQ_time_left_handle_frame_get(scene, seq))) { return seq; } break; @@ -311,18 +315,20 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[ while (seq) { if (seq->machine == (int)y) { /* Check for both normal strips, and strips that have been flipped horizontally. */ - if (((SEQ_time_left_handle_frame_get(seq) < SEQ_time_right_handle_frame_get(seq)) && - (SEQ_time_left_handle_frame_get(seq) <= x && - SEQ_time_right_handle_frame_get(seq) >= x)) || - ((SEQ_time_left_handle_frame_get(seq) > SEQ_time_right_handle_frame_get(seq)) && - (SEQ_time_left_handle_frame_get(seq) >= x && - SEQ_time_right_handle_frame_get(seq) <= x))) { + if (((SEQ_time_left_handle_frame_get(scene, seq) < + SEQ_time_right_handle_frame_get(scene, seq)) && + (SEQ_time_left_handle_frame_get(scene, seq) <= x && + SEQ_time_right_handle_frame_get(scene, seq) >= x)) || + ((SEQ_time_left_handle_frame_get(scene, seq) > + SEQ_time_right_handle_frame_get(scene, seq)) && + (SEQ_time_left_handle_frame_get(scene, seq) >= x && + SEQ_time_right_handle_frame_get(scene, seq) <= x))) { if (SEQ_transform_sequence_can_be_translated(seq)) { /* Clamp handles to defined size in pixel space. */ - handsize = 2.0f * sequence_handle_size_get_clamped(seq, pixelx); - displen = (float)abs(SEQ_time_left_handle_frame_get(seq) - - SEQ_time_right_handle_frame_get(seq)); + handsize = 2.0f * sequence_handle_size_get_clamped(scene, seq, pixelx); + displen = (float)abs(SEQ_time_left_handle_frame_get(scene, seq) - + SEQ_time_right_handle_frame_get(scene, seq)); /* Don't even try to grab the handles of small strips. */ if (displen / pixelx > 16) { @@ -337,10 +343,10 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[ CLAMP(handsize, 7 * pixelx, 30 * pixelx); } - if (handsize + SEQ_time_left_handle_frame_get(seq) >= x) { + if (handsize + SEQ_time_left_handle_frame_get(scene, seq) >= x) { *hand = SEQ_SIDE_LEFT; } - else if (-handsize + SEQ_time_right_handle_frame_get(seq) <= x) { + else if (-handsize + SEQ_time_right_handle_frame_get(scene, seq) <= x) { *hand = SEQ_SIDE_RIGHT; } } @@ -583,8 +589,8 @@ static void sequencer_select_side_of_frame(const bContext *C, const float x = UI_view2d_region_to_view_x(v2d, mval[0]); LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(ed)) { - if (((x < CFRA) && (SEQ_time_right_handle_frame_get(seq_iter) <= CFRA)) || - ((x >= CFRA) && (SEQ_time_left_handle_frame_get(seq_iter) >= CFRA))) { + if (((x < CFRA) && (SEQ_time_right_handle_frame_get(scene, seq_iter) <= CFRA)) || + ((x >= CFRA) && (SEQ_time_left_handle_frame_get(scene, seq_iter) >= CFRA))) { /* Select left or right. */ seq_iter->flag |= SELECT; recurs_sel_seq(seq_iter); @@ -639,8 +645,11 @@ static void sequencer_select_linked_handle(const bContext *C, case SEQ_SIDE_LEFT: if ((seq->flag & SEQ_LEFTSEL) && (neighbor->flag & SEQ_RIGHTSEL)) { seq->flag |= SELECT; - select_active_side( - ed->seqbasep, SEQ_SIDE_LEFT, seq->machine, SEQ_time_left_handle_frame_get(seq)); + select_active_side(scene, + ed->seqbasep, + SEQ_SIDE_LEFT, + seq->machine, + SEQ_time_left_handle_frame_get(scene, seq)); } else { seq->flag |= SELECT; @@ -653,8 +662,11 @@ static void sequencer_select_linked_handle(const bContext *C, case SEQ_SIDE_RIGHT: if ((seq->flag & SEQ_RIGHTSEL) && (neighbor->flag & SEQ_LEFTSEL)) { seq->flag |= SELECT; - select_active_side( - ed->seqbasep, SEQ_SIDE_RIGHT, seq->machine, SEQ_time_left_handle_frame_get(seq)); + select_active_side(scene, + ed->seqbasep, + SEQ_SIDE_RIGHT, + seq->machine, + SEQ_time_left_handle_frame_get(scene, seq)); } else { seq->flag |= SELECT; @@ -669,7 +681,7 @@ static void sequencer_select_linked_handle(const bContext *C, else { select_active_side( - ed->seqbasep, sel_side, seq->machine, SEQ_time_left_handle_frame_get(seq)); + scene, ed->seqbasep, sel_side, seq->machine, SEQ_time_left_handle_frame_get(scene, seq)); } } } @@ -734,7 +746,7 @@ static Sequence *seq_select_seq_from_preview( const bool use_cycle = (!WM_cursor_test_motion_and_update(mval) || extend || toggle); SeqCollection *strips = SEQ_query_rendered_strips( - channels, seqbase, scene->r.cfra, sseq->chanshown); + scene, channels, seqbase, scene->r.cfra, sseq->chanshown); /* Allow strips this far from the closest center to be included. * This allows cycling over center points which are near enough @@ -921,7 +933,7 @@ static int sequencer_select_exec(bContext *C, wmOperator *op) ED_sequencer_deselect_all(scene); } sequencer_select_strip_impl(ed, seq, handle_clicked, extend, deselect, toggle); - select_linked_time(ed->seqbasep, seq); + select_linked_time(scene, ed->seqbasep, seq); sequencer_select_do_updates(C, scene); sequencer_select_set_active(scene, seq); return OPERATOR_FINISHED; @@ -1436,13 +1448,13 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op) bool test = false; switch (side) { case -1: - test = (timeline_frame >= SEQ_time_right_handle_frame_get(seq)); + test = (timeline_frame >= SEQ_time_right_handle_frame_get(scene, seq)); break; case 1: - test = (timeline_frame <= SEQ_time_left_handle_frame_get(seq)); + test = (timeline_frame <= SEQ_time_left_handle_frame_get(scene, seq)); break; case 2: - test = SEQ_time_strip_intersects_frame(seq, timeline_frame); + test = SEQ_time_strip_intersects_frame(scene, seq, timeline_frame); break; } @@ -1513,10 +1525,10 @@ static int sequencer_select_side_exec(bContext *C, wmOperator *op) if (seq->flag & SELECT) { selected = true; if (sel_side == SEQ_SIDE_LEFT) { - *frame_limit_p = max_ii(*frame_limit_p, SEQ_time_left_handle_frame_get(seq)); + *frame_limit_p = max_ii(*frame_limit_p, SEQ_time_left_handle_frame_get(scene, seq)); } else { - *frame_limit_p = min_ii(*frame_limit_p, SEQ_time_left_handle_frame_get(seq)); + *frame_limit_p = min_ii(*frame_limit_p, SEQ_time_left_handle_frame_get(scene, seq)); } } } @@ -1525,7 +1537,7 @@ static int sequencer_select_side_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - select_active_side_range(ed->seqbasep, sel_side, frame_ranges, frame_init); + select_active_side_range(scene, ed->seqbasep, sel_side, frame_ranges, frame_init); ED_outliner_select_sync_from_sequence_tag(C); @@ -1595,7 +1607,7 @@ static void seq_box_select_seq_from_preview(const bContext *C, rctf *rect, const SpaceSeq *sseq = CTX_wm_space_seq(C); SeqCollection *strips = SEQ_query_rendered_strips( - channels, seqbase, scene->r.cfra, sseq->chanshown); + scene, channels, seqbase, scene->r.cfra, sseq->chanshown); Sequence *seq; SEQ_ITERATOR_FOREACH (seq, strips) { if (!seq_box_select_rect_image_isect(scene, seq, rect)) { @@ -1648,15 +1660,15 @@ static int sequencer_box_select_exec(bContext *C, wmOperator *op) LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { rctf rq; - seq_rectf(seq, &rq); + seq_rectf(scene, seq, &rq); if (BLI_rctf_isect(&rq, &rectf, NULL)) { if (handles) { /* Get the handles draw size. */ float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask); - float handsize = sequence_handle_size_get_clamped(seq, pixelx); + float handsize = sequence_handle_size_get_clamped(scene, seq, pixelx); /* Right handle. */ - if (rectf.xmax > (SEQ_time_right_handle_frame_get(seq) - handsize)) { + if (rectf.xmax > (SEQ_time_right_handle_frame_get(scene, seq) - handsize)) { if (select) { seq->flag |= SELECT | SEQ_RIGHTSEL; } @@ -1669,7 +1681,7 @@ static int sequencer_box_select_exec(bContext *C, wmOperator *op) } } /* Left handle. */ - if (rectf.xmin < (SEQ_time_left_handle_frame_get(seq) + handsize)) { + if (rectf.xmin < (SEQ_time_left_handle_frame_get(scene, seq) + handsize)) { if (select) { seq->flag |= SELECT | SEQ_LEFTSEL; } @@ -1953,7 +1965,8 @@ static bool select_grouped_effect(SeqCollection *strips, return changed; } -static bool select_grouped_time_overlap(SeqCollection *strips, +static bool select_grouped_time_overlap(const Scene *scene, + SeqCollection *strips, ListBase *UNUSED(seqbase), Sequence *actseq) { @@ -1961,8 +1974,10 @@ static bool select_grouped_time_overlap(SeqCollection *strips, Sequence *seq; SEQ_ITERATOR_FOREACH (seq, strips) { - if (SEQ_time_left_handle_frame_get(seq) < SEQ_time_right_handle_frame_get(actseq) && - SEQ_time_right_handle_frame_get(seq) > SEQ_time_left_handle_frame_get(actseq)) { + if (SEQ_time_left_handle_frame_get(scene, seq) < + SEQ_time_right_handle_frame_get(scene, actseq) && + SEQ_time_right_handle_frame_get(scene, seq) > + SEQ_time_left_handle_frame_get(scene, actseq)) { seq->flag |= SELECT; changed = true; } @@ -1972,7 +1987,8 @@ static bool select_grouped_time_overlap(SeqCollection *strips, } /* Query strips that are in lower channel and intersect in time with seq_reference. */ -static void query_lower_channel_strips(Sequence *seq_reference, +static void query_lower_channel_strips(const Scene *scene, + Sequence *seq_reference, ListBase *seqbase, SeqCollection *collection) { @@ -1980,10 +1996,10 @@ static void query_lower_channel_strips(Sequence *seq_reference, if (seq_test->machine > seq_reference->machine) { continue; /* Not lower channel. */ } - if (SEQ_time_right_handle_frame_get(seq_test) <= - SEQ_time_left_handle_frame_get(seq_reference) || - SEQ_time_left_handle_frame_get(seq_test) >= - SEQ_time_right_handle_frame_get(seq_reference)) { + if (SEQ_time_right_handle_frame_get(scene, seq_test) <= + SEQ_time_left_handle_frame_get(scene, seq_reference) || + SEQ_time_left_handle_frame_get(scene, seq_test) >= + SEQ_time_right_handle_frame_get(scene, seq_reference)) { continue; /* Not intersecting in time. */ } SEQ_collection_append_strip(seq_test, collection); @@ -1992,7 +2008,8 @@ static void query_lower_channel_strips(Sequence *seq_reference, /* Select all strips within time range and with lower channel of initial selection. Then select * effect chains of these strips. */ -static bool select_grouped_effect_link(SeqCollection *strips, +static bool select_grouped_effect_link(const Scene *scene, + SeqCollection *strips, ListBase *seqbase, Sequence *UNUSED(actseq), const int UNUSED(channel)) @@ -2000,8 +2017,10 @@ static bool select_grouped_effect_link(SeqCollection *strips, /* Get collection of strips. */ SEQ_filter_selected_strips(strips); const int selected_strip_count = SEQ_collection_len(strips); - SEQ_collection_expand(seqbase, strips, query_lower_channel_strips); - SEQ_collection_expand(seqbase, strips, SEQ_query_strip_effect_chain); + // XXX this uses scene as arg, so it does not work with iterator :( I had thought about this, but + // expand function is just so useful... I can just add scene and inject it I guess..... + SEQ_collection_expand(scene, seqbase, strips, query_lower_channel_strips); + SEQ_collection_expand(scene, seqbase, strips, SEQ_query_strip_effect_chain); /* Check if other strips will be affected. */ const bool changed = SEQ_collection_len(strips) > selected_strip_count; @@ -2067,10 +2086,10 @@ static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) changed |= select_grouped_effect(strips, seqbase, actseq, channel); break; case SEQ_SELECT_GROUP_EFFECT_LINK: - changed |= select_grouped_effect_link(strips, seqbase, actseq, channel); + changed |= select_grouped_effect_link(scene, strips, seqbase, actseq, channel); break; case SEQ_SELECT_GROUP_OVERLAP: - changed |= select_grouped_time_overlap(strips, seqbase, actseq); + changed |= select_grouped_time_overlap(scene, strips, seqbase, actseq); break; default: BLI_assert(0); diff --git a/source/blender/editors/space_sequencer/sequencer_thumbnails.c b/source/blender/editors/space_sequencer/sequencer_thumbnails.c index 5c929e6673a..a11b5663620 100644 --- a/source/blender/editors/space_sequencer/sequencer_thumbnails.c +++ b/source/blender/editors/space_sequencer/sequencer_thumbnails.c @@ -69,15 +69,16 @@ static void thumbnail_endjob(void *data) WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, tj->scene); } -static bool check_seq_need_thumbnails(Sequence *seq, rctf *view_area) +static bool check_seq_need_thumbnails(const Scene *scene, Sequence *seq, rctf *view_area) { if (!ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE)) { return false; } - if (min_ii(SEQ_time_left_handle_frame_get(seq), seq->start) > view_area->xmax) { + if (min_ii(SEQ_time_left_handle_frame_get(scene, seq), seq->start) > view_area->xmax) { return false; } - if (max_ii(SEQ_time_right_handle_frame_get(seq), seq->start + seq->len) < view_area->xmin) { + if (max_ii(SEQ_time_right_handle_frame_get(scene, seq), seq->start + seq->len) < + view_area->xmin) { return false; } if (seq->machine + 1.0f < view_area->ymin) { @@ -135,6 +136,7 @@ static void thumbnail_start_job(void *data, float *UNUSED(progress)) { ThumbnailDrawJob *tj = data; + const Scene *scene = tj->scene; float frame_step; GHashIterator gh_iter; @@ -145,7 +147,7 @@ static void thumbnail_start_job(void *data, Sequence *seq_orig = BLI_ghashIterator_getKey(&gh_iter); ThumbDataItem *val = BLI_ghash_lookup(tj->sequences_ghash, seq_orig); - if (check_seq_need_thumbnails(seq_orig, tj->view_area)) { + if (check_seq_need_thumbnails(scene, seq_orig, tj->view_area)) { seq_get_thumb_image_dimensions( val->seq_dupli, tj->pixelx, tj->pixely, &frame_step, tj->thumb_height, NULL, NULL); SEQ_render_thumbnails( @@ -161,7 +163,7 @@ static void thumbnail_start_job(void *data, Sequence *seq_orig = BLI_ghashIterator_getKey(&gh_iter); ThumbDataItem *val = BLI_ghash_lookup(tj->sequences_ghash, seq_orig); - if (check_seq_need_thumbnails(seq_orig, tj->view_area)) { + if (check_seq_need_thumbnails(scene, seq_orig, tj->view_area)) { seq_get_thumb_image_dimensions( val->seq_dupli, tj->pixelx, tj->pixely, &frame_step, tj->thumb_height, NULL, NULL); SEQ_render_thumbnails_base_set(&tj->context, val->seq_dupli, seq_orig, tj->view_area, stop); @@ -197,7 +199,7 @@ static GHash *sequencer_thumbnail_ghash_init(const bContext *C, View2D *v2d, Edi LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { ThumbDataItem *val_need_update = BLI_ghash_lookup(thumb_data_hash, seq); - if (val_need_update == NULL && check_seq_need_thumbnails(seq, &v2d->cur)) { + if (val_need_update == NULL && check_seq_need_thumbnails(scene, seq, &v2d->cur)) { ThumbDataItem *val = MEM_callocN(sizeof(ThumbDataItem), "Thumbnail Hash Values"); val->seq_dupli = SEQ_sequence_dupli_recursive(scene, scene, NULL, seq, 0); val->scene = scene; @@ -206,7 +208,7 @@ static GHash *sequencer_thumbnail_ghash_init(const bContext *C, View2D *v2d, Edi else { if (val_need_update != NULL) { val_need_update->seq_dupli->start = seq->start; - val_need_update->seq_dupli->startdisp = SEQ_time_left_handle_frame_get(seq); + val_need_update->seq_dupli->startdisp = SEQ_time_left_handle_frame_get(scene, seq); } } } @@ -361,18 +363,20 @@ static int sequencer_thumbnail_closest_previous_frame_get(int timeline_frame, return best_frame; } -static int sequencer_thumbnail_closest_guaranteed_frame_get(Sequence *seq, int timeline_frame) +static int sequencer_thumbnail_closest_guaranteed_frame_get(struct Scene *scene, + Sequence *seq, + int timeline_frame) { - if (timeline_frame <= SEQ_time_left_handle_frame_get(seq)) { - return SEQ_time_left_handle_frame_get(seq); + if (timeline_frame <= SEQ_time_left_handle_frame_get(scene, seq)) { + return SEQ_time_left_handle_frame_get(scene, seq); } /* Set of "guaranteed" thumbnails. */ - const int frame_index = timeline_frame - SEQ_time_left_handle_frame_get(seq); - const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(seq); + const int frame_index = timeline_frame - SEQ_time_left_handle_frame_get(scene, seq); + const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(scene, seq); const int relative_base_frame = round_fl_to_int((frame_index / (float)frame_step)) * frame_step; const int nearest_guaranted_absolute_frame = relative_base_frame + - SEQ_time_left_handle_frame_get(seq); + SEQ_time_left_handle_frame_get(scene, seq); return nearest_guaranted_absolute_frame; } @@ -387,7 +391,8 @@ static ImBuf *sequencer_thumbnail_closest_from_memory(const SeqRenderData *conte previously_displayed); ImBuf *ibuf_previous = SEQ_get_thumbnail(context, seq, frame_previous, crop, clipped); - int frame_guaranteed = sequencer_thumbnail_closest_guaranteed_frame_get(seq, timeline_frame); + int frame_guaranteed = sequencer_thumbnail_closest_guaranteed_frame_get( + context->scene, seq, timeline_frame); ImBuf *ibuf_guaranteed = SEQ_get_thumbnail(context, seq, frame_guaranteed, crop, clipped); ImBuf *closest_in_memory = NULL; @@ -450,14 +455,14 @@ void draw_seq_strip_thumbnail(View2D *v2d, float thumb_y_end = y1 + thumb_height; float cut_off = 0; - float upper_thumb_bound = SEQ_time_has_right_still_frames(seq) ? + float upper_thumb_bound = SEQ_time_has_right_still_frames(scene, seq) ? (seq->start + seq->len) : - SEQ_time_right_handle_frame_get(seq); + SEQ_time_right_handle_frame_get(scene, seq); if (seq->type == SEQ_TYPE_IMAGE) { - upper_thumb_bound = SEQ_time_right_handle_frame_get(seq); + upper_thumb_bound = SEQ_time_right_handle_frame_get(scene, seq); } - float timeline_frame = SEQ_render_thumbnail_first_frame_get(seq, thumb_width, &v2d->cur); + float timeline_frame = SEQ_render_thumbnail_first_frame_get(scene, seq, thumb_width, &v2d->cur); float thumb_x_end; GSet *last_displayed_thumbnails = last_displayed_thumbnails_list_ensure(C, seq); @@ -480,8 +485,8 @@ void draw_seq_strip_thumbnail(View2D *v2d, } /* Set the clipping bound to show the left handle moving over thumbs and not shift thumbs. */ - if (IN_RANGE_INCL(SEQ_time_left_handle_frame_get(seq), timeline_frame, thumb_x_end)) { - cut_off = SEQ_time_left_handle_frame_get(seq) - timeline_frame; + if (IN_RANGE_INCL(SEQ_time_left_handle_frame_get(scene, seq), timeline_frame, thumb_x_end)) { + cut_off = SEQ_time_left_handle_frame_get(scene, seq) - timeline_frame; clipped = true; } @@ -558,7 +563,7 @@ void draw_seq_strip_thumbnail(View2D *v2d, IMB_freeImBuf(ibuf); GPU_blend(GPU_BLEND_NONE); cut_off = 0; - timeline_frame = SEQ_render_thumbnail_next_frame_get(seq, timeline_frame, thumb_width); + timeline_frame = SEQ_render_thumbnail_next_frame_get(scene, seq, timeline_frame, thumb_width); } last_displayed_thumbnails_list_cleanup(last_displayed_thumbnails, timeline_frame, FLT_MAX); } diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index f7ca753c052..4d32c00109a 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -84,7 +84,7 @@ static int sequencer_view_all_exec(bContext *C, wmOperator *op) box.xmin = ms->disp_range[0] - 1; box.xmax = ms->disp_range[1] + 1; } - SEQ_timeline_expand_boundbox(SEQ_active_seqbase_get(ed), &box); + SEQ_timeline_expand_boundbox(scene, SEQ_active_seqbase_get(ed), &box); View2D *v2d = ®ion->v2d; rcti scrub_rect; @@ -306,8 +306,8 @@ static void seq_view_collection_rect_timeline(Scene *scene, SeqCollection *strip int xmargin = FPS; SEQ_ITERATOR_FOREACH (seq, strips) { - xmin = min_ii(xmin, SEQ_time_left_handle_frame_get(seq)); - xmax = max_ii(xmax, SEQ_time_right_handle_frame_get(seq)); + xmin = min_ii(xmin, SEQ_time_left_handle_frame_get(scene, seq)); + xmax = max_ii(xmax, SEQ_time_right_handle_frame_get(scene, seq)); ymin = min_ii(ymin, seq->machine); ymax = max_ii(ymax, seq->machine); diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index f95c5f196b6..0199fa81928 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -548,7 +548,8 @@ static void sequencer_main_clamp_view(const bContext *C, ARegion *region) } View2D *v2d = ®ion->v2d; - Editing *ed = SEQ_editing_get(CTX_data_scene(C)); + Scene *scene = CTX_data_scene(C); + Editing *ed = SEQ_editing_get(scene); if (ed == NULL) { return; @@ -563,7 +564,7 @@ static void sequencer_main_clamp_view(const bContext *C, ARegion *region) /* Initialize default view with 7 channels, that are visible even if empty. */ rctf strip_boundbox; BLI_rctf_init(&strip_boundbox, 0.0f, 0.0f, 1.0f, 7.0f); - SEQ_timeline_expand_boundbox(ed->seqbasep, &strip_boundbox); + SEQ_timeline_expand_boundbox(scene, ed->seqbasep, &strip_boundbox); /* Clamp Y max. Scrubbing area height must be added, so strips aren't occluded. */ rcti scrub_rect; diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c index 226b0f84f14..849641fd320 100644 --- a/source/blender/editors/transform/transform_convert_sequencer.c +++ b/source/blender/editors/transform/transform_convert_sequencer.c @@ -91,8 +91,8 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_count, int *r_flag) /* *** Extend Transform *** */ int cfra = CFRA; - int left = SEQ_time_left_handle_frame_get(seq); - int right = SEQ_time_right_handle_frame_get(seq); + int left = SEQ_time_left_handle_frame_get(scene, seq); + int right = SEQ_time_right_handle_frame_get(scene, seq); if (((seq->flag & SELECT) == 0 || SEQ_transform_is_locked(channels, seq))) { *r_count = 0; @@ -163,8 +163,13 @@ static int SeqTransCount(TransInfo *t, ListBase *seqbase) return tot; } -static TransData *SeqToTransData( - TransData *td, TransData2D *td2d, TransDataSeq *tdsq, Sequence *seq, int flag, int sel_flag) +static TransData *SeqToTransData(Scene *scene, + TransData *td, + TransData2D *td2d, + TransDataSeq *tdsq, + Sequence *seq, + int flag, + int sel_flag) { int start_left; @@ -173,16 +178,16 @@ static TransData *SeqToTransData( /* Use seq_tx_get_final_left() and an offset here * so transform has the left hand location of the strip. * tdsq->start_offset is used when flushing the tx data back */ - start_left = SEQ_time_left_handle_frame_get(seq); + 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 */ break; case SEQ_LEFTSEL: - start_left = SEQ_time_left_handle_frame_get(seq); + start_left = SEQ_time_left_handle_frame_get(scene, seq); td2d->loc[0] = start_left; break; case SEQ_RIGHTSEL: - td2d->loc[0] = SEQ_time_right_handle_frame_get(seq); + td2d->loc[0] = SEQ_time_right_handle_frame_get(scene, seq); break; } @@ -227,6 +232,7 @@ static int SeqToTransData_build( TransInfo *t, ListBase *seqbase, TransData *td, TransData2D *td2d, TransDataSeq *tdsq) { Sequence *seq; + Scene *scene = t->scene; int count, flag; int tot = 0; @@ -238,16 +244,16 @@ static int SeqToTransData_build( if (flag & SELECT) { if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) { if (flag & SEQ_LEFTSEL) { - SeqToTransData(td++, td2d++, tdsq++, seq, flag, SEQ_LEFTSEL); + SeqToTransData(scene, td++, td2d++, tdsq++, seq, flag, SEQ_LEFTSEL); tot++; } if (flag & SEQ_RIGHTSEL) { - SeqToTransData(td++, td2d++, tdsq++, seq, flag, SEQ_RIGHTSEL); + SeqToTransData(scene, td++, td2d++, tdsq++, seq, flag, SEQ_RIGHTSEL); tot++; } } else { - SeqToTransData(td++, td2d++, tdsq++, seq, flag, SELECT); + SeqToTransData(scene, td++, td2d++, tdsq++, seq, flag, SELECT); tot++; } } @@ -275,7 +281,7 @@ static void seq_transform_cancel(TransInfo *t, SeqCollection *transformed_strips SEQ_ITERATOR_FOREACH (seq, transformed_strips) { /* Handle pre-existing overlapping strips even when operator is canceled. * This is necessary for SEQUENCER_OT_duplicate_move macro for example. */ - if (SEQ_transform_test_overlap(seqbase, seq)) { + if (SEQ_transform_test_overlap(t->scene, seqbase, seq)) { SEQ_transform_seqbase_shuffle(seqbase, seq, t->scene); } } @@ -318,7 +324,8 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c } SeqCollection *transformed_strips = seq_transform_collection_from_transdata(tc); - SEQ_collection_expand(seqbase_active_get(t), transformed_strips, SEQ_query_strip_effect_chain); + SEQ_collection_expand( + t->scene, seqbase_active_get(t), transformed_strips, SEQ_query_strip_effect_chain); Sequence *seq; SEQ_ITERATOR_FOREACH (seq, transformed_strips) { @@ -363,11 +370,11 @@ typedef enum SeqInputSide { SEQ_INPUT_RIGHT = 1, } SeqInputSide; -static Sequence *effect_input_get(Sequence *effect, SeqInputSide side) +static Sequence *effect_input_get(const Scene *scene, Sequence *effect, SeqInputSide side) { Sequence *input = effect->seq1; - if (effect->seq2 && (SEQ_time_left_handle_frame_get(effect->seq2) - - SEQ_time_left_handle_frame_get(effect->seq1)) * + if (effect->seq2 && (SEQ_time_left_handle_frame_get(scene, effect->seq2) - + SEQ_time_left_handle_frame_get(scene, effect->seq1)) * side > 0) { input = effect->seq2; @@ -375,12 +382,12 @@ static Sequence *effect_input_get(Sequence *effect, SeqInputSide side) return input; } -static Sequence *effect_base_input_get(Sequence *effect, SeqInputSide side) +static Sequence *effect_base_input_get(const Scene *scene, Sequence *effect, SeqInputSide side) { Sequence *input = effect, *seq_iter = effect; while (seq_iter != NULL) { input = seq_iter; - seq_iter = effect_input_get(seq_iter, side); + seq_iter = effect_input_get(scene, seq_iter, side); } return input; } @@ -400,7 +407,7 @@ static SeqCollection *query_time_dependent_strips_strips(TransInfo *t) SeqCollection *strips_no_handles = query_selected_strips_no_handles(seqbase); /* Selection is needed as reference for related strips. */ SeqCollection *dependent = SEQ_collection_duplicate(strips_no_handles); - SEQ_collection_expand(seqbase, strips_no_handles, SEQ_query_strip_effect_chain); + SEQ_collection_expand(t->scene, seqbase, strips_no_handles, SEQ_query_strip_effect_chain); bool strip_added = true; while (strip_added) { @@ -430,7 +437,7 @@ static SeqCollection *query_time_dependent_strips_strips(TransInfo *t) * With single input effect, it is less likely desirable to move animation. */ SeqCollection *selected_strips = SEQ_query_selected_strips(seqbase); - SEQ_collection_expand(seqbase, selected_strips, SEQ_query_strip_effect_chain); + SEQ_collection_expand(t->scene, seqbase, selected_strips, SEQ_query_strip_effect_chain); Sequence *seq; SEQ_ITERATOR_FOREACH (seq, selected_strips) { /* Check only 2 input effects. */ @@ -439,8 +446,8 @@ static SeqCollection *query_time_dependent_strips_strips(TransInfo *t) } /* Find immediate base inputs(left and right side). */ - Sequence *input_left = effect_base_input_get(seq, SEQ_INPUT_LEFT); - Sequence *input_right = effect_base_input_get(seq, SEQ_INPUT_RIGHT); + Sequence *input_left = effect_base_input_get(t->scene, seq, SEQ_INPUT_LEFT); + Sequence *input_right = effect_base_input_get(t->scene, seq, SEQ_INPUT_RIGHT); if ((input_left->flag & SEQ_RIGHTSEL) != 0 && (input_right->flag & SEQ_LEFTSEL) != 0) { SEQ_collection_append_strip(seq, dependent); @@ -571,6 +578,8 @@ static void flushTransSeq(TransInfo *t) TransDataSeq *tdsq = NULL; Sequence *seq; + Scene *scene = t->scene; + TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); /* This is calculated for offsetting animation of effects that change position with inputs. @@ -594,7 +603,7 @@ static void flushTransSeq(TransInfo *t) case SELECT: { if (SEQ_transform_sequence_can_be_translated(seq)) { offset = new_frame - tdsq->start_offset - seq->start; - SEQ_transform_translate_sequence(t->scene, seq, offset); + SEQ_transform_translate_sequence(scene, seq, offset); if (abs(offset) > abs(max_offset)) { max_offset = offset; } @@ -604,24 +613,22 @@ static void flushTransSeq(TransInfo *t) break; } case SEQ_LEFTSEL: { /* No vertical transform. */ - int old_startdisp = SEQ_time_left_handle_frame_get(seq); + int old_startdisp = SEQ_time_left_handle_frame_get(scene, seq); SEQ_time_left_handle_frame_set(t->scene, seq, new_frame); - SEQ_transform_handle_xlimits( - t->scene, seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); SEQ_transform_fix_single_image_seq_offsets(t->scene, seq); - if (abs(SEQ_time_left_handle_frame_get(seq) - old_startdisp) > abs(max_offset)) { - max_offset = SEQ_time_left_handle_frame_get(seq) - old_startdisp; + + if (abs(SEQ_time_left_handle_frame_get(scene, seq) - old_startdisp) > abs(max_offset)) { + max_offset = SEQ_time_left_handle_frame_get(scene, seq) - old_startdisp; } break; } case SEQ_RIGHTSEL: { /* No vertical transform. */ - int old_enddisp = SEQ_time_right_handle_frame_get(seq); + int old_enddisp = SEQ_time_right_handle_frame_get(scene, seq); SEQ_time_right_handle_frame_set(t->scene, seq, new_frame); - SEQ_transform_handle_xlimits( - t->scene, seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); SEQ_transform_fix_single_image_seq_offsets(t->scene, seq); - if (abs(SEQ_time_right_handle_frame_get(seq) - old_enddisp) > abs(max_offset)) { - max_offset = SEQ_time_right_handle_frame_get(seq) - old_enddisp; + + if (abs(SEQ_time_right_handle_frame_get(scene, seq) - old_enddisp) > abs(max_offset)) { + max_offset = SEQ_time_right_handle_frame_get(scene, seq) - old_enddisp; } break; } @@ -638,12 +645,13 @@ static void flushTransSeq(TransInfo *t) /* need to do the overlap check in a new loop otherwise adjacent strips * will not be updated and we'll get false positives */ SeqCollection *transformed_strips = seq_transform_collection_from_transdata(tc); - SEQ_collection_expand(seqbase_active_get(t), transformed_strips, SEQ_query_strip_effect_chain); + SEQ_collection_expand( + t->scene, seqbase_active_get(t), transformed_strips, SEQ_query_strip_effect_chain); SEQ_ITERATOR_FOREACH (seq, transformed_strips) { /* test overlap, displays red outline */ seq->flag &= ~SEQ_OVERLAP; - if (SEQ_transform_test_overlap(seqbasep, seq)) { + if (SEQ_transform_test_overlap(scene, seqbasep, seq)) { seq->flag |= SEQ_OVERLAP; } } diff --git a/source/blender/editors/transform/transform_convert_sequencer_image.c b/source/blender/editors/transform/transform_convert_sequencer_image.c index 76c6632039a..46606d5814f 100644 --- a/source/blender/editors/transform/transform_convert_sequencer_image.c +++ b/source/blender/editors/transform/transform_convert_sequencer_image.c @@ -123,7 +123,8 @@ void createTransSeqImageData(TransInfo *t) ListBase *seqbase = SEQ_active_seqbase_get(ed); ListBase *channels = SEQ_channels_displayed_get(ed); - SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, t->scene->r.cfra, 0); + SeqCollection *strips = SEQ_query_rendered_strips( + t->scene, channels, seqbase, t->scene->r.cfra, 0); SEQ_filter_selected_strips(strips); const int count = SEQ_collection_len(strips); diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index 838b40c2040..426b338f8a7 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -247,7 +247,7 @@ static bool gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min Editing *ed = SEQ_editing_get(scene); ListBase *seqbase = SEQ_active_seqbase_get(ed); ListBase *channels = SEQ_channels_displayed_get(ed); - SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); + SeqCollection *strips = SEQ_query_rendered_strips(scene, channels, seqbase, scene->r.cfra, 0); SEQ_filter_selected_strips(strips); int selected_strips = SEQ_collection_len(strips); if (selected_strips > 0) { @@ -299,7 +299,7 @@ static int gizmo2d_calc_transform_orientation(const bContext *C) Editing *ed = SEQ_editing_get(scene); ListBase *seqbase = SEQ_active_seqbase_get(ed); ListBase *channels = SEQ_channels_displayed_get(ed); - SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); + SeqCollection *strips = SEQ_query_rendered_strips(scene, channels, seqbase, scene->r.cfra, 0); SEQ_filter_selected_strips(strips); bool use_local_orient = SEQ_collection_len(strips) == 1; @@ -322,7 +322,7 @@ static float gizmo2d_calc_rotation(const bContext *C) Editing *ed = SEQ_editing_get(scene); ListBase *seqbase = SEQ_active_seqbase_get(ed); ListBase *channels = SEQ_channels_displayed_get(ed); - SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); + SeqCollection *strips = SEQ_query_rendered_strips(scene, channels, seqbase, scene->r.cfra, 0); SEQ_filter_selected_strips(strips); if (SEQ_collection_len(strips) == 1) { @@ -348,7 +348,7 @@ static bool seq_get_strip_pivot_median(const Scene *scene, float r_pivot[2]) Editing *ed = SEQ_editing_get(scene); ListBase *seqbase = SEQ_active_seqbase_get(ed); ListBase *channels = SEQ_channels_displayed_get(ed); - SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); + SeqCollection *strips = SEQ_query_rendered_strips(scene, channels, seqbase, scene->r.cfra, 0); SEQ_filter_selected_strips(strips); bool has_select = SEQ_collection_len(strips) != 0; @@ -387,7 +387,8 @@ static bool gizmo2d_calc_transform_pivot(const bContext *C, float r_pivot[2]) Editing *ed = SEQ_editing_get(scene); ListBase *seqbase = SEQ_active_seqbase_get(ed); ListBase *channels = SEQ_channels_displayed_get(ed); - SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); + SeqCollection *strips = SEQ_query_rendered_strips( + scene, channels, seqbase, scene->r.cfra, 0); SEQ_filter_selected_strips(strips); has_select = SEQ_collection_len(strips) != 0; SEQ_collection_free(strips); diff --git a/source/blender/editors/transform/transform_snap_sequencer.c b/source/blender/editors/transform/transform_snap_sequencer.c index dbcae2b6320..7972410ad67 100644 --- a/source/blender/editors/transform/transform_snap_sequencer.c +++ b/source/blender/editors/transform/transform_snap_sequencer.c @@ -59,21 +59,23 @@ static int cmp_fn(const void *a, const void *b) return (*(int *)a - *(int *)b); } -static void seq_snap_source_points_build(TransSeqSnapData *snap_data, SeqCollection *snap_sources) +static void seq_snap_source_points_build(const Scene *scene, + TransSeqSnapData *snap_data, + SeqCollection *snap_sources) { int i = 0; Sequence *seq; SEQ_ITERATOR_FOREACH (seq, snap_sources) { int left = 0, right = 0; if (seq->flag & SEQ_LEFTSEL) { - left = right = SEQ_time_left_handle_frame_get(seq); + left = right = SEQ_time_left_handle_frame_get(scene, seq); } else if (seq->flag & SEQ_RIGHTSEL) { - left = right = SEQ_time_right_handle_frame_get(seq); + left = right = SEQ_time_right_handle_frame_get(scene, seq); } else { - left = SEQ_time_left_handle_frame_get(seq); - right = SEQ_time_right_handle_frame_get(seq); + left = SEQ_time_left_handle_frame_get(scene, seq); + right = SEQ_time_right_handle_frame_get(scene, seq); } snap_data->source_snap_points[i] = left; @@ -92,7 +94,8 @@ static void seq_snap_source_points_build(TransSeqSnapData *snap_data, SeqCollect * \{ */ /* Add effect strips directly or indirectly connected to `seq_reference` to `collection`. */ -static void query_strip_effects_fn(Sequence *seq_reference, +static void query_strip_effects_fn(const Scene *scene, + Sequence *seq_reference, ListBase *seqbase, SeqCollection *collection) { @@ -103,7 +106,7 @@ static void query_strip_effects_fn(Sequence *seq_reference, /* Find all strips connected to `seq_reference`. */ LISTBASE_FOREACH (Sequence *, seq_test, seqbase) { if (SEQ_relation_is_effect_of_strip(seq_test, seq_reference)) { - query_strip_effects_fn(seq_test, seqbase, collection); + query_strip_effects_fn(scene, seq_test, seqbase, collection); } } } @@ -145,7 +148,7 @@ static SeqCollection *query_snap_targets(Scene *scene, /* Effects will always change position with strip to which they are connected and they don't have * to be selected. Remove such strips from `snap_targets` collection. */ SeqCollection *snap_sources_temp = SEQ_collection_duplicate(snap_sources); - SEQ_collection_expand(seqbase, snap_sources_temp, query_strip_effects_fn); + SEQ_collection_expand(scene, seqbase, snap_sources_temp, query_strip_effects_fn); SeqCollection *snap_sources_effects = seq_collection_extract_effects(snap_sources_temp); SEQ_collection_exclude(snap_targets, snap_sources_effects); SEQ_collection_free(snap_sources_temp); @@ -194,24 +197,25 @@ static void seq_snap_target_points_build(Scene *scene, Sequence *seq; SEQ_ITERATOR_FOREACH (seq, snap_targets) { - snap_data->target_snap_points[i] = SEQ_time_left_handle_frame_get(seq); - snap_data->target_snap_points[i + 1] = SEQ_time_right_handle_frame_get(seq); + snap_data->target_snap_points[i] = SEQ_time_left_handle_frame_get(scene, seq); + snap_data->target_snap_points[i + 1] = SEQ_time_right_handle_frame_get(scene, seq); i += 2; if (snap_mode & SEQ_SNAP_TO_STRIP_HOLD) { - int content_start = min_ii(SEQ_time_right_handle_frame_get(seq), seq->start); - int content_end = max_ii(SEQ_time_left_handle_frame_get(seq), seq->start + seq->len); + int content_start = min_ii(SEQ_time_right_handle_frame_get(scene, seq), seq->start); + int content_end = max_ii(SEQ_time_left_handle_frame_get(scene, seq), seq->start + seq->len); /* Effects and single image strips produce incorrect content length. Skip these strips. */ if ((seq->type & SEQ_TYPE_EFFECT) != 0 || seq->len == 1) { - content_start = SEQ_time_left_handle_frame_get(seq); - content_end = SEQ_time_right_handle_frame_get(seq); + content_start = SEQ_time_left_handle_frame_get(scene, seq); + content_end = SEQ_time_right_handle_frame_get(scene, seq); } CLAMP(content_start, - SEQ_time_left_handle_frame_get(seq), - SEQ_time_right_handle_frame_get(seq)); - CLAMP( - content_end, SEQ_time_left_handle_frame_get(seq), SEQ_time_right_handle_frame_get(seq)); + SEQ_time_left_handle_frame_get(scene, seq), + SEQ_time_right_handle_frame_get(scene, seq)); + CLAMP(content_end, + SEQ_time_left_handle_frame_get(scene, seq), + SEQ_time_right_handle_frame_get(scene, seq)); snap_data->target_snap_points[i] = content_start; snap_data->target_snap_points[i + 1] = content_end; @@ -260,7 +264,7 @@ TransSeqSnapData *transform_snap_sequencer_data_alloc(const TransInfo *t) /* Build arrays of snap points. */ seq_snap_source_points_alloc(snap_data, snap_sources); - seq_snap_source_points_build(snap_data, snap_sources); + seq_snap_source_points_build(scene, snap_data, snap_sources); SEQ_collection_free(snap_sources); short snap_mode = t->tsnap.mode; diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index db24a775edb..a46d737ba9d 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -151,17 +151,17 @@ typedef struct Sequence { * Start frame of contents of strip in absolute frame coordinates. * For metastrips start of first strip startdisp. */ - int start; + float start; /** * Frames after the first frame where display starts, * frames before the last frame where display ends. */ - int startofs, endofs; + float startofs, endofs; /** * Frames that use the first frame before data begins, * frames that use the last frame after data ends. */ - int startstill, endstill; + float startstill, endstill; /** Machine: the strip channel */ int machine; int _pad3; @@ -213,7 +213,7 @@ typedef struct Sequence { float volume; /** Pitch (-0.1..10), pan -2..2. */ - float pitch, pan; + float pitch DNA_DEPRECATED, pan; float strobe; /** Struct pointer for effect settings. */ @@ -249,6 +249,11 @@ typedef struct Sequence { /* modifiers */ ListBase modifiers; + /* Playback rate of strip content in frames per second. */ + float media_playback_rate; + /* Multiply strip playback speed. */ + float speed_factor; + SequenceRuntime runtime; } Sequence; @@ -563,7 +568,7 @@ enum { SEQ_LOCK = (1 << 14), SEQ_USE_PROXY = (1 << 15), SEQ_IGNORE_CHANNEL_LOCK = (1 << 16), - SEQ_FLAG_UNUSED_22 = (1 << 17), /* cleared */ + SEQ_AUTO_PLAYBACK_RATE = (1 << 17), SEQ_FLAG_UNUSED_18 = (1 << 18), /* cleared */ SEQ_FLAG_UNUSED_19 = (1 << 19), /* cleared */ SEQ_FLAG_UNUSED_21 = (1 << 21), /* cleared */ diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index d14763d2609..f9dfb8544ca 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -292,7 +292,7 @@ static void do_sequence_frame_change_update(Scene *scene, Sequence *seq) { ListBase *seqbase = SEQ_get_seqbase_by_seq(scene, seq); - if (SEQ_transform_test_overlap(seqbase, seq)) { + if (SEQ_transform_test_overlap(scene, seqbase, seq)) { SEQ_transform_seqbase_shuffle(seqbase, seq, scene); } @@ -314,15 +314,17 @@ static void rna_Sequence_frame_change_update(Main *UNUSED(bmain), static int rna_Sequence_frame_final_start_get(PointerRNA *ptr) { - return SEQ_time_left_handle_frame_get((Sequence *)ptr->data); + Scene *scene = (Scene *)ptr->owner_id; + return SEQ_time_left_handle_frame_get(scene, (Sequence *)ptr->data); } static int rna_Sequence_frame_final_end_get(PointerRNA *ptr) { - return SEQ_time_right_handle_frame_get((Sequence *)ptr->data); + Scene *scene = (Scene *)ptr->owner_id; + return SEQ_time_right_handle_frame_get(scene, (Sequence *)ptr->data); } -static void rna_Sequence_start_frame_final_set(PointerRNA *ptr, int value) +static void rna_Sequence_start_frame_final_set(PointerRNA *ptr, float value) { Sequence *seq = (Sequence *)ptr->data; Scene *scene = (Scene *)ptr->owner_id; @@ -354,7 +356,7 @@ static void rna_Sequence_start_frame_set(PointerRNA *ptr, int value) SEQ_relations_invalidate_cache_composite(scene, seq); } -static void rna_Sequence_frame_offset_start_set(PointerRNA *ptr, int value) +static void rna_Sequence_frame_offset_start_set(PointerRNA *ptr, float value) { Sequence *seq = (Sequence *)ptr->data; Scene *scene = (Scene *)ptr->owner_id; @@ -363,7 +365,7 @@ static void rna_Sequence_frame_offset_start_set(PointerRNA *ptr, int value) seq->startofs = value; } -static void rna_Sequence_frame_offset_end_set(PointerRNA *ptr, int value) +static void rna_Sequence_frame_offset_end_set(PointerRNA *ptr, float value) { Sequence *seq = (Sequence *)ptr->data; Scene *scene = (Scene *)ptr->owner_id; @@ -413,7 +415,7 @@ static void rna_Sequence_anim_startofs_final_range( } static void rna_Sequence_frame_offset_start_range( - PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax)) + PointerRNA *ptr, float *min, float *max, float *UNUSED(softmin), float *UNUSED(softmax)) { Sequence *seq = (Sequence *)ptr->data; *min = ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD) ? 0 : INT_MIN; @@ -421,7 +423,7 @@ static void rna_Sequence_frame_offset_start_range( } static void rna_Sequence_frame_offset_end_range( - PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax)) + PointerRNA *ptr, float *min, float *max, float *UNUSED(softmin), float *UNUSED(softmax)) { Sequence *seq = (Sequence *)ptr->data; *min = ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD) ? 0 : INT_MIN; @@ -433,7 +435,7 @@ static void rna_Sequence_frame_length_set(PointerRNA *ptr, int value) Sequence *seq = (Sequence *)ptr->data; Scene *scene = (Scene *)ptr->owner_id; - SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(seq) + value); + SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(scene, seq) + value); do_sequence_frame_change_update(scene, seq); SEQ_relations_invalidate_cache_composite(scene, seq); } @@ -441,7 +443,8 @@ static void rna_Sequence_frame_length_set(PointerRNA *ptr, int value) static int rna_Sequence_frame_length_get(PointerRNA *ptr) { Sequence *seq = (Sequence *)ptr->data; - return SEQ_time_right_handle_frame_get(seq) - SEQ_time_left_handle_frame_get(seq); + 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_editable(PointerRNA *ptr, const char **UNUSED(r_info)) @@ -461,7 +464,7 @@ static void rna_Sequence_channel_set(PointerRNA *ptr, int value) const int channel_delta = (value >= seq->machine) ? 1 : -1; seq->machine = value; - if (SEQ_transform_test_overlap(seqbase, seq)) { + if (SEQ_transform_test_overlap(scene, seqbase, seq)) { SEQ_transform_seqbase_shuffle_ex(seqbase, seq, scene, channel_delta); } SEQ_relations_invalidate_cache_composite(scene, seq); @@ -815,7 +818,20 @@ static int rna_Sequence_proxy_filepath_length(PointerRNA *ptr) static void rna_Sequence_audio_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { - DEG_id_tag_update(ptr->owner_id, ID_RECALC_SEQUENCER_STRIPS); + DEG_id_tag_update(ptr->owner_id, ID_RECALC_SEQUENCER_STRIPS | ID_RECALC_AUDIO); +} + +static void rna_Sequence_speed_factor_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + SEQ_cache_cleanup(scene); + rna_Sequence_audio_update(bmain, scene, ptr); +} + +static void rna_Sequence_speed_factor_set(PointerRNA *ptr, float value) +{ + Sequence *seq = (Sequence *)ptr->data; + Scene *scene = (Scene *)ptr->owner_id; + SEQ_time_speed_factor_set(scene, seq, value); } static void rna_Sequence_pan_range( @@ -1969,11 +1985,12 @@ static void rna_def_sequence(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Length", "The length of the contents of this strip before the handles are applied"); - prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME); - RNA_def_property_int_sdna(prop, NULL, "start"); + 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_int_funcs( + RNA_def_property_ui_range(prop, MINFRAME, MAXFRAME, 3, 0); + RNA_def_property_float_funcs( prop, NULL, "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( @@ -2006,19 +2023,21 @@ static void rna_def_sequence(BlenderRNA *brna) RNA_def_property_update( prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update"); - prop = RNA_def_property(srna, "frame_offset_start", PROP_INT, PROP_TIME); - RNA_def_property_int_sdna(prop, NULL, "startofs"); + 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_int_funcs( + RNA_def_property_ui_range(prop, MINFRAME, MAXFRAME, 3, 0); + RNA_def_property_float_funcs( prop, NULL, "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_INT, PROP_TIME); - RNA_def_property_int_sdna(prop, NULL, "endofs"); + 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_int_funcs( + RNA_def_property_ui_range(prop, MINFRAME, MAXFRAME, 3, 0); + RNA_def_property_float_funcs( prop, NULL, "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"); @@ -2305,6 +2324,20 @@ static void rna_def_editor(BlenderRNA *brna) RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } +static void rna_def_speed_factor(StructRNA *srna) +{ + PropertyRNA *prop = RNA_def_property(srna, "speed_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "speed_factor"); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_range(prop, 0.1f, FLT_MAX); + RNA_def_property_ui_range(prop, 1.0f, 100.0f, 10.0, 3); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Speed Factor", "Multiply playback speed"); + RNA_def_property_float_funcs( + prop, NULL, "rna_Sequence_speed_factor_set", NULL); /* overlap test */ + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_speed_factor_update"); +} + static void rna_def_filter_video(StructRNA *srna) { PropertyRNA *prop; @@ -2537,6 +2570,7 @@ static void rna_def_image(BlenderRNA *brna) rna_def_proxy(srna); rna_def_input(srna); rna_def_color_management(srna); + rna_def_speed_factor(srna); } static void rna_def_meta(BlenderRNA *brna) @@ -2568,6 +2602,7 @@ static void rna_def_meta(BlenderRNA *brna) rna_def_filter_video(srna); rna_def_proxy(srna); rna_def_input(srna); + rna_def_speed_factor(srna); } static void rna_def_scene(BlenderRNA *brna) @@ -2616,6 +2651,7 @@ static void rna_def_scene(BlenderRNA *brna) rna_def_proxy(srna); rna_def_input(srna); rna_def_movie_types(srna); + rna_def_speed_factor(srna); } static void rna_def_movie(BlenderRNA *brna) @@ -2699,6 +2735,7 @@ static void rna_def_movie(BlenderRNA *brna) rna_def_input(srna); rna_def_color_management(srna); rna_def_movie_types(srna); + rna_def_speed_factor(srna); } static void rna_def_movieclip(BlenderRNA *brna) @@ -2726,6 +2763,7 @@ static void rna_def_movieclip(BlenderRNA *brna) rna_def_filter_video(srna); rna_def_input(srna); rna_def_movie_types(srna); + rna_def_speed_factor(srna); } static void rna_def_mask(BlenderRNA *brna) @@ -2744,6 +2782,7 @@ static void rna_def_mask(BlenderRNA *brna) rna_def_filter_video(srna); rna_def_input(srna); + rna_def_speed_factor(srna); } static void rna_def_sound(BlenderRNA *brna) @@ -2770,13 +2809,6 @@ static void rna_def_sound(BlenderRNA *brna) RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SOUND); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_audio_update"); - prop = RNA_def_property(srna, "pitch", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "pitch"); - RNA_def_property_range(prop, 0.1f, 10.0f); - RNA_def_property_ui_text(prop, "Pitch", "Playback pitch of the sound"); - RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SOUND); - RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_audio_update"); - prop = RNA_def_property(srna, "pan", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "pan"); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); @@ -2792,6 +2824,7 @@ static void rna_def_sound(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL); rna_def_input(srna); + rna_def_speed_factor(srna); } static void rna_def_effect(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index 52de98be502..aab6174cab2 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -49,13 +49,21 @@ # include "WM_api.h" -static void rna_Sequence_swap_internal(Sequence *seq_self, +static StripElem *rna_Sequence_strip_elem_from_frame(ID *id, Sequence *self, int timeline_frame) +{ + Scene *scene = (Scene *)id; + return SEQ_render_give_stripelem(scene, self, timeline_frame); +} + +static void rna_Sequence_swap_internal(ID *id, + Sequence *seq_self, ReportList *reports, Sequence *seq_other) { const char *error_msg; + Scene *scene = (Scene *)id; - if (SEQ_edit_sequence_swap(seq_self, seq_other, &error_msg) == 0) { + if (SEQ_edit_sequence_swap(scene, seq_self, seq_other, &error_msg) == 0) { BKE_report(reports, RPT_ERROR, error_msg); } } @@ -247,7 +255,7 @@ static Sequence *rna_Sequences_new_image(ID *id, char dir[FILE_MAX], filename[FILE_MAX]; BLI_split_dirfile(file, dir, filename, sizeof(dir), sizeof(filename)); SEQ_add_image_set_directory(seq, dir); - SEQ_add_image_load_file(seq, 0, filename); + SEQ_add_image_load_file(scene, seq, 0, filename); SEQ_add_image_init_alpha_mode(seq); DEG_relations_tag_update(bmain); @@ -647,7 +655,8 @@ void RNA_api_sequence_strip(StructRNA *srna) {0, NULL, 0, NULL, NULL}, }; - func = RNA_def_function(srna, "strip_elem_from_frame", "SEQ_render_give_stripelem"); + func = RNA_def_function(srna, "strip_elem_from_frame", "rna_Sequence_strip_elem_from_frame"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Return the strip element from a given frame or None"); parm = RNA_def_int(func, "frame", @@ -664,6 +673,7 @@ void RNA_api_sequence_strip(StructRNA *srna) RNA_def_pointer(func, "elem", "SequenceElement", "", "strip element of the current frame")); func = RNA_def_function(srna, "swap", "rna_Sequence_swap_internal"); + RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "other", "Sequence", "Other", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); diff --git a/source/blender/sequencer/SEQ_add.h b/source/blender/sequencer/SEQ_add.h index dea5151598c..7c2d50a815e 100644 --- a/source/blender/sequencer/SEQ_add.h +++ b/source/blender/sequencer/SEQ_add.h @@ -50,6 +50,7 @@ typedef struct SeqLoadData { struct Stereo3dFormat *stereo3d_format; bool allow_invalid_file; /* Used by RNA API to create placeholder strips. */ double r_video_stream_start; /* For AV synchronization. Set by `SEQ_add_movie_strip`. */ + bool adjust_playback_rate; } SeqLoadData; /** @@ -176,7 +177,10 @@ void SEQ_add_image_set_directory(struct Sequence *seq, char *path); * \param strip_frame: frame index of strip to be changed * \param filename: image filename (only filename, not complete path) */ -void SEQ_add_image_load_file(struct Sequence *seq, size_t strip_frame, char *filename); +void SEQ_add_image_load_file(struct Scene *scene, + struct Sequence *seq, + size_t strip_frame, + char *filename); /** * Set image strip alpha mode * diff --git a/source/blender/sequencer/SEQ_edit.h b/source/blender/sequencer/SEQ_edit.h index 2f07d5ae940..ff9c387e527 100644 --- a/source/blender/sequencer/SEQ_edit.h +++ b/source/blender/sequencer/SEQ_edit.h @@ -16,7 +16,10 @@ struct Main; struct Scene; struct Sequence; -int SEQ_edit_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str); +int SEQ_edit_sequence_swap(struct Scene *scene, + struct Sequence *seq_a, + struct Sequence *seq_b, + const char **error_str); /** * Move sequence to seqbase. * diff --git a/source/blender/sequencer/SEQ_effects.h b/source/blender/sequencer/SEQ_effects.h index e5af6f963e2..fa5d6d18736 100644 --- a/source/blender/sequencer/SEQ_effects.h +++ b/source/blender/sequencer/SEQ_effects.h @@ -55,7 +55,10 @@ struct SeqEffectHandle { int (*early_out)(struct Sequence *seq, float fac); /* sets the default `fac` value */ - void (*get_default_fac)(struct Sequence *seq, float timeline_frame, float *fac); + void (*get_default_fac)(const struct Scene *scene, + struct Sequence *seq, + float timeline_frame, + float *fac); /* execute the effect * sequence effects are only required to either support diff --git a/source/blender/sequencer/SEQ_iterator.h b/source/blender/sequencer/SEQ_iterator.h index 1f94574513c..e5adb2a33b1 100644 --- a/source/blender/sequencer/SEQ_iterator.h +++ b/source/blender/sequencer/SEQ_iterator.h @@ -157,9 +157,11 @@ void SEQ_collection_exclude(SeqCollection *collection, SeqCollection *exclude_el * \param collection: SeqCollection to be expanded * \param seq_query_func: query function callback */ -void SEQ_collection_expand(struct ListBase *seqbase, +void SEQ_collection_expand(const struct Scene *scene, + struct ListBase *seqbase, SeqCollection *collection, - void seq_query_func(struct Sequence *seq_reference, + void seq_query_func(const struct Scene *scene, + struct Sequence *seq_reference, struct ListBase *seqbase, SeqCollection *collection)); /** @@ -171,8 +173,10 @@ void SEQ_collection_expand(struct ListBase *seqbase, * \return strip collection */ SeqCollection *SEQ_query_by_reference(struct Sequence *seq_reference, + const struct Scene *scene, struct ListBase *seqbase, - void seq_query_func(struct Sequence *seq_reference, + void seq_query_func(const struct Scene *scene, + struct Sequence *seq_reference, struct ListBase *seqbase, SeqCollection *collection)); /** @@ -211,7 +215,8 @@ SeqCollection *SEQ_query_all_strips_recursive(ListBase *seqbase); * \param displayed_channel: viewed channel. when set to 0, no channel filter is applied * \return strip collection */ -SeqCollection *SEQ_query_rendered_strips(ListBase *channels, +SeqCollection *SEQ_query_rendered_strips(const struct Scene *scene, + ListBase *channels, ListBase *seqbase, int timeline_frame, int displayed_channel); @@ -224,7 +229,8 @@ SeqCollection *SEQ_query_rendered_strips(ListBase *channels, * \param seqbase: ListBase in which strips are queried * \param collection: collection to be filled */ -void SEQ_query_strip_effect_chain(struct Sequence *seq_reference, +void SEQ_query_strip_effect_chain(const struct Scene *scene, + struct Sequence *seq_reference, struct ListBase *seqbase, SeqCollection *collection); void SEQ_filter_selected_strips(SeqCollection *collection); diff --git a/source/blender/sequencer/SEQ_render.h b/source/blender/sequencer/SEQ_render.h index a74eba5fc6f..9c163de4230 100644 --- a/source/blender/sequencer/SEQ_render.h +++ b/source/blender/sequencer/SEQ_render.h @@ -79,20 +79,23 @@ struct ImBuf *SEQ_get_thumbnail(const struct SeqRenderData *context, /** * Get frame for first thumbnail. */ -float SEQ_render_thumbnail_first_frame_get(struct Sequence *seq, +float SEQ_render_thumbnail_first_frame_get(const struct Scene *scene, + struct Sequence *seq, float frame_step, struct rctf *view_area); /** * Get frame for first thumbnail. */ -float SEQ_render_thumbnail_next_frame_get(struct Sequence *seq, +float SEQ_render_thumbnail_next_frame_get(const struct Scene *scene, + struct Sequence *seq, float last_frame, float frame_step); /** * Get frame step for equally spaced thumbnails. These thumbnails should always be present in * memory, so they can be used when zooming. */ -int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const struct Sequence *seq); +int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const struct Scene *scene, + const struct Sequence *seq); /** * Render set of evenly spaced thumbnails that are drawn when zooming.. */ @@ -112,7 +115,9 @@ void SEQ_render_new_render_data(struct Main *bmain, int for_render, SeqRenderData *r_context); int SEQ_render_evaluate_frame(struct ListBase *seqbase, int timeline_frame); -struct StripElem *SEQ_render_give_stripelem(struct Sequence *seq, int timeline_frame); +struct StripElem *SEQ_render_give_stripelem(const struct Scene *scene, + struct Sequence *seq, + int timeline_frame); void SEQ_render_imbuf_from_sequencer_space(struct Scene *scene, struct ImBuf *ibuf); void SEQ_render_pixel_from_sequencer_space_v4(struct Scene *scene, float pixel[4]); diff --git a/source/blender/sequencer/SEQ_sound.h b/source/blender/sequencer/SEQ_sound.h index 52bdb68a554..e49f081109f 100644 --- a/source/blender/sequencer/SEQ_sound.h +++ b/source/blender/sequencer/SEQ_sound.h @@ -20,6 +20,7 @@ void SEQ_sound_update_bounds_all(struct Scene *scene); void SEQ_sound_update_bounds(struct Scene *scene, struct Sequence *seq); void SEQ_sound_update(struct Scene *scene, struct bSound *sound); void SEQ_sound_update_length(struct Main *bmain, struct Scene *scene); +float SEQ_sound_pitch_get(const struct Scene *scene, const struct Sequence *seq); #ifdef __cplusplus } diff --git a/source/blender/sequencer/SEQ_time.h b/source/blender/sequencer/SEQ_time.h index eab10f2e852..69dc20d39ca 100644 --- a/source/blender/sequencer/SEQ_time.h +++ b/source/blender/sequencer/SEQ_time.h @@ -29,7 +29,9 @@ void SEQ_timeline_init_boundbox(const struct Scene *scene, struct rctf *rect); * \param seqbase: ListBase in which strips are located * \param rect: output parameter to be filled with strips' boundaries */ -void SEQ_timeline_expand_boundbox(const struct ListBase *seqbase, struct rctf *rect); +void SEQ_timeline_expand_boundbox(const struct Scene *scene, + const struct ListBase *seqbase, + struct rctf *rect); /** * Define boundary rectangle of sequencer timeline and fill in rect data * @@ -56,15 +58,23 @@ int SEQ_time_find_next_prev_edit(struct Scene *scene, * \param timeline_frame: absolute frame position * \return true if strip intersects with timeline frame. */ -bool SEQ_time_strip_intersects_frame(const struct Sequence *seq, int timeline_frame); -bool SEQ_time_has_still_frames(const struct Sequence *seq); -bool SEQ_time_has_left_still_frames(const struct Sequence *seq); -bool SEQ_time_has_right_still_frames(const struct Sequence *seq); +bool SEQ_time_strip_intersects_frame(const struct Scene *scene, + const struct Sequence *seq, + int timeline_frame); +bool SEQ_time_has_still_frames(const struct Scene *scene, const struct Sequence *seq); +bool SEQ_time_has_left_still_frames(const struct Scene *scene, const struct Sequence *seq); +bool SEQ_time_has_right_still_frames(const struct Scene *scene, const struct Sequence *seq); -int SEQ_time_left_handle_frame_get(const struct Sequence *seq); -int SEQ_time_right_handle_frame_get(const struct Sequence *seq); +int SEQ_time_left_handle_frame_get(const struct Scene *scene, const struct Sequence *seq); +int SEQ_time_right_handle_frame_get(const struct Scene *scene, const struct Sequence *seq); void SEQ_time_left_handle_frame_set(const struct Scene *scene, struct Sequence *seq, int val); void SEQ_time_right_handle_frame_set(const struct Scene *scene, struct Sequence *seq, int val); +int SEQ_time_strip_length_get(const struct Scene *scene, const struct Sequence *seq); +void SEQ_time_speed_factor_set(const struct Scene *scene, + struct Sequence *seq, + const float speed_factor); +float SEQ_time_start_frame_get(const struct Sequence *seq); +void SEQ_time_start_frame_set(const struct Scene *scene, struct Sequence *seq, int timeline_frame); void SEQ_time_update_meta_strip_range(const struct Scene *scene, struct Sequence *seq_meta); #ifdef __cplusplus diff --git a/source/blender/sequencer/SEQ_transform.h b/source/blender/sequencer/SEQ_transform.h index 31a7399f844..8bc7733861c 100644 --- a/source/blender/sequencer/SEQ_transform.h +++ b/source/blender/sequencer/SEQ_transform.h @@ -17,14 +17,6 @@ struct Scene; struct SeqCollection; struct Sequence; -/** - * Use to impose limits when dragging/extending - so impossible situations don't happen. - * Can't use the #SEQ_LEFTSEL and #SEQ_LEFTSEL directly because the strip may be in a meta-strip. - */ -void SEQ_transform_handle_xlimits(const struct Scene *scene, - struct Sequence *seq, - int leftflag, - int rightflag); bool SEQ_transform_sequence_can_be_translated(struct Sequence *seq); /** * Used so we can do a quick check for single image seq @@ -32,8 +24,12 @@ bool SEQ_transform_sequence_can_be_translated(struct Sequence *seq); */ bool SEQ_transform_single_image_check(struct Sequence *seq); void SEQ_transform_fix_single_image_seq_offsets(const struct Scene *scene, struct Sequence *seq); -bool SEQ_transform_test_overlap(struct ListBase *seqbasep, struct Sequence *test); -bool SEQ_transform_test_overlap_seq_seq(struct Sequence *seq1, struct Sequence *seq2); +bool SEQ_transform_test_overlap(const struct Scene *scene, + struct ListBase *seqbasep, + struct Sequence *test); +bool SEQ_transform_test_overlap_seq_seq(const struct Scene *scene, + struct Sequence *seq1, + struct Sequence *seq2); void SEQ_transform_translate_sequence(struct Scene *scene, struct Sequence *seq, int delta); /** * \return 0 if there weren't enough space. diff --git a/source/blender/sequencer/intern/disk_cache.c b/source/blender/sequencer/intern/disk_cache.c index cc34066c432..37830205588 100644 --- a/source/blender/sequencer/intern/disk_cache.c +++ b/source/blender/sequencer/intern/disk_cache.c @@ -412,8 +412,8 @@ void seq_disk_cache_invalidate(SeqDiskCache *disk_cache, BLI_mutex_lock(&disk_cache->read_write_mutex); - start = SEQ_time_left_handle_frame_get(seq_changed) - DCACHE_IMAGES_PER_FILE; - end = SEQ_time_right_handle_frame_get(seq_changed); + start = SEQ_time_left_handle_frame_get(scene, seq_changed) - DCACHE_IMAGES_PER_FILE; + end = SEQ_time_right_handle_frame_get(scene, seq_changed); seq_disk_cache_delete_invalid_files(disk_cache, scene, seq, invalidate_types, start, end); diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c index 0e5e56908b0..368c00534be 100644 --- a/source/blender/sequencer/intern/effects.c +++ b/source/blender/sequencer/intern/effects.c @@ -2475,8 +2475,8 @@ static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, fl * frame is static after end of strip). This is how most strips behave. This way transition * effects that doesn't overlap or speed effect can't fail rendering outside of strip range. */ timeline_frame = clamp_i(timeline_frame, - SEQ_time_left_handle_frame_get(seq), - SEQ_time_right_handle_frame_get(seq) - 1); + SEQ_time_left_handle_frame_get(context->scene, seq), + SEQ_time_right_handle_frame_get(context->scene, seq) - 1); if (seq->machine > 1) { i = seq_render_give_ibuf_seqbase( @@ -2583,13 +2583,14 @@ static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(fac)) * useful to use speed effect on these strips because they can be animated. This can be done by * using their length as is on timeline as content length. See T82698. */ -static int seq_effect_speed_get_strip_content_length(const Sequence *seq) +static int seq_effect_speed_get_strip_content_length(Scene *scene, const Sequence *seq) { if ((seq->type & SEQ_TYPE_EFFECT) != 0 && SEQ_effect_get_num_inputs(seq->type) == 0) { - return SEQ_time_right_handle_frame_get(seq) - SEQ_time_left_handle_frame_get(seq); + return SEQ_time_right_handle_frame_get(scene, seq) - + SEQ_time_left_handle_frame_get(scene, seq); } - return seq->len; + return SEQ_time_strip_length_get(scene, seq); } static FCurve *seq_effect_speed_speed_factor_curve_get(Scene *scene, Sequence *seq) @@ -2613,14 +2614,14 @@ void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq) MEM_freeN(v->frameMap); } - const int effect_strip_length = SEQ_time_right_handle_frame_get(seq) - - SEQ_time_left_handle_frame_get(seq); + const int effect_strip_length = SEQ_time_right_handle_frame_get(scene, seq) - + SEQ_time_left_handle_frame_get(scene, seq); v->frameMap = MEM_mallocN(sizeof(float) * effect_strip_length, __func__); v->frameMap[0] = 0.0f; float target_frame = 0; for (int frame_index = 1; frame_index < effect_strip_length; frame_index++) { - target_frame += evaluate_fcurve(fcu, SEQ_time_left_handle_frame_get(seq) + frame_index); + target_frame += evaluate_fcurve(fcu, SEQ_time_left_handle_frame_get(scene, seq) + frame_index); CLAMP(target_frame, 0, seq->seq1->len); v->frameMap[frame_index] = target_frame; } @@ -2646,7 +2647,7 @@ float seq_speed_effect_target_frame_get(Scene *scene, } SEQ_effect_handle_get(seq_speed); /* Ensure, that data are initialized. */ - int frame_index = seq_give_frame_index(seq_speed, timeline_frame); + int frame_index = seq_give_frame_index(scene, seq_speed, timeline_frame); SpeedControlVars *s = (SpeedControlVars *)seq_speed->effectdata; const Sequence *source = seq_speed->seq1; @@ -2654,10 +2655,11 @@ float seq_speed_effect_target_frame_get(Scene *scene, switch (s->speed_control_type) { case SEQ_SPEED_STRETCH: { /* Only right handle controls effect speed! */ - const float target_content_length = seq_effect_speed_get_strip_content_length(source) - + const float target_content_length = seq_effect_speed_get_strip_content_length(scene, + source) - source->startofs; - const float speed_effetct_length = SEQ_time_right_handle_frame_get(seq_speed) - - SEQ_time_left_handle_frame_get(seq_speed); + const float speed_effetct_length = SEQ_time_right_handle_frame_get(scene, seq_speed) - + SEQ_time_left_handle_frame_get(scene, seq_speed); const float ratio = frame_index / speed_effetct_length; target_frame = target_content_length * ratio; break; @@ -2674,7 +2676,7 @@ float seq_speed_effect_target_frame_get(Scene *scene, break; } case SEQ_SPEED_LENGTH: - target_frame = seq_effect_speed_get_strip_content_length(source) * + target_frame = seq_effect_speed_get_strip_content_length(scene, source) * (s->speed_fader_length / 100.0f); break; case SEQ_SPEED_FRAME_NUMBER: @@ -2682,7 +2684,7 @@ float seq_speed_effect_target_frame_get(Scene *scene, break; } - CLAMP(target_frame, 0, seq_effect_speed_get_strip_content_length(source)); + CLAMP(target_frame, 0, seq_effect_speed_get_strip_content_length(scene, source)); target_frame += seq_speed->start; /* No interpolation. */ @@ -3507,15 +3509,21 @@ static int early_out_mul_input1(Sequence *UNUSED(seq), float fac) return EARLY_DO_EFFECT; } -static void get_default_fac_noop(Sequence *UNUSED(seq), float UNUSED(timeline_frame), float *fac) +static void get_default_fac_noop(const Scene *UNUSED(scene), + Sequence *UNUSED(seq), + float UNUSED(timeline_frame), + float *fac) { *fac = 1.0f; } -static void get_default_fac_fade(Sequence *seq, float timeline_frame, float *fac) +static void get_default_fac_fade(const Scene *scene, + Sequence *seq, + float timeline_frame, + float *fac) { - *fac = (float)(timeline_frame - SEQ_time_left_handle_frame_get(seq)); - *fac /= seq->len; + *fac = (float)(timeline_frame - SEQ_time_left_handle_frame_get(scene, seq)); + *fac /= SEQ_time_strip_length_get(scene, seq); } static struct ImBuf *init_execution(const SeqRenderData *context, diff --git a/source/blender/sequencer/intern/image_cache.c b/source/blender/sequencer/intern/image_cache.c index 47306dbbc6c..53f076c9681 100644 --- a/source/blender/sequencer/intern/image_cache.c +++ b/source/blender/sequencer/intern/image_cache.c @@ -133,21 +133,24 @@ static bool seq_cache_hashcmp(const void *a_, const void *b_) seq_cmp_render_data(&a->context, &b->context)); } -static float seq_cache_timeline_frame_to_frame_index(Sequence *seq, float timeline_frame, int type) +static float seq_cache_timeline_frame_to_frame_index(Scene *scene, + Sequence *seq, + float timeline_frame, + int type) { /* With raw images, map timeline_frame to strip input media frame range. This means that static * images or extended frame range of movies will only generate one cache entry. No special * treatment in converting frame index to timeline_frame is needed. */ if (ELEM(type, SEQ_CACHE_STORE_RAW, SEQ_CACHE_STORE_THUMBNAIL)) { - return seq_give_frame_index(seq, timeline_frame); + return seq_give_frame_index(scene, seq, timeline_frame); } - return timeline_frame - seq->start; + return timeline_frame - SEQ_time_start_frame_get(seq); } float seq_cache_frame_index_to_timeline_frame(Sequence *seq, float frame_index) { - return frame_index + seq->start; + return frame_index + SEQ_time_start_frame_get(seq); } static SeqCache *seq_cache_get_from_scene(Scene *scene) @@ -518,7 +521,8 @@ static void seq_cache_populate_key(SeqCacheKey *key, key->cache_owner = seq_cache_get_from_scene(context->scene); key->seq = seq; key->context = *context; - key->frame_index = seq_cache_timeline_frame_to_frame_index(seq, timeline_frame, type); + key->frame_index = seq_cache_timeline_frame_to_frame_index( + context->scene, seq, timeline_frame, type); key->timeline_frame = timeline_frame; key->type = type; key->link_prev = NULL; @@ -558,10 +562,10 @@ void seq_cache_free_temp_cache(Scene *scene, short id, int timeline_frame) if (key->is_temp_cache && key->task_id == id && key->type != SEQ_CACHE_STORE_THUMBNAIL) { /* Use frame_index here to avoid freeing raw images if they are used for multiple frames. */ float frame_index = seq_cache_timeline_frame_to_frame_index( - key->seq, timeline_frame, key->type); + scene, key->seq, timeline_frame, key->type); if (frame_index != key->frame_index || - timeline_frame > SEQ_time_right_handle_frame_get(key->seq) || - timeline_frame < SEQ_time_left_handle_frame_get(key->seq)) { + timeline_frame > SEQ_time_right_handle_frame_get(scene, key->seq) || + timeline_frame < SEQ_time_left_handle_frame_get(scene, key->seq)) { BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree); } } @@ -636,12 +640,12 @@ void seq_cache_cleanup_sequence(Scene *scene, seq_cache_lock(scene); - int range_start = SEQ_time_left_handle_frame_get(seq_changed); - int range_end = SEQ_time_right_handle_frame_get(seq_changed); + int range_start = SEQ_time_left_handle_frame_get(scene, seq_changed); + int range_end = SEQ_time_right_handle_frame_get(scene, seq_changed); if (!force_seq_changed_range) { - range_start = max_ii(range_start, SEQ_time_left_handle_frame_get(seq)); - range_end = min_ii(range_end, SEQ_time_right_handle_frame_get(seq)); + range_start = max_ii(range_start, SEQ_time_left_handle_frame_get(scene, seq)); + range_end = min_ii(range_end, SEQ_time_right_handle_frame_get(scene, seq)); } int invalidate_composite = invalidate_types & SEQ_CACHE_STORE_FINAL_OUT; @@ -665,8 +669,8 @@ void seq_cache_cleanup_sequence(Scene *scene, } if (key->type & invalidate_source && key->seq == seq && - key->timeline_frame >= SEQ_time_left_handle_frame_get(seq_changed) && - key->timeline_frame <= SEQ_time_right_handle_frame_get(seq_changed)) { + key->timeline_frame >= SEQ_time_left_handle_frame_get(scene, seq_changed) && + key->timeline_frame <= SEQ_time_right_handle_frame_get(scene, seq_changed)) { if (key->link_next || key->link_prev) { seq_cache_relink_keys(key->link_next, key->link_prev); } @@ -697,12 +701,12 @@ void seq_cache_thumbnail_cleanup(Scene *scene, rctf *view_area_safe) SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter); BLI_ghashIterator_step(&gh_iter); - const int frame_index = key->timeline_frame - SEQ_time_left_handle_frame_get(key->seq); - const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(key->seq); + const int frame_index = key->timeline_frame - SEQ_time_left_handle_frame_get(scene, key->seq); + const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(scene, key->seq); const int relative_base_frame = round_fl_to_int((frame_index / (float)frame_step)) * frame_step; const int nearest_guaranted_absolute_frame = relative_base_frame + - SEQ_time_left_handle_frame_get(key->seq); + SEQ_time_left_handle_frame_get(scene, key->seq); if (nearest_guaranted_absolute_frame == key->timeline_frame) { continue; diff --git a/source/blender/sequencer/intern/iterator.c b/source/blender/sequencer/intern/iterator.c index 2710edd6e80..acf6776c4ed 100644 --- a/source/blender/sequencer/intern/iterator.c +++ b/source/blender/sequencer/intern/iterator.c @@ -103,13 +103,15 @@ bool SEQ_collection_has_strip(const Sequence *seq, const SeqCollection *collecti } SeqCollection *SEQ_query_by_reference(Sequence *seq_reference, + const Scene *scene, ListBase *seqbase, - void seq_query_func(Sequence *seq_reference, + void seq_query_func(const Scene *scene, + Sequence *seq_reference, ListBase *seqbase, SeqCollection *collection)) { SeqCollection *collection = SEQ_collection_create(__func__); - seq_query_func(seq_reference, seqbase, collection); + seq_query_func(scene, seq_reference, seqbase, collection); return collection; } bool SEQ_collection_append_strip(Sequence *seq, SeqCollection *collection) @@ -146,9 +148,11 @@ void SEQ_collection_exclude(SeqCollection *collection, SeqCollection *exclude_el SEQ_collection_free(exclude_elements); } -void SEQ_collection_expand(ListBase *seqbase, +void SEQ_collection_expand(const Scene *scene, + ListBase *seqbase, SeqCollection *collection, - void seq_query_func(Sequence *seq_reference, + void seq_query_func(const Scene *scene, + Sequence *seq_reference, ListBase *seqbase, SeqCollection *collection)) { @@ -157,7 +161,8 @@ void SEQ_collection_expand(ListBase *seqbase, Sequence *seq; SEQ_ITERATOR_FOREACH (seq, collection) { - SEQ_collection_merge(query_matches, SEQ_query_by_reference(seq, seqbase, seq_query_func)); + SEQ_collection_merge(query_matches, + SEQ_query_by_reference(seq, scene, seqbase, seq_query_func)); } /* Merge all expanded results in provided SeqIteratorCollection. */ @@ -219,12 +224,14 @@ SeqCollection *SEQ_query_selected_strips(ListBase *seqbase) return collection; } -static SeqCollection *query_strips_at_frame(ListBase *seqbase, const int timeline_frame) +static SeqCollection *query_strips_at_frame(const Scene *scene, + ListBase *seqbase, + const int timeline_frame) { SeqCollection *collection = SEQ_collection_create(__func__); LISTBASE_FOREACH (Sequence *, seq, seqbase) { - if (SEQ_time_strip_intersects_frame(seq, timeline_frame)) { + if (SEQ_time_strip_intersects_frame(scene, seq, timeline_frame)) { SEQ_collection_append_strip(seq, collection); } } @@ -299,12 +306,13 @@ static void collection_filter_rendered_strips(ListBase *channels, SeqCollection } } -SeqCollection *SEQ_query_rendered_strips(ListBase *channels, +SeqCollection *SEQ_query_rendered_strips(const Scene *scene, + ListBase *channels, ListBase *seqbase, const int timeline_frame, const int displayed_channel) { - SeqCollection *collection = query_strips_at_frame(seqbase, timeline_frame); + SeqCollection *collection = query_strips_at_frame(scene, seqbase, timeline_frame); if (displayed_channel != 0) { collection_filter_channel_up_to_incl(collection, displayed_channel); } @@ -324,7 +332,8 @@ SeqCollection *SEQ_query_unselected_strips(ListBase *seqbase) return collection; } -void SEQ_query_strip_effect_chain(Sequence *seq_reference, +void SEQ_query_strip_effect_chain(const Scene *scene, + Sequence *seq_reference, ListBase *seqbase, SeqCollection *collection) { @@ -335,13 +344,13 @@ void SEQ_query_strip_effect_chain(Sequence *seq_reference, /* Find all strips that seq_reference is connected to. */ if (seq_reference->type & SEQ_TYPE_EFFECT) { if (seq_reference->seq1) { - SEQ_query_strip_effect_chain(seq_reference->seq1, seqbase, collection); + SEQ_query_strip_effect_chain(scene, seq_reference->seq1, seqbase, collection); } if (seq_reference->seq2) { - SEQ_query_strip_effect_chain(seq_reference->seq2, seqbase, collection); + SEQ_query_strip_effect_chain(scene, seq_reference->seq2, seqbase, collection); } if (seq_reference->seq3) { - SEQ_query_strip_effect_chain(seq_reference->seq3, seqbase, collection); + SEQ_query_strip_effect_chain(scene, seq_reference->seq3, seqbase, collection); } } @@ -349,7 +358,7 @@ void SEQ_query_strip_effect_chain(Sequence *seq_reference, LISTBASE_FOREACH (Sequence *, seq_test, seqbase) { if (seq_test->seq1 == seq_reference || seq_test->seq2 == seq_reference || seq_test->seq3 == seq_reference) { - SEQ_query_strip_effect_chain(seq_test, seqbase, collection); + SEQ_query_strip_effect_chain(scene, seq_test, seqbase, collection); } } } diff --git a/source/blender/sequencer/intern/prefetch.c b/source/blender/sequencer/intern/prefetch.c index 01f581bc6c1..2a9f7f52779 100644 --- a/source/blender/sequencer/intern/prefetch.c +++ b/source/blender/sequencer/intern/prefetch.c @@ -395,7 +395,7 @@ static bool seq_prefetch_scene_strip_is_rendered(PrefetchJob *pfjob, { float cfra = seq_prefetch_cfra(pfjob); Sequence *seq_arr[MAXSEQ + 1]; - int count = seq_get_shown_sequences(channels, seqbase, cfra, 0, seq_arr); + int count = seq_get_shown_sequences(pfjob->scene_eval, channels, seqbase, cfra, 0, seq_arr); /* Iterate over rendered strips. */ for (int i = 0; i < count; i++) { diff --git a/source/blender/sequencer/intern/proxy.c b/source/blender/sequencer/intern/proxy.c index 464580f5bed..522c64f7791 100644 --- a/source/blender/sequencer/intern/proxy.c +++ b/source/blender/sequencer/intern/proxy.c @@ -123,7 +123,7 @@ bool seq_proxy_get_custom_file_fname(Sequence *seq, char *name, const int view_i return true; } -static bool seq_proxy_get_fname(Editing *ed, +static bool seq_proxy_get_fname(Scene *scene, Sequence *seq, int timeline_frame, eSpaceSeq_Proxy_RenderSize render_size, @@ -132,6 +132,7 @@ static bool seq_proxy_get_fname(Editing *ed, { char dir[PROXY_MAXFILE]; char suffix[24] = {'\0'}; + Editing *ed = SEQ_editing_get(scene); StripProxy *proxy = seq->strip->proxy; if (proxy == NULL) { @@ -179,7 +180,7 @@ static bool seq_proxy_get_fname(Editing *ed, "%s/images/%d/%s_proxy%s", dir, proxy_size_number, - SEQ_render_give_stripelem(seq, timeline_frame)->name, + SEQ_render_give_stripelem(scene, seq, timeline_frame)->name, suffix); BLI_path_abs(name, BKE_main_blendfile_path_from_global()); strcat(name, ".jpg"); @@ -202,7 +203,6 @@ ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int timeline char name[PROXY_MAXFILE]; StripProxy *proxy = seq->strip->proxy; const eSpaceSeq_Proxy_RenderSize psize = context->preview_render_size; - Editing *ed = context->scene->ed; StripAnim *sanim; /* only use proxies, if they are enabled (even if present!) */ @@ -211,9 +211,11 @@ ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int timeline } if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) { - int frameno = (int)seq_give_frame_index(seq, timeline_frame) + seq->anim_startofs; + int frameno = (int)seq_give_frame_index(context->scene, seq, timeline_frame) + + seq->anim_startofs; if (proxy->anim == NULL) { - if (seq_proxy_get_fname(ed, seq, timeline_frame, psize, name, context->view_id) == 0) { + if (seq_proxy_get_fname( + context->scene, seq, timeline_frame, psize, name, context->view_id) == 0) { return NULL; } @@ -232,7 +234,8 @@ ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int timeline return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE); } - if (seq_proxy_get_fname(ed, seq, timeline_frame, psize, name, context->view_id) == 0) { + if (seq_proxy_get_fname(context->scene, seq, timeline_frame, psize, name, context->view_id) == + 0) { return NULL; } @@ -260,9 +263,10 @@ static void seq_proxy_build_frame(const SeqRenderData *context, int quality; int rectx, recty; ImBuf *ibuf_tmp, *ibuf; - Editing *ed = context->scene->ed; + Scene *scene = context->scene; - if (!seq_proxy_get_fname(ed, seq, timeline_frame, proxy_render_size, name, context->view_id)) { + if (!seq_proxy_get_fname( + scene, seq, timeline_frame, proxy_render_size, name, context->view_id)) { return; } @@ -524,8 +528,8 @@ void SEQ_proxy_rebuild(SeqIndexBuildContext *context, SeqRenderState state; seq_render_state_init(&state); - for (timeline_frame = SEQ_time_left_handle_frame_get(seq); - timeline_frame < SEQ_time_right_handle_frame_get(seq); + for (timeline_frame = SEQ_time_left_handle_frame_get(scene, seq); + timeline_frame < SEQ_time_right_handle_frame_get(scene, seq); timeline_frame++) { if (context->size_flags & IMB_PROXY_25) { seq_proxy_build_frame(&render_context, &state, seq, timeline_frame, 25, overwrite); @@ -540,8 +544,9 @@ void SEQ_proxy_rebuild(SeqIndexBuildContext *context, seq_proxy_build_frame(&render_context, &state, seq, timeline_frame, 100, overwrite); } - *progress = (float)(timeline_frame - SEQ_time_left_handle_frame_get(seq)) / - (SEQ_time_right_handle_frame_get(seq) - SEQ_time_left_handle_frame_get(seq)); + *progress = (float)(timeline_frame - SEQ_time_left_handle_frame_get(scene, seq)) / + (SEQ_time_right_handle_frame_get(scene, seq) - + SEQ_time_left_handle_frame_get(scene, seq)); *do_update = true; if (*stop || G.is_break) { diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c index e7a1bbeb9d0..15487a597d1 100644 --- a/source/blender/sequencer/intern/render.c +++ b/source/blender/sequencer/intern/render.c @@ -233,7 +233,7 @@ void seq_render_state_init(SeqRenderState *state) state->scene_parents = NULL; } -StripElem *SEQ_render_give_stripelem(Sequence *seq, int timeline_frame) +StripElem *SEQ_render_give_stripelem(const Scene *scene, Sequence *seq, int timeline_frame) { StripElem *se = seq->strip->stripdata; @@ -242,7 +242,7 @@ StripElem *SEQ_render_give_stripelem(Sequence *seq, int timeline_frame) * all other strips don't use this... */ - int frame_index = (int)seq_give_frame_index(seq, timeline_frame); + int frame_index = (int)seq_give_frame_index(scene, seq, timeline_frame); if (frame_index == -1 || se == NULL) { return NULL; @@ -258,14 +258,15 @@ static int seq_channel_cmp_fn(const void *a, const void *b) return (*(Sequence **)a)->machine - (*(Sequence **)b)->machine; } -int seq_get_shown_sequences(ListBase *channels, +int seq_get_shown_sequences(const Scene *scene, + ListBase *channels, ListBase *seqbase, const int timeline_frame, const int chanshown, Sequence **r_seq_arr) { SeqCollection *collection = SEQ_query_rendered_strips( - channels, seqbase, timeline_frame, chanshown); + scene, channels, seqbase, timeline_frame, chanshown); const int strip_count = BLI_gset_len(collection->set); if (strip_count > MAXSEQ) { @@ -795,7 +796,7 @@ static ImBuf *seq_render_effect_strip_impl(const SeqRenderData *context, } if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) { - sh.get_default_fac(seq, timeline_frame, &fac); + sh.get_default_fac(scene, seq, timeline_frame, &fac); } else { fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "effect_fader", 0, NULL); @@ -936,7 +937,7 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context, char prefix[FILE_MAX]; ImBuf *ibuf = NULL; - StripElem *s_elem = SEQ_render_give_stripelem(seq, timeline_frame); + StripElem *s_elem = SEQ_render_give_stripelem(context->scene, seq, timeline_frame); if (s_elem == NULL) { return NULL; } @@ -1024,7 +1025,8 @@ static ImBuf *seq_render_movie_strip_custom_file_proxy(const SeqRenderData *cont } } - int frameno = (int)seq_give_frame_index(seq, timeline_frame) + seq->anim_startofs; + int frameno = (int)seq_give_frame_index(context->scene, seq, timeline_frame) + + seq->anim_startofs; return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE); } @@ -1622,7 +1624,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, bool *r_is_proxy_image) { ImBuf *ibuf = NULL; - float frame_index = seq_give_frame_index(seq, timeline_frame); + float frame_index = seq_give_frame_index(context->scene, seq, timeline_frame); int type = (seq->type & SEQ_TYPE_EFFECT) ? SEQ_TYPE_EFFECT : seq->type; switch (type) { case SEQ_TYPE_META: { @@ -1826,7 +1828,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ImBuf *out = NULL; count = seq_get_shown_sequences( - channels, seqbasep, timeline_frame, chanshown, (Sequence **)&seq_arr); + context->scene, channels, seqbasep, timeline_frame, chanshown, (Sequence **)&seq_arr); if (count == 0) { return NULL; @@ -1940,7 +1942,7 @@ ImBuf *SEQ_render_give_ibuf(const SeqRenderData *context, float timeline_frame, Sequence *seq_arr[MAXSEQ + 1]; int count; - count = seq_get_shown_sequences(channels, seqbasep, timeline_frame, chanshown, seq_arr); + count = seq_get_shown_sequences(scene, channels, seqbasep, timeline_frame, chanshown, seq_arr); if (count) { out = seq_cache_get(context, seq_arr[count - 1], timeline_frame, SEQ_CACHE_STORE_FINAL_OUT); @@ -1992,14 +1994,17 @@ ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context, return ibuf; } -float SEQ_render_thumbnail_first_frame_get(Sequence *seq, float frame_step, rctf *view_area) +float SEQ_render_thumbnail_first_frame_get(const Scene *scene, + Sequence *seq, + float frame_step, + rctf *view_area) { int first_drawable_frame = max_iii( - SEQ_time_left_handle_frame_get(seq), seq->start, view_area->xmin); + SEQ_time_left_handle_frame_get(scene, seq), seq->start, view_area->xmin); /* First frame should correspond to handle position. */ - if (first_drawable_frame == SEQ_time_left_handle_frame_get(seq)) { - return SEQ_time_left_handle_frame_get(seq); + if (first_drawable_frame == SEQ_time_left_handle_frame_get(scene, seq)) { + return SEQ_time_left_handle_frame_get(scene, seq); } float aligned_frame_offset = (int)((first_drawable_frame - seq->start) / frame_step) * @@ -2007,12 +2012,15 @@ float SEQ_render_thumbnail_first_frame_get(Sequence *seq, float frame_step, rctf return seq->start + aligned_frame_offset; } -float SEQ_render_thumbnail_next_frame_get(Sequence *seq, float last_frame, float frame_step) +float SEQ_render_thumbnail_next_frame_get(const Scene *scene, + Sequence *seq, + float last_frame, + float frame_step) { float next_frame = last_frame + frame_step; /* If handle position was displayed, align next frame with `seq->start`. */ - if (last_frame == SEQ_time_left_handle_frame_get(seq)) { + if (last_frame == SEQ_time_left_handle_frame_get(scene, seq)) { next_frame = seq->start + ((int)((last_frame - seq->start) / frame_step) + 1) * frame_step; } @@ -2086,22 +2094,23 @@ void SEQ_render_thumbnails(const SeqRenderData *context, { SeqRenderState state; seq_render_state_init(&state); + const Scene *scene = context->scene; /* Adding the hold offset value (seq->anim_startofs) to the start frame. Position of image not * affected, but frame loaded affected. */ - float upper_thumb_bound = SEQ_time_has_right_still_frames(seq) ? + float upper_thumb_bound = SEQ_time_has_right_still_frames(scene, seq) ? (seq->start + seq->len) : - SEQ_time_right_handle_frame_get(seq); + SEQ_time_right_handle_frame_get(scene, seq); upper_thumb_bound = (upper_thumb_bound > view_area->xmax) ? view_area->xmax + frame_step : upper_thumb_bound; - float timeline_frame = SEQ_render_thumbnail_first_frame_get(seq, frame_step, view_area); + float timeline_frame = SEQ_render_thumbnail_first_frame_get(scene, seq, frame_step, view_area); while ((timeline_frame < upper_thumb_bound) & !*stop) { ImBuf *ibuf = seq_cache_get( context, seq_orig, round_fl_to_int(timeline_frame), SEQ_CACHE_STORE_THUMBNAIL); if (ibuf) { IMB_freeImBuf(ibuf); - timeline_frame = SEQ_render_thumbnail_next_frame_get(seq, timeline_frame, frame_step); + timeline_frame = SEQ_render_thumbnail_next_frame_get(scene, seq, timeline_frame, frame_step); continue; } @@ -2118,14 +2127,15 @@ void SEQ_render_thumbnails(const SeqRenderData *context, return; } - timeline_frame = SEQ_render_thumbnail_next_frame_get(seq, timeline_frame, frame_step); + timeline_frame = SEQ_render_thumbnail_next_frame_get(scene, seq, timeline_frame, frame_step); } } -int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const Sequence *seq) +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(seq), seq->start); - const int content_end = min_ii(SEQ_time_right_handle_frame_get(seq), seq->start + seq->len); + const int content_start = max_ii(SEQ_time_left_handle_frame_get(scene, seq), seq->start); + const int content_end = min_ii(SEQ_time_right_handle_frame_get(scene, seq), + seq->start + seq->len); const int content_len = content_end - content_start; /* Arbitrary, but due to performance reasons should be as low as possible. */ @@ -2144,11 +2154,12 @@ void SEQ_render_thumbnails_base_set(const SeqRenderData *context, { SeqRenderState state; seq_render_state_init(&state); + const Scene *scene = context->scene; - int timeline_frame = SEQ_time_left_handle_frame_get(seq); - const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(seq); + int timeline_frame = SEQ_time_left_handle_frame_get(scene, seq); + const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(scene, seq); - while (timeline_frame < SEQ_time_right_handle_frame_get(seq) && !*stop) { + while (timeline_frame < SEQ_time_right_handle_frame_get(scene, seq) && !*stop) { ImBuf *ibuf = seq_cache_get( context, seq_orig, roundf(timeline_frame), SEQ_CACHE_STORE_THUMBNAIL); if (ibuf) { diff --git a/source/blender/sequencer/intern/render.h b/source/blender/sequencer/intern/render.h index d41a0e3f86f..3690eb71ac4 100644 --- a/source/blender/sequencer/intern/render.h +++ b/source/blender/sequencer/intern/render.h @@ -44,7 +44,8 @@ struct ImBuf *seq_render_effect_execute_threaded(struct SeqEffectHandle *sh, struct ImBuf *ibuf2, struct ImBuf *ibuf3); void seq_imbuf_to_sequencer_space(struct Scene *scene, struct ImBuf *ibuf, bool make_float); -int seq_get_shown_sequences(struct ListBase *channels, +int seq_get_shown_sequences(const struct Scene *scene, + struct ListBase *channels, struct ListBase *seqbase, int timeline_frame, int chanshown, diff --git a/source/blender/sequencer/intern/sequencer.c b/source/blender/sequencer/intern/sequencer.c index 3f48e6dafdd..a184f727b9e 100644 --- a/source/blender/sequencer/intern/sequencer.c +++ b/source/blender/sequencer/intern/sequencer.c @@ -127,9 +127,10 @@ Sequence *SEQ_sequence_alloc(ListBase *lb, int timeline_frame, int machine, int seq->mul = 1.0; seq->blend_opacity = 100.0; seq->volume = 1.0f; - seq->pitch = 1.0f; seq->scene_sound = NULL; seq->type = type; + seq->media_playback_rate = 0.0f; + seq->speed_factor = 1.0f; if (seq->type == SEQ_TYPE_ADJUSTMENT) { seq->blend_mode = SEQ_TYPE_CROSS; @@ -411,8 +412,8 @@ static MetaStack *seq_meta_stack_alloc(const Scene *scene, Sequence *seq_meta) ms->oldbasep = higher_level_meta ? &higher_level_meta->seqbase : &ed->seqbase; ms->old_channels = higher_level_meta ? &higher_level_meta->channels : &ed->channels; - ms->disp_range[0] = SEQ_time_left_handle_frame_get(ms->parseq); - ms->disp_range[1] = SEQ_time_right_handle_frame_get(ms->parseq); + ms->disp_range[0] = SEQ_time_left_handle_frame_get(scene, ms->parseq); + ms->disp_range[1] = SEQ_time_right_handle_frame_get(scene, ms->parseq); return ms; } @@ -965,8 +966,9 @@ static bool seq_update_seq_cb(Sequence *seq, void *user_data) } BKE_sound_set_scene_sound_volume( seq->scene_sound, seq->volume, (seq->flag & SEQ_AUDIO_VOLUME_ANIMATED) != 0); - BKE_sound_set_scene_sound_pitch( - seq->scene_sound, seq->pitch, (seq->flag & SEQ_AUDIO_PITCH_ANIMATED) != 0); + BKE_sound_set_scene_sound_pitch(seq->scene_sound, + SEQ_sound_pitch_get(scene, seq), + (seq->flag & SEQ_AUDIO_PITCH_ANIMATED) != 0); BKE_sound_set_scene_sound_pan( seq->scene_sound, seq->pan, (seq->flag & SEQ_AUDIO_PAN_ANIMATED) != 0); } diff --git a/source/blender/sequencer/intern/sound.c b/source/blender/sequencer/intern/sound.c index 50c8b76a9a0..c4992848cb5 100644 --- a/source/blender/sequencer/intern/sound.c +++ b/source/blender/sequencer/intern/sound.c @@ -23,6 +23,7 @@ #include "SEQ_sound.h" #include "SEQ_time.h" +#include "sequencer.h" #include "strip_time.h" /* Unlike _update_sound_ funcs, these ones take info from audaspace to update sequence length! */ @@ -99,8 +100,8 @@ void SEQ_sound_update_bounds(Scene *scene, Sequence *seq) BKE_sound_move_scene_sound(scene, seq->scene_sound, - SEQ_time_left_handle_frame_get(seq), - SEQ_time_right_handle_frame_get(seq), + SEQ_time_left_handle_frame_get(scene, seq), + SEQ_time_right_handle_frame_get(scene, seq), startofs, 0.0); } @@ -133,3 +134,12 @@ void SEQ_sound_update(Scene *scene, bSound *sound) seq_update_sound_recursive(scene, &scene->ed->seqbase, sound); } } + +float SEQ_sound_pitch_get(const Scene *scene, const Sequence *seq) +{ + Sequence *meta_parent = seq_sequence_lookup_meta_by_seq(scene, seq); + if (meta_parent != NULL) { + return seq->speed_factor * SEQ_sound_pitch_get(scene, meta_parent); + } + return seq->speed_factor; +} diff --git a/source/blender/sequencer/intern/strip_add.c b/source/blender/sequencer/intern/strip_add.c index 4f0b2e38f56..753a6ee39e0 100644 --- a/source/blender/sequencer/intern/strip_add.c +++ b/source/blender/sequencer/intern/strip_add.c @@ -181,7 +181,7 @@ Sequence *SEQ_add_effect_strip(Scene *scene, ListBase *seqbase, struct SeqLoadDa seq_add_set_name(scene, seq, load_data); seq_add_generic_update(scene, seq); - seq_time_effect_range_set(seq); + seq_time_effect_range_set(scene, seq); return seq; } @@ -191,9 +191,10 @@ void SEQ_add_image_set_directory(Sequence *seq, char *path) BLI_strncpy(seq->strip->dir, path, sizeof(seq->strip->dir)); } -void SEQ_add_image_load_file(Sequence *seq, size_t strip_frame, char *filename) +void SEQ_add_image_load_file(Scene *scene, Sequence *seq, size_t strip_frame, char *filename) { - StripElem *se = SEQ_render_give_stripelem(seq, seq->start + strip_frame); + StripElem *se = SEQ_render_give_stripelem( + scene, seq, SEQ_time_start_frame_get(seq) + strip_frame); BLI_strncpy(se->name, filename, sizeof(se->name)); } @@ -468,9 +469,19 @@ Sequence *SEQ_add_movie_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL orig_height = IMB_anim_get_image_height(anim_arr[0]); SEQ_set_scale_to_fit( seq, orig_width, orig_height, scene->r.xsch, scene->r.ysch, load_data->fit_method); + + short frs_sec; + float frs_sec_base; + if (IMB_anim_get_fps(anim_arr[0], &frs_sec, &frs_sec_base, true)) { + seq->media_playback_rate = (float)frs_sec / frs_sec_base; + } } seq->len = MAX2(1, seq->len); + if (load_data->adjust_playback_rate) { + seq->flag |= SEQ_AUTO_PLAYBACK_RATE; + } + BLI_strncpy(seq->strip->colorspace_settings.name, colorspace, sizeof(seq->strip->colorspace_settings.name)); @@ -511,8 +522,8 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo if (lock_range) { /* keep so we don't have to move the actual start and end points (only the data) */ - prev_startdisp = SEQ_time_left_handle_frame_get(seq); - prev_enddisp = SEQ_time_right_handle_frame_get(seq); + prev_startdisp = SEQ_time_left_handle_frame_get(scene, seq); + prev_enddisp = SEQ_time_right_handle_frame_get(scene, seq); } switch (seq->type) { diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c index 4a88eab0fe2..deab43affee 100644 --- a/source/blender/sequencer/intern/strip_edit.c +++ b/source/blender/sequencer/intern/strip_edit.c @@ -37,11 +37,11 @@ #include "SEQ_transform.h" #include "SEQ_utils.h" -int SEQ_edit_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str) +int SEQ_edit_sequence_swap(Scene *scene, Sequence *seq_a, Sequence *seq_b, const char **error_str) { char name[sizeof(seq_a->name)]; - if (seq_a->len != seq_b->len) { + if (SEQ_time_strip_length_get(scene, seq_a) != SEQ_time_strip_length_get(scene, seq_b)) { *error_str = N_("Strips must be the same length"); return 0; } @@ -84,8 +84,8 @@ int SEQ_edit_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_ SWAP(int, seq_a->startofs, seq_b->startofs); SWAP(int, seq_a->endofs, seq_b->endofs); SWAP(int, seq_a->machine, seq_b->machine); - seq_time_effect_range_set(seq_a); - seq_time_effect_range_set(seq_b); + seq_time_effect_range_set(scene, seq_a); + seq_time_effect_range_set(scene, seq_b); return 1; } @@ -203,7 +203,7 @@ bool SEQ_edit_move_strip_to_seqbase(Scene *scene, SEQ_relations_invalidate_cache_preprocessed(scene, seq); /* Update meta. */ - if (SEQ_transform_test_overlap(dst_seqbase, seq)) { + if (SEQ_transform_test_overlap(scene, dst_seqbase, seq)) { SEQ_transform_seqbase_shuffle(dst_seqbase, seq, scene); } @@ -246,7 +246,7 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene, SeqCollection *collection = SEQ_collection_create(__func__); SEQ_collection_append_strip(src_seq, collection); - SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain); + SEQ_collection_expand(scene, seqbase, collection, SEQ_query_strip_effect_chain); Sequence *seq; SEQ_ITERATOR_FOREACH (seq, collection) { @@ -259,77 +259,58 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene, return true; } -static void seq_split_set_left_hold_offset(const Scene *scene, Sequence *seq, int timeline_frame) +static void seq_split_set_left_hold_offset(Scene *scene, Sequence *seq, int timeline_frame) { /* Adjust within range of extended stillframes before strip. */ if (timeline_frame < seq->start) { - SEQ_time_left_handle_frame_set(scene, seq, timeline_frame); - } - /* Adjust within range of strip contents. */ - else if ((timeline_frame >= seq->start) && (timeline_frame <= (seq->start + seq->len))) { - seq->anim_startofs += timeline_frame - seq->start; - seq->start = timeline_frame; - seq->startofs = 0; - } - /* Adjust within range of extended stillframes after strip. */ - else if ((seq->start + seq->len) < timeline_frame) { - const int right_handle_backup = SEQ_time_right_handle_frame_get(seq); - seq->start += timeline_frame - seq->start; - seq->anim_startofs += seq->len - 1; - seq->len = 1; - SEQ_time_left_handle_frame_set(scene, seq, timeline_frame); - SEQ_time_right_handle_frame_set(scene, seq, right_handle_backup); - } -} - -static void seq_split_set_right_hold_offset(const Scene *scene, Sequence *seq, int timeline_frame) -{ - /* Adjust within range of extended stillframes before strip. */ - if (timeline_frame < seq->start) { - const int left_handle_backup = SEQ_time_left_handle_frame_get(seq); seq->start = timeline_frame - 1; - SEQ_time_left_handle_frame_set(scene, seq, left_handle_backup); - SEQ_time_right_handle_frame_set(scene, seq, timeline_frame); + seq->anim_endofs += SEQ_time_strip_length_get(scene, seq) - 1; + seq->startstill = timeline_frame - seq->startdisp - 1; + seq->endstill = 0; } /* Adjust within range of strip contents. */ - else if ((timeline_frame >= seq->start) && (timeline_frame <= (seq->start + seq->len))) { - seq->anim_endofs += seq->start + seq->len - timeline_frame; + else if ((timeline_frame >= seq->start) && + (timeline_frame <= (seq->start + SEQ_time_strip_length_get(scene, seq)))) { seq->endofs = 0; + seq->endstill = 0; + seq->anim_endofs += (seq->start + SEQ_time_strip_length_get(scene, seq)) - timeline_frame; } /* Adjust within range of extended stillframes after strip. */ - else if ((seq->start + seq->len) < timeline_frame) { - SEQ_time_right_handle_frame_set(scene, seq, timeline_frame); + else if ((seq->start + SEQ_time_strip_length_get(scene, seq)) < timeline_frame) { + seq->endstill = timeline_frame - seq->start - SEQ_time_strip_length_get(scene, seq); } } -static void seq_split_set_right_offset(const Scene *scene, Sequence *seq, int timeline_frame) +static void seq_split_set_right_hold_offset(Scene *scene, Sequence *seq, int timeline_frame) { /* Adjust within range of extended stillframes before strip. */ if (timeline_frame < seq->start) { - const int content_offset = seq->start - timeline_frame + 1; - seq->start = timeline_frame - 1; - seq->startofs += content_offset; + seq->startstill = seq->start - timeline_frame; + } + /* Adjust within range of strip contents. */ + else if ((timeline_frame >= seq->start) && + (timeline_frame <= (seq->start + SEQ_time_strip_length_get(scene, seq)))) { + seq->anim_startofs += timeline_frame - seq->start; + seq->start = timeline_frame; + seq->startstill = 0; + seq->startofs = 0; } - - SEQ_time_right_handle_frame_set(scene, seq, timeline_frame); -} - -static void seq_split_set_left_offset(const Scene *scene, Sequence *seq, int timeline_frame) -{ /* Adjust within range of extended stillframes after strip. */ - if (timeline_frame > seq->start + seq->len) { - const int content_offset = timeline_frame - (seq->start + seq->len) + 1; - seq->start += content_offset; - seq->endofs += content_offset; + else if ((seq->start + SEQ_time_strip_length_get(scene, seq)) < timeline_frame) { + seq->start = timeline_frame; + seq->startofs = 0; + seq->anim_startofs += SEQ_time_strip_length_get(scene, seq) - 1; + seq->endstill = seq->enddisp - timeline_frame - 1; + seq->startstill = 0; } - - SEQ_time_left_handle_frame_set(scene, seq, timeline_frame); } -static bool seq_edit_split_effect_intersect_check(const Sequence *seq, const int timeline_frame) +static bool seq_edit_split_effect_intersect_check(const Scene *scene, + const Sequence *seq, + const int timeline_frame) { - return timeline_frame > SEQ_time_left_handle_frame_get(seq) && - timeline_frame < SEQ_time_right_handle_frame_get(seq); + return timeline_frame > SEQ_time_left_handle_frame_get(scene, seq) && + timeline_frame < SEQ_time_right_handle_frame_get(scene, seq); } static void seq_edit_split_handle_strip_offsets(Main *bmain, @@ -339,10 +320,10 @@ static void seq_edit_split_handle_strip_offsets(Main *bmain, const int timeline_frame, const eSeqSplitMethod method) { - if (seq_edit_split_effect_intersect_check(right_seq, timeline_frame)) { + if (seq_edit_split_effect_intersect_check(scene, right_seq, timeline_frame)) { switch (method) { case SEQ_SPLIT_SOFT: - seq_split_set_left_offset(scene, right_seq, timeline_frame); + 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); @@ -351,10 +332,10 @@ static void seq_edit_split_handle_strip_offsets(Main *bmain, } } - if (seq_edit_split_effect_intersect_check(left_seq, timeline_frame)) { + if (seq_edit_split_effect_intersect_check(scene, left_seq, timeline_frame)) { switch (method) { case SEQ_SPLIT_SOFT: - seq_split_set_right_offset(scene, left_seq, timeline_frame); + 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); @@ -364,31 +345,40 @@ static void seq_edit_split_handle_strip_offsets(Main *bmain, } } -static bool seq_edit_split_effect_inputs_intersect(const Sequence *seq, const int timeline_frame) +static bool seq_edit_split_effect_inputs_intersect(const Scene *scene, + const Sequence *seq, + const int timeline_frame) { bool input_does_intersect = false; if (seq->seq1) { - input_does_intersect |= seq_edit_split_effect_intersect_check(seq->seq1, timeline_frame); + input_does_intersect |= seq_edit_split_effect_intersect_check( + scene, seq->seq1, timeline_frame); if ((seq->seq1->type & SEQ_TYPE_EFFECT) != 0) { - input_does_intersect |= seq_edit_split_effect_inputs_intersect(seq->seq1, timeline_frame); + input_does_intersect |= seq_edit_split_effect_inputs_intersect( + scene, seq->seq1, timeline_frame); } } if (seq->seq2) { - input_does_intersect |= seq_edit_split_effect_intersect_check(seq->seq2, timeline_frame); + input_does_intersect |= seq_edit_split_effect_intersect_check( + scene, seq->seq2, timeline_frame); if ((seq->seq1->type & SEQ_TYPE_EFFECT) != 0) { - input_does_intersect |= seq_edit_split_effect_inputs_intersect(seq->seq2, timeline_frame); + input_does_intersect |= seq_edit_split_effect_inputs_intersect( + scene, seq->seq2, timeline_frame); } } if (seq->seq3) { - input_does_intersect |= seq_edit_split_effect_intersect_check(seq->seq3, timeline_frame); + input_does_intersect |= seq_edit_split_effect_intersect_check( + scene, seq->seq3, timeline_frame); if ((seq->seq1->type & SEQ_TYPE_EFFECT) != 0) { - input_does_intersect |= seq_edit_split_effect_inputs_intersect(seq->seq3, timeline_frame); + input_does_intersect |= seq_edit_split_effect_inputs_intersect( + scene, seq->seq3, timeline_frame); } } return input_does_intersect; } -static bool seq_edit_split_operation_permitted_check(SeqCollection *strips, +static bool seq_edit_split_operation_permitted_check(const Scene *scene, + SeqCollection *strips, const int timeline_frame, const char **r_error) { @@ -397,7 +387,7 @@ static bool seq_edit_split_operation_permitted_check(SeqCollection *strips, if ((seq->type & SEQ_TYPE_EFFECT) == 0) { continue; } - if (!seq_edit_split_effect_intersect_check(seq, timeline_frame)) { + if (!seq_edit_split_effect_intersect_check(scene, seq, timeline_frame)) { continue; } if (SEQ_effect_get_num_inputs(seq->type) <= 1) { @@ -407,7 +397,7 @@ static bool seq_edit_split_operation_permitted_check(SeqCollection *strips, *r_error = "Splitting transition effect is not permitted."; return false; } - if (!seq_edit_split_effect_inputs_intersect(seq, timeline_frame)) { + if (!seq_edit_split_effect_inputs_intersect(scene, seq, timeline_frame)) { *r_error = "Effect inputs don't overlap. Can not split such effect."; return false; } @@ -423,16 +413,16 @@ Sequence *SEQ_edit_strip_split(Main *bmain, const eSeqSplitMethod method, const char **r_error) { - if (!seq_edit_split_effect_intersect_check(seq, timeline_frame)) { + if (!seq_edit_split_effect_intersect_check(scene, seq, timeline_frame)) { return NULL; } /* Whole strip chain must be duplicated in order to preserve relationships. */ SeqCollection *collection = SEQ_collection_create(__func__); SEQ_collection_append_strip(seq, collection); - SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain); + SEQ_collection_expand(scene, seqbase, collection, SEQ_query_strip_effect_chain); - if (!seq_edit_split_operation_permitted_check(collection, timeline_frame, r_error)) { + if (!seq_edit_split_operation_permitted_check(scene, collection, timeline_frame, r_error)) { SEQ_collection_free(collection); return NULL; } @@ -474,10 +464,10 @@ Sequence *SEQ_edit_strip_split(Main *bmain, /* Split strips. */ while (left_seq && right_seq) { - if (SEQ_time_left_handle_frame_get(left_seq) >= timeline_frame) { + if (SEQ_time_left_handle_frame_get(scene, left_seq) >= timeline_frame) { SEQ_edit_flag_for_removal(scene, seqbase, left_seq); } - else if (SEQ_time_right_handle_frame_get(right_seq) <= timeline_frame) { + else if (SEQ_time_right_handle_frame_get(scene, right_seq) <= timeline_frame) { SEQ_edit_flag_for_removal(scene, seqbase, right_seq); } else if (return_seq == NULL) { diff --git a/source/blender/sequencer/intern/strip_relations.c b/source/blender/sequencer/intern/strip_relations.c index a123212cb6e..1132c4dd69d 100644 --- a/source/blender/sequencer/intern/strip_relations.c +++ b/source/blender/sequencer/intern/strip_relations.c @@ -29,6 +29,7 @@ #include "SEQ_relations.h" #include "SEQ_sequencer.h" #include "SEQ_time.h" +#include "SEQ_transform.h" #include "effects.h" #include "image_cache.h" @@ -40,15 +41,15 @@ bool SEQ_relation_is_effect_of_strip(const Sequence *effect, const Sequence *inp } /* check whether sequence cur depends on seq */ -static bool seq_relations_check_depend(Sequence *seq, Sequence *cur) +static bool seq_relations_check_depend(const Scene *scene, Sequence *seq, Sequence *cur) { if (SEQ_relation_is_effect_of_strip(cur, seq)) { return true; } /* sequences are not intersecting in time, assume no dependency exists between them */ - if (SEQ_time_right_handle_frame_get(cur) < SEQ_time_left_handle_frame_get(seq) || - SEQ_time_left_handle_frame_get(cur) > SEQ_time_right_handle_frame_get(seq)) { + if (SEQ_time_right_handle_frame_get(scene, cur) < SEQ_time_left_handle_frame_get(scene, seq) || + SEQ_time_left_handle_frame_get(scene, cur) > SEQ_time_right_handle_frame_get(scene, seq)) { return false; } @@ -78,7 +79,7 @@ static void sequence_do_invalidate_dependent(Scene *scene, Sequence *seq, ListBa continue; } - if (seq_relations_check_depend(seq, cur)) { + if (seq_relations_check_depend(scene, seq, cur)) { /* Effect must be invalidated completely if they depend on invalidated seq. */ if ((cur->type & SEQ_TYPE_EFFECT) != 0) { seq_cache_cleanup_sequence(scene, cur, seq, SEQ_CACHE_ALL_TYPES, false); @@ -249,7 +250,7 @@ void SEQ_relations_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render) SEQ_prefetch_stop(scene); for (seq = seqbase->first; seq; seq = seq->next) { - if (for_render && SEQ_time_strip_intersects_frame(seq, CFRA)) { + if (for_render && SEQ_time_strip_intersects_frame(scene, seq, CFRA)) { continue; } @@ -271,13 +272,14 @@ void SEQ_relations_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render) } } -static void sequencer_all_free_anim_ibufs(Editing *ed, +static void sequencer_all_free_anim_ibufs(const Scene *scene, ListBase *seqbase, int timeline_frame, const int frame_range[2]) { + Editing *ed = SEQ_editing_get(scene); for (Sequence *seq = seqbase->first; seq != NULL; seq = seq->next) { - if (!SEQ_time_strip_intersects_frame(seq, timeline_frame) || + if (!SEQ_time_strip_intersects_frame(scene, seq, timeline_frame) || !((frame_range[0] <= timeline_frame) && (frame_range[1] > timeline_frame))) { SEQ_relations_sequence_free_anim(seq); } @@ -291,11 +293,11 @@ static void sequencer_all_free_anim_ibufs(Editing *ed, } else { /* Limit frame range to meta strip. */ - meta_range[0] = max_ii(frame_range[0], SEQ_time_left_handle_frame_get(seq)); - meta_range[1] = min_ii(frame_range[1], SEQ_time_right_handle_frame_get(seq)); + meta_range[0] = max_ii(frame_range[0], SEQ_time_left_handle_frame_get(scene, seq)); + meta_range[1] = min_ii(frame_range[1], SEQ_time_right_handle_frame_get(scene, seq)); } - sequencer_all_free_anim_ibufs(ed, &seq->seqbase, timeline_frame, meta_range); + sequencer_all_free_anim_ibufs(scene, &seq->seqbase, timeline_frame, meta_range); } } } @@ -308,7 +310,7 @@ void SEQ_relations_free_all_anim_ibufs(Scene *scene, int timeline_frame) } const int frame_range[2] = {-MAXFRAME, MAXFRAME}; - sequencer_all_free_anim_ibufs(ed, &ed->seqbase, timeline_frame, frame_range); + sequencer_all_free_anim_ibufs(scene, &ed->seqbase, timeline_frame, frame_range); } static Sequence *sequencer_check_scene_recursion(Scene *scene, ListBase *seqbase) @@ -346,7 +348,7 @@ bool SEQ_relations_check_scene_recursion(Scene *scene, ReportList *reports) RPT_WARNING, "Recursion detected in video sequencer. Strip %s at frame %d will not be rendered", recursive_seq->name + 2, - SEQ_time_left_handle_frame_get(recursive_seq)); + SEQ_time_left_handle_frame_get(scene, recursive_seq)); LISTBASE_FOREACH (Sequence *, seq, &ed->seqbase) { if (seq->type != SEQ_TYPE_SCENE && sequencer_seq_generates_image(seq)) { diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c index 4d6efb1639b..d4357fe28b6 100644 --- a/source/blender/sequencer/intern/strip_time.c +++ b/source/blender/sequencer/intern/strip_time.c @@ -31,14 +31,32 @@ #include "strip_time.h" #include "utils.h" -float seq_give_frame_index(Sequence *seq, float timeline_frame) +static 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; + } + if (seq->media_playback_rate == 0.0f) { + return 1.0f; + } + + float scene_playback_rate = (float)scene->r.frs_sec / scene->r.frs_sec_base; + return seq->media_playback_rate / scene_playback_rate; +} + +static 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; +} + +float seq_give_frame_index(const Scene *scene, Sequence *seq, float timeline_frame) { float frame_index; - int sta = seq->start; - int end = seq->start + seq->len - 1; + float sta = SEQ_time_start_frame_get(seq); + float end = SEQ_time_start_frame_get(seq) + SEQ_time_strip_length_get(scene, seq) - 1; if (seq->type & SEQ_TYPE_EFFECT) { - end = SEQ_time_right_handle_frame_get(seq); + end = SEQ_time_right_handle_frame_get(scene, seq); } if (end < sta) { @@ -46,29 +64,16 @@ float seq_give_frame_index(Sequence *seq, float timeline_frame) } if (seq->flag & SEQ_REVERSE_FRAMES) { - /* Reverse frame in this sequence. */ - if (timeline_frame <= sta) { - frame_index = end - sta; - } - else if (timeline_frame >= end) { - frame_index = 0; - } - else { - frame_index = end - timeline_frame; - } + frame_index = end - timeline_frame; } else { - if (timeline_frame <= sta) { - frame_index = 0; - } - else if (timeline_frame >= end) { - frame_index = end - sta; - } - else { - frame_index = timeline_frame - sta; - } + frame_index = timeline_frame - sta; } + /* Clamp frame index to strip frame range. */ + frame_index = clamp_f(frame_index, 0, end - sta); + frame_index *= seq_time_playback_rate_factor_get(scene, seq); + if (seq->strobe < 1.0f) { seq->strobe = 1.0f; } @@ -149,14 +154,14 @@ void SEQ_time_update_meta_strip_range(const Scene *scene, Sequence *seq_meta) return; } - const int strip_start = SEQ_time_left_handle_frame_get(seq_meta); - const int strip_end = SEQ_time_right_handle_frame_get(seq_meta); + const int strip_start = SEQ_time_left_handle_frame_get(scene, seq_meta); + const int strip_end = SEQ_time_right_handle_frame_get(scene, seq_meta); int min = MAXFRAME * 2; int max = -MAXFRAME * 2; LISTBASE_FOREACH (Sequence *, seq, &seq_meta->seqbase) { - min = min_ii(SEQ_time_left_handle_frame_get(seq), min); - max = max_ii(SEQ_time_right_handle_frame_get(seq), max); + min = min_ii(SEQ_time_left_handle_frame_get(scene, seq), min); + max = max_ii(SEQ_time_right_handle_frame_get(scene, seq), max); } seq_meta->start = min + seq_meta->anim_startofs; @@ -171,25 +176,25 @@ void SEQ_time_update_meta_strip_range(const Scene *scene, Sequence *seq_meta) SEQ_time_right_handle_frame_set(scene, seq_meta, strip_end); } -void seq_time_effect_range_set(Sequence *seq) +void seq_time_effect_range_set(const Scene *scene, Sequence *seq) { if (seq->seq1 == NULL && seq->seq2 == NULL) { return; } if (seq->seq1 && seq->seq2) { /* 2 - input effect. */ - seq->startdisp = max_ii(SEQ_time_left_handle_frame_get(seq->seq1), - SEQ_time_left_handle_frame_get(seq->seq2)); - seq->enddisp = min_ii(SEQ_time_right_handle_frame_get(seq->seq1), - SEQ_time_right_handle_frame_get(seq->seq2)); + seq->startdisp = max_ii(SEQ_time_left_handle_frame_get(scene, seq->seq1), + SEQ_time_left_handle_frame_get(scene, seq->seq2)); + seq->enddisp = min_ii(SEQ_time_right_handle_frame_get(scene, seq->seq1), + SEQ_time_right_handle_frame_get(scene, seq->seq2)); } else if (seq->seq1) { /* Single input effect. */ - seq->startdisp = SEQ_time_right_handle_frame_get(seq->seq1); - seq->enddisp = SEQ_time_left_handle_frame_get(seq->seq1); + seq->startdisp = SEQ_time_right_handle_frame_get(scene, seq->seq1); + seq->enddisp = SEQ_time_left_handle_frame_get(scene, seq->seq1); } else if (seq->seq2) { /* Strip may be missing one of inputs. */ - seq->startdisp = SEQ_time_right_handle_frame_get(seq->seq2); - seq->enddisp = SEQ_time_left_handle_frame_get(seq->seq2); + seq->startdisp = SEQ_time_right_handle_frame_get(scene, seq->seq2); + seq->enddisp = SEQ_time_left_handle_frame_get(scene, seq->seq2); } if (seq->startdisp > seq->enddisp) { @@ -210,7 +215,7 @@ void seq_time_update_effects_strip_range(const Scene *scene, SeqCollection *effe Sequence *seq; /* First pass: Update length of immediate effects. */ SEQ_ITERATOR_FOREACH (seq, effects) { - seq_time_effect_range_set(seq); + seq_time_effect_range_set(scene, seq); } /* Second pass: Recursive call to update effects in chain and in order, so they inherit length @@ -255,14 +260,14 @@ int SEQ_time_find_next_prev_edit(Scene *scene, } if (do_center) { - seq_frames[0] = (SEQ_time_left_handle_frame_get(seq) + - SEQ_time_right_handle_frame_get(seq)) / + seq_frames[0] = (SEQ_time_left_handle_frame_get(scene, seq) + + SEQ_time_right_handle_frame_get(scene, seq)) / 2; seq_frames_tot = 1; } else { - seq_frames[0] = SEQ_time_left_handle_frame_get(seq); - seq_frames[1] = SEQ_time_right_handle_frame_get(seq); + seq_frames[0] = SEQ_time_left_handle_frame_get(scene, seq); + seq_frames[1] = SEQ_time_right_handle_frame_get(scene, seq); seq_frames_tot = 2; } @@ -339,18 +344,18 @@ void SEQ_timeline_init_boundbox(const Scene *scene, rctf *rect) rect->ymax = 8.0f; } -void SEQ_timeline_expand_boundbox(const ListBase *seqbase, rctf *rect) +void SEQ_timeline_expand_boundbox(const Scene *scene, const ListBase *seqbase, rctf *rect) { if (seqbase == NULL) { return; } LISTBASE_FOREACH (Sequence *, seq, seqbase) { - if (rect->xmin > SEQ_time_left_handle_frame_get(seq) - 1) { - rect->xmin = SEQ_time_left_handle_frame_get(seq) - 1; + if (rect->xmin > SEQ_time_left_handle_frame_get(scene, seq) - 1) { + rect->xmin = SEQ_time_left_handle_frame_get(scene, seq) - 1; } - if (rect->xmax < SEQ_time_right_handle_frame_get(seq) + 1) { - rect->xmax = SEQ_time_right_handle_frame_get(seq) + 1; + if (rect->xmax < SEQ_time_right_handle_frame_get(scene, seq) + 1) { + rect->xmax = SEQ_time_right_handle_frame_get(scene, seq) + 1; } if (rect->ymax < seq->machine) { rect->ymax = seq->machine; @@ -361,14 +366,16 @@ void SEQ_timeline_expand_boundbox(const ListBase *seqbase, rctf *rect) void SEQ_timeline_boundbox(const Scene *scene, const ListBase *seqbase, rctf *rect) { SEQ_timeline_init_boundbox(scene, rect); - SEQ_timeline_expand_boundbox(seqbase, rect); + SEQ_timeline_expand_boundbox(scene, seqbase, rect); } -static bool strip_exists_at_frame(SeqCollection *all_strips, const int timeline_frame) +static bool strip_exists_at_frame(const Scene *scene, + SeqCollection *all_strips, + const int timeline_frame) { Sequence *seq; SEQ_ITERATOR_FOREACH (seq, all_strips) { - if (SEQ_time_strip_intersects_frame(seq, timeline_frame)) { + if (SEQ_time_strip_intersects_frame(scene, seq, timeline_frame)) { return true; } } @@ -390,10 +397,10 @@ void seq_time_gap_info_get(const Scene *scene, SeqCollection *collection = SEQ_query_all_strips(seqbase); - if (!strip_exists_at_frame(collection, initial_frame)) { + if (!strip_exists_at_frame(scene, collection, initial_frame)) { /* Search backward for gap_start_frame. */ for (; timeline_frame >= sfra; timeline_frame--) { - if (strip_exists_at_frame(collection, timeline_frame)) { + if (strip_exists_at_frame(scene, collection, timeline_frame)) { break; } } @@ -403,7 +410,7 @@ void seq_time_gap_info_get(const Scene *scene, else { /* Search forward for gap_start_frame. */ for (; timeline_frame <= efra; timeline_frame++) { - if (!strip_exists_at_frame(collection, timeline_frame)) { + if (!strip_exists_at_frame(scene, collection, timeline_frame)) { r_gap_info->gap_start_frame = timeline_frame; break; } @@ -411,7 +418,7 @@ void seq_time_gap_info_get(const Scene *scene, } /* Search forward for gap_end_frame. */ for (; timeline_frame <= efra; timeline_frame++) { - if (strip_exists_at_frame(collection, timeline_frame)) { + if (strip_exists_at_frame(scene, collection, timeline_frame)) { const int gap_end_frame = timeline_frame; r_gap_info->gap_length = gap_end_frame - r_gap_info->gap_start_frame; r_gap_info->gap_exists = true; @@ -420,28 +427,67 @@ void seq_time_gap_info_get(const Scene *scene, } } -bool SEQ_time_strip_intersects_frame(const Sequence *seq, const int timeline_frame) +bool SEQ_time_strip_intersects_frame(const Scene *scene, + const Sequence *seq, + const int timeline_frame) +{ + return (SEQ_time_left_handle_frame_get(scene, seq) <= timeline_frame) && + (SEQ_time_right_handle_frame_get(scene, seq) > timeline_frame); +} + +void SEQ_time_speed_factor_set(const Scene *scene, Sequence *seq, const float speed_factor) +{ + const float left_handle_frame = SEQ_time_left_handle_frame_get(scene, seq); + const float unity_start_offset = seq->startofs * seq->speed_factor; + const float unity_end_offset = seq->endofs * seq->speed_factor; + + /* Left handle is pivot point for content scaling - it must always show same frame. */ + seq->speed_factor = speed_factor; + seq->startofs = unity_start_offset / speed_factor; + seq->start = left_handle_frame - seq->startofs; + seq->endofs = unity_end_offset / speed_factor; + + 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)); +} + +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); +} + +bool SEQ_time_has_right_still_frames(const Scene *scene, const Sequence *seq) +{ + return SEQ_time_right_handle_frame_get(scene, seq) > + SEQ_time_start_frame_get(seq) + SEQ_time_strip_length_get(scene, seq); +} + +bool SEQ_time_has_still_frames(const Scene *scene, const Sequence *seq) { - return (SEQ_time_left_handle_frame_get(seq) <= timeline_frame) && - (SEQ_time_right_handle_frame_get(seq) > timeline_frame); + return SEQ_time_has_right_still_frames(scene, seq) || SEQ_time_has_left_still_frames(scene, seq); } -bool SEQ_time_has_left_still_frames(const Sequence *seq) +/* Length of strip content in frames. This is number of original frames adjusted by playback rate + * factor */ +int SEQ_time_strip_length_get(const Scene *scene, const Sequence *seq) { - return seq->startofs < 0; + return seq->len / seq_time_playback_rate_factor_get(scene, seq); } -bool SEQ_time_has_right_still_frames(const Sequence *seq) +/* Return timeline frame, where strip content starts. */ +float SEQ_time_start_frame_get(const Sequence *seq) { - return seq->endofs < 0; + return seq->start; } -bool SEQ_time_has_still_frames(const Sequence *seq) +void SEQ_time_start_frame_set(const Scene *scene, Sequence *seq, int timeline_frame) { - return SEQ_time_has_right_still_frames(seq) || SEQ_time_has_left_still_frames(seq); + seq->start = 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)); } -int SEQ_time_left_handle_frame_get(const Sequence *seq) +int SEQ_time_left_handle_frame_get(const Scene *UNUSED(scene), const Sequence *seq) { if (seq->seq1 || seq->seq2) { return seq->startdisp; @@ -450,27 +496,42 @@ int SEQ_time_left_handle_frame_get(const Sequence *seq) return seq->start + seq->startofs; } -int SEQ_time_right_handle_frame_get(const Sequence *seq) +int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq) { if (seq->seq1 || seq->seq2) { return seq->enddisp; } - return seq->start + seq->len - seq->endofs; + return seq->start + SEQ_time_strip_length_get(scene, seq) - seq->endofs; } void SEQ_time_left_handle_frame_set(const Scene *scene, Sequence *seq, int val) { + const float right_handle_orig_frame = SEQ_time_right_handle_frame_get(scene, seq); + + if (val >= right_handle_orig_frame) { + val = right_handle_orig_frame - 1; + } + seq->startofs = val - seq->start; seq->startdisp = val; /* Only to make files usable in older versions. */ + SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq)); seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq)); } void SEQ_time_right_handle_frame_set(const Scene *scene, Sequence *seq, int val) { - seq->endofs = seq->start + seq->len - val; + const float strip_content_end_frame = seq->start + SEQ_time_strip_length_get(scene, seq); + const float left_handle_orig_frame = SEQ_time_left_handle_frame_get(scene, seq); + + if (val <= left_handle_orig_frame) { + val = left_handle_orig_frame + 1; + } + + seq->endofs = strip_content_end_frame - val; seq->enddisp = val; /* Only to make files usable in older versions. */ + SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq)); seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq)); } diff --git a/source/blender/sequencer/intern/strip_time.h b/source/blender/sequencer/intern/strip_time.h index 7a75aeac1a6..db581649f8a 100644 --- a/source/blender/sequencer/intern/strip_time.h +++ b/source/blender/sequencer/intern/strip_time.h @@ -16,7 +16,7 @@ struct Scene; struct Sequence; struct SeqCollection; -float seq_give_frame_index(struct Sequence *seq, float timeline_frame); +float seq_give_frame_index(const struct Scene *scene, struct Sequence *seq, float timeline_frame); void seq_update_sound_bounds_recursive(const struct Scene *scene, struct Sequence *metaseq); /* Describes gap between strips in timeline. */ @@ -38,7 +38,7 @@ void seq_time_gap_info_get(const struct Scene *scene, struct ListBase *seqbase, int initial_frame, struct GapInfo *r_gap_info); -void seq_time_effect_range_set(Sequence *seq); +void seq_time_effect_range_set(const struct Scene *scene, Sequence *seq); void seq_time_update_effects_strip_range(const struct Scene *scene, struct SeqCollection *effects); #ifdef __cplusplus diff --git a/source/blender/sequencer/intern/strip_transform.c b/source/blender/sequencer/intern/strip_transform.c index 19caf12ff2a..68b30c9ce19 100644 --- a/source/blender/sequencer/intern/strip_transform.c +++ b/source/blender/sequencer/intern/strip_transform.c @@ -34,15 +34,6 @@ static CLG_LogRef LOG = {"seq.strip_transform"}; -static int seq_tx_get_start(Sequence *seq) -{ - return seq->start; -} -static int seq_tx_get_end(Sequence *seq) -{ - return seq->start + seq->len; -} - bool SEQ_transform_single_image_check(Sequence *seq) { return ((seq->len == 1) && @@ -91,49 +82,6 @@ bool SEQ_transform_seqbase_isolated_sel_check(ListBase *seqbase) return true; } -void SEQ_transform_handle_xlimits(const Scene *scene, Sequence *seq, int leftflag, int rightflag) -{ - if (leftflag) { - if (SEQ_time_left_handle_frame_get(seq) >= SEQ_time_right_handle_frame_get(seq)) { - SEQ_time_left_handle_frame_set(scene, seq, SEQ_time_right_handle_frame_get(seq) - 1); - } - - if (SEQ_transform_single_image_check(seq) == 0) { - if (SEQ_time_left_handle_frame_get(seq) >= seq_tx_get_end(seq)) { - SEQ_time_left_handle_frame_set(scene, seq, seq_tx_get_end(seq) - 1); - } - - /* TODO: This doesn't work at the moment. */ -#if 0 - if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq, 0)) { - int ofs; - ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq, 0); - seq->start -= ofs; - seq_tx_set_final_left(seq, seq_tx_get_final_left(seq, 0) + ofs); - } -#endif - } - } - - if (rightflag) { - if (SEQ_time_right_handle_frame_get(seq) <= SEQ_time_left_handle_frame_get(seq)) { - SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(seq) + 1); - } - - if (SEQ_transform_single_image_check(seq) == 0) { - if (SEQ_time_right_handle_frame_get(seq) <= seq_tx_get_start(seq)) { - SEQ_time_right_handle_frame_set(scene, seq, seq_tx_get_start(seq) + 1); - } - } - } - - /* sounds cannot be extended past their endpoints */ - if (seq->type == SEQ_TYPE_SOUND_RAM) { - CLAMP(seq->startofs, 0, MAXFRAME); - CLAMP(seq->endofs, 0, MAXFRAME); - } -} - void SEQ_transform_fix_single_image_seq_offsets(const Scene *scene, Sequence *seq) { int left, start, offset; @@ -143,12 +91,14 @@ void SEQ_transform_fix_single_image_seq_offsets(const Scene *scene, Sequence *se /* make sure the image is always at the start since there is only one, * adjusting its start should be ok */ - left = SEQ_time_left_handle_frame_get(seq); + left = SEQ_time_left_handle_frame_get(scene, seq); start = seq->start; if (start != left) { offset = left - start; - SEQ_time_left_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(seq) - offset); - SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_right_handle_frame_get(seq) - offset); + SEQ_time_left_handle_frame_set( + scene, seq, SEQ_time_left_handle_frame_get(scene, seq) - offset); + SEQ_time_right_handle_frame_set( + scene, seq, SEQ_time_right_handle_frame_get(scene, seq) - offset); seq->start += offset; } } @@ -158,20 +108,22 @@ bool SEQ_transform_sequence_can_be_translated(Sequence *seq) return !(seq->type & SEQ_TYPE_EFFECT) || (SEQ_effect_get_num_inputs(seq->type) == 0); } -bool SEQ_transform_test_overlap_seq_seq(Sequence *seq1, Sequence *seq2) +bool SEQ_transform_test_overlap_seq_seq(const Scene *scene, Sequence *seq1, Sequence *seq2) { return (seq1 != seq2 && seq1->machine == seq2->machine && - ((SEQ_time_right_handle_frame_get(seq1) <= SEQ_time_left_handle_frame_get(seq2)) || - (SEQ_time_left_handle_frame_get(seq1) >= SEQ_time_right_handle_frame_get(seq2))) == 0); + ((SEQ_time_right_handle_frame_get(scene, seq1) <= + SEQ_time_left_handle_frame_get(scene, seq2)) || + (SEQ_time_left_handle_frame_get(scene, seq1) >= + SEQ_time_right_handle_frame_get(scene, seq2))) == 0); } -bool SEQ_transform_test_overlap(ListBase *seqbasep, Sequence *test) +bool SEQ_transform_test_overlap(const Scene *scene, ListBase *seqbasep, Sequence *test) { Sequence *seq; seq = seqbasep->first; while (seq) { - if (SEQ_transform_test_overlap_seq_seq(test, seq)) { + if (SEQ_transform_test_overlap_seq_seq(scene, test, seq)) { return true; } @@ -194,14 +146,16 @@ void SEQ_transform_translate_sequence(Scene *evil_scene, Sequence *seq, int delt SEQ_transform_translate_sequence(evil_scene, seq_child, delta); } /* Move meta start/end points. */ - SEQ_time_left_handle_frame_set(evil_scene, seq, SEQ_time_left_handle_frame_get(seq) + delta); - SEQ_time_right_handle_frame_set(evil_scene, seq, SEQ_time_right_handle_frame_get(seq) + delta); + SEQ_time_left_handle_frame_set( + evil_scene, seq, SEQ_time_left_handle_frame_get(evil_scene, seq) + delta); + SEQ_time_right_handle_frame_set( + evil_scene, seq, SEQ_time_right_handle_frame_get(evil_scene, seq) + delta); } else { /* All other strip types. */ seq->start += delta; /* Only to make files usable in older versions. */ - seq->startdisp = SEQ_time_left_handle_frame_get(seq); - seq->enddisp = SEQ_time_right_handle_frame_get(seq); + seq->startdisp = SEQ_time_left_handle_frame_get(evil_scene, seq); + seq->enddisp = SEQ_time_right_handle_frame_get(evil_scene, seq); } SEQ_offset_animdata(evil_scene, seq, delta); @@ -219,7 +173,7 @@ bool SEQ_transform_seqbase_shuffle_ex(ListBase *seqbasep, BLI_assert(ELEM(channel_delta, -1, 1)); test->machine += channel_delta; - while (SEQ_transform_test_overlap(seqbasep, test)) { + while (SEQ_transform_test_overlap(evil_scene, seqbasep, test)) { if ((channel_delta > 0) ? (test->machine >= MAXSEQ) : (test->machine < 1)) { break; } @@ -232,17 +186,17 @@ bool SEQ_transform_seqbase_shuffle_ex(ListBase *seqbasep, * nicer to move it to the end */ Sequence *seq; - int new_frame = SEQ_time_right_handle_frame_get(test); + int new_frame = SEQ_time_right_handle_frame_get(evil_scene, test); for (seq = seqbasep->first; seq; seq = seq->next) { if (seq->machine == orig_machine) { - new_frame = max_ii(new_frame, SEQ_time_right_handle_frame_get(seq)); + new_frame = max_ii(new_frame, SEQ_time_right_handle_frame_get(evil_scene, seq)); } } test->machine = orig_machine; - new_frame = new_frame + - (test->start - SEQ_time_left_handle_frame_get(test)); /* adjust by the startdisp */ + new_frame = new_frame + (test->start - SEQ_time_left_handle_frame_get( + evil_scene, test)); /* adjust by the startdisp */ SEQ_transform_translate_sequence(evil_scene, test, new_frame - test->start); return false; } @@ -255,16 +209,20 @@ bool SEQ_transform_seqbase_shuffle(ListBase *seqbasep, Sequence *test, Scene *ev return SEQ_transform_seqbase_shuffle_ex(seqbasep, test, evil_scene, 1); } -static bool shuffle_seq_test_overlap(const Sequence *seq1, const Sequence *seq2, const int offset) +static bool shuffle_seq_test_overlap(const Scene *scene, + const Sequence *seq1, + const Sequence *seq2, + const int offset) { - return ( - seq1 != seq2 && seq1->machine == seq2->machine && - ((SEQ_time_right_handle_frame_get(seq1) + offset <= SEQ_time_left_handle_frame_get(seq2)) || - (SEQ_time_left_handle_frame_get(seq1) + offset >= SEQ_time_right_handle_frame_get(seq2))) == - 0); + return (seq1 != seq2 && seq1->machine == seq2->machine && + ((SEQ_time_right_handle_frame_get(scene, seq1) + offset <= + SEQ_time_left_handle_frame_get(scene, seq2)) || + (SEQ_time_left_handle_frame_get(scene, seq1) + offset >= + SEQ_time_right_handle_frame_get(scene, seq2))) == 0); } -static int shuffle_seq_time_offset_get(SeqCollection *strips_to_shuffle, +static int shuffle_seq_time_offset_get(const Scene *scene, + SeqCollection *strips_to_shuffle, ListBase *seqbasep, char dir) { @@ -276,7 +234,7 @@ static int shuffle_seq_time_offset_get(SeqCollection *strips_to_shuffle, all_conflicts_resolved = true; SEQ_ITERATOR_FOREACH (seq, strips_to_shuffle) { LISTBASE_FOREACH (Sequence *, seq_other, seqbasep) { - if (!shuffle_seq_test_overlap(seq, seq_other, offset)) { + if (!shuffle_seq_test_overlap(scene, seq, seq_other, offset)) { continue; } if (SEQ_relation_is_effect_of_strip(seq_other, seq)) { @@ -293,13 +251,13 @@ static int shuffle_seq_time_offset_get(SeqCollection *strips_to_shuffle, if (dir == 'L') { offset = min_ii(offset, - SEQ_time_left_handle_frame_get(seq_other) - - SEQ_time_right_handle_frame_get(seq)); + SEQ_time_left_handle_frame_get(scene, seq_other) - + SEQ_time_right_handle_frame_get(scene, seq)); } else { offset = max_ii(offset, - SEQ_time_right_handle_frame_get(seq_other) - - SEQ_time_left_handle_frame_get(seq)); + SEQ_time_right_handle_frame_get(scene, seq_other) - + SEQ_time_left_handle_frame_get(scene, seq)); } } } @@ -315,8 +273,8 @@ bool SEQ_transform_seqbase_shuffle_time(SeqCollection *strips_to_shuffle, ListBase *markers, const bool use_sync_markers) { - int offset_l = shuffle_seq_time_offset_get(strips_to_shuffle, seqbasep, 'L'); - int offset_r = shuffle_seq_time_offset_get(strips_to_shuffle, seqbasep, 'R'); + int offset_l = shuffle_seq_time_offset_get(evil_scene, strips_to_shuffle, seqbasep, 'L'); + int offset_r = shuffle_seq_time_offset_get(evil_scene, strips_to_shuffle, seqbasep, 'R'); int offset = (-offset_l < offset_r) ? offset_l : offset_r; if (offset) { @@ -359,7 +317,8 @@ static SeqCollection *extract_standalone_strips(SeqCollection *transformed_strip } /* Query strips positioned after left edge of transformed strips bound-box. */ -static SeqCollection *query_right_side_strips(ListBase *seqbase, +static SeqCollection *query_right_side_strips(const Scene *scene, + ListBase *seqbase, SeqCollection *transformed_strips, SeqCollection *time_dependent_strips) { @@ -367,7 +326,7 @@ static SeqCollection *query_right_side_strips(ListBase *seqbase, { Sequence *seq; SEQ_ITERATOR_FOREACH (seq, transformed_strips) { - minframe = min_ii(minframe, SEQ_time_left_handle_frame_get(seq)); + minframe = min_ii(minframe, SEQ_time_left_handle_frame_get(scene, seq)); } } @@ -380,7 +339,7 @@ static SeqCollection *query_right_side_strips(ListBase *seqbase, continue; } - if ((seq->flag & SELECT) == 0 && SEQ_time_left_handle_frame_get(seq) >= minframe) { + if ((seq->flag & SELECT) == 0 && SEQ_time_left_handle_frame_get(scene, seq) >= minframe) { SEQ_collection_append_strip(seq, collection); } } @@ -398,7 +357,7 @@ static void seq_transform_handle_expand_to_fit(Scene *scene, ListBase *markers = &scene->markers; SeqCollection *right_side_strips = query_right_side_strips( - seqbasep, transformed_strips, time_dependent_strips); + scene, seqbasep, transformed_strips, time_dependent_strips); /* Temporarily move right side strips beyond timeline boundary. */ Sequence *seq; @@ -424,7 +383,8 @@ static void seq_transform_handle_expand_to_fit(Scene *scene, SEQ_collection_free(right_side_strips); } -static SeqCollection *query_overwrite_targets(ListBase *seqbasep, +static SeqCollection *query_overwrite_targets(const Scene *scene, + ListBase *seqbasep, SeqCollection *transformed_strips) { SeqCollection *collection = SEQ_query_unselected_strips(seqbasep); @@ -438,7 +398,7 @@ static SeqCollection *query_overwrite_targets(ListBase *seqbasep, if (seq == seq_transformed) { SEQ_collection_remove_strip(seq, collection); } - if (SEQ_transform_test_overlap_seq_seq(seq, seq_transformed)) { + if (SEQ_transform_test_overlap_seq_seq(scene, seq, seq_transformed)) { does_overlap = true; } } @@ -463,23 +423,32 @@ typedef enum eOvelapDescrition { STRIP_OVERLAP_RIGHT_SIDE, } eOvelapDescrition; -static eOvelapDescrition overlap_description_get(const Sequence *transformed, +static eOvelapDescrition overlap_description_get(const Scene *scene, + const Sequence *transformed, const Sequence *target) { - if (SEQ_time_left_handle_frame_get(transformed) <= SEQ_time_left_handle_frame_get(target) && - SEQ_time_right_handle_frame_get(transformed) >= SEQ_time_right_handle_frame_get(target)) { + if (SEQ_time_left_handle_frame_get(scene, transformed) <= + SEQ_time_left_handle_frame_get(scene, target) && + SEQ_time_right_handle_frame_get(scene, transformed) >= + SEQ_time_right_handle_frame_get(scene, target)) { return STRIP_OVERLAP_IS_FULL; } - if (SEQ_time_left_handle_frame_get(transformed) > SEQ_time_left_handle_frame_get(target) && - SEQ_time_right_handle_frame_get(transformed) < SEQ_time_right_handle_frame_get(target)) { + if (SEQ_time_left_handle_frame_get(scene, transformed) > + SEQ_time_left_handle_frame_get(scene, target) && + SEQ_time_right_handle_frame_get(scene, transformed) < + SEQ_time_right_handle_frame_get(scene, target)) { return STRIP_OVERLAP_IS_INSIDE; } - if (SEQ_time_left_handle_frame_get(transformed) <= SEQ_time_left_handle_frame_get(target) && - SEQ_time_left_handle_frame_get(target) <= SEQ_time_right_handle_frame_get(transformed)) { + if (SEQ_time_left_handle_frame_get(scene, transformed) <= + SEQ_time_left_handle_frame_get(scene, target) && + SEQ_time_left_handle_frame_get(scene, target) <= + SEQ_time_right_handle_frame_get(scene, transformed)) { return STRIP_OVERLAP_LEFT_SIDE; } - if (SEQ_time_left_handle_frame_get(transformed) <= SEQ_time_right_handle_frame_get(target) && - SEQ_time_right_handle_frame_get(target) <= SEQ_time_right_handle_frame_get(transformed)) { + if (SEQ_time_left_handle_frame_get(scene, transformed) <= + SEQ_time_right_handle_frame_get(scene, target) && + SEQ_time_right_handle_frame_get(scene, target) <= + SEQ_time_right_handle_frame_get(scene, transformed)) { return STRIP_OVERLAP_RIGHT_SIDE; } return STRIP_OVERLAP_NONE; @@ -499,14 +468,14 @@ static void seq_transform_handle_overwrite_split(Scene *scene, scene, seqbasep, target, - SEQ_time_left_handle_frame_get(transformed), + SEQ_time_left_handle_frame_get(scene, transformed), SEQ_SPLIT_SOFT, NULL); SEQ_edit_strip_split(bmain, scene, seqbasep, split_strip, - SEQ_time_right_handle_frame_get(transformed), + SEQ_time_right_handle_frame_get(scene, transformed), SEQ_SPLIT_SOFT, NULL); SEQ_edit_flag_for_removal(scene, seqbasep, split_strip); @@ -521,11 +490,12 @@ static void seq_transform_handle_overwrite_trim(Scene *scene, Sequence *target, const eOvelapDescrition overlap) { - SeqCollection *targets = SEQ_query_by_reference(target, seqbasep, SEQ_query_strip_effect_chain); + SeqCollection *targets = SEQ_query_by_reference( + target, scene, seqbasep, SEQ_query_strip_effect_chain); /* Expand collection by adding all target's children, effects and their children. */ if ((target->type & SEQ_TYPE_EFFECT) != 0) { - SEQ_collection_expand(seqbasep, targets, SEQ_query_strip_effect_chain); + SEQ_collection_expand(scene, seqbasep, targets, SEQ_query_strip_effect_chain); } /* Trim all non effects, that have influence on effect length which is overlapping. */ @@ -535,11 +505,13 @@ static void seq_transform_handle_overwrite_trim(Scene *scene, continue; } if (overlap == STRIP_OVERLAP_LEFT_SIDE) { - SEQ_time_left_handle_frame_set(scene, seq, SEQ_time_right_handle_frame_get(transformed)); + SEQ_time_left_handle_frame_set( + scene, seq, SEQ_time_right_handle_frame_get(scene, transformed)); } else { BLI_assert(overlap == STRIP_OVERLAP_RIGHT_SIDE); - SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(transformed)); + SEQ_time_right_handle_frame_set( + scene, seq, SEQ_time_left_handle_frame_get(scene, transformed)); } } SEQ_collection_free(targets); @@ -549,7 +521,7 @@ static void seq_transform_handle_overwrite(Scene *scene, ListBase *seqbasep, SeqCollection *transformed_strips) { - SeqCollection *targets = query_overwrite_targets(seqbasep, transformed_strips); + SeqCollection *targets = query_overwrite_targets(scene, seqbasep, transformed_strips); SeqCollection *strips_to_delete = SEQ_collection_create(__func__); Sequence *target; @@ -560,7 +532,7 @@ static void seq_transform_handle_overwrite(Scene *scene, continue; } - const eOvelapDescrition overlap = overlap_description_get(transformed, target); + const eOvelapDescrition overlap = overlap_description_get(scene, transformed, target); if (overlap == STRIP_OVERLAP_IS_FULL) { SEQ_collection_append_strip(target, strips_to_delete); @@ -629,7 +601,7 @@ void SEQ_transform_handle_overlap(Scene *scene, * In some cases other strips can be overlapping still, see T90646. */ Sequence *seq; SEQ_ITERATOR_FOREACH (seq, transformed_strips) { - if (SEQ_transform_test_overlap(seqbasep, seq)) { + if (SEQ_transform_test_overlap(scene, seqbasep, seq)) { SEQ_transform_seqbase_shuffle(seqbasep, seq, scene); } seq->flag &= ~SEQ_OVERLAP; @@ -642,7 +614,7 @@ void SEQ_transform_offset_after_frame(Scene *scene, const int timeline_frame) { LISTBASE_FOREACH (Sequence *, seq, seqbase) { - if (SEQ_time_left_handle_frame_get(seq) >= timeline_frame) { + if (SEQ_time_left_handle_frame_get(scene, seq) >= timeline_frame) { SEQ_transform_translate_sequence(scene, seq, delta); SEQ_relations_invalidate_cache_preprocessed(scene, seq); } diff --git a/source/blender/sequencer/intern/utils.c b/source/blender/sequencer/intern/utils.c index 3cfe63e284f..2026e322763 100644 --- a/source/blender/sequencer/intern/utils.c +++ b/source/blender/sequencer/intern/utils.c @@ -187,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->start; + *r_offset = SEQ_time_start_frame_get(seq); break; } case SEQ_TYPE_SCENE: { @@ -347,7 +347,8 @@ const Sequence *SEQ_get_topmost_sequence(const Scene *scene, int frame) } for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if (SEQ_render_is_muted(channels, seq) || !SEQ_time_strip_intersects_frame(seq, frame)) { + if (SEQ_render_is_muted(channels, seq) || + !SEQ_time_strip_intersects_frame(scene, seq, frame)) { continue; } /* Only use strips that generate an image, not ones that combine |