Blender  V3.3
strip_relations.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved.
3  * 2003-2009 Blender Foundation.
4  * 2005-2006 Peter Schlaile <peter [at] schlaile [dot] de> */
5 
10 #include "DNA_scene_types.h"
11 #include "DNA_sequence_types.h"
12 
13 #include "BLI_ghash.h"
14 #include "BLI_listbase.h"
15 #include "BLI_math.h"
16 #include "BLI_session_uuid.h"
17 
18 #include "BKE_main.h"
19 #include "BKE_report.h"
20 #include "BKE_scene.h"
21 
22 #include "DEG_depsgraph.h"
23 #include "DEG_depsgraph_query.h"
24 
25 #include "IMB_imbuf.h"
26 
27 #include "SEQ_iterator.h"
28 #include "SEQ_prefetch.h"
29 #include "SEQ_relations.h"
30 #include "SEQ_sequencer.h"
31 #include "SEQ_time.h"
32 #include "SEQ_transform.h"
33 
34 #include "effects.h"
35 #include "image_cache.h"
36 #include "utils.h"
37 
39 {
40  return ELEM(input, effect->seq1, effect->seq2);
41 }
42 
43 /* check whether sequence cur depends on seq */
44 static bool seq_relations_check_depend(const Scene *scene, Sequence *seq, Sequence *cur)
45 {
46  if (SEQ_relation_is_effect_of_strip(cur, seq)) {
47  return true;
48  }
49 
50  /* sequences are not intersecting in time, assume no dependency exists between them */
53  return false;
54  }
55 
56  /* checking sequence is below reference one, not dependent on it */
57  if (cur->machine < seq->machine) {
58  return false;
59  }
60 
61  /* sequence is not blending with lower machines, no dependency here occurs
62  * check for non-effects only since effect could use lower machines as input
63  */
64  if ((cur->type & SEQ_TYPE_EFFECT) == 0 &&
65  ((cur->blend_mode == SEQ_BLEND_REPLACE) ||
66  (cur->blend_mode == SEQ_TYPE_CROSS && cur->blend_opacity == 100.0f))) {
67  return false;
68  }
69 
70  return true;
71 }
72 
74 {
75  Sequence *cur;
76 
77  for (cur = seqbase->first; cur; cur = cur->next) {
78  if (cur == seq) {
79  continue;
80  }
81 
82  if (seq_relations_check_depend(scene, seq, cur)) {
83  /* Effect must be invalidated completely if they depend on invalidated seq. */
84  if ((cur->type & SEQ_TYPE_EFFECT) != 0) {
86  }
87  else {
88  /* In case of alpha over for example only invalidate composite image */
91  }
92  }
93 
94  if (cur->seqbase.first) {
96  }
97  }
98 }
99 
101  Sequence *seq,
102  bool invalidate_self,
103  int invalidate_types)
104 {
105  Editing *ed = scene->ed;
106 
107  if (invalidate_self) {
108  seq_cache_cleanup_sequence(scene, seq, seq, invalidate_types, false);
109  }
110 
111  if (seq->effectdata && seq->type == SEQ_TYPE_SPEED) {
113  }
114 
118 }
119 
120 /* Find metastrips that contain invalidated_seq and invalidate them. */
122  Sequence *invalidated_seq,
123  Sequence *meta_seq)
124 {
125  ListBase *seqbase;
126 
127  if (meta_seq == NULL) {
129  seqbase = &ed->seqbase;
130  }
131  else {
132  seqbase = &meta_seq->seqbase;
133  }
134 
135  LISTBASE_FOREACH (Sequence *, seq, seqbase) {
136  if (seq->type == SEQ_TYPE_META) {
137  if (seq_relations_find_and_invalidate_metas(scene, invalidated_seq, seq)) {
139  return true;
140  }
141  }
142  if (seq == invalidated_seq && meta_seq != NULL) {
144  return true;
145  }
146  }
147  return false;
148 }
149 
151  Sequence *seq,
152  Sequence *range_mask,
153  int invalidate_types)
154 {
155  seq_cache_cleanup_sequence(scene, seq, range_mask, invalidate_types, true);
157 }
158 
160 {
163 }
164 
166 {
168  seq,
169  true,
173 }
174 
176 {
178  return;
179  }
180 
184 }
185 
187 {
189  return;
190  }
191 
195 }
196 
197 static void invalidate_scene_strips(Scene *scene, Scene *scene_target, ListBase *seqbase)
198 {
199  for (Sequence *seq = seqbase->first; seq != NULL; seq = seq->next) {
200  if (seq->scene == scene_target) {
202  }
203 
204  if (seq->seqbase.first != NULL) {
205  invalidate_scene_strips(scene, scene_target, &seq->seqbase);
206  }
207  }
208 }
209 
211 {
212  for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
213  if (scene->ed != NULL) {
214  invalidate_scene_strips(scene, scene_target, &scene->ed->seqbase);
215  }
216  }
217 }
218 
219 static void invalidate_movieclip_strips(Scene *scene, MovieClip *clip_target, ListBase *seqbase)
220 {
221  for (Sequence *seq = seqbase->first; seq != NULL; seq = seq->next) {
222  if (seq->clip == clip_target) {
224  }
225 
226  if (seq->seqbase.first != NULL) {
227  invalidate_movieclip_strips(scene, clip_target, &seq->seqbase);
228  }
229  }
230 }
231 
233 {
234  for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
235  if (scene->ed != NULL) {
237  }
238  }
239 }
240 
241 void SEQ_relations_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render)
242 {
243  if (scene->ed == NULL) {
244  return;
245  }
246 
247  Sequence *seq;
248 
251 
252  for (seq = seqbase->first; seq; seq = seq->next) {
253  if (for_render && SEQ_time_strip_intersects_frame(scene, seq, scene->r.cfra)) {
254  continue;
255  }
256 
257  if (seq->strip) {
258  if (seq->type == SEQ_TYPE_MOVIE) {
260  }
261  if (seq->type == SEQ_TYPE_SPEED) {
263  }
264  }
265  if (seq->type == SEQ_TYPE_META) {
266  SEQ_relations_free_imbuf(scene, &seq->seqbase, for_render);
267  }
268  if (seq->type == SEQ_TYPE_SCENE) {
269  /* FIXME: recurse downwards,
270  * but do recurse protection somehow! */
271  }
272  }
273 }
274 
276  ListBase *seqbase,
277  int timeline_frame,
278  const int frame_range[2])
279 {
281  for (Sequence *seq = seqbase->first; seq != NULL; seq = seq->next) {
282  if (!SEQ_time_strip_intersects_frame(scene, seq, timeline_frame) ||
283  !((frame_range[0] <= timeline_frame) && (frame_range[1] > timeline_frame))) {
285  }
286  if (seq->type == SEQ_TYPE_META) {
287  int meta_range[2];
288 
290  if (ms != NULL && ms->parseq == seq) {
291  meta_range[0] = -MAXFRAME;
292  meta_range[1] = MAXFRAME;
293  }
294  else {
295  /* Limit frame range to meta strip. */
296  meta_range[0] = max_ii(frame_range[0], SEQ_time_left_handle_frame_get(scene, seq));
297  meta_range[1] = min_ii(frame_range[1], SEQ_time_right_handle_frame_get(scene, seq));
298  }
299 
300  sequencer_all_free_anim_ibufs(scene, &seq->seqbase, timeline_frame, meta_range);
301  }
302  }
303 }
304 
306 {
308  if (ed == NULL) {
309  return;
310  }
311 
312  const int frame_range[2] = {-MAXFRAME, MAXFRAME};
313  sequencer_all_free_anim_ibufs(scene, &ed->seqbase, timeline_frame, frame_range);
314 }
315 
317 {
318  LISTBASE_FOREACH (Sequence *, seq, seqbase) {
319  if (seq->type == SEQ_TYPE_SCENE && seq->scene == scene) {
320  return seq;
321  }
322 
323  if (seq->type == SEQ_TYPE_SCENE && (seq->flag & SEQ_SCENE_STRIPS)) {
324  if (sequencer_check_scene_recursion(scene, &seq->scene->ed->seqbase)) {
325  return seq;
326  }
327  }
328 
329  if (seq->type == SEQ_TYPE_META && sequencer_check_scene_recursion(scene, &seq->seqbase)) {
330  return seq;
331  }
332  }
333 
334  return NULL;
335 }
336 
338 {
340  if (ed == NULL) {
341  return false;
342  }
343 
344  Sequence *recursive_seq = sequencer_check_scene_recursion(scene, &ed->seqbase);
345 
346  if (recursive_seq != NULL) {
347  BKE_reportf(reports,
348  RPT_WARNING,
349  "Recursion detected in video sequencer. Strip %s at frame %d will not be rendered",
350  recursive_seq->name + 2,
351  SEQ_time_left_handle_frame_get(scene, recursive_seq));
352 
353  LISTBASE_FOREACH (Sequence *, seq, &ed->seqbase) {
354  if (seq->type != SEQ_TYPE_SCENE && sequencer_seq_generates_image(seq)) {
355  /* There are other strips to render, so render them. */
356  return false;
357  }
358  }
359  /* No other strips to render - cancel operator. */
360  return true;
361  }
362 
363  return false;
364 }
365 
367 {
368  if (seq_main == NULL || seq == NULL) {
369  return false;
370  }
371 
372  if (seq_main == seq) {
373  return true;
374  }
375 
376  if ((seq_main->seq1 && SEQ_relations_render_loop_check(seq_main->seq1, seq)) ||
377  (seq_main->seq2 && SEQ_relations_render_loop_check(seq_main->seq2, seq)) ||
378  (seq_main->seq3 && SEQ_relations_render_loop_check(seq_main->seq3, seq))) {
379  return true;
380  }
381 
383  for (smd = seq_main->modifiers.first; smd; smd = smd->next) {
385  return true;
386  }
387  }
388 
389  return false;
390 }
391 
393 {
394  while (seq->anims.last) {
395  StripAnim *sanim = seq->anims.last;
396 
397  if (sanim->anim) {
398  IMB_free_anim(sanim->anim);
399  sanim->anim = NULL;
400  }
401 
402  BLI_freelinkN(&seq->anims, sanim);
403  }
404  BLI_listbase_clear(&seq->anims);
405 }
406 
408 {
410 }
411 
412 static bool get_uuids_cb(Sequence *seq, void *user_data)
413 {
414  struct GSet *used_uuids = (struct GSet *)user_data;
415  const SessionUUID *session_uuid = &seq->runtime.session_uuid;
416  if (!BLI_session_uuid_is_generated(session_uuid)) {
417  printf("Sequence %s does not have UUID generated.\n", seq->name);
418  return true;
419  }
420 
421  if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) {
422  printf("Sequence %s has duplicate UUID generated.\n", seq->name);
423  return true;
424  }
425 
426  BLI_gset_insert(used_uuids, (void *)session_uuid);
427  return true;
428 }
429 
431 {
432  if (scene->ed == NULL) {
433  return;
434  }
435 
436  struct GSet *used_uuids = BLI_gset_new(
438 
440 
441  BLI_gset_free(used_uuids, NULL);
442 }
443 
445 {
446  Sequence *iseq;
447 
448  for (iseq = seqbase->first; iseq; iseq = iseq->next) {
449  Sequence *rval;
450 
451  if (seq == iseq) {
452  return meta;
453  }
454  if (iseq->seqbase.first &&
455  (rval = SEQ_find_metastrip_by_sequence(&iseq->seqbase, iseq, seq))) {
456  return rval;
457  }
458  }
459 
460  return NULL;
461 }
462 
464 {
465  LISTBASE_FOREACH (Sequence *, seq_test, seqbase) {
466  if (seq_test->type == SEQ_TYPE_META && SEQ_exists_in_seqbase(seq, &seq_test->seqbase)) {
467  return true;
468  }
469  if (seq_test == seq) {
470  return true;
471  }
472  }
473  return false;
474 }
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
struct GSet GSet
Definition: BLI_ghash.h:340
GSet * BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:947
void * BLI_gset_lookup(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:1061
void BLI_gset_insert(GSet *gs, void *key)
Definition: BLI_ghash.c:962
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1037
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:239
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
bool BLI_session_uuid_ghash_compare(const void *lhs_v, const void *rhs_v)
Definition: session_uuid.c:59
SessionUUID BLI_session_uuid_generate(void)
Definition: session_uuid.c:22
uint BLI_session_uuid_ghash_hash(const void *uuid_v)
Definition: session_uuid.c:53
bool BLI_session_uuid_is_generated(const SessionUUID *uuid)
Definition: session_uuid.c:38
#define ELEM(...)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_SEQUENCER_STRIPS
Definition: DNA_ID.h:838
#define MAXFRAME
#define SEQ_BLEND_REPLACE
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_CROSS
@ SEQ_TYPE_SOUND_HD
@ SEQ_TYPE_META
@ SEQ_TYPE_SCENE
@ SEQ_TYPE_SPEED
@ SEQ_TYPE_EFFECT
@ SEQ_TYPE_MOVIE
@ SEQ_CACHE_ALL_TYPES
@ SEQ_CACHE_STORE_PREPROCESSED
@ SEQ_CACHE_STORE_FINAL_OUT
@ SEQ_CACHE_STORE_COMPOSITE
@ SEQ_SCENE_STRIPS
void IMB_free_anim(struct anim *anim)
Definition: anim_movie.c:193
Scene scene
void * user_data
void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq)
Definition: effects.c:2591
void SEQ_cache_cleanup(Scene *scene)
Definition: image_cache.c:602
void seq_cache_cleanup_sequence(Scene *scene, Sequence *seq, Sequence *seq_changed, int invalidate_types, bool force_seq_changed_range)
Definition: image_cache.c:626
void SEQ_for_each_callback(ListBase *seqbase, SeqForEachFunc callback, void *user_data)
Definition: iterator.c:76
ccl_global KernelShaderEvalInput * input
void SEQ_prefetch_stop(Scene *scene)
Definition: prefetch.c:254
MetaStack * SEQ_meta_stack_active_get(const Editing *ed)
Definition: sequencer.c:420
Editing * SEQ_editing_get(const Scene *scene)
Definition: sequencer.c:241
void SEQ_relations_check_uuids_unique_and_report(const Scene *scene)
bool SEQ_relations_render_loop_check(Sequence *seq_main, Sequence *seq)
void SEQ_relations_invalidate_cache_raw(Scene *scene, Sequence *seq)
static void sequence_invalidate_cache(Scene *scene, Sequence *seq, bool invalidate_self, int invalidate_types)
static bool seq_relations_find_and_invalidate_metas(Scene *scene, Sequence *invalidated_seq, Sequence *meta_seq)
static void sequencer_all_free_anim_ibufs(const Scene *scene, ListBase *seqbase, int timeline_frame, const int frame_range[2])
bool SEQ_exists_in_seqbase(const Sequence *seq, const ListBase *seqbase)
static Sequence * sequencer_check_scene_recursion(Scene *scene, ListBase *seqbase)
static bool seq_relations_check_depend(const Scene *scene, Sequence *seq, Sequence *cur)
void SEQ_relations_invalidate_cache_in_range(Scene *scene, Sequence *seq, Sequence *range_mask, int invalidate_types)
void SEQ_relations_sequence_free_anim(Sequence *seq)
struct Sequence * SEQ_find_metastrip_by_sequence(ListBase *seqbase, Sequence *meta, Sequence *seq)
static bool get_uuids_cb(Sequence *seq, void *user_data)
bool SEQ_relations_check_scene_recursion(Scene *scene, ReportList *reports)
void SEQ_relations_invalidate_scene_strips(Main *bmain, Scene *scene_target)
void SEQ_relations_free_all_anim_ibufs(Scene *scene, int timeline_frame)
static void sequence_do_invalidate_dependent(Scene *scene, Sequence *seq, ListBase *seqbase)
static void invalidate_scene_strips(Scene *scene, Scene *scene_target, ListBase *seqbase)
void SEQ_relations_session_uuid_generate(struct Sequence *sequence)
void SEQ_relations_invalidate_dependent(Scene *scene, Sequence *seq)
bool SEQ_relation_is_effect_of_strip(const Sequence *effect, const Sequence *input)
void SEQ_relations_invalidate_movieclip_strips(Main *bmain, MovieClip *clip_target)
static void invalidate_movieclip_strips(Scene *scene, MovieClip *clip_target, ListBase *seqbase)
void SEQ_relations_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render)
void SEQ_relations_invalidate_cache_preprocessed(Scene *scene, Sequence *seq)
void SEQ_relations_invalidate_cache_composite(Scene *scene, Sequence *seq)
int SEQ_time_left_handle_frame_get(const Scene *UNUSED(scene), const Sequence *seq)
Definition: strip_time.c:506
bool SEQ_time_strip_intersects_frame(const Scene *scene, const Sequence *seq, const int timeline_frame)
Definition: strip_time.c:437
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
Definition: strip_time.c:515
ListBase seqbase
void * next
Definition: DNA_ID.h:369
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
ListBase scenes
Definition: BKE_main.h:168
Sequence * parseq
struct Editing * ed
struct RenderData r
struct SequenceModifierData * next
struct Sequence * mask_sequence
SessionUUID session_uuid
ListBase anims
struct Sequence * seq3
ListBase modifiers
ListBase seqbase
struct Sequence * seq1
struct Sequence * seq2
struct Sequence * next
SequenceRuntime runtime
struct anim * anim
bool sequencer_seq_generates_image(Sequence *seq)
Definition: utils.c:477