diff options
Diffstat (limited to 'source/blender/blenkernel/intern/sequencer.c')
-rw-r--r-- | source/blender/blenkernel/intern/sequencer.c | 419 |
1 files changed, 267 insertions, 152 deletions
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 9fb28fe250a..90edebfaa97 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -39,6 +39,7 @@ #include "DNA_sequence_types.h" #include "DNA_sound_types.h" #include "DNA_space_types.h" +#include "DNA_windowmanager_types.h" #include "BLI_fileops.h" #include "BLI_linklist.h" @@ -58,6 +59,7 @@ #include "BLT_translation.h" +#include "BKE_anim_data.h" #include "BKE_animsys.h" #include "BKE_fcurve.h" #include "BKE_global.h" @@ -68,6 +70,7 @@ #include "BKE_main.h" #include "BKE_mask.h" #include "BKE_movieclip.h" +#include "BKE_report.h" #include "BKE_scene.h" #include "BKE_sequencer.h" #include "BKE_sequencer_offscreen.h" @@ -105,6 +108,14 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seqbasep, float cfra, int chanshown); +static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context, + Sequence *seq, + ImBuf *ibuf, + float cfra, + clock_t begin, + bool use_preprocess, + const bool is_proxy_image, + const bool is_preprocessed); static ImBuf *seq_render_strip(const SeqRenderData *context, SeqRenderState *state, Sequence *seq, @@ -120,7 +131,8 @@ static ThreadMutex seq_render_mutex = BLI_MUTEX_INITIALIZER; #define SELECT 1 ListBase seqbase_clipboard; int seqbase_clipboard_frame; -SequencerDrawView sequencer_view3d_cb = NULL; /* NULL in background mode */ + +SequencerDrawView sequencer_view3d_fn = NULL; /* NULL in background mode */ #if 0 /* unused function */ static void printf_strip(Sequence *seq) @@ -152,28 +164,28 @@ static void sequencer_state_init(SeqRenderState *state) } int BKE_sequencer_base_recursive_apply(ListBase *seqbase, - int (*apply_func)(Sequence *seq, void *), + int (*apply_fn)(Sequence *seq, void *), void *arg) { Sequence *iseq; for (iseq = seqbase->first; iseq; iseq = iseq->next) { - if (BKE_sequencer_recursive_apply(iseq, apply_func, arg) == -1) { + if (BKE_sequencer_recursive_apply(iseq, apply_fn, arg) == -1) { return -1; /* bail out */ } } return 1; } -int BKE_sequencer_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg) +int BKE_sequencer_recursive_apply(Sequence *seq, int (*apply_fn)(Sequence *, void *), void *arg) { - int ret = apply_func(seq, arg); + int ret = apply_fn(seq, arg); if (ret == -1) { return -1; /* bail out */ } if (ret && seq->seqbase.first) { - ret = BKE_sequencer_base_recursive_apply(&seq->seqbase, apply_func, arg); + ret = BKE_sequencer_base_recursive_apply(&seq->seqbase, apply_fn, arg); } return ret; @@ -227,7 +239,8 @@ static void seq_free_strip(Strip *strip) static void BKE_sequence_free_ex(Scene *scene, Sequence *seq, const bool do_cache, - const bool do_id_user) + const bool do_id_user, + const bool do_clean_animdata) { if (seq->strip) { seq_free_strip(seq->strip); @@ -262,7 +275,10 @@ static void BKE_sequence_free_ex(Scene *scene, BKE_sound_remove_scene_sound(scene, seq->scene_sound); } - seq_free_animdata(scene, seq); + /* XXX This must not be done in BKE code. */ + if (do_clean_animdata) { + seq_free_animdata(scene, seq); + } } if (seq->prop) { @@ -290,9 +306,9 @@ static void BKE_sequence_free_ex(Scene *scene, MEM_freeN(seq); } -void BKE_sequence_free(Scene *scene, Sequence *seq) +void BKE_sequence_free(Scene *scene, Sequence *seq, const bool do_clean_animdata) { - BKE_sequence_free_ex(scene, seq, true, true); + BKE_sequence_free_ex(scene, seq, true, true, do_clean_animdata); } /* Function to free imbuf and anim data on changes */ @@ -322,7 +338,7 @@ static void seq_free_sequence_recurse(Scene *scene, Sequence *seq, const bool do seq_free_sequence_recurse(scene, iseq, do_id_user); } - BKE_sequence_free_ex(scene, seq, false, do_id_user); + BKE_sequence_free_ex(scene, seq, false, do_id_user, true); } Editing *BKE_sequencer_editing_get(Scene *scene, bool alloc) @@ -492,7 +508,7 @@ void BKE_sequencer_editing_free(Scene *scene, const bool do_id_user) SEQ_BEGIN (ed, seq) { /* handle cache freeing above */ - BKE_sequence_free_ex(scene, seq, false, do_id_user); + BKE_sequence_free_ex(scene, seq, false, do_id_user, false); } SEQ_END; @@ -752,10 +768,10 @@ static int metaseq_end(Sequence *metaseq) return metaseq->start + metaseq->len - metaseq->endofs; } -static void seq_update_sound_bounds_recursive_rec(Scene *scene, - Sequence *metaseq, - int start, - int end) +static void seq_update_sound_bounds_recursive_impl(Scene *scene, + Sequence *metaseq, + int start, + int end) { Sequence *seq; @@ -763,7 +779,7 @@ static void seq_update_sound_bounds_recursive_rec(Scene *scene, * since sound is played outside of evaluating the imbufs, */ for (seq = metaseq->seqbase.first; seq; seq = seq->next) { if (seq->type == SEQ_TYPE_META) { - seq_update_sound_bounds_recursive_rec( + seq_update_sound_bounds_recursive_impl( scene, seq, max_ii(start, metaseq_start(seq)), min_ii(end, metaseq_end(seq))); } else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) { @@ -790,7 +806,7 @@ static void seq_update_sound_bounds_recursive_rec(Scene *scene, static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq) { - seq_update_sound_bounds_recursive_rec( + seq_update_sound_bounds_recursive_impl( scene, metaseq, metaseq_start(metaseq), metaseq_end(metaseq)); } @@ -1138,7 +1154,7 @@ int BKE_sequencer_cmp_time_startdisp(const void *a, const void *b) return (seq_a->startdisp > seq_b->startdisp); } -static int clear_scene_in_allseqs_cb(Sequence *seq, void *arg_pt) +static int clear_scene_in_allseqs_fn(Sequence *seq, void *arg_pt) { if (seq->scene == (Scene *)arg_pt) { seq->scene = NULL; @@ -1154,7 +1170,7 @@ void BKE_sequencer_clear_scene_in_allseqs(Main *bmain, Scene *scene) for (scene_iter = bmain->scenes.first; scene_iter; scene_iter = scene_iter->id.next) { if (scene_iter != scene && scene_iter->ed) { BKE_sequencer_base_recursive_apply( - &scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene); + &scene_iter->ed->seqbase, clear_scene_in_allseqs_fn, scene); } } } @@ -1184,7 +1200,7 @@ static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui) } } -static int seqbase_unique_name_recursive_cb(Sequence *seq, void *arg_pt) +static int seqbase_unique_name_recursive_fn(Sequence *seq, void *arg_pt) { if (seq->seqbase.first) { seqbase_unique_name(&seq->seqbase, (SeqUniqueInfo *)arg_pt); @@ -1216,7 +1232,7 @@ void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, Sequence *seq) while (sui.match) { sui.match = 0; seqbase_unique_name(seqbasep, &sui); - BKE_sequencer_base_recursive_apply(seqbasep, seqbase_unique_name_recursive_cb, &sui); + BKE_sequencer_base_recursive_apply(seqbasep, seqbase_unique_name_recursive_fn, &sui); } BLI_strncpy(seq->name + 2, sui.name_dest, sizeof(seq->name) - 2); @@ -1381,7 +1397,7 @@ static void multibuf(ImBuf *ibuf, const float fmul) } } -static float give_stripelem_index(Sequence *seq, float cfra) +float BKE_sequencer_give_stripelem_index(Sequence *seq, float cfra) { float nr; int sta = seq->start; @@ -1439,7 +1455,7 @@ StripElem *BKE_sequencer_give_stripelem(Sequence *seq, int cfra) * all other strips don't use this... */ - int nr = (int)give_stripelem_index(seq, cfra); + int nr = (int)BKE_sequencer_give_stripelem_index(seq, cfra); if (nr == -1 || se == NULL) { return NULL; @@ -1458,7 +1474,7 @@ static int evaluate_seq_frame_gen(Sequence **seq_arr, ListBase *seqbase, int cfr memset(seq_arr, 0, sizeof(Sequence *) * (MAXSEQ + 1)); - for (Sequence *seq = seqbase->first; seq; seq = seq->next) { + LISTBASE_FOREACH (Sequence *, seq, seqbase) { if ((seq->startdisp <= cfra) && (seq->enddisp > cfra)) { if ((seq->type & SEQ_TYPE_EFFECT) && !(seq->flag & SEQ_MUTE)) { @@ -1522,7 +1538,10 @@ static bool video_seq_is_rendered(Sequence *seq) return (seq && !(seq->flag & SEQ_MUTE) && seq->type != SEQ_TYPE_SOUND_RAM); } -static int get_shown_sequences(ListBase *seqbasep, int cfra, int chanshown, Sequence **seq_arr_out) +int BKE_sequencer_get_shown_sequences(ListBase *seqbasep, + int cfra, + int chanshown, + Sequence **seq_arr_out) { Sequence *seq_arr[MAXSEQ + 1]; int b = chanshown; @@ -1876,7 +1895,7 @@ static bool seq_proxy_get_fname(Editing *ed, frameno = 1; } else { - frameno = (int)give_stripelem_index(seq, cfra) + seq->anim_startofs; + frameno = (int)BKE_sequencer_give_stripelem_index(seq, cfra) + seq->anim_startofs; BLI_snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####%s", dir, proxy_size_number, suffix); } @@ -1891,9 +1910,10 @@ static bool seq_proxy_get_fname(Editing *ed, static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int cfra) { char name[PROXY_MAXFILE]; - IMB_Proxy_Size psize = seq_rendersize_to_proxysize(context->preview_render_size); - int size_flags; StripProxy *proxy = seq->strip->proxy; + const eSpaceSeq_Proxy_RenderSize psize = context->preview_render_size; + const IMB_Proxy_Size psize_flag = seq_rendersize_to_proxysize(psize); + int size_flags; Editing *ed = context->scene->ed; StripAnim *sanim; @@ -1904,12 +1924,12 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c size_flags = proxy->build_size_flags; /* only use proxies, if they are enabled (even if present!) */ - if (psize == IMB_PROXY_NONE || (size_flags & psize) == 0) { + if (psize_flag == IMB_PROXY_NONE || (size_flags & psize_flag) == 0) { return NULL; } if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) { - int frameno = (int)give_stripelem_index(seq, cfra) + seq->anim_startofs; + int frameno = (int)BKE_sequencer_give_stripelem_index(seq, cfra) + seq->anim_startofs; if (proxy->anim == NULL) { if (seq_proxy_get_fname(ed, seq, cfra, psize, name, context->view_id) == 0) { return NULL; @@ -2874,15 +2894,15 @@ static void *render_effect_execute_do_thread(void *thread_data_v) return NULL; } -static ImBuf *seq_render_effect_execute_threaded(struct SeqEffectHandle *sh, - const SeqRenderData *context, - Sequence *seq, - float cfra, - float facf0, - float facf1, - ImBuf *ibuf1, - ImBuf *ibuf2, - ImBuf *ibuf3) +ImBuf *BKE_sequencer_effect_execute_threaded(struct SeqEffectHandle *sh, + const SeqRenderData *context, + Sequence *seq, + float cfra, + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *ibuf3) { RenderEffectInitData init_data; ImBuf *out = sh->init_execution(context, ibuf1, ibuf2, ibuf3); @@ -2956,14 +2976,21 @@ static ImBuf *seq_render_effect_strip_impl(const SeqRenderData *context, break; case EARLY_DO_EFFECT: for (i = 0; i < 3; i++) { - if (input[i]) { - ibuf[i] = seq_render_strip(context, state, input[i], cfra); + /* Speed effect requires time remapping of cfra for input(s). */ + if (input[1] && seq->type == SEQ_TYPE_SPEED) { + float target_frame = BKE_sequencer_speed_effect_target_frame_get(context, seq, cfra, i); + ibuf[i] = seq_render_strip(context, state, input[i], target_frame); + } + else { /* Other effects. */ + if (input[i]) { + ibuf[i] = seq_render_strip(context, state, input[i], cfra); + } } } if (ibuf[0] && ibuf[1]) { if (sh.multithreaded) { - out = seq_render_effect_execute_threaded( + out = BKE_sequencer_effect_execute_threaded( &sh, context, seq, cfra, fac, facf, ibuf[0], ibuf[1], ibuf[2]); } else { @@ -3025,7 +3052,6 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context, struct ImBuf **ibufs_arr; char prefix[FILE_MAX]; const char *ext = NULL; - int i; if (totfiles > 1) { BKE_scene_multiview_view_prefix_get(context->scene, name, prefix, &ext); @@ -3040,21 +3066,21 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context, totviews = BKE_scene_multiview_num_views_get(&context->scene->r); ibufs_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs"); - for (i = 0; i < totfiles; i++) { + for (int view_id = 0; view_id < totfiles; view_id++) { if (prefix[0] == '\0') { - ibufs_arr[i] = IMB_loadiffname(name, flag, seq->strip->colorspace_settings.name); + ibufs_arr[view_id] = IMB_loadiffname(name, flag, seq->strip->colorspace_settings.name); } else { char str[FILE_MAX]; - seq_multiview_name(context->scene, i, prefix, ext, str, FILE_MAX); - ibufs_arr[i] = IMB_loadiffname(str, flag, seq->strip->colorspace_settings.name); + seq_multiview_name(context->scene, view_id, prefix, ext, str, FILE_MAX); + ibufs_arr[view_id] = IMB_loadiffname(str, flag, seq->strip->colorspace_settings.name); } - if (ibufs_arr[i]) { + if (ibufs_arr[view_id]) { /* we don't need both (speed reasons)! */ - if (ibufs_arr[i]->rect_float && ibufs_arr[i]->rect) { - imb_freerectImBuf(ibufs_arr[i]); + if (ibufs_arr[view_id]->rect_float && ibufs_arr[view_id]->rect) { + imb_freerectImBuf(ibufs_arr[view_id]); } } } @@ -3063,17 +3089,17 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context, IMB_ImBufFromStereo3d(seq->stereo3d_format, ibufs_arr[0], &ibufs_arr[0], &ibufs_arr[1]); } - for (i = 0; i < totviews; i++) { - if (ibufs_arr[i]) { + for (int view_id = 0; view_id < totviews; view_id++) { + if (ibufs_arr[view_id]) { SeqRenderData localcontext = *context; - localcontext.view_id = i; + localcontext.view_id = view_id; /* all sequencer color is done in SRGB space, linear gives odd crossfades */ - BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibufs_arr[i], false); + BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibufs_arr[view_id], false); - if (i != context->view_id) { - BKE_sequencer_cache_put( - &localcontext, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED, ibufs_arr[i], 0, false); + if (view_id != context->view_id) { + ibufs_arr[view_id] = seq_render_preprocess_ibuf( + &localcontext, seq, ibufs_arr[view_id], cfra, clock(), true, false, false); } } } @@ -3086,9 +3112,9 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context, } /* "remove" the others (decrease their refcount) */ - for (i = 0; i < totviews; i++) { - if (ibufs_arr[i] != ibuf) { - IMB_freeImBuf(ibufs_arr[i]); + for (int view_id = 0; view_id < totviews; view_id++) { + if (ibufs_arr[view_id] != ibuf) { + IMB_freeImBuf(ibufs_arr[view_id]); } } @@ -3136,7 +3162,7 @@ static ImBuf *seq_render_movie_strip(const SeqRenderData *context, ImBuf **ibuf_arr; const int totfiles = seq_num_files(context->scene, seq->views_format, true); int totviews; - int i; + int ibuf_view_id; if (totfiles != BLI_listbase_count_at_most(&seq->anims, totfiles + 1)) { goto monoview_movie; @@ -3145,28 +3171,28 @@ static ImBuf *seq_render_movie_strip(const SeqRenderData *context, totviews = BKE_scene_multiview_num_views_get(&context->scene->r); ibuf_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs"); - for (i = 0, sanim = seq->anims.first; sanim; sanim = sanim->next, i++) { + for (ibuf_view_id = 0, sanim = seq->anims.first; sanim; sanim = sanim->next, ibuf_view_id++) { if (sanim->anim) { IMB_anim_set_preseek(sanim->anim, seq->anim_preseek); - ibuf_arr[i] = IMB_anim_absolute(sanim->anim, - nr + seq->anim_startofs, - seq->strip->proxy ? seq->strip->proxy->tc : - IMB_TC_RECORD_RUN, - psize); + ibuf_arr[ibuf_view_id] = IMB_anim_absolute(sanim->anim, + nr + seq->anim_startofs, + seq->strip->proxy ? seq->strip->proxy->tc : + IMB_TC_RECORD_RUN, + psize); /* fetching for requested proxy size failed, try fetching the original instead */ - if (!ibuf_arr[i] && psize != IMB_PROXY_NONE) { - ibuf_arr[i] = IMB_anim_absolute(sanim->anim, - nr + seq->anim_startofs, - seq->strip->proxy ? seq->strip->proxy->tc : - IMB_TC_RECORD_RUN, - IMB_PROXY_NONE); + if (!ibuf_arr[ibuf_view_id] && psize != IMB_PROXY_NONE) { + ibuf_arr[ibuf_view_id] = IMB_anim_absolute(sanim->anim, + nr + seq->anim_startofs, + seq->strip->proxy ? seq->strip->proxy->tc : + IMB_TC_RECORD_RUN, + IMB_PROXY_NONE); } - if (ibuf_arr[i]) { + if (ibuf_arr[ibuf_view_id]) { /* we don't need both (speed reasons)! */ - if (ibuf_arr[i]->rect_float && ibuf_arr[i]->rect) { - imb_freerectImBuf(ibuf_arr[i]); + if (ibuf_arr[ibuf_view_id]->rect_float && ibuf_arr[ibuf_view_id]->rect) { + imb_freerectImBuf(ibuf_arr[ibuf_view_id]); } } } @@ -3183,17 +3209,17 @@ static ImBuf *seq_render_movie_strip(const SeqRenderData *context, } } - for (i = 0; i < totviews; i++) { + for (int view_id = 0; view_id < totviews; view_id++) { SeqRenderData localcontext = *context; - localcontext.view_id = i; + localcontext.view_id = view_id; - if (ibuf_arr[i]) { + if (ibuf_arr[view_id]) { /* all sequencer color is done in SRGB space, linear gives odd crossfades */ - BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf_arr[i], false); + BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf_arr[view_id], false); } - if (i != context->view_id) { - BKE_sequencer_cache_put( - &localcontext, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED, ibuf_arr[i], 0, false); + if (view_id != context->view_id) { + ibuf_arr[view_id] = seq_render_preprocess_ibuf( + &localcontext, seq, ibuf_arr[view_id], cfra, clock(), true, false, false); } } @@ -3205,9 +3231,9 @@ static ImBuf *seq_render_movie_strip(const SeqRenderData *context, } /* "remove" the others (decrease their refcount) */ - for (i = 0; i < totviews; i++) { - if (ibuf_arr[i] != ibuf) { - IMB_freeImBuf(ibuf_arr[i]); + for (int view_id = 0; view_id < totviews; view_id++) { + if (ibuf_arr[view_id] != ibuf) { + IMB_freeImBuf(ibuf_arr[view_id]); } } @@ -3318,8 +3344,7 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr /* anim-data */ adt = BKE_animdata_from_id(&mask->id); - BKE_animsys_evaluate_animdata( - context->scene, &mask_temp->id, adt, mask->sfra + nr, ADT_RECALC_ANIM, false); + BKE_animsys_evaluate_animdata(&mask_temp->id, adt, mask->sfra + nr, ADT_RECALC_ANIM, false); maskbuf = MEM_mallocN(sizeof(float) * context->rectx * context->recty, __func__); @@ -3450,6 +3475,11 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, return NULL; } + /* Prevent rendering scene recursively. */ + if (seq->scene == context->scene) { + return NULL; + } + scene = seq->scene; frame = (double)scene->r.sfra + (double)nr + (double)seq->anim_startofs; @@ -3498,7 +3528,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, is_frame_update = (orig_data.cfra != scene->r.cfra) || (orig_data.subframe != scene->r.subframe); - if ((sequencer_view3d_cb && do_seq_gl && camera) && is_thread_main) { + if ((sequencer_view3d_fn && do_seq_gl && camera) && is_thread_main) { char err_out[256] = "unknown"; const int width = (scene->r.xsch * scene->r.size) / 100; const int height = (scene->r.ysch * scene->r.size) / 100; @@ -3519,7 +3549,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, /* opengl offscreen render */ depsgraph = BKE_scene_get_depsgraph(context->bmain, scene, view_layer, true); BKE_scene_graph_update_for_newframe(depsgraph, context->bmain); - ibuf = sequencer_view3d_cb( + ibuf = sequencer_view3d_fn( /* set for OpenGL render (NULL when scrubbing) */ depsgraph, scene, @@ -3541,7 +3571,6 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, else { Render *re = RE_GetSceneRender(scene); const int totviews = BKE_scene_multiview_num_views_get(&scene->r); - int i; ImBuf **ibufs_arr; ibufs_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs"); @@ -3566,34 +3595,37 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, G.is_rendering = is_rendering; } - for (i = 0; i < totviews; i++) { + for (int view_id = 0; view_id < totviews; view_id++) { SeqRenderData localcontext = *context; RenderResult rres; - localcontext.view_id = i; + localcontext.view_id = view_id; - RE_AcquireResultImage(re, &rres, i); + RE_AcquireResultImage(re, &rres, view_id); if (rres.rectf) { - ibufs_arr[i] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat); - memcpy(ibufs_arr[i]->rect_float, rres.rectf, 4 * sizeof(float) * rres.rectx * rres.recty); + ibufs_arr[view_id] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat); + memcpy(ibufs_arr[view_id]->rect_float, + rres.rectf, + 4 * sizeof(float) * rres.rectx * rres.recty); if (rres.rectz) { - addzbuffloatImBuf(ibufs_arr[i]); - memcpy(ibufs_arr[i]->zbuf_float, rres.rectz, sizeof(float) * rres.rectx * rres.recty); + addzbuffloatImBuf(ibufs_arr[view_id]); + memcpy( + ibufs_arr[view_id]->zbuf_float, rres.rectz, sizeof(float) * rres.rectx * rres.recty); } /* float buffers in the sequencer are not linear */ - BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibufs_arr[i], false); + BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibufs_arr[view_id], false); } else if (rres.rect32) { - ibufs_arr[i] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect); - memcpy(ibufs_arr[i]->rect, rres.rect32, 4 * rres.rectx * rres.recty); + ibufs_arr[view_id] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect); + memcpy(ibufs_arr[view_id]->rect, rres.rect32, 4 * rres.rectx * rres.recty); } - if (i != context->view_id) { + if (view_id != context->view_id) { BKE_sequencer_cache_put( - &localcontext, seq, cfra, SEQ_CACHE_STORE_RAW, ibufs_arr[i], 0, false); + &localcontext, seq, cfra, SEQ_CACHE_STORE_RAW, ibufs_arr[view_id], 0, false); } RE_ReleaseResultImage(re); @@ -3603,9 +3635,9 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, ibuf = ibufs_arr[context->view_id]; /* "remove" the others (decrease their refcount) */ - for (i = 0; i < totviews; i++) { - if (ibufs_arr[i] != ibuf) { - IMB_freeImBuf(ibufs_arr[i]); + for (int view_id = 0; view_id < totviews; view_id++) { + if (ibufs_arr[view_id] != ibuf) { + IMB_freeImBuf(ibufs_arr[view_id]); } } MEM_freeN(ibufs_arr); @@ -3646,8 +3678,7 @@ static ImBuf *do_render_strip_seqbase(const SeqRenderData *context, if (seqbase && !BLI_listbase_is_empty(seqbase)) { if (seq->flag & SEQ_SCENE_STRIPS && seq->scene) { - BKE_animsys_evaluate_all_animation( - context->bmain, context->depsgraph, seq->scene, nr + offset); + BKE_animsys_evaluate_all_animation(context->bmain, context->depsgraph, nr + offset); } ibuf = seq_render_strip_stack(context, @@ -3667,9 +3698,8 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, float cfra) { ImBuf *ibuf = NULL; - float nr = give_stripelem_index(seq, cfra); - int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT : - seq->type; + float nr = BKE_sequencer_give_stripelem_index(seq, cfra); + int type = (seq->type & SEQ_TYPE_EFFECT) ? SEQ_TYPE_EFFECT : seq->type; switch (type) { case SEQ_TYPE_META: { ibuf = do_render_strip_seqbase(context, state, seq, nr); @@ -3711,21 +3741,8 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, break; } - case SEQ_TYPE_SPEED: { - float f_cfra; - SpeedControlVars *s = (SpeedControlVars *)seq->effectdata; - - BKE_sequence_effect_speed_rebuild_map(context->scene, seq, false); - - /* weeek! */ - f_cfra = seq->start + s->frameMap[(int)nr]; - ibuf = seq_render_strip(context, state, seq->seq1, f_cfra); - - break; - } - case SEQ_TYPE_EFFECT: { - ibuf = seq_render_effect_strip_impl(context, state, seq, seq->start + nr); + ibuf = seq_render_effect_strip_impl(context, state, seq, cfra); break; } @@ -3790,6 +3807,34 @@ static float seq_estimate_render_cost_end(Scene *scene, clock_t begin) } } +static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context, + Sequence *seq, + ImBuf *ibuf, + float cfra, + clock_t begin, + bool use_preprocess, + const bool is_proxy_image, + const bool is_preprocessed) +{ + if (context->is_proxy_render == false && + (ibuf->x != context->rectx || ibuf->y != context->recty)) { + use_preprocess = true; + } + + if (use_preprocess) { + float cost = seq_estimate_render_cost_end(context->scene, begin); + BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost, false); + + /* Reset timer so we can get partial render time. */ + begin = seq_estimate_render_cost_begin(); + ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image, is_preprocessed); + } + + float cost = seq_estimate_render_cost_end(context->scene, begin); + BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED, ibuf, cost, false); + return ibuf; +} + static ImBuf *seq_render_strip(const SeqRenderData *context, SeqRenderState *state, Sequence *seq, @@ -3838,22 +3883,8 @@ static ImBuf *seq_render_strip(const SeqRenderData *context, sequencer_imbuf_assign_spaces(context->scene, ibuf); } - if (context->is_proxy_render == false && - (ibuf->x != context->rectx || ibuf->y != context->recty)) { - use_preprocess = true; - } - - if (use_preprocess) { - float cost = seq_estimate_render_cost_end(context->scene, begin); - BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost, false); - - /* reset timer so we can get partial render time */ - begin = seq_estimate_render_cost_begin(); - ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image, is_preprocessed); - } - - float cost = seq_estimate_render_cost_end(context->scene, begin); - BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED, ibuf, cost, false); + ibuf = seq_render_preprocess_ibuf( + context, seq, ibuf, cfra, begin, use_preprocess, is_proxy_image, is_preprocessed); } return ibuf; } @@ -3905,7 +3936,7 @@ static ImBuf *seq_render_strip_stack_apply_effect( if (swap_input) { if (sh.multithreaded) { - out = seq_render_effect_execute_threaded( + out = BKE_sequencer_effect_execute_threaded( &sh, context, seq, cfra, facf, facf, ibuf2, ibuf1, NULL); } else { @@ -3914,7 +3945,7 @@ static ImBuf *seq_render_strip_stack_apply_effect( } else { if (sh.multithreaded) { - out = seq_render_effect_execute_threaded( + out = BKE_sequencer_effect_execute_threaded( &sh, context, seq, cfra, facf, facf, ibuf1, ibuf2, NULL); } else { @@ -3937,7 +3968,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ImBuf *out = NULL; clock_t begin; - count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr); + count = BKE_sequencer_get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr); if (count == 0) { return NULL; @@ -4045,7 +4076,7 @@ ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int cha Sequence *seq_arr[MAXSEQ + 1]; int count; - count = get_shown_sequences(seqbasep, cfra, chanshown, seq_arr); + count = BKE_sequencer_get_shown_sequences(seqbasep, cfra, chanshown, seq_arr); if (count) { out = BKE_sequencer_cache_get( @@ -4138,8 +4169,15 @@ static void sequence_do_invalidate_dependent(Scene *scene, Sequence *seq, ListBa } if (BKE_sequence_check_depend(seq, cur)) { - BKE_sequencer_cache_cleanup_sequence( - scene, cur, seq, SEQ_CACHE_STORE_COMPOSITE | SEQ_CACHE_STORE_FINAL_OUT); + /* Effect must be invalidated completely if they depend on invalidated seq. */ + if ((cur->type & SEQ_TYPE_EFFECT) != 0) { + BKE_sequencer_cache_cleanup_sequence(scene, cur, seq, SEQ_CACHE_ALL_TYPES, false); + } + else { + /* In case of alpha over for example only invalidate composite image */ + BKE_sequencer_cache_cleanup_sequence( + scene, cur, seq, SEQ_CACHE_STORE_COMPOSITE | SEQ_CACHE_STORE_FINAL_OUT, false); + } } if (cur->seqbase.first) { @@ -4157,7 +4195,7 @@ static void sequence_invalidate_cache(Scene *scene, if (invalidate_self) { BKE_sequence_free_anim(seq); - BKE_sequencer_cache_cleanup_sequence(scene, seq, seq, invalidate_types); + BKE_sequencer_cache_cleanup_sequence(scene, seq, seq, invalidate_types, false); } if (seq->effectdata && seq->type == SEQ_TYPE_SPEED) { @@ -4169,6 +4207,14 @@ static void sequence_invalidate_cache(Scene *scene, BKE_sequencer_prefetch_stop(scene); } +void BKE_sequence_invalidate_cache_in_range(Scene *scene, + Sequence *seq, + Sequence *range_mask, + int invalidate_types) +{ + BKE_sequencer_cache_cleanup_sequence(scene, seq, range_mask, invalidate_types, true); +} + void BKE_sequence_invalidate_cache_raw(Scene *scene, Sequence *seq) { sequence_invalidate_cache(scene, seq, true, SEQ_CACHE_ALL_TYPES); @@ -4568,6 +4614,10 @@ bool BKE_sequence_test_overlap(ListBase *seqbasep, Sequence *test) void BKE_sequence_translate(Scene *evil_scene, Sequence *seq, int delta) { + if (delta == 0) { + return; + } + BKE_sequencer_offset_animdata(evil_scene, seq, delta); seq->start += delta; @@ -5069,7 +5119,7 @@ void BKE_sequencer_dupe_animdata(Scene *scene, const char *name_src, const char for (fcu = scene->adt->action->curves.first; fcu && fcu->prev != fcu_last; fcu = fcu->next) { if (STREQLEN(fcu->rna_path, str_from, str_from_len)) { - fcu_cpy = copy_fcurve(fcu); + fcu_cpy = BKE_fcurve_copy(fcu); BLI_addtail(&lb, fcu_cpy); } } @@ -5102,7 +5152,7 @@ static void seq_free_animdata(Scene *scene, Sequence *seq) FCurve *next_fcu = fcu->next; BLI_remlink(&scene->adt->action->curves, fcu); - free_fcurve(fcu); + BKE_fcurve_free(fcu); fcu = next_fcu; } @@ -5775,7 +5825,7 @@ void BKE_sequence_base_dupli_recursive(const Scene *scene_src, Sequence *seqn = NULL; Sequence *last_seq = BKE_sequencer_active_get((Scene *)scene_src); /* always include meta's strips */ - int dupe_flag_recursive = dupe_flag | SEQ_DUPE_ALL; + int dupe_flag_recursive = dupe_flag | SEQ_DUPE_ALL | SEQ_DUPE_IS_RECURSIVE_CALL; for (seq = seqbase->first; seq; seq = seq->next) { seq->tmp = NULL; @@ -5801,6 +5851,12 @@ void BKE_sequence_base_dupli_recursive(const Scene *scene_src, } } + /* Fix modifier links recursively from the top level only, when all sequences have been + * copied. */ + if (dupe_flag & SEQ_DUPE_IS_RECURSIVE_CALL) { + return; + } + /* fix modifier linking */ for (seq = nseqbase->first; seq; seq = seq->next) { seq_new_fix_links_recursive(seq); @@ -5921,3 +5977,62 @@ void BKE_sequencer_all_free_anim_ibufs(Scene *scene, int cfra) sequencer_all_free_anim_ibufs(&ed->seqbase, cfra); BKE_sequencer_cache_cleanup(scene); } + +static bool sequencer_seq_generates_image(Sequence *seq) +{ + switch (seq->type) { + case SEQ_TYPE_IMAGE: + case SEQ_TYPE_SCENE: + case SEQ_TYPE_MOVIE: + case SEQ_TYPE_MOVIECLIP: + case SEQ_TYPE_MASK: + case SEQ_TYPE_COLOR: + case SEQ_TYPE_TEXT: + return true; + } + return false; +} + +static Sequence *sequencer_check_scene_recursion(Scene *scene, ListBase *seqbase) +{ + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + if (seq->type == SEQ_TYPE_SCENE && seq->scene == scene) { + return seq; + } + + if (seq->type == SEQ_TYPE_META && sequencer_check_scene_recursion(scene, &seq->seqbase)) { + return seq; + } + } + + return NULL; +} + +bool BKE_sequencer_check_scene_recursion(Scene *scene, ReportList *reports) +{ + Editing *ed = BKE_sequencer_editing_get(scene, false); + if (ed == NULL) { + return false; + } + + Sequence *recursive_seq = sequencer_check_scene_recursion(scene, &ed->seqbase); + + if (recursive_seq != NULL) { + BKE_reportf(reports, + RPT_WARNING, + "Recursion detected in video sequencer. Strip %s at frame %d will not be rendered", + recursive_seq->name + 2, + recursive_seq->startdisp); + + LISTBASE_FOREACH (Sequence *, seq, &ed->seqbase) { + if (seq->type != SEQ_TYPE_SCENE && sequencer_seq_generates_image(seq)) { + /* There are other strips to render, so render them. */ + return false; + } + } + /* No other strips to render - cancel operator. */ + return true; + } + + return false; +} |