[Bf-blender-cvs] [c5fe16e121e] master: Sound: Make sound handles only be in evaluated datablocks

Sergey Sharybin noreply at git.blender.org
Fri May 3 15:52:56 CEST 2019


Commit: c5fe16e121eefe5dd02cc9f9ba572053c383ccfa
Author: Sergey Sharybin
Date:   Thu May 2 14:31:33 2019 +0200
Branches: master
https://developer.blender.org/rBc5fe16e121eefe5dd02cc9f9ba572053c383ccfa

Sound: Make sound handles only be in evaluated datablocks

Quite straightforward change, which makes it so audio handles are
only created inside of evaluated datablocks.

Exception is adding sound strip to the sequencer, which needs an
audio handle to query length and number of channels. This is done
by temporarily loading sound file into an original datablock, and
then tossing it away.

There is an assert in sound.c which verifies that audio system is
used from an evaluated domain, which should help porting all the
cases which are likely missed by this commit.

Some annoying parts:

- `BKE_sound_update_scene()` is iterating over all bases, and does
  special ID tags to see whether sound has been handled or not
  already. This can not be done the old fashion now.

  Ideally, this will be done as a speaker datablock evaluation,
  but seems that would require a lock since audio API is not safe
  for threading. So this is not a desired way i'd say.

  Possible solution here would be to iterate over ID datablocks
  using dependency graph query API.

- Frame jump needs to call `BKE_sound_seek_scene()` directly
  because there might be some flags assigned to the scene which
  could be clear after operator execution is over.

  Need to verify if that's the case though. This is a bit hairy
  code, so sticking to a safest and known to work approach for
  now.

- Removed check for format when opening new sound file.
  Maybe we can have some utility function which queries channel
  and duration information, leaving the caller's code clean and
  tidy.

Tested following cases:
- Adding/removing/moving sequencer's sound strips.
- Adding/moving speakers in viewport.
- Rendering audio.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D4779

===================================================================

M	source/blender/blenkernel/BKE_sound.h
M	source/blender/blenkernel/intern/scene.c
M	source/blender/blenkernel/intern/sequencer.c
M	source/blender/blenkernel/intern/sound.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
M	source/blender/depsgraph/intern/depsgraph_tag.cc
M	source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
M	source/blender/editors/animation/anim_ops.c
M	source/blender/editors/screen/screen_ops.c
M	source/blender/editors/sound/CMakeLists.txt
M	source/blender/editors/sound/sound_ops.c
M	source/blender/makesdna/DNA_ID.h
M	source/blender/windowmanager/intern/wm_event_system.c
M	source/blender/windowmanager/intern/wm_init_exit.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index d95be9fde97..0c1ab2cc4c3 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -71,12 +71,17 @@ void BKE_sound_cache(struct bSound *sound);
 
 void BKE_sound_delete_cache(struct bSound *sound);
 
-void BKE_sound_reset_pointers(struct bSound *sound);
+void BKE_sound_reset_runtime(struct bSound *sound);
 void BKE_sound_load(struct Main *main, struct bSound *sound);
 void BKE_sound_ensure_loaded(struct Main *bmain, struct bSound *sound);
 
 void BKE_sound_free(struct bSound *sound);
 
+/* Is used by sequencer to temporarily load audio to access information about channels and
+ * duration. */
+void BKE_sound_load_audio(struct Main *main, struct bSound *sound);
+void BKE_sound_free_audio(struct bSound *sound);
+
 void BKE_sound_copy_data(struct Main *bmain,
                          struct bSound *sound_dst,
                          const struct bSound *sound_src,
@@ -88,7 +93,7 @@ void BKE_sound_make_local(struct Main *bmain, struct bSound *sound, const bool l
 AUD_Device *BKE_sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume);
 #endif
 
-void BKE_sound_reset_scene_pointers(struct Scene *scene);
+void BKE_sound_reset_scene_runtime(struct Scene *scene);
 void BKE_sound_create_scene(struct Scene *scene);
 void BKE_sound_ensure_scene(struct Scene *scene);
 
@@ -154,6 +159,11 @@ float BKE_sound_get_length(struct bSound *sound);
 
 char **BKE_sound_get_device_names(void);
 
+typedef void (*SoundJackSyncCallback)(struct Main *bmain, int mode, float time);
+
+void BKE_sound_jack_sync_callback_set(SoundJackSyncCallback callback);
+void BKE_sound_jack_scene_update(struct Scene *scene, int mode, float time);
+
 /* Evaluation. */
 
 struct Depsgraph;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 14e011fca3b..733e76fef2d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -309,7 +309,7 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons
                                                             flag_subdata);
   }
 
