diff options
Diffstat (limited to 'source/blender/blenkernel/intern/sequencer.c')
-rw-r--r-- | source/blender/blenkernel/intern/sequencer.c | 332 |
1 files changed, 240 insertions, 92 deletions
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index f0e59eda321..c82f3a3af23 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -47,6 +47,7 @@ #include "BLI_math.h" #include "BLI_fileops.h" #include "BLI_listbase.h" +#include "BLI_linklist.h" #include "BLI_path_util.h" #include "BLI_string.h" #include "BLI_string_utf8.h" @@ -91,12 +92,21 @@ # include AUD_SPECIAL_H #endif -static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seqbasep, float cfra, int chanshown); -static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, float cfra); +/* mutable state for sequencer */ +typedef struct SeqRenderState { + LinkNode *scene_parents; +} SeqRenderState; + +static ImBuf *seq_render_strip_stack( + const SeqRenderData *context, SeqRenderState *state, ListBase *seqbasep, + float cfra, int chanshown); +static ImBuf *seq_render_strip( + const SeqRenderData *context, SeqRenderState *state, + Sequence *seq, float cfra); static void seq_free_animdata(Scene *scene, Sequence *seq); static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr, bool make_float); -static size_t seq_num_files(Scene *scene, char views_format, const bool is_multiview); -static void seq_anim_add_suffix(Scene *scene, struct anim *anim, const size_t view_id); +static int seq_num_files(Scene *scene, char views_format, const bool is_multiview); +static void seq_anim_add_suffix(Scene *scene, struct anim *anim, const int view_id); /* **** XXX ******** */ #define SELECT 1 @@ -117,6 +127,11 @@ static void printf_strip(Sequence *seq) } #endif +static void sequencer_state_init(SeqRenderState *state) +{ + state->scene_parents = NULL; +} + int BKE_sequencer_base_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg) { Sequence *iseq; @@ -198,7 +213,7 @@ static void BKE_sequence_free_ex(Scene *scene, Sequence *seq, const bool do_cach } if (seq->sound) { - ((ID *)seq->sound)->us--; + id_us_min(((ID *)seq->sound)); } if (seq->stereo3d_format) { @@ -563,6 +578,9 @@ void BKE_sequencer_new_render_data( r_context->skip_cache = false; r_context->is_proxy_render = false; r_context->view_id = 0; + r_context->gpu_offscreen = NULL; + r_context->gpu_samples = (scene->r.mode & R_OSA) ? scene->r.osa : 0; + r_context->gpu_full_samples = (r_context->gpu_samples) && (scene->r.scemode & R_FULL_SAMPLE); } /* ************************* iterator ************************** */ @@ -797,8 +815,9 @@ void BKE_sequence_calc(Scene *scene, Sequence *seq) } } -static void seq_multiview_name(Scene *scene, const size_t view_id, const char *prefix, - const char *ext, char *r_path, size_t r_size) +static void seq_multiview_name( + Scene *scene, const int view_id, const char *prefix, const char *ext, + char *r_path, size_t r_size) { const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, view_id); BLI_snprintf(r_path, r_size, "%s%s%s", prefix, suffix, ext); @@ -855,7 +874,7 @@ void BKE_sequence_reload_new_file(Scene *scene, Sequence *seq, const bool lock_r if (is_multiview && (seq->views_format == R_IMF_VIEWS_INDIVIDUAL)) { char prefix[FILE_MAX]; const char *ext = NULL; - size_t totfiles = seq_num_files(scene, seq->views_format, true); + const int totfiles = seq_num_files(scene, seq->views_format, true); int i = 0; BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext); @@ -1013,6 +1032,15 @@ void BKE_sequencer_sort(Scene *scene) *(ed->seqbasep) = seqbase; } +/** Comparision function suitable to be used with BLI_listbase_sort()... */ +int BKE_sequencer_cmp_time_startdisp(const void *a, const void *b) +{ + const Sequence *seq_a = a; + const Sequence *seq_b = b; + + return (seq_a->startdisp > seq_b->startdisp); +} + static int clear_scene_in_allseqs_cb(Sequence *seq, void *arg_pt) { if (seq->scene == (Scene *)arg_pt) @@ -1136,6 +1164,33 @@ const char *BKE_sequence_give_name(Sequence *seq) return name; } +ListBase *BKE_sequence_seqbase_get(Sequence *seq, int *r_offset) +{ + ListBase *seqbase = NULL; + + switch (seq->type) { + case SEQ_TYPE_META: + { + seqbase = &seq->seqbase; + *r_offset = seq->start; + break; + } + case SEQ_TYPE_SCENE: + { + if (seq->flag & SEQ_SCENE_STRIPS) { + Editing *ed = BKE_sequencer_editing_get(seq->scene, false); + if (ed) { + seqbase = &ed->seqbase; + *r_offset = seq->scene->r.sfra; + } + } + break; + } + } + + return seqbase; +} + /*********************** DO THE SEQUENCE *************************/ static void make_black_ibuf(ImBuf *ibuf) @@ -1372,7 +1427,7 @@ typedef struct SeqIndexBuildContext { int size_flags; int quality; bool overwrite; - size_t view_id; + int view_id; Main *bmain; Scene *scene; @@ -1413,7 +1468,7 @@ static double seq_rendersize_to_scale_factor(int size) } /* the number of files will vary according to the stereo format */ -static size_t seq_num_files(Scene *scene, char views_format, const bool is_multiview) +static int seq_num_files(Scene *scene, char views_format, const bool is_multiview) { if (!is_multiview) { return 1; @@ -1478,7 +1533,7 @@ static void seq_open_anim_file(Scene *scene, Sequence *seq, bool openfile) } if (is_multiview && seq->views_format == R_IMF_VIEWS_INDIVIDUAL) { - size_t totfiles = seq_num_files(scene, seq->views_format, true); + int totfiles = seq_num_files(scene, seq->views_format, true); char prefix[FILE_MAX]; const char *ext = NULL; int i; @@ -1561,7 +1616,7 @@ static void seq_open_anim_file(Scene *scene, Sequence *seq, bool openfile) } } -static bool seq_proxy_get_fname(Editing *ed, Sequence *seq, int cfra, int render_size, char *name, const size_t view_id) +static bool seq_proxy_get_fname(Editing *ed, Sequence *seq, int cfra, int render_size, char *name, const int view_id) { int frameno; char dir[PROXY_MAXFILE]; @@ -1619,7 +1674,7 @@ static bool seq_proxy_get_fname(Editing *ed, Sequence *seq, int cfra, int render } if (view_id > 0) - BLI_snprintf(suffix, sizeof(suffix), "_%zu", view_id); + BLI_snprintf(suffix, sizeof(suffix), "_%d", view_id); if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE && sanim && sanim->anim && ed->proxy_storage != SEQ_EDIT_PROXY_DIR_STORAGE) @@ -1716,8 +1771,10 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c } } -static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, int cfra, - int proxy_render_size, const bool overwrite) +static void seq_proxy_build_frame( + const SeqRenderData *context, SeqRenderState *state, + Sequence *seq, int cfra, + int proxy_render_size, const bool overwrite) { char name[PROXY_MAXFILE]; int quality; @@ -1734,7 +1791,7 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i return; } - ibuf_tmp = seq_render_strip(context, seq, cfra); + ibuf_tmp = seq_render_strip(context, state, seq, cfra); rectx = (proxy_render_size * ibuf_tmp->x) / 100; recty = (proxy_render_size * ibuf_tmp->y) / 100; @@ -1771,7 +1828,7 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i /* returns whether the file this context would read from even exist, if not, don't create the context */ -static bool seq_proxy_multiview_context_invalid(Sequence *seq, Scene *scene, const size_t view_id) +static bool seq_proxy_multiview_context_invalid(Sequence *seq, Scene *scene, const int view_id) { if ((scene->r.scemode & R_MULTIVIEW) == 0) return false; @@ -1807,9 +1864,9 @@ static bool seq_proxy_multiview_context_invalid(Sequence *seq, Scene *scene, con /** This returns the maximum possible number of required contexts */ -static size_t seq_proxy_context_count(Sequence *seq, Scene *scene) +static int seq_proxy_context_count(Sequence *seq, Scene *scene) { - size_t num_views = 1; + int num_views = 1; if ((scene->r.scemode & R_MULTIVIEW) == 0) return 1; @@ -1847,8 +1904,8 @@ void BKE_sequencer_proxy_rebuild_context(Main *bmain, Scene *scene, Sequence *se SeqIndexBuildContext *context; Sequence *nseq; LinkData *link; - size_t i; - size_t num_files; + int num_files; + int i; if (!seq->strip || !seq->strip->proxy) { return; @@ -1936,18 +1993,21 @@ void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, sho render_context.is_proxy_render = true; render_context.view_id = context->view_id; + SeqRenderState state; + sequencer_state_init(&state); + for (cfra = seq->startdisp + seq->startstill; cfra < seq->enddisp - seq->endstill; cfra++) { if (context->size_flags & IMB_PROXY_25) { - seq_proxy_build_frame(&render_context, seq, cfra, 25, overwrite); + seq_proxy_build_frame(&render_context, &state, seq, cfra, 25, overwrite); } if (context->size_flags & IMB_PROXY_50) { - seq_proxy_build_frame(&render_context, seq, cfra, 50, overwrite); + seq_proxy_build_frame(&render_context, &state, seq, cfra, 50, overwrite); } if (context->size_flags & IMB_PROXY_75) { - seq_proxy_build_frame(&render_context, seq, cfra, 75, overwrite); + seq_proxy_build_frame(&render_context, &state, seq, cfra, 75, overwrite); } if (context->size_flags & IMB_PROXY_100) { - seq_proxy_build_frame(&render_context, seq, cfra, 100, overwrite); + seq_proxy_build_frame(&render_context, &state, seq, cfra, 100, overwrite); } *progress = (float) (cfra - seq->startdisp - seq->startstill) / (seq->enddisp - seq->endstill - seq->startdisp - seq->startstill); @@ -2256,7 +2316,10 @@ ImBuf *BKE_sequencer_render_mask_input( if (mask_input_type == SEQUENCE_MASK_INPUT_STRIP) { if (mask_sequence) { - mask_input = seq_render_strip(context, mask_sequence, cfra); + SeqRenderState state; + sequencer_state_init(&state); + + mask_input = seq_render_strip(context, &state, mask_sequence, cfra); if (make_float) { if (!mask_input->rect_float) @@ -2617,7 +2680,9 @@ static ImBuf *seq_render_effect_execute_threaded(struct SeqEffectHandle *sh, con return out; } -static ImBuf *seq_render_effect_strip_impl(const SeqRenderData *context, Sequence *seq, float cfra) +static ImBuf *seq_render_effect_strip_impl( + const SeqRenderData *context, SeqRenderState *state, + Sequence *seq, float cfra) { Scene *scene = context->scene; float fac, facf; @@ -2667,7 +2732,7 @@ static ImBuf *seq_render_effect_strip_impl(const SeqRenderData *context, Sequenc case EARLY_DO_EFFECT: for (i = 0; i < 3; i++) { if (input[i]) - ibuf[i] = seq_render_strip(context, input[i], cfra); + ibuf[i] = seq_render_strip(context, state, input[i], cfra); } if (ibuf[0] && ibuf[1]) { @@ -2679,7 +2744,7 @@ static ImBuf *seq_render_effect_strip_impl(const SeqRenderData *context, Sequenc break; case EARLY_USE_INPUT_1: if (input[0]) { - ibuf[0] = seq_render_strip(context, input[0], cfra); + ibuf[0] = seq_render_strip(context, state, input[0], cfra); } if (ibuf[0]) { if (BKE_sequencer_input_have_to_preprocess(context, seq, cfra)) { @@ -2693,7 +2758,7 @@ static ImBuf *seq_render_effect_strip_impl(const SeqRenderData *context, Sequenc break; case EARLY_USE_INPUT_2: if (input[1]) { - ibuf[1] = seq_render_strip(context, input[1], cfra); + ibuf[1] = seq_render_strip(context, state, input[1], cfra); } if (ibuf[1]) { if (BKE_sequencer_input_have_to_preprocess(context, seq, cfra)) { @@ -2740,8 +2805,8 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context, Sequence *seq /* don't do anything */ } else if (is_multiview) { - size_t totfiles = seq_num_files(context->scene, seq->views_format, true); - size_t totviews; + const int totfiles = seq_num_files(context->scene, seq->views_format, true); + int totviews; struct ImBuf **ibufs_arr; char prefix[FILE_MAX]; const char *ext = NULL; @@ -2842,8 +2907,8 @@ static ImBuf *seq_render_movie_strip(const SeqRenderData *context, Sequence *seq if (is_multiview) { ImBuf **ibuf_arr; - size_t totviews; - size_t totfiles = seq_num_files(context->scene, seq->views_format, true); + const int totfiles = seq_num_files(context->scene, seq->views_format, true); + int totviews; int i; if (totfiles != BLI_listbase_count_ex(&seq->anims, totfiles + 1)) @@ -3009,6 +3074,7 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr return NULL; } else { + AnimData *adt; Mask *mask_temp; MaskRasterHandle *mr_handle; @@ -3016,6 +3082,10 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr BKE_mask_evaluate(mask_temp, mask->sfra + nr, true); + /* anim-data */ + adt = BKE_animdata_from_id(&mask->id); + BKE_animsys_evaluate_animdata(context->scene, &mask_temp->id, adt, nr, ADT_RECALC_ANIM); + maskbuf = MEM_mallocN(sizeof(float) * context->rectx * context->recty, __func__); mr_handle = BKE_maskrasterize_handle_new(); @@ -3189,26 +3259,31 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq char err_out[256] = "unknown"; int width = (scene->r.xsch * scene->r.size) / 100; int height = (scene->r.ysch * scene->r.size) / 100; + const bool use_background = (scene->r.alphamode == R_ADDSKY); const char *viewname = BKE_scene_multiview_render_view_name_get(&scene->r, context->view_id); - /* for old scened this can be uninitialized, + /* for old scene this can be uninitialized, * should probably be added to do_versions at some point if the functionality stays */ if (context->scene->r.seq_prev_type == 0) context->scene->r.seq_prev_type = 3 /* == OB_SOLID */; /* opengl offscreen render */ BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene, scene->lay); - ibuf = sequencer_view3d_cb(scene, camera, width, height, IB_rect, - context->scene->r.seq_prev_type, - (context->scene->r.seq_flag & R_SEQ_SOLID_TEX) != 0, - use_gpencil, true, scene->r.alphamode, viewname, err_out); + ibuf = sequencer_view3d_cb( + /* set for OpenGL render (NULL when scrubbing) */ + scene, camera, width, height, IB_rect, + context->scene->r.seq_prev_type, + (context->scene->r.seq_flag & R_SEQ_SOLID_TEX) != 0, + use_gpencil, use_background, scene->r.alphamode, + context->gpu_samples, context->gpu_full_samples, viewname, + context->gpu_fx, context->gpu_offscreen, err_out); if (ibuf == NULL) { fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out); } } else { Render *re = RE_GetRender(scene->id.name); - size_t totviews = BKE_scene_multiview_num_views_get(&scene->r); + const int totviews = BKE_scene_multiview_num_views_get(&scene->r); int i; ImBuf **ibufs_arr; @@ -3276,8 +3351,6 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq } } MEM_freeN(ibufs_arr); - - // BIF_end_render_callbacks(); } @@ -3299,7 +3372,43 @@ finally: return ibuf; } -static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *seq, float cfra) +/** + * Used for meta-strips & scenes with #SEQ_SCENE_STRIPS flag set. + */ +static ImBuf *do_render_strip_seqbase( + const SeqRenderData *context, SeqRenderState *state, + Sequence *seq, float nr, bool use_preprocess) +{ + ImBuf *meta_ibuf = NULL, *ibuf = NULL; + ListBase *seqbase = NULL; + int offset; + + seqbase = BKE_sequence_seqbase_get(seq, &offset); + + if (seqbase && !BLI_listbase_is_empty(seqbase)) { + meta_ibuf = seq_render_strip_stack( + context, state, seqbase, + /* scene strips don't have their start taken into account */ + nr + offset, 0); + } + + if (meta_ibuf) { + ibuf = meta_ibuf; + if (ibuf && use_preprocess) { + ImBuf *i = IMB_dupImBuf(ibuf); + + IMB_freeImBuf(ibuf); + + ibuf = i; + } + } + + return ibuf; +} + +static ImBuf *do_render_strip_uncached( + const SeqRenderData *context, SeqRenderState *state, + Sequence *seq, float cfra) { ImBuf *ibuf = NULL; float nr = give_stripelem_index(seq, cfra); @@ -3309,22 +3418,37 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s switch (type) { case SEQ_TYPE_META: { - ImBuf *meta_ibuf = NULL; - - if (seq->seqbase.first) - meta_ibuf = seq_render_strip_stack(context, &seq->seqbase, seq->start + nr, 0); + ibuf = do_render_strip_seqbase(context, state, seq, nr, use_preprocess); + break; + } - if (meta_ibuf) { - ibuf = meta_ibuf; - if (ibuf && use_preprocess) { - ImBuf *i = IMB_dupImBuf(ibuf); + case SEQ_TYPE_SCENE: + { + if (seq->flag & SEQ_SCENE_STRIPS) { + if (seq->scene && (context->scene != seq->scene)) { + /* recusrive check */ + if (BLI_linklist_index(state->scene_parents, seq->scene) != -1) { + break; + } + LinkNode scene_parent = {.next = state->scene_parents, .link = seq->scene}; + state->scene_parents = &scene_parent; + /* end check */ - IMB_freeImBuf(ibuf); + ibuf = do_render_strip_seqbase(context, state, seq, nr, use_preprocess); - ibuf = i; + /* step back in the list */ + state->scene_parents = state->scene_parents->next; } } + else { + /* scene can be NULL after deletions */ + ibuf = seq_render_scene_strip(context, seq, nr, cfra); + + /* Scene strips update all animation, so we need to restore original state.*/ + BKE_animsys_evaluate_all_animation(context->bmain, context->scene, cfra); + copy_to_ibuf_still(context, seq, nr, ibuf); + } break; } @@ -3340,7 +3464,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s /* weeek! */ f_cfra = seq->start + s->frameMap[(int)nr]; - child_ibuf = seq_render_strip(context, seq->seq1, f_cfra); + child_ibuf = seq_render_strip(context, state, seq->seq1, f_cfra); if (child_ibuf) { ibuf = child_ibuf; @@ -3357,7 +3481,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s case SEQ_TYPE_EFFECT: { - ibuf = seq_render_effect_strip_impl(context, seq, seq->start + nr); + ibuf = seq_render_effect_strip_impl(context, state, seq, seq->start + nr); break; } @@ -3375,18 +3499,6 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s break; } - case SEQ_TYPE_SCENE: - { - /* scene can be NULL after deletions */ - ibuf = seq_render_scene_strip(context, seq, nr, cfra); - - /* Scene strips update all animation, so we need to restore original state.*/ - BKE_animsys_evaluate_all_animation(context->bmain, context->scene, cfra); - - copy_to_ibuf_still(context, seq, nr, ibuf); - break; - } - case SEQ_TYPE_MOVIECLIP: { ibuf = seq_render_movieclip_strip(context, seq, nr); @@ -3408,7 +3520,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s case SEQ_TYPE_MASK: { - /* ibuf is alwats new */ + /* ibuf is always new */ ibuf = seq_render_mask_strip(context, seq, nr); copy_to_ibuf_still(context, seq, nr, ibuf); @@ -3422,7 +3534,9 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s return ibuf; } -static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, float cfra) +static ImBuf *seq_render_strip( + const SeqRenderData *context, SeqRenderState *state, + Sequence *seq, float cfra) { ImBuf *ibuf = NULL; bool use_preprocess = false; @@ -3430,7 +3544,7 @@ static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, floa float nr = give_stripelem_index(seq, cfra); /* all effects are handled similarly with the exception of speed effect */ int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT : seq->type; - bool is_preprocessed = !ELEM(type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE); + bool is_preprocessed = !ELEM(type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIECLIP); ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF); @@ -3448,7 +3562,7 @@ static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, floa } if (ibuf == NULL) - ibuf = do_render_strip_uncached(context, seq, cfra); + ibuf = do_render_strip_uncached(context, state, seq, cfra); if (ibuf) { if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP)) { @@ -3549,7 +3663,9 @@ static ImBuf *seq_render_strip_stack_apply_effect(const SeqRenderData *context, return out; } -static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seqbasep, float cfra, int chanshown) +static ImBuf *seq_render_strip_stack( + const SeqRenderData *context, SeqRenderState *state, ListBase *seqbasep, + float cfra, int chanshown) { Sequence *seq_arr[MAXSEQ + 1]; int count; @@ -3592,13 +3708,13 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seq } if (ELEM(early_out, EARLY_NO_INPUT, EARLY_USE_INPUT_2)) { - out = seq_render_strip(context, seq, cfra); + out = seq_render_strip(context, state, seq, cfra); } else if (early_out == EARLY_USE_INPUT_1) { out = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); } else { - out = seq_render_strip(context, seq, cfra); + out = seq_render_strip(context, state, seq, cfra); if (early_out == EARLY_DO_EFFECT) { ImBuf *ibuf1 = IMB_allocImBuf(context->rectx, context->recty, 32, @@ -3606,8 +3722,9 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seq ImBuf *ibuf2 = out; out = seq_render_strip_stack_apply_effect(context, seq, cfra, ibuf1, ibuf2); - - IMB_metadata_copy(out, ibuf2); + if (out) { + IMB_metadata_copy(out, ibuf2); + } IMB_freeImBuf(ibuf1); IMB_freeImBuf(ibuf2); @@ -3615,7 +3732,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seq } } else { - out = seq_render_strip(context, seq, cfra); + out = seq_render_strip(context, state, seq, cfra); } BKE_sequencer_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF_COMP, out); @@ -3633,7 +3750,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seq break; } if (seq->blend_mode == SEQ_BLEND_REPLACE) { - out = seq_render_strip(context, seq, cfra); + out = seq_render_strip(context, state, seq, cfra); break; } @@ -3642,7 +3759,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seq switch (early_out) { case EARLY_NO_INPUT: case EARLY_USE_INPUT_2: - out = seq_render_strip(context, seq, cfra); + out = seq_render_strip(context, state, seq, cfra); break; case EARLY_USE_INPUT_1: if (i == 0) { @@ -3652,7 +3769,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seq case EARLY_DO_EFFECT: if (i == 0) { ImBuf *ibuf1 = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); - ImBuf *ibuf2 = seq_render_strip(context, seq, cfra); + ImBuf *ibuf2 = seq_render_strip(context, state, seq, cfra); out = seq_render_strip_stack_apply_effect(context, seq, cfra, ibuf1, ibuf2); @@ -3676,7 +3793,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seq if (seq_get_early_out_for_blend_mode(seq) == EARLY_DO_EFFECT) { ImBuf *ibuf1 = out; - ImBuf *ibuf2 = seq_render_strip(context, seq, cfra); + ImBuf *ibuf2 = seq_render_strip(context, state, seq, cfra); out = seq_render_strip_stack_apply_effect(context, seq, cfra, ibuf1, ibuf2); @@ -3711,18 +3828,27 @@ ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int cha seqbasep = ed->seqbasep; } - return seq_render_strip_stack(context, seqbasep, cfra, chanshown); + SeqRenderState state; + sequencer_state_init(&state); + + return seq_render_strip_stack(context, &state, seqbasep, cfra, chanshown); } ImBuf *BKE_sequencer_give_ibuf_seqbase(const SeqRenderData *context, float cfra, int chanshown, ListBase *seqbasep) { - return seq_render_strip_stack(context, seqbasep, cfra, chanshown); + SeqRenderState state; + sequencer_state_init(&state); + + return seq_render_strip_stack(context, &state, seqbasep, cfra, chanshown); } ImBuf *BKE_sequencer_give_ibuf_direct(const SeqRenderData *context, float cfra, Sequence *seq) { - return seq_render_strip(context, seq, cfra); + SeqRenderState state; + sequencer_state_init(&state); + + return seq_render_strip(context, &state, seq, cfra); } /* *********************** threading api ******************* */ @@ -4232,6 +4358,17 @@ bool BKE_sequence_tx_test(Sequence *seq) return !(seq->type & SEQ_TYPE_EFFECT) || (BKE_sequence_effect_get_num_inputs(seq->type) == 0); } +/** + * Return \a true if given \a seq needs a complete cleanup of its cache when it is transformed. + * + * Some (effect) strip types need a complete recache of themselves when they are transformed, because + * they do not 'contain' anything and do not have any explicit relations to other strips. + */ +bool BKE_sequence_tx_fullupdate_test(Sequence *seq) +{ + return BKE_sequence_tx_test(seq) && ELEM(seq->type, SEQ_TYPE_ADJUSTMENT, SEQ_TYPE_MULTICAM); +} + static bool seq_overlap(Sequence *seq1, Sequence *seq2) { return (seq1 != seq2 && seq1->machine == seq2->machine && @@ -4317,7 +4454,7 @@ bool BKE_sequence_base_shuffle_ex(ListBase *seqbasep, Sequence *test, Scene *evi test->machine += channel_delta; BKE_sequence_calc(evil_scene, test); while (BKE_sequence_test_overlap(seqbasep, test)) { - if ((channel_delta > 0) ? (test->machine >= MAXSEQ) : (test->machine <= 1)) { + if ((channel_delta > 0) ? (test->machine >= MAXSEQ) : (test->machine < 1)) { break; } @@ -4866,7 +5003,7 @@ Mask *BKE_sequencer_mask_get(Scene *scene) /* api like funcs for adding */ -static void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load) +static void seq_load_apply(Main *bmain, Scene *scene, Sequence *seq, SeqLoadInfo *seq_load) { if (seq) { BLI_strncpy_utf8(seq->name + 2, seq_load->name, sizeof(seq->name) - 2); @@ -4882,6 +5019,11 @@ static void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load) BKE_sequencer_active_set(scene, seq); } + if (seq_load->flag & SEQ_LOAD_SOUND_MONO) { + seq->sound->flags |= SOUND_FLAGS_MONO; + BKE_sound_load(bmain, seq->sound); + } + if (seq_load->flag & SEQ_LOAD_SOUND_CACHE) { if (seq->sound) BKE_sound_cache(seq->sound); @@ -4979,7 +5121,7 @@ Sequence *BKE_sequencer_add_image_strip(bContext *C, ListBase *seqbasep, SeqLoad seq->views_format = seq_load->views_format; seq->flag |= seq_load->flag & SEQ_USE_VIEWS; - seq_load_apply(scene, seq, seq_load); + seq_load_apply(CTX_data_main(C), scene, seq, seq_load); return seq; } @@ -5029,7 +5171,8 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad /* basic defaults */ seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); - seq->len = (int)ceil((double)info.length * FPS); + /* We add a very small negative offset here, because ceil(132.0) == 133.0, not nice with videos, see T47135. */ + seq->len = (int)ceil((double)info.length * FPS - 1e-4); strip->us = 1; /* we only need 1 element to store the filename */ @@ -5044,7 +5187,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad /* last active name */ BLI_strncpy(ed->act_sounddir, strip->dir, FILE_MAXDIR); - seq_load_apply(scene, seq, seq_load); + seq_load_apply(bmain, scene, seq, seq_load); return seq; } @@ -5058,7 +5201,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad } #endif // WITH_AUDASPACE -static void seq_anim_add_suffix(Scene *scene, struct anim *anim, const size_t view_id) +static void seq_anim_add_suffix(Scene *scene, struct anim *anim, const int view_id) { const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, view_id); IMB_suffix_anim(anim, suffix); @@ -5075,7 +5218,7 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad char colorspace[64] = "\0"; /* MAX_COLORSPACE_NAME */ bool is_multiview_loaded = false; const bool is_multiview = (seq_load->flag & SEQ_USE_VIEWS) != 0; - size_t totfiles = seq_num_files(scene, seq_load->views_format, is_multiview); + const int totfiles = seq_num_files(scene, seq_load->views_format, is_multiview); struct anim **anim_arr; int i; @@ -5147,6 +5290,11 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad seq->anim_preseek = IMB_anim_get_preseek(anim_arr[0]); BLI_strncpy(seq->name + 2, "Movie", SEQ_NAME_MAXSTR - 2); BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); + + /* adjust scene's frame rate settings to match */ + if (seq_load->flag & SEQ_LOAD_SYNC_FPS) { + IMB_anim_get_fps(anim_arr[0], &scene->r.frs_sec, &scene->r.frs_sec_base, true); + } /* basic defaults */ seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); @@ -5176,7 +5324,7 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad } /* can be NULL */ - seq_load_apply(scene, seq, seq_load); + seq_load_apply(CTX_data_main(C), scene, seq, seq_load); MEM_freeN(anim_arr); return seq; |