Blender V5.0
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 bool check_sound_media_missing(const bSound *sound)
30{
31 if (sound == nullptr) {
32 return false;
33 }
34
35 char filepath[FILE_MAX];
36 STRNCPY(filepath, sound->filepath);
37 BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL(&sound->id));
38 return !BLI_exists(filepath);
39}
40
41static bool check_media_missing(const Scene *scene, const Strip *strip)
42{
43 if (strip == nullptr || strip->data == nullptr) {
44 return false;
45 }
46
47 /* Images or movies. */
48 if (ELEM((strip)->type, STRIP_TYPE_MOVIE, STRIP_TYPE_IMAGE)) {
49 const StripElem *elem = strip->data->stripdata;
50 if (elem != nullptr) {
51 int paths_count = 1;
52 if (strip->type == STRIP_TYPE_IMAGE) {
53 /* Image strip has array of file names. */
54 paths_count = int(MEM_allocN_len(elem) / sizeof(*elem));
55 }
56 char filepath[FILE_MAX];
57 const char *basepath = ID_BLEND_PATH_FROM_GLOBAL(&scene->id);
58 for (int i = 0; i < paths_count; i++, elem++) {
59 BLI_path_join(filepath, sizeof(filepath), strip->data->dirpath, elem->filename);
60 BLI_path_abs(filepath, basepath);
61 if (!BLI_exists(filepath)) {
62 return true;
63 }
64 }
65 }
66 }
67
68 /* Recurse into meta strips. */
69 if (strip->type == STRIP_TYPE_META) {
70 LISTBASE_FOREACH (Strip *, strip_n, &strip->seqbase) {
71 if (check_media_missing(scene, strip_n)) {
72 return true;
73 }
74 }
75 }
76
77 /* Nothing is missing. */
78 return false;
79}
80
85
87{
88 MediaPresence **presence = &scene->ed->runtime.media_presence;
89 if (*presence == nullptr) {
90 *presence = MEM_new<MediaPresence>(__func__);
91 }
92 return *presence;
93}
94
95bool media_presence_is_missing(Scene *scene, const Strip *strip)
96{
97 if (strip == nullptr || scene == nullptr || scene->ed == nullptr) {
98 return false;
99 }
100
101 std::scoped_lock lock(presence_lock);
102
103 MediaPresence *presence = get_media_presence_cache(scene);
104
105 bool missing = false;
106
107 /* Strips that reference another data block that has path to media
108 * (e.g. sound strips) need to key the presence cache on that data
109 * block. Since it can be used by multiple strips. */
110 if (strip->type == STRIP_TYPE_SOUND_RAM) {
111 const bSound *sound = strip->sound;
112 const bool *val = presence->map_sound.lookup_ptr(sound);
113 if (val != nullptr) {
114 missing = *val;
115 }
116 else {
117 missing = check_sound_media_missing(sound);
118 presence->map_sound.add_new(sound, missing);
119 }
120 }
121 else {
122 /* Regular strips that point to media directly. */
123 const bool *val = presence->map_seq.lookup_ptr(strip);
124 if (val != nullptr) {
125 missing = *val;
126 }
127 else {
128 missing = check_media_missing(scene, strip);
129 presence->map_seq.add_new(strip, missing);
130 }
131 }
132
133 return missing;
134}
135
136void media_presence_set_missing(Scene *scene, const Strip *strip, bool missing)
137{
138 if (strip == nullptr || scene == nullptr || scene->ed == nullptr) {
139 return;
140 }
141
142 std::scoped_lock lock(presence_lock);
143
144 MediaPresence *presence = get_media_presence_cache(scene);
145
146 if (strip->type == STRIP_TYPE_SOUND_RAM) {
147 const bSound *sound = strip->sound;
148 presence->map_sound.add_overwrite(sound, missing);
149 }
150 else {
151 presence->map_seq.add_overwrite(strip, missing);
152 }
153}
154
156{
157 std::scoped_lock lock(presence_lock);
158 if (scene != nullptr && scene->ed != nullptr && scene->ed->runtime.media_presence != nullptr) {
159 scene->ed->runtime.media_presence->map_seq.remove(strip);
160 }
161}
162
164{
165 std::scoped_lock lock(presence_lock);
166 if (scene != nullptr && scene->ed != nullptr && scene->ed->runtime.media_presence != nullptr) {
167 scene->ed->runtime.media_presence->map_sound.remove(sound);
168 }
169}
170
172{
173 std::scoped_lock lock(presence_lock);
174 if (scene != nullptr && scene->ed != nullptr && scene->ed->runtime.media_presence != nullptr) {
175 MEM_delete(scene->ed->runtime.media_presence);
176 scene->ed->runtime.media_presence = nullptr;
177 }
178}
179
180} // namespace blender::seq
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:360
#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:693
#define ELEM(...)
#define ID_BLEND_PATH_FROM_GLOBAL(_id)
Definition DNA_ID.h:688
@ 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
size_t(* MEM_allocN_len)(const void *vmemh)
Definition mallocn.cc:36
bool media_presence_is_missing(Scene *scene, const Strip *strip)
void media_presence_free(Scene *scene)
static bool check_sound_media_missing(const bSound *sound)
static bool check_media_missing(const Scene *scene, 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 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 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