diff options
author | Richard Antalik <richardantalik@gmail.com> | 2021-11-15 22:33:34 +0300 |
---|---|---|
committer | Richard Antalik <richardantalik@gmail.com> | 2021-11-15 22:33:34 +0300 |
commit | 46f5f60c13717849990fb31ac4e5f995010e65a9 (patch) | |
tree | 1423a434ef1c5f33207609874e293eddc30cf055 | |
parent | 10a6a540af31e1c96f13a0faee75e3c924a772e5 (diff) | |
parent | a040d2a93a7d5b615dc7d408925f00e87a603472 (diff) |
Merge branch 'blender-v3.0-release'
-rw-r--r-- | source/blender/blenkernel/BKE_movieclip.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/movieclip.c | 5 | ||||
-rw-r--r-- | source/blender/editors/space_sequencer/sequencer_draw.c | 5 | ||||
-rw-r--r-- | source/blender/editors/space_sequencer/sequencer_edit.c | 31 | ||||
-rw-r--r-- | source/blender/imbuf/intern/anim_movie.c | 54 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_sequencer.c | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_sequencer_api.c | 3 | ||||
-rw-r--r-- | source/blender/sequencer/SEQ_relations.h | 4 | ||||
-rw-r--r-- | source/blender/sequencer/SEQ_time.h | 1 | ||||
-rw-r--r-- | source/blender/sequencer/intern/render.c | 3 | ||||
-rw-r--r-- | source/blender/sequencer/intern/strip_add.c | 2 | ||||
-rw-r--r-- | source/blender/sequencer/intern/strip_relations.c | 74 | ||||
-rw-r--r-- | source/blender/sequencer/intern/strip_time.c | 59 |
13 files changed, 115 insertions, 132 deletions
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h index 067dc694109..73c7494b8fa 100644 --- a/source/blender/blenkernel/BKE_movieclip.h +++ b/source/blender/blenkernel/BKE_movieclip.h @@ -95,6 +95,7 @@ void BKE_movieclip_build_proxy_frame_for_ibuf(struct MovieClip *clip, int *build_sizes, int build_count, bool undistorted); +bool BKE_movieclip_proxy_enabled(struct MovieClip *clip); float BKE_movieclip_remap_scene_to_clip_frame(const struct MovieClip *clip, float framenr); float BKE_movieclip_remap_clip_to_scene_frame(const struct MovieClip *clip, float framenr); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index f4db81fffc5..34fb9f71bd9 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -1925,6 +1925,11 @@ void BKE_movieclip_build_proxy_frame_for_ibuf(MovieClip *clip, } } +bool BKE_movieclip_proxy_enabled(MovieClip *clip) +{ + return clip->flag & MCLIP_USE_PROXY; +} + float BKE_movieclip_remap_scene_to_clip_frame(const MovieClip *clip, float framenr) { return framenr - (float)clip->start_frame + 1.0f; diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 3374ff11726..72e39d369a5 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -2721,8 +2721,6 @@ void draw_timeline_seq(const bContext *C, ARegion *region) } UI_view2d_view_ortho(v2d); - /* Get timeline bound-box, needed for the scroll-bars. */ - SEQ_timeline_boundbox(scene, SEQ_active_seqbase_get(ed), &v2d->tot); draw_seq_backdrop(v2d); if ((sseq->flag & SEQ_SHOW_OVERLAY) && (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_GRID)) { U.v2d_min_gridsize *= 3; @@ -2806,5 +2804,8 @@ void draw_timeline_seq_display(const bContext *C, ARegion *region) } ED_time_scrub_draw_current_frame(region, scene, !(sseq->flag & SEQ_DRAWFRAMES)); + + const ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); + SEQ_timeline_boundbox(scene, seqbase, &v2d->tot); UI_view2d_scrollers_draw(v2d, NULL); } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 8c70f4e3f7a..12a6981baee 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -818,8 +818,6 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even case EVT_ESCKEY: case RIGHTMOUSE: { - Editing *ed = SEQ_editing_get(scene); - for (int i = 0; i < data->num_seq; i++) { transseq_restore(data->ts + i, data->seq_array[i]); } @@ -839,8 +837,6 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); - SEQ_relations_free_imbuf(scene, &ed->seqbase, false); - if (area) { ED_area_status_text(area, NULL); } @@ -1116,7 +1112,6 @@ static int sequencer_reload_exec(bContext *C, wmOperator *op) for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT) { - SEQ_relations_update_changed_seq_and_deps(scene, seq, 0, 1); SEQ_add_reload_new_file(bmain, scene, seq, !adjust_length); if (adjust_length) { @@ -1326,7 +1321,9 @@ static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op) last_seq->seq3 = seq3; int old_start = last_seq->start; - SEQ_relations_update_changed_seq_and_deps(scene, last_seq, 1, 1); + SEQ_time_update_recursive(scene, last_seq); + + SEQ_relations_invalidate_cache_preprocessed(scene, last_seq); SEQ_offset_animdata(scene, last_seq, (last_seq->start - old_start)); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1384,7 +1381,7 @@ static int sequencer_swap_inputs_exec(bContext *C, wmOperator *op) last_seq->seq1 = last_seq->seq2; last_seq->seq2 = seq; - SEQ_relations_update_changed_seq_and_deps(scene, last_seq, 1, 1); + SEQ_relations_invalidate_cache_preprocessed(scene, last_seq); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1791,6 +1788,7 @@ static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op)) while (seq) { ListBase *seqbase = SEQ_active_seqbase_get(ed); SEQ_time_update_sequence(scene, seqbase, seq); + SEQ_relations_invalidate_cache_preprocessed(scene, seq); seq = seq->next; } @@ -2202,10 +2200,12 @@ static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb) seq_b_start = (seqb->start - seqb->startdisp) + seqa->startdisp; SEQ_transform_translate_sequence(scene, seqb, seq_b_start - seqb->start); SEQ_time_update_sequence(scene, seqbase, seqb); + SEQ_relations_invalidate_cache_preprocessed(scene, seqb); seq_a_start = (seqa->start - seqa->startdisp) + seqb->enddisp + gap; SEQ_transform_translate_sequence(scene, seqa, seq_a_start - seqa->start); SEQ_time_update_sequence(scene, seqbase, seqa); + SEQ_relations_invalidate_cache_preprocessed(scene, seqa); } static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, int sel) @@ -2673,7 +2673,6 @@ static const EnumPropertyItem prop_change_effect_input_types[] = { static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene); Sequence *seq = SEQ_select_active_get(scene); Sequence **seq_1, **seq_2; @@ -2700,10 +2699,7 @@ static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op) SWAP(Sequence *, *seq_1, *seq_2); - SEQ_relations_update_changed_seq_and_deps(scene, seq, 0, 1); - - /* Invalidate cache. */ - SEQ_relations_free_imbuf(scene, &ed->seqbase, false); + SEQ_relations_invalidate_cache_preprocessed(scene, seq); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -2757,7 +2753,6 @@ EnumPropertyItem sequencer_prop_effect_types[] = { static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene); Sequence *seq = SEQ_select_active_get(scene); const int new_type = RNA_enum_get(op->ptr, "type"); @@ -2783,10 +2778,7 @@ static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op) sh = SEQ_effect_handle_get(seq); sh.init(seq); - SEQ_relations_update_changed_seq_and_deps(scene, seq, 0, 1); - /* Invalidate cache. */ - SEQ_relations_free_imbuf(scene, &ed->seqbase, false); - + SEQ_relations_invalidate_cache_preprocessed(scene, seq); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -2880,9 +2872,6 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op) ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); SEQ_time_update_sequence(scene, seqbase, seq); - - /* Invalidate cache. */ - SEQ_relations_free_imbuf(scene, seqbase, false); } else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) { bSound *sound = seq->sound; @@ -2906,8 +2895,10 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op) prop = RNA_struct_find_property(&seq_ptr, "filepath"); RNA_property_string_set(&seq_ptr, prop, filepath); RNA_property_update(C, &seq_ptr, prop); + SEQ_relations_sequence_free_anim(seq); } + SEQ_relations_invalidate_cache_raw(scene, seq); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index c11c6d778a1..87f2fd124c0 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -939,14 +939,36 @@ static void ffmpeg_postprocess(struct anim *anim) } } -/* decode one video frame also considering the packet read into cur_packet */ +static void ffmpeg_decode_store_frame_pts(struct anim *anim) +{ + anim->cur_pts = av_get_pts_from_frame(anim->pFrame); + + if (anim->pFrame->key_frame) { + anim->cur_key_frame_pts = anim->cur_pts; + } + + av_log(anim->pFormatCtx, + AV_LOG_DEBUG, + " FRAME DONE: cur_pts=%" PRId64 ", guessed_pts=%" PRId64 "\n", + (anim->pFrame->pts == AV_NOPTS_VALUE) ? -1 : (int64_t)anim->pFrame->pts, + (int64_t)anim->cur_pts); +} +/* decode one video frame also considering the packet read into cur_packet */ static int ffmpeg_decode_video_frame(struct anim *anim) { - int rval = 0; - av_log(anim->pFormatCtx, AV_LOG_DEBUG, " DECODE VIDEO FRAME\n"); + /* Sometimes, decoder returns more than one frame per sent packet. Check if frames are available. + * This frames must be read, otherwise decoding will fail. See T91405. */ + anim->pFrameComplete = avcodec_receive_frame(anim->pCodecCtx, anim->pFrame) == 0; + if (anim->pFrameComplete) { + av_log(anim->pFormatCtx, AV_LOG_DEBUG, " DECODE FROM CODEC BUFFER\n"); + ffmpeg_decode_store_frame_pts(anim); + return 1; + } + + int rval = 0; if (anim->cur_packet->stream_index == anim->videoStream) { av_packet_unref(anim->cur_packet); anim->cur_packet->stream_index = -1; @@ -963,22 +985,11 @@ static int ffmpeg_decode_video_frame(struct anim *anim) (anim->cur_packet->pts == AV_NOPTS_VALUE) ? -1 : (int64_t)anim->cur_packet->pts, (anim->cur_packet->flags & AV_PKT_FLAG_KEY) ? " KEY" : ""); if (anim->cur_packet->stream_index == anim->videoStream) { - anim->pFrameComplete = 0; - avcodec_send_packet(anim->pCodecCtx, anim->cur_packet); anim->pFrameComplete = avcodec_receive_frame(anim->pCodecCtx, anim->pFrame) == 0; if (anim->pFrameComplete) { - anim->cur_pts = av_get_pts_from_frame(anim->pFrame); - - if (anim->pFrame->key_frame) { - anim->cur_key_frame_pts = anim->cur_pts; - } - av_log(anim->pFormatCtx, - AV_LOG_DEBUG, - " FRAME DONE: cur_pts=%" PRId64 ", guessed_pts=%" PRId64 "\n", - (anim->pFrame->pts == AV_NOPTS_VALUE) ? -1 : (int64_t)anim->pFrame->pts, - (int64_t)anim->cur_pts); + ffmpeg_decode_store_frame_pts(anim); break; } } @@ -988,22 +999,11 @@ static int ffmpeg_decode_video_frame(struct anim *anim) if (rval == AVERROR_EOF) { /* Flush any remaining frames out of the decoder. */ - anim->pFrameComplete = 0; - avcodec_send_packet(anim->pCodecCtx, NULL); anim->pFrameComplete = avcodec_receive_frame(anim->pCodecCtx, anim->pFrame) == 0; if (anim->pFrameComplete) { - anim->cur_pts = av_get_pts_from_frame(anim->pFrame); - - if (anim->pFrame->key_frame) { - anim->cur_key_frame_pts = anim->cur_pts; - } - av_log(anim->pFormatCtx, - AV_LOG_DEBUG, - " FRAME DONE (after EOF): cur_pts=%" PRId64 ", guessed_pts=%" PRId64 "\n", - (anim->pFrame->pts == AV_NOPTS_VALUE) ? -1 : (int64_t)anim->pFrame->pts, - (int64_t)anim->cur_pts); + ffmpeg_decode_store_frame_pts(anim); rval = 0; } } diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 21a7131c46f..61b3f1d63d6 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -2250,7 +2250,7 @@ static void rna_def_filter_video(StructRNA *srna) prop = RNA_def_property(srna, "use_reverse_frames", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_REVERSE_FRAMES); RNA_def_property_ui_text(prop, "Reverse Frames", "Reverse frame order"); - RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update"); prop = RNA_def_property(srna, "color_multiply", PROP_FLOAT, PROP_UNSIGNED); RNA_def_property_float_sdna(prop, NULL, "mul"); @@ -2272,7 +2272,8 @@ static void rna_def_filter_video(StructRNA *srna) prop = RNA_def_property(srna, "strobe", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 1.0f, 30.0f); RNA_def_property_ui_text(prop, "Strobe", "Only display every nth frame"); - RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL); + RNA_def_property_update( + prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update"); prop = RNA_def_property(srna, "transform", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "strip->transform"); diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index ec6c4c2f32f..7989c316c4c 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -59,6 +59,7 @@ # include "SEQ_relations.h" # include "SEQ_render.h" # include "SEQ_sequencer.h" +# include "SEQ_time.h" # include "WM_api.h" @@ -69,7 +70,7 @@ static void rna_Sequence_update_rnafunc(ID *id, Sequence *self, bool do_data) ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, self); if (do_data) { - SEQ_relations_update_changed_seq_and_deps(scene, self, true, true); + SEQ_time_update_recursive(scene, self); // new_tstripdata(self); /* need 2.6x version of this. */ } diff --git a/source/blender/sequencer/SEQ_relations.h b/source/blender/sequencer/SEQ_relations.h index 54e53193b48..3b9d430a3c9 100644 --- a/source/blender/sequencer/SEQ_relations.h +++ b/source/blender/sequencer/SEQ_relations.h @@ -35,10 +35,6 @@ struct Scene; struct Sequence; void SEQ_relations_sequence_free_anim(struct Sequence *seq); -void SEQ_relations_update_changed_seq_and_deps(struct Scene *scene, - struct Sequence *changed_seq, - int len_change, - int ibuf_change); bool SEQ_relations_check_scene_recursion(struct Scene *scene, struct ReportList *reports); bool SEQ_relations_render_loop_check(struct Sequence *seq_main, struct Sequence *seq); void SEQ_relations_free_imbuf(struct Scene *scene, struct ListBase *seqbasep, bool for_render); diff --git a/source/blender/sequencer/SEQ_time.h b/source/blender/sequencer/SEQ_time.h index df3c9a40409..a0abaf8813a 100644 --- a/source/blender/sequencer/SEQ_time.h +++ b/source/blender/sequencer/SEQ_time.h @@ -45,6 +45,7 @@ int SEQ_time_find_next_prev_edit(struct Scene *scene, const bool do_center, const bool do_unselected); void SEQ_time_update_sequence(struct Scene *scene, struct ListBase *seqbase, struct Sequence *seq); +void SEQ_time_update_recursive(struct Scene *scene, struct Sequence *changed_seq); bool SEQ_time_strip_intersects_frame(const struct Sequence *seq, const int timeline_frame); void SEQ_time_update_meta_strip_range(struct Scene *scene, struct Sequence *seq_meta); diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c index 4405253586b..12d97d7e3e3 100644 --- a/source/blender/sequencer/intern/render.c +++ b/source/blender/sequencer/intern/render.c @@ -1181,7 +1181,8 @@ static ImBuf *seq_render_movieclip_strip(const SeqRenderData *context, /* Try to get a proxy image. */ ibuf = seq_get_movieclip_ibuf(seq, user); - if (ibuf != NULL && psize != IMB_PROXY_NONE) { + /* If clip doesn't use proxies, it will fallback to full size render of original file. */ + if (ibuf != NULL && psize != IMB_PROXY_NONE && BKE_movieclip_proxy_enabled(seq->clip)) { *r_is_proxy_image = true; } diff --git a/source/blender/sequencer/intern/strip_add.c b/source/blender/sequencer/intern/strip_add.c index 6f635b5db5f..70ac2620e20 100644 --- a/source/blender/sequencer/intern/strip_add.c +++ b/source/blender/sequencer/intern/strip_add.c @@ -248,7 +248,6 @@ Sequence *SEQ_add_effect_strip(Scene *scene, ListBase *seqbase, struct SeqLoadDa SEQ_transform_set_right_handle_frame(seq, load_data->effect.end_frame); } - SEQ_relations_update_changed_seq_and_deps(scene, seq, 1, 1); /* Runs SEQ_time_update_sequence. */ seq_add_set_name(scene, seq, load_data); seq_add_generic_update(scene, seqbase, seq); @@ -798,6 +797,7 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); SEQ_time_update_sequence(scene, seqbase, seq); + SEQ_relations_invalidate_cache_raw(scene, seq); } void SEQ_add_movie_reload_if_needed(struct Main *bmain, diff --git a/source/blender/sequencer/intern/strip_relations.c b/source/blender/sequencer/intern/strip_relations.c index d17a37cb9d8..e6d9cd330b3 100644 --- a/source/blender/sequencer/intern/strip_relations.c +++ b/source/blender/sequencer/intern/strip_relations.c @@ -281,80 +281,6 @@ void SEQ_relations_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render) } } -static bool update_changed_seq_recurs( - Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change) -{ - Sequence *subseq; - bool free_imbuf = false; - - /* recurse downwards to see if this seq depends on the changed seq */ - - if (seq == NULL) { - return false; - } - - if (seq == changed_seq) { - free_imbuf = true; - } - - for (subseq = seq->seqbase.first; subseq; subseq = subseq->next) { - if (update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change)) { - free_imbuf = true; - } - } - - if (seq->seq1) { - if (update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change)) { - free_imbuf = true; - } - } - if (seq->seq2 && (seq->seq2 != seq->seq1)) { - if (update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change)) { - free_imbuf = true; - } - } - if (seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2)) { - if (update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change)) { - free_imbuf = true; - } - } - - if (free_imbuf) { - if (ibuf_change) { - if (seq->type == SEQ_TYPE_MOVIE) { - SEQ_relations_sequence_free_anim(seq); - } - else if (seq->type == SEQ_TYPE_SPEED) { - seq_effect_speed_rebuild_map(scene, seq); - } - } - - if (len_change) { - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); - SEQ_time_update_sequence(scene, seqbase, seq); - } - } - - return free_imbuf; -} - -void SEQ_relations_update_changed_seq_and_deps(Scene *scene, - Sequence *changed_seq, - int len_change, - int ibuf_change) -{ - Editing *ed = SEQ_editing_get(scene); - Sequence *seq; - - if (ed == NULL) { - return; - } - - for (seq = ed->seqbase.first; seq; seq = seq->next) { - update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change); - } -} - static void sequencer_all_free_anim_ibufs(ListBase *seqbase, int timeline_frame) { for (Sequence *seq = seqbase->first; seq != NULL; seq = seq->next) { diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c index 92ac580f3b1..a8e07f37a0b 100644 --- a/source/blender/sequencer/intern/strip_time.c +++ b/source/blender/sequencer/intern/strip_time.c @@ -267,6 +267,65 @@ void SEQ_time_update_sequence(Scene *scene, ListBase *seqbase, Sequence *seq) seq_time_update_sequence_bounds(scene, seq); } +static bool update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq) +{ + Sequence *subseq; + bool do_update = false; + + /* recurse downwards to see if this seq depends on the changed seq */ + + if (seq == NULL) { + return false; + } + + if (seq == changed_seq) { + do_update = true; + } + + for (subseq = seq->seqbase.first; subseq; subseq = subseq->next) { + if (update_changed_seq_recurs(scene, subseq, changed_seq)) { + do_update = true; + } + } + + if (seq->seq1) { + if (update_changed_seq_recurs(scene, seq->seq1, changed_seq)) { + do_update = true; + } + } + if (seq->seq2 && (seq->seq2 != seq->seq1)) { + if (update_changed_seq_recurs(scene, seq->seq2, changed_seq)) { + do_update = true; + } + } + if (seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2)) { + if (update_changed_seq_recurs(scene, seq->seq3, changed_seq)) { + do_update = true; + } + } + + if (do_update) { + ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); + SEQ_time_update_sequence(scene, seqbase, seq); + } + + return do_update; +} + +void SEQ_time_update_recursive(Scene *scene, Sequence *changed_seq) +{ + Editing *ed = SEQ_editing_get(scene); + Sequence *seq; + + if (ed == NULL) { + return; + } + + for (seq = ed->seqbase.first; seq; seq = seq->next) { + update_changed_seq_recurs(scene, seq, changed_seq); + } +} + int SEQ_time_find_next_prev_edit(Scene *scene, int timeline_frame, const short side, |