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/intern/sequencer.c
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/intern/sequencer.c')
-rw-r--r--source/blender/sequencer/intern/sequencer.c337
1 files changed, 329 insertions, 8 deletions
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);
+}