Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Parborg <darkdefende@gmail.com>2021-08-20 17:30:34 +0300
committerSebastian Parborg <darkdefende@gmail.com>2021-08-25 18:30:39 +0300
commitf49d438ced7c5874dbf43976d9901a462176f541 (patch)
treefae7b745eaf1e793b53119f3ec27c34621727c58 /source/blender/sequencer
parent796035ad930383c26302ab6a57e8e6c90394603b (diff)
Cleanup and remove SEQ_ALL_BEGIN macro
We now use a for_each function with callback to iterate through all sequences in the scene. This has the benefit that we now only loop over the sequences in the scene once. Before we would loop over them twice and allocate memory to store temporary data. The allocation of temporary data lead to unintentional memory leaks if the code used returns to exit out of the iteration loop. The new for_each callback method doesn't allocate any temporary data and only iterates though all sequences once. Reviewed By: Richard Antalik, Bastien Montagne Differential Revision: http://developer.blender.org/D12278
Diffstat (limited to 'source/blender/sequencer')
-rw-r--r--source/blender/sequencer/SEQ_iterator.h25
-rw-r--r--source/blender/sequencer/SEQ_sequencer.h20
-rw-r--r--source/blender/sequencer/SEQ_utils.h6
-rw-r--r--source/blender/sequencer/intern/clipboard.c2
-rw-r--r--source/blender/sequencer/intern/iterator.c57
-rw-r--r--source/blender/sequencer/intern/proxy.c2
-rw-r--r--source/blender/sequencer/intern/sequencer.c337
-rw-r--r--source/blender/sequencer/intern/sequencer.h5
-rw-r--r--source/blender/sequencer/intern/strip_relations.c35
-rw-r--r--source/blender/sequencer/intern/utils.c34
10 files changed, 430 insertions, 93 deletions
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