-  BKE_sound_reset_scene_pointers(sce_dst);
+  BKE_sound_reset_scene_runtime(sce_dst);
 
   /* Copy sequencer, this is local data! */
   if (sce_src->ed) {
@@ -399,7 +399,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
       sce_copy->r.ffcodecdata.properties = IDP_CopyProperty(sce->r.ffcodecdata.properties);
     }
 
-    BKE_sound_reset_scene_pointers(sce_copy);
+    BKE_sound_reset_scene_runtime(sce_copy);
 
     /* grease pencil */
     sce_copy->gpd = NULL;
@@ -779,7 +779,7 @@ void BKE_scene_init(Scene *sce)
   srv = sce->r.views.last;
   BLI_strncpy(srv->suffix, STEREO_RIGHT_SUFFIX, sizeof(srv->suffix));
 
-  BKE_sound_reset_scene_pointers(sce);
+  BKE_sound_reset_scene_runtime(sce);
 
   /* color management */
   colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_SEQUENCER);
@@ -1509,7 +1509,7 @@ static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_
 
 static void scene_update_sound(Depsgraph *depsgraph, Main *bmain)
 {
-  Scene *scene = DEG_get_input_scene(depsgraph);
+  Scene *scene = DEG_get_evaluated_scene(depsgraph);
   BKE_sound_ensure_scene(scene);
   BKE_sound_update_scene(bmain, scene);
 }
@@ -2398,23 +2398,17 @@ void BKE_scene_cursor_quat_to_rot(View3DCursor *cursor, const float quat[4], boo
 void BKE_scene_eval_sequencer_sequences(Depsgraph *depsgraph, Scene *scene)
 {
   DEG_debug_print_eval(depsgraph, __func__, scene->id.name, scene);
-  /* TODO(sergey): For now we keep sound handlers in an original IDs, but it
-   * should really be moved to an evaluated one. */
-  if (!DEG_is_active(depsgraph)) {
-    return;
-  }
-  Scene *scene_orig = (Scene *)DEG_get_original_id(&scene->id);
-  if (scene_orig->ed == NULL) {
+  if (scene->ed == NULL) {
     return;
   }
-  BKE_sound_ensure_scene(scene_orig);
+  BKE_sound_ensure_scene(scene);
   Sequence *seq;
-  SEQ_BEGIN (scene_orig->ed, seq) {
+  SEQ_BEGIN (scene->ed, seq) {
     if (seq->sound != NULL && seq->scene_sound == NULL) {
-      seq->scene_sound = BKE_sound_add_scene_sound_defaults(scene_orig, seq);
+      seq->scene_sound = BKE_sound_add_scene_sound_defaults(scene, seq);
     }
   }
   SEQ_END;
-  BKE_sequencer_update_muting(scene_orig->ed);
-  BKE_sequencer_update_sound_bounds_all(scene_orig);
+  BKE_sequencer_update_muting(scene->ed);
+  BKE_sequencer_update_sound_bounds_all(scene);
 }
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index f593713b79c..74541c13c4f 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -808,10 +808,7 @@ void BKE_sequence_calc_disp(Scene *scene, Sequence *seq)
     seq->handsize = (float)((seq->enddisp - seq->startdisp) / 25);
   }
 
-  if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
-    BKE_sequencer_update_sound_bounds(scene, seq);
-  }
-  else if (seq->type == SEQ_TYPE_META) {
+  if (seq->type == SEQ_TYPE_META) {
     seq_update_sound_bounds_recursive(scene, seq);
   }
 }
@@ -5491,17 +5488,18 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
   Strip *strip;
   StripElem *se;
 
-  AUD_SoundInfo info;
-
   sound = BKE_sound_new_file(bmain, seq_load->path); /* handles relative paths */
 
+  /* Load the original sound, so we can access number of channels and length information.
+   * We free the sound handle on the original bSound datablock before existing this function, it is
+   * to be allocated on an evaluated version after this. */
+  BKE_sound_load_audio(bmain, sound);
+  AUD_SoundInfo info = AUD_getInfo(sound->playback_handle);
   if (sound->playback_handle == NULL) {
     BKE_id_free(bmain, sound);
     return NULL;
   }
 
-  info = AUD_getInfo(sound->playback_handle);
-
   if (info.specs.channels == AUD_CHANNELS_INVALID) {
     BKE_id_free(bmain, sound);
     return NULL;
@@ -5526,8 +5524,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
 
   BLI_split_dirfile(seq_load->path, strip->dir, se->name, sizeof(strip->dir), sizeof(se->name));
 
-  seq->scene_sound = BKE_sound_add_scene_sound(
-      scene, seq, seq_load->start_frame, seq_load->start_frame + seq->len, 0);
+  seq->scene_sound = NULL;
 
   BKE_sequence_calc_disp(scene, seq);
 
@@ -5536,6 +5533,11 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
 
   seq_load_apply(bmain, scene, seq, seq_load);
 
+  BKE_sound_free_audio(sound);
+
+  /* TODO(sergey): Shall we tag here or in the oeprator? */
+  DEG_relations_tag_update(bmain);
+
   return seq;
 }
 #else   // WITH_AUDASPACE
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 18093173f7c..9e5fb3dac63 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -38,6 +38,7 @@
 #include "DNA_screen_types.h"
 #include "DNA_sound_types.h"
 #include "DNA_speaker_types.h"
+#include "DNA_windowmanager_types.h"
 
 #ifdef WITH_AUDASPACE
 #  include <AUD_Sound.h>
@@ -64,6 +65,28 @@ static int sound_cfra;
 static char **audio_device_names = NULL;
 #endif
 
+BLI_INLINE void sound_verify_evaluated_id(ID *id)
+{
+  UNUSED_VARS_NDEBUG(id);
+  /* This is a bit tricky and not quite reliable, but good enough check.
+   *
+   * We don't want audio system handles to be allocated on amn original datablocks, and only want
+   * them to be allocated on a datablocks which are result of dependency graph evaluation.
+   *
+   * Datablocks which are covered by a copy-on-write system of dependency graph will have
+   * LIB_TAG_COPIED_ON_WRITE tag set on them. But if some of datablocks during its evaluation
+   * decides to re-allocate it's nested one (for example, object evaluation could re-allocate mesh
+   * when evaluating modifier stack). Such datablocks will have LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT
+   * tag set on them.
+   *
+   * Additionally, we also allow datablocks outside of main database. Those can not be "original"
+   * and could be used as a temporary evaluated result during operations like baking.
+   *
+   * NOTE: We conder ID evaluated if ANY of those flags is set. We do NOT require ALL of them. */
+  BLI_assert(id->tag &
+             (LIB_TAG_COPIED_ON_WRITE | LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT | LIB_TAG_NO_MAIN));
+}
+
 bSound *BKE_sound_new_file(Main *bmain, const char *filepath)
 {
   bSound *sound;
@@ -80,7 +103,7 @@ bSound *BKE_sound_new_file(Main *bmain, const char *filepath)
   BLI_strncpy(sound->name, filepath, FILE_MAX);
   /* sound->type = SOUND_TYPE_FILE; */ /* XXX unused currently */
 
-  BKE_sound_load(bmain, sound);
+  BKE_sound_reset_runtime(sound);
 
   return sound;
 }
@@ -128,6 +151,17 @@ void BKE_sound_free(bSound *sound)
     sound->packedfile = NULL;
   }
 
