Blender V4.5
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
8
9#include "BLI_fileops.h"
10#include "BLI_listbase.h"
11#include "BLI_map.hh"
12#include "BLI_mutex.hh"
13#include "BLI_path_utils.hh"
14#include "BLI_string.h"
15
16#include "DNA_scene_types.h"
17#include "DNA_sequence_types.h"
18#include "DNA_sound_types.h"
19
20#include "BKE_library.hh"
21#include "BKE_main.hh"
22
23#include "SEQ_utils.hh"
24
25namespace blender::seq {
26
28
29static const char *strip_base_path_get(const Strip *strip)
30{
31 return strip->scene ? ID_BLEND_PATH_FROM_GLOBAL(&strip->scene->id) :
33}
34
35static bool check_sound_media_missing(const bSound *sound, const Strip *strip)
36{
37 if (sound == nullptr) {
38 return false;
39 }
40
41 char filepath[FILE_MAX];
42 STRNCPY(filepath, sound->filepath);
43 const char *basepath = strip_base_path_get(strip);
44 BLI_path_abs(filepath, basepath);
45 return !BLI_exists(filepath);
46}
47
48static bool check_media_missing(const Strip *strip)
49{
50 if (strip == nullptr || strip->data == nullptr) {
51 return false;
52 }
53
54 /* Images or movies. */
55 if (ELEM((strip)->type, STRIP_TYPE_MOVIE, STRIP_TYPE_IMAGE)) {
56 const StripElem *elem = strip->data->stripdata;
57 if (elem != nullptr) {
58 int paths_count = 1;
59 if (strip->type == STRIP_TYPE_IMAGE) {
60 /* Image strip has array of file names. */
61 paths_count = int(MEM_allocN_len(elem) / sizeof(*elem));
62 }
63 char filepath[FILE_MAX];
64 const char *basepath = strip_base_path_get(strip);
65 for (int i = 0; i < paths_count; i++, elem++) {
66 BLI_path_join(filepath, sizeof(filepath), strip->data->dirpath, elem->filename);
67 BLI_path_abs(filepath, basepath);
68 if (!BLI_exists(filepath)) {
69 return true;
70 }
71 }
72 }
73 }
74
75 /* Recurse into meta strips. */
76 if (strip->type == STRIP_TYPE_META) {
77 LISTBASE_FOREACH (Strip *, strip_n, &strip->seqbase) {
78 if (check_media_missing(strip_n)) {
79 return true;
80 }
81 }
82 }
83
84 /* Nothing is missing. */
85 return false;
86}
87
92
94{
95 MediaPresence **presence = &scene->ed->runtime.media_presence;
96 if (*presence == nullptr) {
97 *presence = MEM_new<MediaPresence>(__func__);
98 }
99 return *presence;
100}
101
102bool media_presence_is_missing(Scene *scene, const Strip *strip)
103{
104 if (strip == nullptr || scene == nullptr || scene->ed == nullptr) {
105 return false;
106 }
107
108 std::scoped_lock lock(presence_lock);
109
110 MediaPresence *presence = get_media_presence_cache(scene);
111
112 bool missing = false;
113
114 /* Strips that reference another data block that has path to media
115 * (e.g. sound strips) need to key the presence cache on that data
116 * block. Since it can be used by multiple strips. */
117 if (strip->type == STRIP_TYPE_SOUND_RAM) {
118 const bSound *sound = strip->sound;
119 const bool *val = presence->map_sound.lookup_ptr(sound);
120 if (val != nullptr) {
121 missing = *val;
122 }
123 else {
124 missing = check_sound_media_missing(sound, strip);
125 presence->map_sound.add_new(sound, missing);
126 }
127 }
128 else {
129 /* Regular strips that point to media directly. */
130 const bool *val = presence->map_seq.lookup_ptr(strip);
131 if (val != nullptr) {
132 missing = *val;
133 }
134 else {
135 missing = check_media_missing(strip);
136 presence->map_seq.add_new(strip, missing);
137 }
138 }
139
140 return missing;
141}
142
143void media_presence_set_missing(Scene *scene, const Strip *strip, bool missing)
144{
145 if (strip == nullptr || scene == nullptr || scene->ed == nullptr) {
146 return;
147 }
148
149 std::scoped_lock lock(presence_lock);
150
151 MediaPresence *presence = get_media_presence_cache(scene);
152
153 if (strip->type == STRIP_TYPE_SOUND_RAM) {
154 const bSound *sound = strip->sound;
155 presence->map_sound.add_overwrite(sound, missing);
156 }
157 else {
158 presence->map_seq.add_overwrite(strip, missing);
159 }
160}
161
163{
164 std::scoped_lock lock(presence_lock);
165 if (scene != nullptr && scene->ed != nullptr && scene->ed->runtime.media_presence != nullptr) {
166 scene->ed->runtime.media_presence->map_seq.remove(strip);
167 }
168}
169
171{
172 std::scoped_lock lock(presence_lock);
173 if (scene != nullptr && scene->ed != nullptr && scene->ed->runtime.media_presence != nullptr) {
174 scene->ed->runtime.media_presence->map_sound.remove(sound);
175 }
176}
177
179{
180 std::scoped_lock lock(presence_lock);
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 }
185}
186
187} // namespace blender::seq
const char * BKE_main_blendfile_path_from_global()
Definition main.cc:877
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:373
#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(...)
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
#define ELEM(...)
@ STRIP_TYPE_SOUND_RAM
@ STRIP_TYPE_IMAGE
@ STRIP_TYPE_MOVIE
@ STRIP_TYPE_META
volatile int lock
const Value * lookup_ptr(const Key &key) const
Definition BLI_map.hh:508
bool add_overwrite(const Key &key, const Value &value)
Definition BLI_map.hh:325
void add_new(const Key &key, const Value &value)
Definition BLI_map.hh:265
bool remove(const Key &key)
Definition BLI_map.hh:368
#define ID_BLEND_PATH_FROM_GLOBAL(_id)
size_t(* MEM_allocN_len)(const void *vmemh)
Definition mallocn.cc:36
static const char * strip_base_path_get(const Strip *strip)
bool media_presence_is_missing(Scene *scene, const Strip *strip)
void media_presence_free(Scene *scene)
static bool check_media_missing(const Strip *strip)
void media_presence_invalidate_sound(Scene *scene, const bSound *sound)
static blender::Mutex presence_lock
void media_presence_invalidate_strip(Scene *scene, const Strip *strip)
void media_presence_set_missing(Scene *scene, const Strip *strip, bool missing)
static bool check_sound_media_missing(const bSound *sound, const Strip *strip)
static MediaPresence * get_media_presence_cache(Scene *scene)
std::mutex Mutex
Definition BLI_mutex.hh:47
MediaPresence * media_presence
EditingRuntime runtime
struct Editing * ed
StripElem * stripdata
char dirpath[768]
char filename[256]
StripData * data
struct Scene * scene
struct bSound * sound
ListBase seqbase
char filepath[1024]
Map< const void *, bool > map_seq
Map< const bSound *, bool > map_sound
i
Definition text_draw.cc:230