Blender V4.3
media_presence.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BKE_main.hh"
10#include "BLI_fileops.h"
11#include "BLI_map.hh"
12#include "BLI_path_utils.hh"
13#include "BLI_string.h"
14#include "BLI_threads.h"
15#include "DNA_scene_types.h"
16#include "DNA_sequence_types.h"
17#include "DNA_sound_types.h"
18#include "SEQ_utils.hh"
19
20namespace blender::seq {
21
23
24static const char *get_seq_base_path(const Sequence *seq)
25{
26 return seq->scene ? ID_BLEND_PATH_FROM_GLOBAL(&seq->scene->id) :
28}
29
30static bool check_sound_media_missing(const bSound *sound, const Sequence *seq)
31{
32 if (sound == nullptr) {
33 return false;
34 }
35
36 char filepath[FILE_MAX];
37 STRNCPY(filepath, sound->filepath);
38 const char *basepath = get_seq_base_path(seq);
39 BLI_path_abs(filepath, basepath);
40 return !BLI_exists(filepath);
41}
42
43static bool check_media_missing(const Sequence *seq)
44{
45 if (seq == nullptr || seq->strip == nullptr) {
46 return false;
47 }
48
49 /* Images or movies. */
50 if (ELEM((seq)->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE)) {
51 const StripElem *elem = seq->strip->stripdata;
52 if (elem != nullptr) {
53 int paths_count = 1;
54 if (seq->type == SEQ_TYPE_IMAGE) {
55 /* Image strip has array of file names. */
56 paths_count = int(MEM_allocN_len(elem) / sizeof(*elem));
57 }
58 char filepath[FILE_MAX];
59 const char *basepath = get_seq_base_path(seq);
60 for (int i = 0; i < paths_count; i++, elem++) {
61 BLI_path_join(filepath, sizeof(filepath), seq->strip->dirpath, elem->filename);
62 BLI_path_abs(filepath, basepath);
63 if (!BLI_exists(filepath)) {
64 return true;
65 }
66 }
67 }
68 }
69
70 /* Recurse into meta strips. */
71 if (seq->type == SEQ_TYPE_META) {
72 LISTBASE_FOREACH (Sequence *, seqn, &seq->seqbase) {
73 if (check_media_missing(seqn)) {
74 return true;
75 }
76 }
77 }
78
79 /* Nothing is missing. */
80 return false;
81}
82
87
89{
90 MediaPresence **presence = &scene->ed->runtime.media_presence;
91 if (*presence == nullptr) {
92 *presence = MEM_new<MediaPresence>(__func__);
93 }
94 return *presence;
95}
96
98{
99 if (seq == nullptr || scene == nullptr || scene->ed == nullptr) {
100 return false;
101 }
102
104
105 MediaPresence *presence = get_media_presence_cache(scene);
106
107 bool missing = false;
108
109 /* Strips that reference another data block that has path to media
110 * (e.g. sound strips) need to key the presence cache on that data
111 * block. Since it can be used by multiple strips. */
112 if (seq->type == SEQ_TYPE_SOUND_RAM) {
113 const bSound *sound = seq->sound;
114 const bool *val = presence->map_sound.lookup_ptr(sound);
115 if (val != nullptr) {
116 missing = *val;
117 }
118 else {
119 missing = check_sound_media_missing(sound, seq);
120 presence->map_sound.add_new(sound, missing);
121 }
122 }
123 else {
124 /* Regular strips that point to media directly. */
125 const bool *val = presence->map_seq.lookup_ptr(seq);
126 if (val != nullptr) {
127 missing = *val;
128 }
129 else {
130 missing = check_media_missing(seq);
131 presence->map_seq.add_new(seq, missing);
132 }
133 }
134
136 return missing;
137}
138
139void media_presence_set_missing(Scene *scene, const Sequence *seq, bool missing)
140{
141 if (seq == nullptr || scene == nullptr || scene->ed == nullptr) {
142 return;
143 }
144
146
147 MediaPresence *presence = get_media_presence_cache(scene);
148
149 if (seq->type == SEQ_TYPE_SOUND_RAM) {
150 const bSound *sound = seq->sound;
151 presence->map_sound.add_overwrite(sound, missing);
152 }
153 else {
154 presence->map_seq.add_overwrite(seq, missing);
155 }
156
158}
159
161{
163 if (scene != nullptr && scene->ed != nullptr && scene->ed->runtime.media_presence != nullptr) {
164 scene->ed->runtime.media_presence->map_seq.remove(seq);
165 }
167}
168
170{
172 if (scene != nullptr && scene->ed != nullptr && scene->ed->runtime.media_presence != nullptr) {
173 scene->ed->runtime.media_presence->map_sound.remove(sound);
174 }
176}
177
179{
181 if (scene != nullptr && scene->ed != nullptr && scene->ed->runtime.media_presence != nullptr) {
182 MEM_delete(scene->ed->runtime.media_presence);
183 scene->ed->runtime.media_presence = nullptr;
184 }
186}
187
188} // namespace blender::seq
const char * BKE_main_blendfile_path_from_global()
Definition main.cc:837
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:350
#define LISTBASE_FOREACH(type, var, list)
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
#define FILE_MAX
#define BLI_path_join(...)
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define BLI_MUTEX_INITIALIZER
Definition BLI_threads.h:84
void BLI_mutex_lock(ThreadMutex *mutex)
Definition threads.cc:345
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition threads.cc:350
pthread_mutex_t ThreadMutex
Definition BLI_threads.h:83
#define ELEM(...)
#define ID_BLEND_PATH_FROM_GLOBAL(_id)
Definition DNA_ID.h:649
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_META
@ SEQ_TYPE_IMAGE
@ SEQ_TYPE_MOVIE
const Value * lookup_ptr(const Key &key) const
Definition BLI_map.hh:484
bool add_overwrite(const Key &key, const Value &value)
Definition BLI_map.hh:301
void add_new(const Key &key, const Value &value)
Definition BLI_map.hh:241
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
size_t(* MEM_allocN_len)(const void *vmemh)
Definition mallocn.cc:36
static bool check_sound_media_missing(const bSound *sound, const Sequence *seq)
static bool check_media_missing(const Sequence *seq)
void media_presence_free(Scene *scene)
void media_presence_set_missing(Scene *scene, const Sequence *seq, bool missing)
static ThreadMutex presence_lock
void media_presence_invalidate_sound(Scene *scene, const bSound *sound)
static const char * get_seq_base_path(const Sequence *seq)
void media_presence_invalidate_strip(Scene *scene, const Sequence *seq)
bool media_presence_is_missing(Scene *scene, const Sequence *seq)
static MediaPresence * get_media_presence_cache(Scene *scene)
struct Scene * scene
struct bSound * sound
char filename[256]
char dirpath[768]
StripElem * stripdata
char filepath[1024]
Map< const void *, bool > map_seq
Map< const bSound *, bool > map_sound