+  BKE_sound_free_audio(sound);
+
+  if (sound->spinlock) {
+    BLI_spin_end(sound->spinlock);
+    MEM_freeN(sound->spinlock);
+    sound->spinlock = NULL;
+  }
+}
+
+void BKE_sound_free_audio(bSound *sound)
+{
 #ifdef WITH_AUDASPACE
   if (sound->handle) {
     AUD_Sound_free(sound->handle);
@@ -143,11 +177,6 @@ void BKE_sound_free(bSound *sound)
   BKE_sound_free_waveform(sound);
 
 #endif /* WITH_AUDASPACE */
-  if (sound->spinlock) {
-    BLI_spin_end(sound->spinlock);
-    MEM_freeN(sound->spinlock);
-    sound->spinlock = NULL;
-  }
 }
 
 /**
@@ -160,7 +189,7 @@ void BKE_sound_free(bSound *sound)
  *
  * \param flag: Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
  */
-void BKE_sound_copy_data(Main *bmain,
+void BKE_sound_copy_data(Main *UNUSED(bmain),
                          bSound *sound_dst,
                          const bSound *UNUSED(sound_src),
                          const int UNUSED(flag))
@@ -180,8 +209,7 @@ void BKE_sound_copy_data(Main *bmain,
     sound_dst->packedfile = dupPackedFile(sound_dst->packedfile);
   }
 
-  /* Initialize whole runtime (audaspace) stuff. */
-  BKE_sound_load(bmain, sound_dst);
+  BKE_sound_r

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list