diff options
Diffstat (limited to 'source')
28 files changed, 918 insertions, 738 deletions
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 83ce5e72794..f3edf8e9f64 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -264,14 +264,6 @@ void BKE_scene_cursor_from_mat4(struct View3DCursor *cursor, const float mat[4][4], bool use_compat); -/* Dependency graph evaluation. */ - -/* Evaluate parts of sequences which needs to be done as a part of a dependency graph evaluation. - * This does NOT include actual rendering of the strips, but rather makes them up-to-date for - * animation playback and makes them ready for the sequencer's rendering pipeline to render them. - */ -void BKE_scene_eval_sequencer_sequences(struct Depsgraph *depsgraph, struct Scene *scene); - #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c index 70274de8bff..1684e22dece 100644 --- a/source/blender/blenkernel/intern/bpath.c +++ b/source/blender/blenkernel/intern/bpath.c @@ -534,6 +534,46 @@ static bool rewrite_path_alloc(char **path, return false; } +typedef struct Seq_callback_data { + const char *absbase; + void *bpath_user_data; + BPathVisitor visit_cb; + const int flag; +} Seq_callback_data; + +static bool seq_rewrite_path_callback(Sequence *seq, void *user_data) +{ + if (SEQ_HAS_PATH(seq)) { + StripElem *se = seq->strip->stripdata; + Seq_callback_data *cd = (Seq_callback_data *)user_data; + + if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM) && se) { + rewrite_path_fixed_dirfile( + seq->strip->dir, se->name, cd->visit_cb, cd->absbase, cd->bpath_user_data); + } + else if ((seq->type == SEQ_TYPE_IMAGE) && se) { + /* might want an option not to loop over all strips */ + unsigned int len = (unsigned int)MEM_allocN_len(se) / (unsigned int)sizeof(*se); + unsigned int i; + + if (cd->flag & BKE_BPATH_TRAVERSE_SKIP_MULTIFILE) { + /* only operate on one path */ + len = MIN2(1u, len); + } + + for (i = 0; i < len; i++, se++) { + rewrite_path_fixed_dirfile( + seq->strip->dir, se->name, cd->visit_cb, cd->absbase, cd->bpath_user_data); + } + } + else { + /* simple case */ + rewrite_path_fixed(seq->strip->dir, cd->visit_cb, cd->absbase, cd->bpath_user_data); + } + } + return true; +} + /** * Run visitor function 'visit' on all paths contained in 'id'. */ @@ -701,38 +741,8 @@ void BKE_bpath_traverse_id( case ID_SCE: { Scene *scene = (Scene *)id; if (scene->ed) { - Sequence *seq; - - SEQ_ALL_BEGIN (scene->ed, seq) { - if (SEQ_HAS_PATH(seq)) { - StripElem *se = seq->strip->stripdata; - - if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM) && se) { - rewrite_path_fixed_dirfile( - seq->strip->dir, se->name, visit_cb, absbase, bpath_user_data); - } - else if ((seq->type == SEQ_TYPE_IMAGE) && se) { - /* might want an option not to loop over all strips */ - unsigned int len = (unsigned int)MEM_allocN_len(se) / (unsigned int)sizeof(*se); - unsigned int i; - - if (flag & BKE_BPATH_TRAVERSE_SKIP_MULTIFILE) { - /* only operate on one path */ - len = MIN2(1u, len); - } - - for (i = 0; i < len; i++, se++) { - rewrite_path_fixed_dirfile( - seq->strip->dir, se->name, visit_cb, absbase, bpath_user_data); - } - } - else { - /* simple case */ - rewrite_path_fixed(seq->strip->dir, visit_cb, absbase, bpath_user_data); - } - } - } - SEQ_ALL_END; + Seq_callback_data user_data = {absbase, bpath_user_data, visit_cb, flag}; + SEQ_for_each_callback(&scene->ed->seqbase, seq_rewrite_path_callback, &user_data); } break; } diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 8a70f065e40..aac081991e3 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -2038,6 +2038,58 @@ static void nlastrips_to_animdata(ID *id, ListBase *strips) } } +typedef struct Seq_callback_data { + Main *bmain; + Scene *scene; + AnimData *adt; +} Seq_callback_data; + +static bool seq_convert_callback(Sequence *seq, void *userdata) +{ + IpoCurve *icu = (seq->ipo) ? seq->ipo->curve.first : NULL; + short adrcode = SEQ_FAC1; + + if (G.debug & G_DEBUG) { + printf("\tconverting sequence strip %s\n", seq->name + 2); + } + + if (ELEM(NULL, seq->ipo, icu)) { + seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE; + return true; + } + + /* patch adrcode, so that we can map + * to different DNA variables later + * (semi-hack (tm) ) + */ + switch (seq->type) { + case SEQ_TYPE_IMAGE: + case SEQ_TYPE_META: + case SEQ_TYPE_SCENE: + case SEQ_TYPE_MOVIE: + case SEQ_TYPE_COLOR: + adrcode = SEQ_FAC_OPACITY; + break; + case SEQ_TYPE_SPEED: + adrcode = SEQ_FAC_SPEED; + break; + } + icu->adrcode = adrcode; + + Seq_callback_data *cd = (Seq_callback_data *)userdata; + + /* convert IPO */ + ipo_to_animdata(cd->bmain, (ID *)cd->scene, seq->ipo, NULL, NULL, seq); + + if (cd->adt->action) { + cd->adt->action->idroot = ID_SCE; /* scene-rooted */ + } + + id_us_min(&seq->ipo->id); + seq->ipo = NULL; + return true; +} + /* *************************************************** */ /* External API - Only Called from do_versions() */ @@ -2286,52 +2338,8 @@ void do_versions_ipos_to_animato(Main *bmain) Scene *scene = (Scene *)id; Editing *ed = scene->ed; if (ed && ed->seqbasep) { - Sequence *seq; - - AnimData *adt = BKE_animdata_ensure_id(id); - - SEQ_ALL_BEGIN (ed, seq) { - IpoCurve *icu = (seq->ipo) ? seq->ipo->curve.first : NULL; - short adrcode = SEQ_FAC1; - - if (G.debug & G_DEBUG) { - printf("\tconverting sequence strip %s\n", seq->name + 2); - } - - if (ELEM(NULL, seq->ipo, icu)) { - seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE; - continue; - } - - /* patch adrcode, so that we can map - * to different DNA variables later - * (semi-hack (tm) ) - */ - switch (seq->type) { - case SEQ_TYPE_IMAGE: - case SEQ_TYPE_META: - case SEQ_TYPE_SCENE: - case SEQ_TYPE_MOVIE: - case SEQ_TYPE_COLOR: - adrcode = SEQ_FAC_OPACITY; - break; - case SEQ_TYPE_SPEED: - adrcode = SEQ_FAC_SPEED; - break; - } - icu->adrcode = adrcode; - - /* convert IPO */ - ipo_to_animdata(bmain, (ID *)scene, seq->ipo, NULL, NULL, seq); - - if (adt->action) { - adt->action->idroot = ID_SCE; /* scene-rooted */ - } - - id_us_min(&seq->ipo->id); - seq->ipo = NULL; - } - SEQ_ALL_END; + Seq_callback_data cb_data = {bmain, scene, BKE_animdata_ensure_id(id)}; + SEQ_for_each_callback(&ed->seqbase, seq_convert_callback, &cb_data); } } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 5a668746956..de82f0832d8 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -113,11 +113,7 @@ #include "SEQ_edit.h" #include "SEQ_iterator.h" -#include "SEQ_modifier.h" -#include "SEQ_proxy.h" -#include "SEQ_relations.h" #include "SEQ_sequencer.h" -#include "SEQ_sound.h" #include "BLO_read_write.h" @@ -702,6 +698,40 @@ static void scene_foreach_layer_collection(LibraryForeachIDData *data, ListBase } } +static bool seq_foreach_member_id_cb(Sequence *seq, void *user_data) +{ + LibraryForeachIDData *data = (LibraryForeachIDData *)user_data; + +#define FOREACHID_PROCESS(_data, _id_super, _cb_flag) \ + { \ + CHECK_TYPE(&((_id_super)->id), ID *); \ + if (!BKE_lib_query_foreachid_process((_data), (ID **)&(_id_super), (_cb_flag))) { \ + return false; \ + } \ + } \ + ((void)0) + + FOREACHID_PROCESS(data, seq->scene, IDWALK_CB_NEVER_SELF); + FOREACHID_PROCESS(data, seq->scene_camera, IDWALK_CB_NOP); + FOREACHID_PROCESS(data, seq->clip, IDWALK_CB_USER); + FOREACHID_PROCESS(data, seq->mask, IDWALK_CB_USER); + FOREACHID_PROCESS(data, seq->sound, IDWALK_CB_USER); + IDP_foreach_property( + seq->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data); + LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) { + FOREACHID_PROCESS(data, smd->mask_id, IDWALK_CB_USER); + } + + if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) { + TextVars *text_data = seq->effectdata; + FOREACHID_PROCESS(data, text_data->text_font, IDWALK_CB_USER); + } + +#undef FOREACHID_PROCESS + + return true; +} + static void scene_foreach_id(ID *id, LibraryForeachIDData *data) { Scene *scene = (Scene *)id; @@ -717,25 +747,7 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data) BKE_library_foreach_ID_embedded(data, (ID **)&scene->nodetree); } if (scene->ed) { - Sequence *seq; - SEQ_ALL_BEGIN (scene->ed, seq) { - BKE_LIB_FOREACHID_PROCESS(data, seq->scene, IDWALK_CB_NEVER_SELF); - BKE_LIB_FOREACHID_PROCESS(data, seq->scene_camera, IDWALK_CB_NOP); - BKE_LIB_FOREACHID_PROCESS(data, seq->clip, IDWALK_CB_USER); - BKE_LIB_FOREACHID_PROCESS(data, seq->mask, IDWALK_CB_USER); - BKE_LIB_FOREACHID_PROCESS(data, seq->sound, IDWALK_CB_USER); - IDP_foreach_property( - seq->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data); - LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) { - BKE_LIB_FOREACHID_PROCESS(data, smd->mask_id, IDWALK_CB_USER); - } - - if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) { - TextVars *text_data = seq->effectdata; - BKE_LIB_FOREACHID_PROCESS(data, text_data->text_font, IDWALK_CB_USER); - } - } - SEQ_ALL_END; + SEQ_for_each_callback(&scene->ed->seqbase, seq_foreach_member_id_cb, data); } /* This pointer can be NULL during old files reading, better be safe than sorry. */ @@ -883,87 +895,9 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres Editing *ed = sce->ed; if (ed) { - Sequence *seq; - BLO_write_struct(writer, Editing, ed); - /* reset write flags too */ - - SEQ_ALL_BEGIN (ed, seq) { - if (seq->strip) { - seq->strip->done = false; - } - BLO_write_struct(writer, Sequence, seq); - } - SEQ_ALL_END; - - SEQ_ALL_BEGIN (ed, seq) { - if (seq->strip && seq->strip->done == 0) { - /* write strip with 'done' at 0 because readfile */ - - if (seq->effectdata) { - switch (seq->type) { - case SEQ_TYPE_COLOR: - BLO_write_struct(writer, SolidColorVars, seq->effectdata); - break; - case SEQ_TYPE_SPEED: - BLO_write_struct(writer, SpeedControlVars, seq->effectdata); - break; - case SEQ_TYPE_WIPE: - BLO_write_struct(writer, WipeVars, seq->effectdata); - break; - case SEQ_TYPE_GLOW: - BLO_write_struct(writer, GlowVars, seq->effectdata); - break; - case SEQ_TYPE_TRANSFORM: - BLO_write_struct(writer, TransformVars, seq->effectdata); - break; - case SEQ_TYPE_GAUSSIAN_BLUR: - BLO_write_struct(writer, GaussianBlurVars, seq->effectdata); - break; - case SEQ_TYPE_TEXT: - BLO_write_struct(writer, TextVars, seq->effectdata); - break; - case SEQ_TYPE_COLORMIX: - BLO_write_struct(writer, ColorMixVars, seq->effectdata); - break; - } - } - - BLO_write_struct(writer, Stereo3dFormat, seq->stereo3d_format); - - Strip *strip = seq->strip; - BLO_write_struct(writer, Strip, strip); - if (strip->crop) { - BLO_write_struct(writer, StripCrop, strip->crop); - } - if (strip->transform) { - BLO_write_struct(writer, StripTransform, strip->transform); - } - if (strip->proxy) { - BLO_write_struct(writer, StripProxy, strip->proxy); - } - if (seq->type == SEQ_TYPE_IMAGE) { - BLO_write_struct_array(writer, - StripElem, - MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem), - strip->stripdata); - } - else if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) { - BLO_write_struct(writer, StripElem, strip->stripdata); - } - - strip->done = true; - } - - if (seq->prop) { - IDP_BlendWrite(writer, seq->prop); - } - - SEQ_modifier_blend_write(writer, &seq->modifiers); - } - SEQ_ALL_END; - + SEQ_blend_write(writer, &ed->seqbase); /* new; meta stack too, even when its nasty restore code */ LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) { BLO_write_struct(writer, MetaStack, ms); @@ -1155,66 +1089,8 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id) /* recursive link sequences, lb will be correctly initialized */ link_recurs_seq(reader, &ed->seqbase); - Sequence *seq; - SEQ_ALL_BEGIN (ed, seq) { - /* Do as early as possible, so that other parts of reading can rely on valid session UUID. */ - SEQ_relations_session_uuid_generate(seq); - - BLO_read_data_address(reader, &seq->seq1); - BLO_read_data_address(reader, &seq->seq2); - BLO_read_data_address(reader, &seq->seq3); - - /* a patch: after introduction of effects with 3 input strips */ - if (seq->seq3 == NULL) { - seq->seq3 = seq->seq2; - } - - BLO_read_data_address(reader, &seq->effectdata); - BLO_read_data_address(reader, &seq->stereo3d_format); - - if (seq->type & SEQ_TYPE_EFFECT) { - seq->flag |= SEQ_EFFECT_NOT_LOADED; - } - - if (seq->type == SEQ_TYPE_TEXT) { - TextVars *t = seq->effectdata; - t->text_blf_id = SEQ_FONT_NOT_LOADED; - } - - BLO_read_data_address(reader, &seq->prop); - IDP_BlendDataRead(reader, &seq->prop); - - BLO_read_data_address(reader, &seq->strip); - if (seq->strip && seq->strip->done == 0) { - seq->strip->done = true; - - if (ELEM(seq->type, - SEQ_TYPE_IMAGE, - SEQ_TYPE_MOVIE, - SEQ_TYPE_SOUND_RAM, - SEQ_TYPE_SOUND_HD)) { - BLO_read_data_address(reader, &seq->strip->stripdata); - } - else { - seq->strip->stripdata = NULL; - } - BLO_read_data_address(reader, &seq->strip->crop); - BLO_read_data_address(reader, &seq->strip->transform); - BLO_read_data_address(reader, &seq->strip->proxy); - if (seq->strip->proxy) { - seq->strip->proxy->anim = NULL; - } - else if (seq->flag & SEQ_USE_PROXY) { - SEQ_proxy_set(seq, true); - } - - /* need to load color balance to it could be converted to modifier */ - BLO_read_data_address(reader, &seq->strip->color_balance); - } - - SEQ_modifier_blend_read_data(reader, &seq->modifiers); - } - SEQ_ALL_END; + /* Read in sequence member data. */ + SEQ_blend_read(reader, &ed->seqbase); /* link metastack, slight abuse of structs here, * have to restore pointer to internal part in struct */ @@ -1461,50 +1337,9 @@ static void scene_blend_read_lib(BlendLibReader *reader, ID *id) } } - Sequence *seq; - SEQ_ALL_BEGIN (sce->ed, seq) { - IDP_BlendReadLib(reader, seq->prop); - - if (seq->ipo) { - /* XXX: deprecated - old animation system. */ - BLO_read_id_address(reader, sce->id.lib, &seq->ipo); - } - seq->scene_sound = NULL; - if (seq->scene) { - BLO_read_id_address(reader, sce->id.lib, &seq->scene); - seq->scene_sound = NULL; - } - if (seq->clip) { - BLO_read_id_address(reader, sce->id.lib, &seq->clip); - } - if (seq->mask) { - BLO_read_id_address(reader, sce->id.lib, &seq->mask); - } - if (seq->scene_camera) { - BLO_read_id_address(reader, sce->id.lib, &seq->scene_camera); - } - if (seq->sound) { - seq->scene_sound = NULL; - if (seq->type == SEQ_TYPE_SOUND_HD) { - seq->type = SEQ_TYPE_SOUND_RAM; - } - else { - BLO_read_id_address(reader, sce->id.lib, &seq->sound); - } - if (seq->sound) { - id_us_plus_no_lib((ID *)seq->sound); - seq->scene_sound = NULL; - } - } - if (seq->type == SEQ_TYPE_TEXT) { - TextVars *t = seq->effectdata; - BLO_read_id_address(reader, sce->id.lib, &t->text_font); - } - BLI_listbase_clear(&seq->anims); - - SEQ_modifier_blend_read_lib(reader, sce, &seq->modifiers); + if (sce->ed) { + SEQ_blend_read_lib(reader, sce, &sce->ed->seqbase); } - SEQ_ALL_END; LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) { IDP_BlendReadLib(reader, marker->prop); @@ -1619,33 +1454,7 @@ static void scene_blend_read_expand(BlendExpander *expander, ID *id) } if (sce->ed) { - Sequence *seq; - - SEQ_ALL_BEGIN (sce->ed, seq) { - IDP_BlendReadExpand(expander, seq->prop); - - if (seq->scene) { - BLO_expand(expander, seq->scene); - } - if (seq->scene_camera) { - BLO_expand(expander, seq->scene_camera); - } - if (seq->clip) { - BLO_expand(expander, seq->clip); - } - if (seq->mask) { - BLO_expand(expander, seq->mask); - } - if (seq->sound) { - BLO_expand(expander, seq->sound); - } - - if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) { - TextVars *data = seq->effectdata; - BLO_expand(expander, data->text_font); - } - } - SEQ_ALL_END; + SEQ_blend_read_expand(expander, &sce->ed->seqbase); } if (sce->rigidbody_world) { @@ -3781,69 +3590,3 @@ void BKE_scene_cursor_from_mat4(View3DCursor *cursor, const float mat[4][4], boo } /** \} */ - -/* Dependency graph evaluation. */ - -static void scene_sequencer_disable_sound_strips(Scene *scene) -{ - if (scene->sound_scene == NULL) { - return; - } - Sequence *seq; - SEQ_ALL_BEGIN (scene->ed, seq) { - if (seq->scene_sound != NULL) { - BKE_sound_remove_scene_sound(scene, seq->scene_sound); - seq->scene_sound = NULL; - } - } - SEQ_ALL_END; -} - -void BKE_scene_eval_sequencer_sequences(Depsgraph *depsgraph, Scene *scene) -{ - DEG_debug_print_eval(depsgraph, __func__, scene->id.name, scene); - if (scene->ed == NULL) { - return; - } - BKE_sound_ensure_scene(scene); - Sequence *seq; - SEQ_ALL_BEGIN (scene->ed, seq) { - if (seq->scene_sound == NULL) { - if (seq->sound != NULL) { - seq->scene_sound = BKE_sound_add_scene_sound_defaults(scene, seq); - } - else if (seq->type == SEQ_TYPE_SCENE) { - if (seq->scene != NULL) { - BKE_sound_ensure_scene(seq->scene); - seq->scene_sound = BKE_sound_scene_add_scene_sound_defaults(scene, seq); - } - } - } - if (seq->scene_sound != NULL) { - /* Make sure changing volume via sequence's properties panel works correct. - * - * Ideally, the entire BKE_scene_update_sound() will happen from a dependency graph, so - * then it is no longer needed to do such manual forced updates. */ - if (seq->type == SEQ_TYPE_SCENE && seq->scene != NULL) { - BKE_sound_set_scene_volume(seq->scene, seq->scene->audio.volume); - if ((seq->flag & SEQ_SCENE_STRIPS) == 0) { - scene_sequencer_disable_sound_strips(seq->scene); - } - } - if (seq->sound != NULL) { - if (scene->id.recalc & ID_RECALC_AUDIO || seq->sound->id.recalc & ID_RECALC_AUDIO) { - BKE_sound_update_scene_sound(seq->scene_sound, seq->sound); - } - } - 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_pan( - seq->scene_sound, seq->pan, (seq->flag & SEQ_AUDIO_PAN_ANIMATED) != 0); - } - } - SEQ_ALL_END; - SEQ_edit_update_muting(scene->ed); - SEQ_sound_update_bounds_all(scene); -} diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 49c3497f996..2ee66206878 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2419,7 +2419,7 @@ static void lib_link_seq_clipboard_pt_restore(ID *id, struct IDNameLib_Map *id_m id->newid = restore_pointer_by_name(id_map, id->newid, USER_REAL); } } -static int lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt) +static bool lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt) { struct IDNameLib_Map *id_map = arg_pt; @@ -2428,13 +2428,13 @@ static int lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt) lib_link_seq_clipboard_pt_restore((ID *)seq->clip, id_map); lib_link_seq_clipboard_pt_restore((ID *)seq->mask, id_map); lib_link_seq_clipboard_pt_restore((ID *)seq->sound, id_map); - return 1; + return true; } static void lib_link_clipboard_restore(struct IDNameLib_Map *id_map) { /* update IDs stored in sequencer clipboard */ - SEQ_seqbase_recursive_apply(&seqbase_clipboard, lib_link_seq_clipboard_cb, id_map); + SEQ_for_each_callback(&seqbase_clipboard, lib_link_seq_clipboard_cb, id_map); } static int lib_link_main_data_restore_cb(LibraryIDLinkCallbackData *cb_data) diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 436645c2241..54e673b51eb 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -638,6 +638,46 @@ static void do_versions_socket_default_value_259(bNodeSocket *sock) } } +static bool seq_sound_proxy_update_cb(Sequence *seq, void *user_data) +{ + Main *bmain = (Main *)user_data; + if (seq->type == SEQ_TYPE_SOUND_HD) { + char str[FILE_MAX]; + BLI_join_dirfile(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name); + BLI_path_abs(str, BKE_main_blendfile_path(bmain)); + seq->sound = BKE_sound_new_file(bmain, str); + } +#define SEQ_USE_PROXY_CUSTOM_DIR (1 << 19) +#define SEQ_USE_PROXY_CUSTOM_FILE (1 << 21) + /* don't know, if anybody used that this way, but just in case, upgrade to new way... */ + if ((seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) && !(seq->flag & SEQ_USE_PROXY_CUSTOM_DIR)) { + BLI_snprintf(seq->strip->proxy->dir, FILE_MAXDIR, "%s/BL_proxy", seq->strip->dir); + } +#undef SEQ_USE_PROXY_CUSTOM_DIR +#undef SEQ_USE_PROXY_CUSTOM_FILE + return true; +} + +static bool seq_set_volume_cb(Sequence *seq, void *UNUSED(user_data)) +{ + seq->volume = 1.0f; + return true; +} + +static bool seq_set_sat_cb(Sequence *seq, void *UNUSED(user_data)) +{ + if (seq->sat == 0.0f) { + seq->sat = 1.0f; + } + return true; +} + +static bool seq_set_pitch_cb(Sequence *seq, void *UNUSED(user_data)) +{ + seq->pitch = 1.0f; + return true; +} + /* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) { @@ -660,7 +700,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) #endif bSound *sound; - Sequence *seq; for (sound = bmain->sounds.first; sound; sound = sound->id.next) { if (sound->newpackedfile) { @@ -671,23 +710,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) for (scene = bmain->scenes.first; scene; scene = scene->id.next) { if (scene->ed && scene->ed->seqbasep) { - SEQ_ALL_BEGIN (scene->ed, seq) { - if (seq->type == SEQ_TYPE_SOUND_HD) { - char str[FILE_MAX]; - BLI_join_dirfile(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name); - BLI_path_abs(str, BKE_main_blendfile_path(bmain)); - seq->sound = BKE_sound_new_file(bmain, str); - } -#define SEQ_USE_PROXY_CUSTOM_DIR (1 << 19) -#define SEQ_USE_PROXY_CUSTOM_FILE (1 << 21) - /* don't know, if anybody used that this way, but just in case, upgrade to new way... */ - if ((seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) && !(seq->flag & SEQ_USE_PROXY_CUSTOM_DIR)) { - BLI_snprintf(seq->strip->proxy->dir, FILE_MAXDIR, "%s/BL_proxy", seq->strip->dir); - } -#undef SEQ_USE_PROXY_CUSTOM_DIR -#undef SEQ_USE_PROXY_CUSTOM_FILE - } - SEQ_ALL_END; + SEQ_for_each_callback(&scene->ed->seqbase, seq_sound_proxy_update_cb, bmain); } } @@ -1391,7 +1414,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 250, 17)) { Scene *sce; - Sequence *seq; /* initialize to sane default so toggling on border shows something */ for (sce = bmain->scenes.first; sce; sce = sce->id.next) { @@ -1406,11 +1428,9 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if ((sce->r.ffcodecdata.flags & FFMPEG_MULTIPLEX_AUDIO) == 0) { sce->r.ffcodecdata.audio_codec = 0x0; /* `CODEC_ID_NONE` */ } - - SEQ_ALL_BEGIN (sce->ed, seq) { - seq->volume = 1.0f; + if (sce->ed) { + SEQ_for_each_callback(&sce->ed->seqbase, seq_set_volume_cb, NULL); } - SEQ_ALL_END; } /* particle brush strength factor was changed from int to float */ @@ -1678,13 +1698,9 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) } for (scene = bmain->scenes.first; scene; scene = scene->id.next) { - Sequence *seq; - SEQ_ALL_BEGIN (scene->ed, seq) { - if (seq->sat == 0.0f) { - seq->sat = 1.0f; - } + if (scene->ed) { + SEQ_for_each_callback(&scene->ed->seqbase, seq_set_sat_cb, NULL); } - SEQ_ALL_END; } /* GSOC 2010 Sculpt - New settings for Brush */ @@ -2159,15 +2175,13 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 259, 1)) { { Scene *scene; - Sequence *seq; for (scene = bmain->scenes.first; scene; scene = scene->id.next) { scene->r.ffcodecdata.audio_channels = 2; scene->audio.volume = 1.0f; - SEQ_ALL_BEGIN (scene->ed, seq) { - seq->pitch = 1.0f; + if (scene->ed) { + SEQ_for_each_callback(&scene->ed->seqbase, seq_set_pitch_cb, NULL); } - SEQ_ALL_END; } } diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index 7c644fa3b55..b71dd5a27bb 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -663,6 +663,53 @@ static void do_versions_nodetree_customnodes(bNodeTree *ntree, int UNUSED(is_gro } } +static bool seq_colorbalance_update_cb(Sequence *seq, void *UNUSED(user_data)) +{ + Strip *strip = seq->strip; + + if (strip && strip->color_balance) { + SequenceModifierData *smd; + ColorBalanceModifierData *cbmd; + + smd = SEQ_modifier_new(seq, NULL, seqModifierType_ColorBalance); + cbmd = (ColorBalanceModifierData *)smd; + + cbmd->color_balance = *strip->color_balance; + + /* multiplication with color balance used is handled differently, + * so we need to move multiplication to modifier so files would be + * compatible + */ + cbmd->color_multiply = seq->mul; + seq->mul = 1.0f; + + MEM_freeN(strip->color_balance); + strip->color_balance = NULL; + } + return true; +} + +static bool seq_set_alpha_mode_cb(Sequence *seq, void *UNUSED(user_data)) +{ + enum { SEQ_MAKE_PREMUL = (1 << 6) }; + if (seq->flag & SEQ_MAKE_PREMUL) { + seq->alpha_mode = SEQ_ALPHA_STRAIGHT; + } + else { + SEQ_alpha_mode_from_file_extension(seq); + } + return true; +} + +static bool seq_set_wipe_angle_cb(Sequence *seq, void *UNUSED(user_data)) +{ + if (seq->type == SEQ_TYPE_WIPE) { + WipeVars *wv = seq->effectdata; + wv->angle = DEG2RADF(wv->angle); + } + return true; +} + /* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) { @@ -1492,32 +1539,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) for (scene = bmain->scenes.first; scene; scene = scene->id.next) { if (scene->ed) { - Sequence *seq; - - SEQ_ALL_BEGIN (scene->ed, seq) { - Strip *strip = seq->strip; - - if (strip && strip->color_balance) { - SequenceModifierData *smd; - ColorBalanceModifierData *cbmd; - - smd = SEQ_modifier_new(seq, NULL, seqModifierType_ColorBalance); - cbmd = (ColorBalanceModifierData *)smd; - - cbmd->color_balance = *strip->color_balance; - - /* multiplication with color balance used is handled differently, - * so we need to move multiplication to modifier so files would be - * compatible - */ - cbmd->color_multiply = seq->mul; - seq->mul = 1.0f; - - MEM_freeN(strip->color_balance); - strip->color_balance = NULL; - } - } - SEQ_ALL_END; + SEQ_for_each_callback(&scene->ed->seqbase, seq_colorbalance_update_cb, NULL); } } } @@ -1807,18 +1829,9 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) Tex *tex; for (scene = bmain->scenes.first; scene; scene = scene->id.next) { - Sequence *seq; - - SEQ_ALL_BEGIN (scene->ed, seq) { - enum { SEQ_MAKE_PREMUL = (1 << 6) }; - if (seq->flag & SEQ_MAKE_PREMUL) { - seq->alpha_mode = SEQ_ALPHA_STRAIGHT; - } - else { - SEQ_alpha_mode_from_file_extension(seq); - } + if (scene->ed) { + SEQ_for_each_callback(&scene->ed->seqbase, seq_set_alpha_mode_cb, NULL); } - SEQ_ALL_END; if (scene->r.bake_samples == 0) { scene->r.bake_samples = 256; @@ -2450,14 +2463,9 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (scene = bmain->scenes.first; scene; scene = scene->id.next) { - Sequence *seq; - SEQ_ALL_BEGIN (scene->ed, seq) { - if (seq->type == SEQ_TYPE_WIPE) { - WipeVars *wv = seq->effectdata; - wv->angle = DEG2RADF(wv->angle); - } + if (scene->ed) { + SEQ_for_each_callback(&scene->ed->seqbase, seq_set_wipe_angle_cb, NULL); } - SEQ_ALL_END; } FOREACH_NODETREE_BEGIN (bmain, ntree, id) { diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 1d46c0d5790..6492f0d1f69 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -425,6 +425,45 @@ static void do_version_bbone_easing_fcurve_fix(ID *UNUSED(id), } } +static bool seq_update_proxy_cb(Sequence *seq, void *UNUSED(user_data)) +{ + seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Stereo Display 3d Format"); + +#define SEQ_USE_PROXY_CUSTOM_DIR (1 << 19) +#define SEQ_USE_PROXY_CUSTOM_FILE (1 << 21) + if (seq->strip && seq->strip->proxy && !seq->strip->proxy->storage) { + if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) { + seq->strip->proxy->storage = SEQ_STORAGE_PROXY_CUSTOM_DIR; + } + if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { + seq->strip->proxy->storage = SEQ_STORAGE_PROXY_CUSTOM_FILE; + } + } +#undef SEQ_USE_PROXY_CUSTOM_DIR +#undef SEQ_USE_PROXY_CUSTOM_FILE + return true; +} + +static bool seq_update_effectdata_cb(Sequence *seq, void *UNUSED(user_data)) +{ + + if (seq->type != SEQ_TYPE_TEXT) { + return true; + } + + if (seq->effectdata == NULL) { + struct SeqEffectHandle effect_handle = SEQ_effect_handle_get(seq); + effect_handle.init(seq); + } + + TextVars *data = seq->effectdata; + if (data->color[3] == 0.0f) { + copy_v4_fl(data->color, 1.0f); + data->shadow_color[3] = 1.0f; + } + return true; +} + /* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) { @@ -908,8 +947,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) Image *ima; for (scene = bmain->scenes.first; scene; scene = scene->id.next) { - Sequence *seq; - BKE_scene_add_render_view(scene, STEREO_LEFT_NAME); srv = scene->r.views.first; BLI_strncpy(srv->suffix, STEREO_LEFT_SUFFIX, sizeof(srv->suffix)); @@ -918,23 +955,9 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) srv = scene->r.views.last; BLI_strncpy(srv->suffix, STEREO_RIGHT_SUFFIX, sizeof(srv->suffix)); - SEQ_ALL_BEGIN (scene->ed, seq) { - seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Stereo Display 3d Format"); - -#define SEQ_USE_PROXY_CUSTOM_DIR (1 << 19) -#define SEQ_USE_PROXY_CUSTOM_FILE (1 << 21) - if (seq->strip && seq->strip->proxy && !seq->strip->proxy->storage) { - if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) { - seq->strip->proxy->storage = SEQ_STORAGE_PROXY_CUSTOM_DIR; - } - if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { - seq->strip->proxy->storage = SEQ_STORAGE_PROXY_CUSTOM_FILE; - } - } -#undef SEQ_USE_PROXY_CUSTOM_DIR -#undef SEQ_USE_PROXY_CUSTOM_FILE + if (scene->ed) { + SEQ_for_each_callback(&scene->ed->seqbase, seq_update_proxy_cb, NULL); } - SEQ_ALL_END; } for (screen = bmain->screens.first; screen; screen = screen->id.next) { @@ -1215,25 +1238,9 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { - Sequence *seq; - - SEQ_ALL_BEGIN (scene->ed, seq) { - if (seq->type != SEQ_TYPE_TEXT) { - continue; - } - - if (seq->effectdata == NULL) { - struct SeqEffectHandle effect_handle = SEQ_effect_handle_get(seq); - effect_handle.init(seq); - } - - TextVars *data = seq->effectdata; - if (data->color[3] == 0.0f) { - copy_v4_fl(data->color, 1.0f); - data->shadow_color[3] = 1.0f; - } + if (scene->ed) { + SEQ_for_each_callback(&scene->ed->seqbase, seq_update_effectdata_cb, NULL); } - SEQ_ALL_END; } /* Adding "Properties" region to DopeSheet */ diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 9d65488e8d4..f77d0361e51 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1772,6 +1772,16 @@ static void do_versions_seq_set_cache_defaults(Editing *ed) ed->recycle_max_cost = 10.0f; } +static bool seq_update_flags_cb(Sequence *seq, void *UNUSED(user_data)) +{ + seq->flag &= ~(SEQ_FLAG_UNUSED_6 | SEQ_FLAG_UNUSED_18 | SEQ_FLAG_UNUSED_19 | SEQ_FLAG_UNUSED_21); + if (seq->type == SEQ_TYPE_SPEED) { + SpeedControlVars *s = (SpeedControlVars *)seq->effectdata; + s->flags &= ~(SEQ_SPEED_UNUSED_1); + } + return true; +} + /* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) { @@ -3447,16 +3457,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (scene->ed) { - Sequence *seq; - SEQ_ALL_BEGIN (scene->ed, seq) { - seq->flag &= ~(SEQ_FLAG_UNUSED_6 | SEQ_FLAG_UNUSED_18 | SEQ_FLAG_UNUSED_19 | - SEQ_FLAG_UNUSED_21); - if (seq->type == SEQ_TYPE_SPEED) { - SpeedControlVars *s = (SpeedControlVars *)seq->effectdata; - s->flags &= ~(SEQ_SPEED_UNUSED_1); - } - } - SEQ_ALL_END; + SEQ_for_each_callback(&scene->ed->seqbase, seq_update_flags_cb, NULL); } } diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index 6ba27b6ee9e..62cc2aa3662 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -482,6 +482,22 @@ void blo_do_version_old_trackto_to_constraints(Object *ob) ob->track = NULL; } +static bool seq_set_alpha_mode_cb(Sequence *seq, void *UNUSED(user_data)) +{ + if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { + seq->alpha_mode = SEQ_ALPHA_STRAIGHT; + } + return true; +} + +static bool seq_set_blend_mode_cb(Sequence *seq, void *UNUSED(user_data)) +{ + if (seq->blend_mode == 0) { + seq->blend_opacity = 100.0f; + } + return true; +} + /* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) { @@ -1228,7 +1244,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) if (bmain->versionfile <= 235) { Tex *tex = bmain->textures.first; Scene *sce = bmain->scenes.first; - Sequence *seq; Editing *ed; while (tex) { @@ -1240,12 +1255,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) while (sce) { ed = sce->ed; if (ed) { - SEQ_ALL_BEGIN (sce->ed, seq) { - if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { - seq->alpha_mode = SEQ_ALPHA_STRAIGHT; - } - } - SEQ_ALL_END; + SEQ_for_each_callback(&sce->ed->seqbase, seq_set_alpha_mode_cb, NULL); } sce = sce->id.next; @@ -2404,15 +2414,11 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 245, 14)) { Scene *sce; - Sequence *seq; for (sce = bmain->scenes.first; sce; sce = sce->id.next) { - SEQ_ALL_BEGIN (sce->ed, seq) { - if (seq->blend_mode == 0) { - seq->blend_opacity = 100.0f; - } + if (sce->ed) { + SEQ_for_each_callback(&sce->ed->seqbase, seq_set_blend_mode_cb, NULL); } - SEQ_ALL_END; } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 22bce10937d..a739a0fe337 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -112,6 +112,7 @@ #include "DEG_depsgraph_build.h" #include "SEQ_iterator.h" +#include "SEQ_sequencer.h" #include "intern/builder/deg_builder.h" #include "intern/builder/deg_builder_rna.h" @@ -2032,6 +2033,27 @@ void DepsgraphNodeBuilder::build_simulation(Simulation *simulation) }); } +static bool seq_node_build_cb(Sequence *seq, void *user_data) +{ + DepsgraphNodeBuilder *nb = (DepsgraphNodeBuilder *)user_data; + nb->build_idproperties(seq->prop); + if (seq->sound != nullptr) { + nb->build_sound(seq->sound); + } + if (seq->scene != nullptr) { + nb->build_scene_parameters(seq->scene); + } + if (seq->type == SEQ_TYPE_SCENE && seq->scene != nullptr) { + if (seq->flag & SEQ_SCENE_STRIPS) { + nb->build_scene_sequencer(seq->scene); + } + ViewLayer *sequence_view_layer = BKE_view_layer_default_render(seq->scene); + nb->build_scene_speakers(seq->scene, sequence_view_layer); + } + /* TODO(sergey): Movie clip, scene, camera, mask. */ + return true; +} + void DepsgraphNodeBuilder::build_scene_sequencer(Scene *scene) { if (scene->ed == nullptr) { @@ -2046,28 +2068,10 @@ void DepsgraphNodeBuilder::build_scene_sequencer(Scene *scene) NodeType::SEQUENCER, OperationCode::SEQUENCES_EVAL, [scene_cow](::Depsgraph *depsgraph) { - BKE_scene_eval_sequencer_sequences(depsgraph, scene_cow); + SEQ_eval_sequences(depsgraph, scene_cow, &scene_cow->ed->seqbase); }); /* Make sure data for sequences is in the graph. */ - Sequence *seq; - SEQ_ALL_BEGIN (scene->ed, seq) { - build_idproperties(seq->prop); - if (seq->sound != nullptr) { - build_sound(seq->sound); - } - if (seq->scene != nullptr) { - build_scene_parameters(seq->scene); - } - if (seq->type == SEQ_TYPE_SCENE && seq->scene != nullptr) { - if (seq->flag & SEQ_SCENE_STRIPS) { - build_scene_sequencer(seq->scene); - } - ViewLayer *sequence_view_layer = BKE_view_layer_default_render(seq->scene); - build_scene_speakers(seq->scene, sequence_view_layer); - } - /* TODO(sergey): Movie clip, scene, camera, mask. */ - } - SEQ_ALL_END; + SEQ_for_each_callback(&scene->ed->seqbase, seq_node_build_cb, this); } void DepsgraphNodeBuilder::build_scene_audio(Scene *scene) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index d88e9bc9c04..ab3081cb1ae 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -2769,6 +2769,45 @@ void DepsgraphRelationBuilder::build_simulation(Simulation *simulation) add_relation(nodetree_key, simulation_eval_key, "NodeTree -> Simulation", 0); } +using Seq_build_prop_cb_data = struct Seq_build_prop_cb_data { + DepsgraphRelationBuilder *builder; + ComponentKey sequencer_key; + bool has_audio_strips; +}; + +static bool seq_build_prop_cb(Sequence *seq, void *user_data) +{ + Seq_build_prop_cb_data *cd = (Seq_build_prop_cb_data *)user_data; + + cd->builder->build_idproperties(seq->prop); + if (seq->sound != nullptr) { + cd->builder->build_sound(seq->sound); + ComponentKey sound_key(&seq->sound->id, NodeType::AUDIO); + cd->builder->add_relation(sound_key, cd->sequencer_key, "Sound -> Sequencer"); + cd->has_audio_strips = true; + } + if (seq->scene != nullptr) { + cd->builder->build_scene_parameters(seq->scene); + /* This is to support 3D audio. */ + cd->has_audio_strips = true; + } + if (seq->type == SEQ_TYPE_SCENE && seq->scene != nullptr) { + if (seq->flag & SEQ_SCENE_STRIPS) { + cd->builder->build_scene_sequencer(seq->scene); + ComponentKey sequence_scene_audio_key(&seq->scene->id, NodeType::AUDIO); + cd->builder->add_relation( + sequence_scene_audio_key, cd->sequencer_key, "Sequence Scene Audio -> Sequencer"); + ComponentKey sequence_scene_key(&seq->scene->id, NodeType::SEQUENCER); + cd->builder->add_relation( + sequence_scene_key, cd->sequencer_key, "Sequence Scene -> Sequencer"); + } + ViewLayer *sequence_view_layer = BKE_view_layer_default_render(seq->scene); + cd->builder->build_scene_speakers(seq->scene, sequence_view_layer); + } + /* TODO(sergey): Movie clip, camera, mask. */ + return true; +} + void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene) { if (scene->ed == nullptr) { @@ -2781,36 +2820,11 @@ void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene) ComponentKey scene_audio_key(&scene->id, NodeType::AUDIO); /* Make sure dependencies from sequences data goes to the sequencer evaluation. */ ComponentKey sequencer_key(&scene->id, NodeType::SEQUENCER); - Sequence *seq; - bool has_audio_strips = false; - SEQ_ALL_BEGIN (scene->ed, seq) { - build_idproperties(seq->prop); - if (seq->sound != nullptr) { - build_sound(seq->sound); - ComponentKey sound_key(&seq->sound->id, NodeType::AUDIO); - add_relation(sound_key, sequencer_key, "Sound -> Sequencer"); - has_audio_strips = true; - } - if (seq->scene != nullptr) { - build_scene_parameters(seq->scene); - /* This is to support 3D audio. */ - has_audio_strips = true; - } - if (seq->type == SEQ_TYPE_SCENE && seq->scene != nullptr) { - if (seq->flag & SEQ_SCENE_STRIPS) { - build_scene_sequencer(seq->scene); - ComponentKey sequence_scene_audio_key(&seq->scene->id, NodeType::AUDIO); - add_relation(sequence_scene_audio_key, sequencer_key, "Sequence Scene Audio -> Sequencer"); - ComponentKey sequence_scene_key(&seq->scene->id, NodeType::SEQUENCER); - add_relation(sequence_scene_key, sequencer_key, "Sequence Scene -> Sequencer"); - } - ViewLayer *sequence_view_layer = BKE_view_layer_default_render(seq->scene); - build_scene_speakers(seq->scene, sequence_view_layer); - } - /* TODO(sergey): Movie clip, camera, mask. */ - } - SEQ_ALL_END; - if (has_audio_strips) { + + Seq_build_prop_cb_data cb_data = {this, sequencer_key, false}; + + SEQ_for_each_callback(&scene->ed->seqbase, seq_build_prop_cb, &cb_data); + if (cb_data.has_audio_strips) { add_relation(sequencer_key, scene_audio_key, "Sequencer -> Audio"); } } diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc index 34c23740730..166ca37bc35 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc @@ -38,33 +38,43 @@ SequencerBackup::SequencerBackup(const Depsgraph *depsgraph) : depsgraph(depsgra { } +static bool seq_init_cb(Sequence *seq, void *user_data) +{ + SequencerBackup *sb = (SequencerBackup *)user_data; + SequenceBackup sequence_backup(sb->depsgraph); + sequence_backup.init_from_sequence(seq); + if (!sequence_backup.isEmpty()) { + const SessionUUID &session_uuid = seq->runtime.session_uuid; + BLI_assert(BLI_session_uuid_is_generated(&session_uuid)); + sb->sequences_backup.add(session_uuid, sequence_backup); + } + return true; +} + void SequencerBackup::init_from_scene(Scene *scene) { - Sequence *sequence; - SEQ_ALL_BEGIN (scene->ed, sequence) { - SequenceBackup sequence_backup(depsgraph); - sequence_backup.init_from_sequence(sequence); - if (!sequence_backup.isEmpty()) { - const SessionUUID &session_uuid = sequence->runtime.session_uuid; - BLI_assert(BLI_session_uuid_is_generated(&session_uuid)); - sequences_backup.add(session_uuid, sequence_backup); - } + if (scene->ed != nullptr) { + SEQ_for_each_callback(&scene->ed->seqbase, seq_init_cb, this); } - SEQ_ALL_END; +} + +static bool seq_restore_cb(Sequence *seq, void *user_data) +{ + SequencerBackup *sb = (SequencerBackup *)user_data; + const SessionUUID &session_uuid = seq->runtime.session_uuid; + BLI_assert(BLI_session_uuid_is_generated(&session_uuid)); + SequenceBackup *sequence_backup = sb->sequences_backup.lookup_ptr(session_uuid); + if (sequence_backup != nullptr) { + sequence_backup->restore_to_sequence(seq); + } + return true; } void SequencerBackup::restore_to_scene(Scene *scene) { - Sequence *sequence; - SEQ_ALL_BEGIN (scene->ed, sequence) { - const SessionUUID &session_uuid = sequence->runtime.session_uuid; - BLI_assert(BLI_session_uuid_is_generated(&session_uuid)); - SequenceBackup *sequence_backup = sequences_backup.lookup_ptr(session_uuid); - if (sequence_backup != nullptr) { - sequence_backup->restore_to_sequence(sequence); - } + if (scene->ed != nullptr) { + SEQ_for_each_callback(&scene->ed->seqbase, seq_restore_cb, this); } - SEQ_ALL_END; /* Cleanup audio while the scene is still known. */ for (SequenceBackup &sequence_backup : sequences_backup.values()) { if (sequence_backup.scene_sound != nullptr) { diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index fe0a53ae964..85f6647ddd0 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -207,7 +207,7 @@ static void SOUND_OT_open_mono(wmOperatorType *ot) static void sound_update_animation_flags(Scene *scene); -static int sound_update_animation_flags_fn(Sequence *seq, void *user_data) +static bool sound_update_animation_flags_fn(Sequence *seq, void *user_data) { struct FCurve *fcu; Scene *scene = (Scene *)user_data; @@ -244,24 +244,22 @@ static int sound_update_animation_flags_fn(Sequence *seq, void *user_data) sound_update_animation_flags(seq->scene); } - return 0; + return true; } static void sound_update_animation_flags(Scene *scene) { struct FCurve *fcu; bool driven; - Sequence *seq; if (scene->id.tag & LIB_TAG_DOIT) { return; } scene->id.tag |= LIB_TAG_DOIT; - SEQ_ALL_BEGIN (scene->ed, seq) { - SEQ_recursive_apply(seq, sound_update_animation_flags_fn, scene); + if (scene->ed != NULL) { + SEQ_for_each_callback(&scene->ed->seqbase, sound_update_animation_flags_fn, scene); } - SEQ_ALL_END; fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven); if (fcu || driven) { diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 694e5fbb41d..935bc97d0b2 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2980,6 +2980,22 @@ static int sequencer_export_subtitles_invoke(bContext *C, return OPERATOR_RUNNING_MODAL; } +typedef struct Seq_get_text_cb_data { + ListBase *text_seq; + Scene *scene; +} Seq_get_text_cb_data; + +static bool seq_get_text_strip_cb(Sequence *seq, void *user_data) +{ + Seq_get_text_cb_data *cd = (Seq_get_text_cb_data *)user_data; + /* Only text strips that are not muted and don't end with negative frame. */ + if ((seq->type == SEQ_TYPE_TEXT) && ((seq->flag & SEQ_MUTE) == 0) && + (seq->enddisp > cd->scene->r.sfra)) { + BLI_addtail(cd->text_seq, MEM_dupallocN(seq)); + } + return true; +} + static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); @@ -3011,14 +3027,10 @@ static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - /* Only text strips that are not muted and don't end with negative frame. */ - SEQ_ALL_BEGIN (ed, seq) { - if ((seq->type == SEQ_TYPE_TEXT) && ((seq->flag & SEQ_MUTE) == 0) && - (seq->enddisp > scene->r.sfra)) { - BLI_addtail(&text_seq, MEM_dupallocN(seq)); - } + if (ed != NULL) { + Seq_get_text_cb_data cb_data = {&text_seq, scene}; + SEQ_for_each_callback(&ed->seqbase, seq_get_text_strip_cb, &cb_data); } - SEQ_ALL_END; if (BLI_listbase_is_empty(&text_seq)) { BKE_report(op->reports, RPT_ERROR, "No subtitles (text strips) to export"); diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 8b2ac2ed22d..119ef3ff971 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -1185,6 +1185,14 @@ static void colormanage_check_colorspace_settings( (void)what; } +static bool seq_callback(Sequence *seq, void *UNUSED(user_data)) +{ + if (seq->strip) { + colormanage_check_colorspace_settings(&seq->strip->colorspace_settings, "sequencer strip"); + } + return true; +} + void IMB_colormanagement_check_file_config(Main *bmain) { Scene *scene; @@ -1217,13 +1225,9 @@ void IMB_colormanagement_check_file_config(Main *bmain) } /* check sequencer strip input color space settings */ - Sequence *seq; - SEQ_ALL_BEGIN (scene->ed, seq) { - if (seq->strip) { - colormanage_check_colorspace_settings(&seq->strip->colorspace_settings, "sequencer strip"); - } + if (scene->ed != NULL) { + SEQ_for_each_callback(&scene->ed->seqbase, seq_callback, NULL); } - SEQ_ALL_END; } /* ** check input color space settings ** */ diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 5f198a8ed4c..1ac6dd021e9 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -597,6 +597,27 @@ static const EnumPropertyItem *rna_ColorManagedColorspaceSettings_colorspace_ite return items; } +typedef struct Seq_colorspace_cb_data { + ColorManagedColorspaceSettings *colorspace_settings; + Sequence *r_seq; +} Seq_colorspace_cb_data; + +static bool seq_find_colorspace_settings_cb(Sequence *seq, void *user_data) +{ + Seq_colorspace_cb_data *cd = (Seq_colorspace_cb_data *)user_data; + if (seq->strip && &seq->strip->colorspace_settings == cd->colorspace_settings) { + cd->r_seq = seq; + return false; + } + return true; +} + +static bool seq_free_anim_cb(Sequence *seq, void *UNUSED(user_data)) +{ + SEQ_relations_sequence_free_anim(seq); + return true; +} + static void rna_ColorManagedColorspaceSettings_reload_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) @@ -629,20 +650,14 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *bmain, if (scene->ed) { ColorManagedColorspaceSettings *colorspace_settings = (ColorManagedColorspaceSettings *) ptr->data; - Sequence *seq; - bool seq_found = false; + Seq_colorspace_cb_data cb_data = {colorspace_settings, NULL}; if (&scene->sequencer_colorspace_settings != colorspace_settings) { - SEQ_ALL_BEGIN (scene->ed, seq) { - if (seq->strip && &seq->strip->colorspace_settings == colorspace_settings) { - seq_found = true; - break; - } - } - SEQ_ALL_END; + SEQ_for_each_callback(&scene->ed->seqbase, seq_find_colorspace_settings_cb, &cb_data); } + Sequence *seq = cb_data.r_seq; - if (seq_found) { + if (seq) { SEQ_relations_sequence_free_anim(seq); if (seq->strip->proxy && seq->strip->proxy->anim) { @@ -653,10 +668,7 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *bmain, SEQ_relations_invalidate_cache_raw(scene, seq); } else { - SEQ_ALL_BEGIN (scene->ed, seq) { - SEQ_relations_sequence_free_anim(seq); - } - SEQ_ALL_END; + SEQ_for_each_callback(&scene->ed->seqbase, seq_free_anim_cb, NULL); } WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL); diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index dad77b4aad5..9dee7bc841c 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -495,15 +495,15 @@ static void rna_Sequence_use_proxy_set(PointerRNA *ptr, bool value) SEQ_proxy_set(seq, value != 0); } -static int transform_seq_cmp_fn(Sequence *seq, void *arg_pt) +static bool transform_seq_cmp_fn(Sequence *seq, void *arg_pt) { SequenceSearchData *data = arg_pt; if (seq->strip && seq->strip->transform == data->data) { data->seq = seq; - return -1; /* done so bail out */ + return false; /* done so bail out */ } - return 1; + return true; } static Sequence *sequence_get_by_transform(Editing *ed, StripTransform *transform) @@ -514,7 +514,7 @@ static Sequence *sequence_get_by_transform(Editing *ed, StripTransform *transfor data.data = transform; /* irritating we need to search for our sequence! */ - SEQ_seqbase_recursive_apply(&ed->seqbase, transform_seq_cmp_fn, &data); + SEQ_for_each_callback(&ed->seqbase, transform_seq_cmp_fn, &data); return data.seq; } @@ -547,15 +547,15 @@ static void rna_SequenceTransform_update(Main *UNUSED(bmain), SEQ_relations_invalidate_cache_preprocessed(scene, seq); } -static int crop_seq_cmp_fn(Sequence *seq, void *arg_pt) +static bool crop_seq_cmp_fn(Sequence *seq, void *arg_pt) { SequenceSearchData *data = arg_pt; if (seq->strip && seq->strip->crop == data->data) { data->seq = seq; - return -1; /* done so bail out */ + return false; /* done so bail out */ } - return 1; + return true; } static Sequence *sequence_get_by_crop(Editing *ed, StripCrop *crop) @@ -566,7 +566,7 @@ static Sequence *sequence_get_by_crop(Editing *ed, StripCrop *crop) data.data = crop; /* irritating we need to search for our sequence! */ - SEQ_seqbase_recursive_apply(&ed->seqbase, crop_seq_cmp_fn, &data); + SEQ_for_each_callback(&ed->seqbase, crop_seq_cmp_fn, &data); return data.seq; } @@ -935,15 +935,15 @@ static void rna_Sequence_sound_update(Main *bmain, Scene *scene, PointerRNA *UNU DEG_relations_tag_update(bmain); } -static int seqproxy_seq_cmp_fn(Sequence *seq, void *arg_pt) +static bool seqproxy_seq_cmp_fn(Sequence *seq, void *arg_pt) { SequenceSearchData *data = arg_pt; if (seq->strip && seq->strip->proxy == data->data) { data->seq = seq; - return -1; /* done so bail out */ + return false; /* done so bail out */ } - return 1; + return true; } static Sequence *sequence_get_by_proxy(Editing *ed, StripProxy *proxy) @@ -953,7 +953,7 @@ static Sequence *sequence_get_by_proxy(Editing *ed, StripProxy *proxy) data.seq = NULL; data.data = proxy; - SEQ_seqbase_recursive_apply(&ed->seqbase, seqproxy_seq_cmp_fn, &data); + SEQ_for_each_callback(&ed->seqbase, seqproxy_seq_cmp_fn, &data); return data.seq; } @@ -988,7 +988,7 @@ static void rna_Sequence_opacity_set(PointerRNA *ptr, float value) seq->blend_opacity = value * 100.0f; } -static int colbalance_seq_cmp_fn(Sequence *seq, void *arg_pt) +static bool colbalance_seq_cmp_fn(Sequence *seq, void *arg_pt) { SequenceSearchData *data = arg_pt; @@ -999,12 +999,12 @@ static int colbalance_seq_cmp_fn(Sequence *seq, void *arg_pt) if (&cbmd->color_balance == data->data) { data->seq = seq; data->smd = smd; - return -1; /* done so bail out */ + return false; /* done so bail out */ } } } - return 1; + return true; } static Sequence *sequence_get_by_colorbalance(Editing *ed, @@ -1018,7 +1018,7 @@ static Sequence *sequence_get_by_colorbalance(Editing *ed, data.data = cb; /* irritating we need to search for our sequence! */ - SEQ_seqbase_recursive_apply(&ed->seqbase, colbalance_seq_cmp_fn, &data); + SEQ_for_each_callback(&ed->seqbase, colbalance_seq_cmp_fn, &data); *r_smd = data.smd; @@ -1122,16 +1122,16 @@ static void rna_SequenceEditor_overlay_frame_set(PointerRNA *ptr, int value) } } -static int modifier_seq_cmp_fn(Sequence *seq, void *arg_pt) +static bool modifier_seq_cmp_fn(Sequence *seq, void *arg_pt) { SequenceSearchData *data = arg_pt; if (BLI_findindex(&seq->modifiers, data->data) != -1) { data->seq = seq; - return -1; /* done so bail out */ + return false; /* done so bail out */ } - return 1; + return true; } static Sequence *sequence_get_by_modifier(Editing *ed, SequenceModifierData *smd) @@ -1142,7 +1142,7 @@ static Sequence *sequence_get_by_modifier(Editing *ed, SequenceModifierData *smd data.data = smd; /* irritating we need to search for our sequence! */ - SEQ_seqbase_recursive_apply(&ed->seqbase, modifier_seq_cmp_fn, &data); + SEQ_for_each_callback(&ed->seqbase, modifier_seq_cmp_fn, &data); return data.seq; } diff --git a/source/blender/sequencer/SEQ_iterator.h b/source/blender/sequencer/SEQ_iterator.h index 3ade7309f89..055db07f646 100644 --- a/source/blender/sequencer/SEQ_iterator.h +++ b/source/blender/sequencer/SEQ_iterator.h @@ -39,23 +39,7 @@ struct Sequence; SEQ_iterator_ensure(collection, &iter, &var) && var != NULL; \ var = SEQ_iterator_yield(&iter)) -#define SEQ_ALL_BEGIN(ed, var) \ - { \ - if (ed != NULL) { \ - SeqCollection *all_strips = SEQ_query_all_strips_recursive(&ed->seqbase); \ - GSetIterator gsi; \ - GSET_ITER (gsi, all_strips->set) { \ - var = (Sequence *)(BLI_gsetIterator_getKey(&gsi)); - -#define SEQ_ALL_END \ - } \ - SEQ_collection_free(all_strips); \ - } \ - } \ - ((void)0) - typedef struct SeqCollection { - struct SeqCollection *next, *prev; struct GSet *set; } SeqCollection; @@ -70,6 +54,11 @@ bool SEQ_iterator_ensure(SeqCollection *collection, struct Sequence **r_seq); struct Sequence *SEQ_iterator_yield(SeqIterator *iterator); +/* Callback format for the for_each function below. */ +typedef bool (*SeqForEachFunc)(struct Sequence *seq, void *user_data); + +void SEQ_for_each_callback(struct ListBase *seqbase, SeqForEachFunc callback, void *user_data); + SeqCollection *SEQ_collection_create(const char *name); SeqCollection *SEQ_collection_duplicate(SeqCollection *collection); uint SEQ_collection_len(const SeqCollection *collection); @@ -90,8 +79,8 @@ SeqCollection *SEQ_query_by_reference(struct Sequence *seq_reference, struct ListBase *seqbase, SeqCollection *collection)); SeqCollection *SEQ_query_selected_strips(struct ListBase *seqbase); -SeqCollection *SEQ_query_all_strips(ListBase *seqbase); -SeqCollection *SEQ_query_all_strips_recursive(ListBase *seqbase); +SeqCollection *SEQ_query_all_strips(struct ListBase *seqbase); +SeqCollection *SEQ_query_all_strips_recursive(struct ListBase *seqbase); void SEQ_query_strip_effect_chain(struct Sequence *seq_reference, struct ListBase *seqbase, SeqCollection *collection); diff --git a/source/blender/sequencer/SEQ_sequencer.h b/source/blender/sequencer/SEQ_sequencer.h index f4338d13c8f..27463379ae0 100644 --- a/source/blender/sequencer/SEQ_sequencer.h +++ b/source/blender/sequencer/SEQ_sequencer.h @@ -29,6 +29,11 @@ extern "C" { #include "DNA_scene_types.h" +struct BlendWriter; +struct BlendDataReader; +struct BlendLibReader; +struct BlendExpander; +struct Depsgraph; struct Editing; struct Scene; struct Sequence; @@ -83,6 +88,21 @@ void SEQ_sequence_base_dupli_recursive(const struct Scene *scene_src, int dupe_flag, const int flag); +/* Read and Write functions for .blend file data */ +void SEQ_blend_write(struct BlendWriter *writer, struct ListBase *seqbase); +void SEQ_blend_read(struct BlendDataReader *reader, struct ListBase *seqbase); + +void SEQ_blend_read_lib(struct BlendLibReader *reader, + struct Scene *scene, + struct ListBase *seqbase); + +void SEQ_blend_read_expand(struct BlendExpander *expander, struct ListBase *seqbase); + +/* Depsgraph update function */ +void SEQ_eval_sequences(struct Depsgraph *depsgraph, + struct Scene *scene, + struct ListBase *seqbase); + /* Defined in sequence_lookup.c */ typedef enum eSequenceLookupTag { diff --git a/source/blender/sequencer/SEQ_utils.h b/source/blender/sequencer/SEQ_utils.h index 99603dc8a3e..09de7bc67e9 100644 --- a/source/blender/sequencer/SEQ_utils.h +++ b/source/blender/sequencer/SEQ_utils.h @@ -56,12 +56,6 @@ void SEQ_set_scale_to_fit(const struct Sequence *seq, const int preview_width, const int preview_height, const eSeqImageFitMethod fit_method); -int SEQ_seqbase_recursive_apply(struct ListBase *seqbase, - int (*apply_fn)(struct Sequence *seq, void *), - void *arg); -int SEQ_recursive_apply(struct Sequence *seq, - int (*apply_fn)(struct Sequence *, void *), - void *arg); void SEQ_ensure_unique_name(struct Sequence *seq, struct Scene *scene); #ifdef __cplusplus diff --git a/source/blender/sequencer/intern/clipboard.c b/source/blender/sequencer/intern/clipboard.c index 9e702a4e60b..05406c50303 100644 --- a/source/blender/sequencer/intern/clipboard.c +++ b/source/blender/sequencer/intern/clipboard.c @@ -71,7 +71,7 @@ void SEQ_clipboard_free(void) for (seq = seqbase_clipboard.first; seq; seq = nseq) { nseq = seq->next; - seq_free_sequence_recurse(NULL, seq, false); + seq_free_sequence_recurse(NULL, seq, false, true); } BLI_listbase_clear(&seqbase_clipboard); } diff --git a/source/blender/sequencer/intern/iterator.c b/source/blender/sequencer/intern/iterator.c index 333a8e46c44..2ac93ccc9d3 100644 --- a/source/blender/sequencer/intern/iterator.c +++ b/source/blender/sequencer/intern/iterator.c @@ -90,6 +90,37 @@ Sequence *SEQ_iterator_yield(SeqIterator *iterator) return seq; } +static bool seq_for_each_recursive(ListBase *seqbase, SeqForEachFunc callback, void *user_data) +{ + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + if (!callback(seq, user_data)) { + /* Callback signaled stop, return. */ + return false; + } + if (seq->type == SEQ_TYPE_META) { + if (!seq_for_each_recursive(&seq->seqbase, callback, user_data)) { + return false; + } + } + } + return true; +} + +/** + * Utility function to recursivily iterate through all sequence strips in a seqbase list. + * Uses callback to do operations on each sequence element. + * The callback can stop the iteration if needed. + * + * \param seqbase: ListBase of sequences to be iterated over + * \param callback: query function callback, returns false if iteration should stop + * \param user_data: pointer to user data that can be used in the callback function + * + */ +void SEQ_for_each_callback(ListBase *seqbase, SeqForEachFunc callback, void *user_data) +{ + seq_for_each_recursive(seqbase, callback, user_data); +} + /** * Free strip collection. * @@ -222,19 +253,15 @@ void SEQ_collection_expand(ListBase *seqbase, SeqCollection *collection)) { /* Collect expanded results for each sequence in provided SeqIteratorCollection. */ - ListBase expand_collections = {0}; + SeqCollection *query_matches = SEQ_collection_create(__func__); Sequence *seq; SEQ_ITERATOR_FOREACH (seq, collection) { - SeqCollection *expand_collection = SEQ_query_by_reference(seq, seqbase, seq_query_func); - BLI_addtail(&expand_collections, expand_collection); + SEQ_collection_merge(query_matches, SEQ_query_by_reference(seq, seqbase, seq_query_func)); } /* Merge all expanded results in provided SeqIteratorCollection. */ - LISTBASE_FOREACH_MUTABLE (SeqCollection *, expand_collection, &expand_collections) { - BLI_remlink(&expand_collections, expand_collection); - SEQ_collection_merge(collection, expand_collection); - } + SEQ_collection_merge(collection, query_matches); } /** @@ -255,6 +282,16 @@ SeqCollection *SEQ_collection_duplicate(SeqCollection *collection) /** \} */ +static void query_all_strips_recursive(ListBase *seqbase, SeqCollection *collection) +{ + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + if (seq->type == SEQ_TYPE_META) { + query_all_strips_recursive(&seq->seqbase, collection); + } + SEQ_collection_append_strip(seq, collection); + } +} + /** * Query all strips in seqbase and nested meta strips. * @@ -266,7 +303,7 @@ SeqCollection *SEQ_query_all_strips_recursive(ListBase *seqbase) SeqCollection *collection = SEQ_collection_create(__func__); LISTBASE_FOREACH (Sequence *, seq, seqbase) { if (seq->type == SEQ_TYPE_META) { - SEQ_collection_merge(collection, SEQ_query_all_strips_recursive(&seq->seqbase)); + query_all_strips_recursive(&seq->seqbase, collection); } SEQ_collection_append_strip(seq, collection); } @@ -282,9 +319,7 @@ SeqCollection *SEQ_query_all_strips_recursive(ListBase *seqbase) SeqCollection *SEQ_query_all_strips(ListBase *seqbase) { SeqCollection *collection = SEQ_collection_create(__func__); - LISTBASE_FOREACH (Sequence *, seq, seqbase) { - SEQ_collection_append_strip(seq, collection); - } + query_all_strips_recursive(seqbase, collection); return collection; } diff --git a/source/blender/sequencer/intern/proxy.c b/source/blender/sequencer/intern/proxy.c index bd7ea5b958c..2bc294c91cd 100644 --- a/source/blender/sequencer/intern/proxy.c +++ b/source/blender/sequencer/intern/proxy.c @@ -576,7 +576,7 @@ void SEQ_proxy_rebuild_finish(SeqIndexBuildContext *context, bool stop) IMB_anim_index_rebuild_finish(context->index_context, stop); } - seq_free_sequence_recurse(NULL, context->seq, true); + seq_free_sequence_recurse(NULL, context->seq, true, true); MEM_freeN(context); } diff --git a/source/blender/sequencer/intern/sequencer.c b/source/blender/sequencer/intern/sequencer.c index 7dc19cf39a6..49d08d0e022 100644 --- a/source/blender/sequencer/intern/sequencer.c +++ b/source/blender/sequencer/intern/sequencer.c @@ -24,11 +24,14 @@ * \ingroup bke */ +#define DNA_DEPRECATED_ALLOW + #include "MEM_guardedalloc.h" #include "DNA_anim_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" +#include "DNA_sound_types.h" #include "BLI_listbase.h" #include "BLI_string.h" @@ -44,14 +47,19 @@ #include "IMB_colormanagement.h" #include "IMB_imbuf.h" +#include "SEQ_edit.h" #include "SEQ_effects.h" #include "SEQ_iterator.h" #include "SEQ_modifier.h" +#include "SEQ_proxy.h" #include "SEQ_relations.h" #include "SEQ_select.h" #include "SEQ_sequencer.h" +#include "SEQ_sound.h" #include "SEQ_utils.h" +#include "BLO_read_write.h" + #include "image_cache.h" #include "prefetch.h" #include "sequencer.h" @@ -217,16 +225,19 @@ void SEQ_sequence_free(Scene *scene, Sequence *seq, const bool do_clean_animdata /* cache must be freed before calling this function * since it leaves the seqbase in an invalid state */ -void seq_free_sequence_recurse(Scene *scene, Sequence *seq, const bool do_id_user) +void seq_free_sequence_recurse(Scene *scene, + Sequence *seq, + const bool do_id_user, + const bool do_clean_animdata) { Sequence *iseq, *iseq_next; for (iseq = seq->seqbase.first; iseq; iseq = iseq_next) { iseq_next = iseq->next; - seq_free_sequence_recurse(scene, iseq, do_id_user); + seq_free_sequence_recurse(scene, iseq, do_id_user, do_clean_animdata); } - seq_sequence_free_ex(scene, seq, false, do_id_user, true); + seq_sequence_free_ex(scene, seq, false, do_id_user, do_clean_animdata); } Editing *SEQ_editing_get(Scene *scene, bool alloc) @@ -255,7 +266,6 @@ Editing *SEQ_editing_ensure(Scene *scene) void SEQ_editing_free(Scene *scene, const bool do_id_user) { Editing *ed = scene->ed; - Sequence *seq; if (ed == NULL) { return; @@ -264,11 +274,10 @@ void SEQ_editing_free(Scene *scene, const bool do_id_user) seq_prefetch_free(scene); seq_cache_destruct(scene); - SEQ_ALL_BEGIN (ed, seq) { - /* handle cache freeing above */ - seq_sequence_free_ex(scene, seq, false, do_id_user, false); + /* handle cache freeing above */ + LISTBASE_FOREACH_MUTABLE (Sequence *, seq, &ed->seqbase) { + seq_free_sequence_recurse(scene, seq, do_id_user, false); } - SEQ_ALL_END; BLI_freelistN(&ed->metastack); SEQ_sequence_lookup_free(scene); @@ -732,3 +741,315 @@ SequencerToolSettings *SEQ_tool_settings_copy(SequencerToolSettings *tool_settin } /** \} */ + +static bool seq_set_strip_done_cb(Sequence *seq, void *UNUSED(userdata)) +{ + if (seq->strip) { + seq->strip->done = false; + } + return true; +} + +static bool seq_write_data_cb(Sequence *seq, void *userdata) +{ + BlendWriter *writer = (BlendWriter *)userdata; + BLO_write_struct(writer, Sequence, seq); + if (seq->strip && seq->strip->done == 0) { + /* write strip with 'done' at 0 because readfile */ + + // TODO this doesn't depend on the `Strip` data to be present? + if (seq->effectdata) { + switch (seq->type) { + case SEQ_TYPE_COLOR: + BLO_write_struct(writer, SolidColorVars, seq->effectdata); + break; + case SEQ_TYPE_SPEED: + BLO_write_struct(writer, SpeedControlVars, seq->effectdata); + break; + case SEQ_TYPE_WIPE: + BLO_write_struct(writer, WipeVars, seq->effectdata); + break; + case SEQ_TYPE_GLOW: + BLO_write_struct(writer, GlowVars, seq->effectdata); + break; + case SEQ_TYPE_TRANSFORM: + BLO_write_struct(writer, TransformVars, seq->effectdata); + break; + case SEQ_TYPE_GAUSSIAN_BLUR: + BLO_write_struct(writer, GaussianBlurVars, seq->effectdata); + break; + case SEQ_TYPE_TEXT: + BLO_write_struct(writer, TextVars, seq->effectdata); + break; + case SEQ_TYPE_COLORMIX: + BLO_write_struct(writer, ColorMixVars, seq->effectdata); + break; + } + } + + BLO_write_struct(writer, Stereo3dFormat, seq->stereo3d_format); + + Strip *strip = seq->strip; + BLO_write_struct(writer, Strip, strip); + if (strip->crop) { + BLO_write_struct(writer, StripCrop, strip->crop); + } + if (strip->transform) { + BLO_write_struct(writer, StripTransform, strip->transform); + } + if (strip->proxy) { + BLO_write_struct(writer, StripProxy, strip->proxy); + } + if (seq->type == SEQ_TYPE_IMAGE) { + BLO_write_struct_array(writer, + StripElem, + MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem), + strip->stripdata); + } + else if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) { + BLO_write_struct(writer, StripElem, strip->stripdata); + } + + strip->done = true; + } + + if (seq->prop) { + IDP_BlendWrite(writer, seq->prop); + } + + SEQ_modifier_blend_write(writer, &seq->modifiers); + return true; +} + +void SEQ_blend_write(BlendWriter *writer, ListBase *seqbase) +{ + /* reset write flags */ + SEQ_for_each_callback(seqbase, seq_set_strip_done_cb, NULL); + + SEQ_for_each_callback(seqbase, seq_write_data_cb, writer); +} + +static bool seq_read_data_cb(Sequence *seq, void *user_data) +{ + BlendDataReader *reader = (BlendDataReader *)user_data; + + /* Do as early as possible, so that other parts of reading can rely on valid session UUID. */ + SEQ_relations_session_uuid_generate(seq); + + BLO_read_data_address(reader, &seq->seq1); + BLO_read_data_address(reader, &seq->seq2); + BLO_read_data_address(reader, &seq->seq3); + + /* a patch: after introduction of effects with 3 input strips */ + if (seq->seq3 == NULL) { + seq->seq3 = seq->seq2; + } + + BLO_read_data_address(reader, &seq->effectdata); + BLO_read_data_address(reader, &seq->stereo3d_format); + + if (seq->type & SEQ_TYPE_EFFECT) { + seq->flag |= SEQ_EFFECT_NOT_LOADED; + } + + if (seq->type == SEQ_TYPE_TEXT) { + TextVars *t = seq->effectdata; + t->text_blf_id = SEQ_FONT_NOT_LOADED; + } + + BLO_read_data_address(reader, &seq->prop); + IDP_BlendDataRead(reader, &seq->prop); + + BLO_read_data_address(reader, &seq->strip); + if (seq->strip && seq->strip->done == 0) { + seq->strip->done = true; + + if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) { + BLO_read_data_address(reader, &seq->strip->stripdata); + } + else { + seq->strip->stripdata = NULL; + } + BLO_read_data_address(reader, &seq->strip->crop); + BLO_read_data_address(reader, &seq->strip->transform); + BLO_read_data_address(reader, &seq->strip->proxy); + if (seq->strip->proxy) { + seq->strip->proxy->anim = NULL; + } + else if (seq->flag & SEQ_USE_PROXY) { + SEQ_proxy_set(seq, true); + } + + /* need to load color balance to it could be converted to modifier */ + BLO_read_data_address(reader, &seq->strip->color_balance); + } + + SEQ_modifier_blend_read_data(reader, &seq->modifiers); + return true; +} +void SEQ_blend_read(BlendDataReader *reader, ListBase *seqbase) +{ + SEQ_for_each_callback(seqbase, seq_read_data_cb, reader); +} + +typedef struct Read_lib_data { + BlendLibReader *reader; + Scene *scene; +} Read_lib_data; + +static bool seq_read_lib_cb(Sequence *seq, void *user_data) +{ + Read_lib_data *data = (Read_lib_data *)user_data; + BlendLibReader *reader = data->reader; + Scene *sce = data->scene; + + IDP_BlendReadLib(reader, seq->prop); + + if (seq->ipo) { + /* XXX: deprecated - old animation system. */ + BLO_read_id_address(reader, sce->id.lib, &seq->ipo); + } + seq->scene_sound = NULL; + if (seq->scene) { + BLO_read_id_address(reader, sce->id.lib, &seq->scene); + seq->scene_sound = NULL; + } + if (seq->clip) { + BLO_read_id_address(reader, sce->id.lib, &seq->clip); + } + if (seq->mask) { + BLO_read_id_address(reader, sce->id.lib, &seq->mask); + } + if (seq->scene_camera) { + BLO_read_id_address(reader, sce->id.lib, &seq->scene_camera); + } + if (seq->sound) { + seq->scene_sound = NULL; + if (seq->type == SEQ_TYPE_SOUND_HD) { + seq->type = SEQ_TYPE_SOUND_RAM; + } + else { + BLO_read_id_address(reader, sce->id.lib, &seq->sound); + } + if (seq->sound) { + id_us_plus_no_lib((ID *)seq->sound); + seq->scene_sound = NULL; + } + } + if (seq->type == SEQ_TYPE_TEXT) { + TextVars *t = seq->effectdata; + BLO_read_id_address(reader, sce->id.lib, &t->text_font); + } + BLI_listbase_clear(&seq->anims); + + SEQ_modifier_blend_read_lib(reader, sce, &seq->modifiers); + return true; +} + +void SEQ_blend_read_lib(BlendLibReader *reader, Scene *scene, ListBase *seqbase) +{ + Read_lib_data data = {reader, scene}; + SEQ_for_each_callback(seqbase, seq_read_lib_cb, &data); +} + +static bool seq_blend_read_expand(Sequence *seq, void *user_data) +{ + BlendExpander *expander = (BlendExpander *)user_data; + + IDP_BlendReadExpand(expander, seq->prop); + + if (seq->scene) { + BLO_expand(expander, seq->scene); + } + if (seq->scene_camera) { + BLO_expand(expander, seq->scene_camera); + } + if (seq->clip) { + BLO_expand(expander, seq->clip); + } + if (seq->mask) { + BLO_expand(expander, seq->mask); + } + if (seq->sound) { + BLO_expand(expander, seq->sound); + } + + if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) { + TextVars *data = seq->effectdata; + BLO_expand(expander, data->text_font); + } + return true; +} + +void SEQ_blend_read_expand(BlendExpander *expander, ListBase *seqbase) +{ + SEQ_for_each_callback(seqbase, seq_blend_read_expand, expander); +} + +/* Depsgraph update functions. */ + +static bool seq_disable_sound_strips_cb(Sequence *seq, void *user_data) +{ + Scene *scene = (Scene *)user_data; + if (seq->scene_sound != NULL) { + BKE_sound_remove_scene_sound(scene, seq->scene_sound); + seq->scene_sound = NULL; + } + return true; +} + +static bool seq_update_seq_cb(Sequence *seq, void *user_data) +{ + Scene *scene = (Scene *)user_data; + if (seq->scene_sound == NULL) { + if (seq->sound != NULL) { + seq->scene_sound = BKE_sound_add_scene_sound_defaults(scene, seq); + } + else if (seq->type == SEQ_TYPE_SCENE) { + if (seq->scene != NULL) { + BKE_sound_ensure_scene(seq->scene); + seq->scene_sound = BKE_sound_scene_add_scene_sound_defaults(scene, seq); + } + } + } + if (seq->scene_sound != NULL) { + /* Make sure changing volume via sequence's properties panel works correct. + * + * Ideally, the entire BKE_scene_update_sound() will happen from a dependency graph, so + * then it is no longer needed to do such manual forced updates. */ + if (seq->type == SEQ_TYPE_SCENE && seq->scene != NULL) { + BKE_sound_set_scene_volume(seq->scene, seq->scene->audio.volume); + if ((seq->flag & SEQ_SCENE_STRIPS) == 0 && seq->scene->sound_scene != NULL && + seq->scene->ed != NULL) { + SEQ_for_each_callback(&seq->scene->ed->seqbase, seq_disable_sound_strips_cb, seq->scene); + } + } + if (seq->sound != NULL) { + if (scene->id.recalc & ID_RECALC_AUDIO || seq->sound->id.recalc & ID_RECALC_AUDIO) { + BKE_sound_update_scene_sound(seq->scene_sound, seq->sound); + } + } + 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_pan( + seq->scene_sound, seq->pan, (seq->flag & SEQ_AUDIO_PAN_ANIMATED) != 0); + } + return true; +} + +/* Evaluate parts of sequences which needs to be done as a part of a dependency graph evaluation. + * This does NOT include actual rendering of the strips, but rather makes them up-to-date for + * animation playback and makes them ready for the sequencer's rendering pipeline to render them. + */ +void SEQ_eval_sequences(Depsgraph *depsgraph, Scene *scene, ListBase *seqbase) +{ + DEG_debug_print_eval(depsgraph, __func__, scene->id.name, scene); + BKE_sound_ensure_scene(scene); + + SEQ_for_each_callback(seqbase, seq_update_seq_cb, scene); + + SEQ_edit_update_muting(scene->ed); + SEQ_sound_update_bounds_all(scene); +} diff --git a/source/blender/sequencer/intern/sequencer.h b/source/blender/sequencer/intern/sequencer.h index 928b3edd728..e43535d14ee 100644 --- a/source/blender/sequencer/intern/sequencer.h +++ b/source/blender/sequencer/intern/sequencer.h @@ -30,7 +30,10 @@ extern "C" { struct Scene; struct Sequence; -void seq_free_sequence_recurse(struct Scene *scene, struct Sequence *seq, const bool do_id_user); +void seq_free_sequence_recurse(struct Scene *scene, + struct Sequence *seq, + const bool do_id_user, + const bool do_clean_animdata); #ifdef __cplusplus } diff --git a/source/blender/sequencer/intern/strip_relations.c b/source/blender/sequencer/intern/strip_relations.c index ec70a683da5..b840b19f244 100644 --- a/source/blender/sequencer/intern/strip_relations.c +++ b/source/blender/sequencer/intern/strip_relations.c @@ -476,6 +476,24 @@ void SEQ_relations_session_uuid_generate(struct Sequence *sequence) sequence->runtime.session_uuid = BLI_session_uuid_generate(); } +static bool get_uuids_cb(Sequence *seq, void *user_data) +{ + struct GSet *used_uuids = (struct GSet *)user_data; + const SessionUUID *session_uuid = &seq->runtime.session_uuid; + if (!BLI_session_uuid_is_generated(session_uuid)) { + printf("Sequence %s does not have UUID generated.\n", seq->name); + return true; + } + + if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) { + printf("Sequence %s has duplicate UUID generated.\n", seq->name); + return true; + } + + BLI_gset_insert(used_uuids, (void *)session_uuid); + return true; +} + void SEQ_relations_check_uuids_unique_and_report(const Scene *scene) { if (scene->ed == NULL) { @@ -485,22 +503,7 @@ void SEQ_relations_check_uuids_unique_and_report(const Scene *scene) struct GSet *used_uuids = BLI_gset_new( BLI_session_uuid_ghash_hash, BLI_session_uuid_ghash_compare, "sequencer used uuids"); - const Sequence *sequence; - SEQ_ALL_BEGIN (scene->ed, sequence) { - const SessionUUID *session_uuid = &sequence->runtime.session_uuid; - if (!BLI_session_uuid_is_generated(session_uuid)) { - printf("Sequence %s does not have UUID generated.\n", sequence->name); - continue; - } - - if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) { - printf("Sequence %s has duplicate UUID generated.\n", sequence->name); - continue; - } - - BLI_gset_insert(used_uuids, (void *)session_uuid); - } - SEQ_ALL_END; + SEQ_for_each_callback(&scene->ed->seqbase, get_uuids_cb, used_uuids); BLI_gset_free(used_uuids, NULL); } diff --git a/source/blender/sequencer/intern/utils.c b/source/blender/sequencer/intern/utils.c index f946affe1d8..e4eecaf552c 100644 --- a/source/blender/sequencer/intern/utils.c +++ b/source/blender/sequencer/intern/utils.c @@ -133,12 +133,12 @@ static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui) } } -static int seqbase_unique_name_recursive_fn(Sequence *seq, void *arg_pt) +static bool seqbase_unique_name_recursive_fn(Sequence *seq, void *arg_pt) { if (seq->seqbase.first) { seqbase_unique_name(&seq->seqbase, (SeqUniqueInfo *)arg_pt); } - return 1; + return true; } void SEQ_sequence_base_unique_name_recursive(struct Scene *scene, @@ -167,7 +167,7 @@ void SEQ_sequence_base_unique_name_recursive(struct Scene *scene, while (sui.match) { sui.match = 0; seqbase_unique_name(seqbasep, &sui); - SEQ_seqbase_recursive_apply(seqbasep, seqbase_unique_name_recursive_fn, &sui); + SEQ_for_each_callback(seqbasep, seqbase_unique_name_recursive_fn, &sui); } SEQ_edit_sequence_name_set(scene, seq, sui.name_dest); @@ -573,34 +573,6 @@ void SEQ_set_scale_to_fit(const Sequence *seq, } } -int SEQ_seqbase_recursive_apply(ListBase *seqbase, - int (*apply_fn)(Sequence *seq, void *), - void *arg) -{ - Sequence *iseq; - for (iseq = seqbase->first; iseq; iseq = iseq->next) { - if (SEQ_recursive_apply(iseq, apply_fn, arg) == -1) { - return -1; /* bail out */ - } - } - return 1; -} - -int SEQ_recursive_apply(Sequence *seq, int (*apply_fn)(Sequence *, void *), void *arg) -{ - int ret = apply_fn(seq, arg); - - if (ret == -1) { - return -1; /* bail out */ - } - - if (ret && seq->seqbase.first) { - ret = SEQ_seqbase_recursive_apply(&seq->seqbase, apply_fn, arg); - } - - return ret; -} - /** * Ensure, that provided Sequence has unique name. If animation data exists for this Sequence, it * will be duplicated and mapped onto new name |