Blender  V2.93
strip_relations.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  *
19  * - Blender Foundation, 2003-2009
20  * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
21  */
22 
27 #include "DNA_scene_types.h"
28 #include "DNA_sequence_types.h"
29 
30 #include "BLI_ghash.h"
31 #include "BLI_listbase.h"
32 #include "BLI_session_uuid.h"
33 
34 #include "BKE_main.h"
35 #include "BKE_report.h"
36 #include "BKE_scene.h"
37 
38 #include "DEG_depsgraph.h"
39 #include "DEG_depsgraph_query.h"
40 
41 #include "IMB_imbuf.h"
42 
43 #include "SEQ_iterator.h"
44 #include "SEQ_prefetch.h"
45 #include "SEQ_relations.h"
46 #include "SEQ_sequencer.h"
47 #include "SEQ_time.h"
48 
49 #include "effects.h"
50 #include "image_cache.h"
51 #include "utils.h"
52 
53 /* check whether sequence cur depends on seq */
55 {
56  if (cur->seq1 == seq || cur->seq2 == seq || cur->seq3 == seq) {
57  return true;
58  }
59 
60  /* sequences are not intersecting in time, assume no dependency exists between them */
61  if (cur->enddisp < seq->startdisp || cur->startdisp > seq->enddisp) {
62  return false;
63  }
64 
65  /* checking sequence is below reference one, not dependent on it */
66  if (cur->machine < seq->machine) {
67  return false;
68  }
69 
70  /* sequence is not blending with lower machines, no dependency here occurs
71  * check for non-effects only since effect could use lower machines as input
72  */
73  if ((cur->type & SEQ_TYPE_EFFECT) == 0 &&
74  ((cur->blend_mode == SEQ_BLEND_REPLACE) ||
75  (cur->blend_mode == SEQ_TYPE_CROSS && cur->blend_opacity == 100.0f))) {
76  return false;
77  }
78 
79  return true;
80 }
81 
83 {
84  Sequence *cur;
85 
86  for (cur = seqbase->first; cur; cur = cur->next) {
87  if (cur == seq) {
88  continue;
89  }
90 
91  if (seq_relations_check_depend(seq, cur)) {
92  /* Effect must be invalidated completely if they depend on invalidated seq. */
93  if ((cur->type & SEQ_TYPE_EFFECT) != 0) {
95  }
96  else {
97  /* In case of alpha over for example only invalidate composite image */
100  }
101  }
102 
103  if (cur->seqbase.first) {
105  }
106  }
107 }
108 
110  Sequence *seq,
111  bool invalidate_self,
112  int invalidate_types)
113 {
114  Editing *ed = scene->ed;
115 
116  if (invalidate_self) {
117  seq_cache_cleanup_sequence(scene, seq, seq, invalidate_types, false);
118  }
119 
120  if (seq->effectdata && seq->type == SEQ_TYPE_SPEED) {
122  }
123 
127 }
128 
129 /* Find metastrips that contain invalidated_seq and invalidate them. */
131  Sequence *invalidated_seq,
132  Sequence *meta_seq)
133 {
134  ListBase *seqbase;
135 
136  if (meta_seq == NULL) {
137  Editing *ed = SEQ_editing_get(scene, false);
138  seqbase = &ed->seqbase;
139  }
140  else {
141  seqbase = &meta_seq->seqbase;
142  }
143 
144  LISTBASE_FOREACH (Sequence *, seq, seqbase) {
145  if (seq->type == SEQ_TYPE_META) {
146  if (seq_relations_find_and_invalidate_metas(scene, invalidated_seq, seq)) {
148  return true;
149  }
150  }
151  if (seq == invalidated_seq && meta_seq != NULL) {
153  return true;
154  }
155  }
156  return false;
157 }
158 
160  Sequence *seq,
161  Sequence *range_mask,
162  int invalidate_types)
163 {
164  seq_cache_cleanup_sequence(scene, seq, range_mask, invalidate_types, true);
166 }
167 
169 {
172 }
173 
175 {
177  seq,
178  true,
182 }
183 
185 {
187  return;
188  }
189 
193 }
194 
196 {
198  return;
199  }
200 
204 }
205 
206 static void invalidate_scene_strips(Scene *scene, Scene *scene_target, ListBase *seqbase)
207 {
208  for (Sequence *seq = seqbase->first; seq != NULL; seq = seq->next) {
209  if (seq->scene == scene_target) {
211  }
212 
213  if (seq->seqbase.first != NULL) {
214  invalidate_scene_strips(scene, scene_target, &seq->seqbase);
215  }
216  }
217 }
218 
220 {
221  for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
222  if (scene->ed != NULL) {
223  invalidate_scene_strips(scene, scene_target, &scene->ed->seqbase);
224  }
225  }
226 }
227 
228 static void invalidate_movieclip_strips(Scene *scene, MovieClip *clip_target, ListBase *seqbase)
229 {
230  for (Sequence *seq = seqbase->first; seq != NULL; seq = seq->next) {
231  if (seq->clip == clip_target) {
233  }
234 
235  if (seq->seqbase.first != NULL) {
236  invalidate_movieclip_strips(scene, clip_target, &seq->seqbase);
237  }
238  }
239 }
240 
242 {
243  for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
244  if (scene->ed != NULL) {
246  }
247  }
248 }
249 
250 void SEQ_relations_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render)
251 {
252  if (scene->ed == NULL) {
253  return;
254  }
255 
256  Sequence *seq;
257 
260 
261  for (seq = seqbase->first; seq; seq = seq->next) {
262  if (for_render && CFRA >= seq->startdisp && CFRA <= seq->enddisp) {
263  continue;
264  }
265 
266  if (seq->strip) {
267  if (seq->type == SEQ_TYPE_MOVIE) {
269  }
270  if (seq->type == SEQ_TYPE_SPEED) {
272  }
273  }
274  if (seq->type == SEQ_TYPE_META) {
275  SEQ_relations_free_imbuf(scene, &seq->seqbase, for_render);
276  }
277  if (seq->type == SEQ_TYPE_SCENE) {
278  /* FIXME: recurse downwards,
279  * but do recurse protection somehow! */
280  }
281  }
282 }
283 
285  Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
286 {
287  Sequence *subseq;
288  bool free_imbuf = false;
289 
290  /* recurse downwards to see if this seq depends on the changed seq */
291 
292  if (seq == NULL) {
293  return false;
294  }
295 
296  if (seq == changed_seq) {
297  free_imbuf = true;
298  }
299 
300  for (subseq = seq->seqbase.first; subseq; subseq = subseq->next) {
301  if (update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change)) {
302  free_imbuf = true;
303  }
304  }
305 
306  if (seq->seq1) {
307  if (update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change)) {
308  free_imbuf = true;
309  }
310  }
311  if (seq->seq2 && (seq->seq2 != seq->seq1)) {
312  if (update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change)) {
313  free_imbuf = true;
314  }
315  }
316  if (seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2)) {
317  if (update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change)) {
318  free_imbuf = true;
319  }
320  }
321 
322  if (free_imbuf) {
323  if (ibuf_change) {
324  if (seq->type == SEQ_TYPE_MOVIE) {
326  }
327  else if (seq->type == SEQ_TYPE_SPEED) {
329  }
330  }
331 
332  if (len_change) {
334  }
335  }
336 
337  return free_imbuf;
338 }
339 
341  Sequence *changed_seq,
342  int len_change,
343  int ibuf_change)
344 {
345  Editing *ed = SEQ_editing_get(scene, false);
346  Sequence *seq;
347 
348  if (ed == NULL) {
349  return;
350  }
351 
352  for (seq = ed->seqbase.first; seq; seq = seq->next) {
353  update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change);
354  }
355 }
356 
357 /* Unused */
358 static void sequencer_all_free_anim_ibufs(ListBase *seqbase, int timeline_frame)
359 {
360  for (Sequence *seq = seqbase->first; seq != NULL; seq = seq->next) {
361  if (seq->enddisp < timeline_frame || seq->startdisp > timeline_frame) {
363  }
364  if (seq->type == SEQ_TYPE_META) {
365  sequencer_all_free_anim_ibufs(&seq->seqbase, timeline_frame);
366  }
367  }
368 }
369 
370 /* Unused */
372 {
373  Editing *ed = SEQ_editing_get(scene, false);
374  if (ed == NULL) {
375  return;
376  }
377  sequencer_all_free_anim_ibufs(&ed->seqbase, timeline_frame);
379 }
380 
382 {
383  LISTBASE_FOREACH (Sequence *, seq, seqbase) {
384  if (seq->type == SEQ_TYPE_SCENE && seq->scene == scene) {
385  return seq;
386  }
387 
388  if (seq->type == SEQ_TYPE_SCENE && (seq->flag & SEQ_SCENE_STRIPS)) {
389  if (sequencer_check_scene_recursion(scene, &seq->scene->ed->seqbase)) {
390  return seq;
391  }
392  }
393 
394  if (seq->type == SEQ_TYPE_META && sequencer_check_scene_recursion(scene, &seq->seqbase)) {
395  return seq;
396  }
397  }
398 
399  return NULL;
400 }
401 
403 {
404  Editing *ed = SEQ_editing_get(scene, false);
405  if (ed == NULL) {
406  return false;
407  }
408 
409  Sequence *recursive_seq = sequencer_check_scene_recursion(scene, &ed->seqbase);
410 
411  if (recursive_seq != NULL) {
412  BKE_reportf(reports,
413  RPT_WARNING,
414  "Recursion detected in video sequencer. Strip %s at frame %d will not be rendered",
415  recursive_seq->name + 2,
416  recursive_seq->startdisp);
417 
418  LISTBASE_FOREACH (Sequence *, seq, &ed->seqbase) {
419  if (seq->type != SEQ_TYPE_SCENE && sequencer_seq_generates_image(seq)) {
420  /* There are other strips to render, so render them. */
421  return false;
422  }
423  }
424  /* No other strips to render - cancel operator. */
425  return true;
426  }
427 
428  return false;
429 }
430 
431 /* Check if "seq_main" (indirectly) uses strip "seq". */
433 {
434  if (seq_main == NULL || seq == NULL) {
435  return false;
436  }
437 
438  if (seq_main == seq) {
439  return true;
440  }
441 
442  if ((seq_main->seq1 && SEQ_relations_render_loop_check(seq_main->seq1, seq)) ||
443  (seq_main->seq2 && SEQ_relations_render_loop_check(seq_main->seq2, seq)) ||
444  (seq_main->seq3 && SEQ_relations_render_loop_check(seq_main->seq3, seq))) {
445  return true;
446  }
447 
449  for (smd = seq_main->modifiers.first; smd; smd = smd->next) {
451  return true;
452  }
453  }
454 
455  return false;
456 }
457 
458 /* Function to free imbuf and anim data on changes */
460 {
461  while (seq->anims.last) {
462  StripAnim *sanim = seq->anims.last;
463 
464  if (sanim->anim) {
465  IMB_free_anim(sanim->anim);
466  sanim->anim = NULL;
467  }
468 
469  BLI_freelinkN(&seq->anims, sanim);
470  }
471  BLI_listbase_clear(&seq->anims);
472 }
473 
475 {
477 }
478 
480 {
481  if (scene->ed == NULL) {
482  return;
483  }
484 
485  struct GSet *used_uuids = BLI_gset_new(
487 
488  const Sequence *sequence;
489  SEQ_ALL_BEGIN (scene->ed, sequence) {
490  const SessionUUID *session_uuid = &sequence->runtime.session_uuid;
491  if (!BLI_session_uuid_is_generated(session_uuid)) {
492  printf("Sequence %s does not have UUID generated.\n", sequence->name);
493  continue;
494  }
495 
496  if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) {
497  printf("Sequence %s has duplicate UUID generated.\n", sequence->name);
498  continue;
499  }
500 
501  BLI_gset_insert(used_uuids, (void *)session_uuid);
502  }
503  SEQ_ALL_END;
504 
505  BLI_gset_free(used_uuids, NULL);
506 }
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
struct GSet GSet
Definition: BLI_ghash.h:189
GSet * BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:1125
void BLI_gset_insert(GSet *gs, void *key)
Definition: BLI_ghash.c:1147
void * BLI_gset_lookup(GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:1280
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1253
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:281
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
bool BLI_session_uuid_ghash_compare(const void *lhs_v, const void *rhs_v)
Definition: session_uuid.c:73
SessionUUID BLI_session_uuid_generate(void)
Definition: session_uuid.c:36
uint BLI_session_uuid_ghash_hash(const void *uuid_v)
Definition: session_uuid.c:67
bool BLI_session_uuid_is_generated(const SessionUUID *uuid)
Definition: session_uuid.c:52
#define ELEM(...)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_SEQUENCER_STRIPS
Definition: DNA_ID.h:658
#define CFRA
#define SEQ_BLEND_REPLACE
@ SEQ_SCENE_STRIPS
@ SEQ_CACHE_ALL_TYPES
@ SEQ_CACHE_STORE_PREPROCESSED
@ SEQ_CACHE_STORE_FINAL_OUT
@ SEQ_CACHE_STORE_COMPOSITE
@ 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
void IMB_free_anim(struct anim *anim)
Definition: anim_movie.c:207
#define SEQ_ALL_END
Definition: SEQ_iterator.h:48
#define SEQ_ALL_BEGIN(ed, _seq)
Definition: SEQ_iterator.h:41
Scene scene
void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq, bool force)
Definition: effects.c:3172
void SEQ_cache_cleanup(Scene *scene)
Definition: image_cache.c:1251
void seq_cache_cleanup_sequence(Scene *scene, Sequence *seq, Sequence *seq_changed, int invalidate_types, bool force_seq_changed_range)
Definition: image_cache.c:1274
void SEQ_prefetch_stop(Scene *scene)
Definition: prefetch.c:272
Editing * SEQ_editing_get(Scene *scene, bool alloc)
Definition: sequencer.c:232
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)
void SEQ_relations_update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
static bool seq_relations_find_and_invalidate_metas(Scene *scene, Sequence *invalidated_seq, Sequence *meta_seq)
static Sequence * sequencer_check_scene_recursion(Scene *scene, ListBase *seqbase)
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)
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)
static void sequencer_all_free_anim_ibufs(ListBase *seqbase, int timeline_frame)
void SEQ_relations_session_uuid_generate(struct Sequence *sequence)
void SEQ_relations_invalidate_dependent(Scene *scene, Sequence *seq)
static bool seq_relations_check_depend(Sequence *seq, Sequence *cur)
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)
static bool update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
void SEQ_relations_invalidate_cache_preprocessed(Scene *scene, Sequence *seq)
void SEQ_relations_invalidate_cache_composite(Scene *scene, Sequence *seq)
void SEQ_time_update_sequence(Scene *scene, Sequence *seq)
Definition: strip_time.c:197
ListBase seqbase
void * next
Definition: DNA_ID.h:274
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
ListBase scenes
Definition: BKE_main.h:146
struct Editing * ed
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:542