diff options
Diffstat (limited to 'source/blender/sequencer')
25 files changed, 513 insertions, 398 deletions
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 |