Blender  V3.3
strip_edit.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_listbase.h"
14 #include "BLI_math.h"
15 #include "BLI_string.h"
16 #include "BLI_string_utf8.h"
17 
18 #include "BLT_translation.h"
19 
20 #include "BKE_main.h"
21 #include "BKE_movieclip.h"
22 #include "BKE_scene.h"
23 #include "BKE_sound.h"
24 
25 #include "strip_time.h"
26 #include "utils.h"
27 
28 #include "SEQ_add.h"
29 #include "SEQ_animation.h"
30 #include "SEQ_edit.h"
31 #include "SEQ_effects.h"
32 #include "SEQ_iterator.h"
33 #include "SEQ_relations.h"
34 #include "SEQ_render.h"
35 #include "SEQ_sequencer.h"
36 #include "SEQ_time.h"
37 #include "SEQ_transform.h"
38 #include "SEQ_utils.h"
39 
40 int SEQ_edit_sequence_swap(Scene *scene, Sequence *seq_a, Sequence *seq_b, const char **error_str)
41 {
42  char name[sizeof(seq_a->name)];
43 
45  *error_str = N_("Strips must be the same length");
46  return 0;
47  }
48 
49  /* type checking, could be more advanced but disallow sound vs non-sound copy */
50  if (seq_a->type != seq_b->type) {
51  if (seq_a->type == SEQ_TYPE_SOUND_RAM || seq_b->type == SEQ_TYPE_SOUND_RAM) {
52  *error_str = N_("Strips were not compatible");
53  return 0;
54  }
55 
56  /* disallow effects to swap with non-effects strips */
57  if ((seq_a->type & SEQ_TYPE_EFFECT) != (seq_b->type & SEQ_TYPE_EFFECT)) {
58  *error_str = N_("Strips were not compatible");
59  return 0;
60  }
61 
62  if ((seq_a->type & SEQ_TYPE_EFFECT) && (seq_b->type & SEQ_TYPE_EFFECT)) {
64  *error_str = N_("Strips must have the same number of inputs");
65  return 0;
66  }
67  }
68  }
69 
70  SWAP(Sequence, *seq_a, *seq_b);
71 
72  /* swap back names so animation fcurves don't get swapped */
73  BLI_strncpy(name, seq_a->name + 2, sizeof(name));
74  BLI_strncpy(seq_a->name + 2, seq_b->name + 2, sizeof(seq_b->name) - 2);
75  BLI_strncpy(seq_b->name + 2, name, sizeof(seq_b->name) - 2);
76 
77  /* swap back opacity, and overlay mode */
78  SWAP(int, seq_a->blend_mode, seq_b->blend_mode);
79  SWAP(float, seq_a->blend_opacity, seq_b->blend_opacity);
80 
81  SWAP(Sequence *, seq_a->prev, seq_b->prev);
82  SWAP(Sequence *, seq_a->next, seq_b->next);
83  SWAP(float, seq_a->start, seq_b->start);
84  SWAP(float, seq_a->startofs, seq_b->startofs);
85  SWAP(float, seq_a->endofs, seq_b->endofs);
86  SWAP(int, seq_a->machine, seq_b->machine);
89 
90  return 1;
91 }
92 
94  ListBase *seqbasep,
95  Sequence *metaseq,
96  int mute)
97 {
98  Sequence *seq;
99  int seqmute;
100 
101  /* For sound we go over full meta tree to update muted state,
102  * since sound is played outside of evaluating the imbufs. */
103  for (seq = seqbasep->first; seq; seq = seq->next) {
104  seqmute = (mute || SEQ_render_is_muted(channels, seq));
105 
106  if (seq->type == SEQ_TYPE_META) {
107  /* if this is the current meta sequence, unmute because
108  * all sequences above this were set to mute */
109  if (seq == metaseq) {
110  seqmute = 0;
111  }
112 
113  seq_update_muting_recursive(&seq->channels, &seq->seqbase, metaseq, seqmute);
114  }
115  else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
116  if (seq->scene_sound) {
118  }
119  }
120  }
121 }
122 
124 {
125  if (ed) {
126  /* mute all sounds up to current metastack list */
127  MetaStack *ms = ed->metastack.last;
128 
129  if (ms) {
131  }
132  else {
134  }
135  }
136 }
137 
139 {
140  LISTBASE_FOREACH (Sequence *, user_seq, seqbase) {
141  /* Look in meta-strips for usage of seq. */
142  if (user_seq->type == SEQ_TYPE_META) {
143  sequencer_flag_users_for_removal(scene, &user_seq->seqbase, seq);
144  }
145 
146  /* Clear seq from modifiers. */
148  for (smd = user_seq->modifiers.first; smd; smd = smd->next) {
149  if (smd->mask_sequence == seq) {
150  smd->mask_sequence = NULL;
151  }
152  }
153 
154  /* Remove effects, that use seq. */
155  if (SEQ_relation_is_effect_of_strip(user_seq, seq)) {
156  user_seq->flag |= SEQ_FLAG_DELETE;
157  /* Strips can be used as mask even if not in same seqbase. */
159  }
160  }
161 }
162 
164 {
165  if (seq == NULL || (seq->flag & SEQ_FLAG_DELETE) != 0) {
166  return;
167  }
168 
169  /* Flag and remove meta children. */
170  if (seq->type == SEQ_TYPE_META) {
171  LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) {
172  SEQ_edit_flag_for_removal(scene, &seq->seqbase, meta_child);
173  }
174  }
175 
176  seq->flag |= SEQ_FLAG_DELETE;
178 }
179 
181 {
182  LISTBASE_FOREACH_MUTABLE (Sequence *, seq, seqbase) {
183  if (seq->flag & SEQ_FLAG_DELETE) {
184  if (seq->type == SEQ_TYPE_META) {
186  }
187  SEQ_free_animdata(scene, seq);
188  BLI_remlink(seqbase, seq);
189  SEQ_sequence_free(scene, seq);
191  }
192  }
193 }
194 
196  ListBase *seqbase,
197  Sequence *seq,
198  ListBase *dst_seqbase)
199 {
200  /* Move to meta. */
201  BLI_remlink(seqbase, seq);
202  BLI_addtail(dst_seqbase, seq);
204 
205  /* Update meta. */
206  if (SEQ_transform_test_overlap(scene, dst_seqbase, seq)) {
207  SEQ_transform_seqbase_shuffle(dst_seqbase, seq, scene);
208  }
209 
210  return true;
211 }
212 
214  Sequence *src_seq,
215  Sequence *dst_seqm,
216  const char **error_str)
217 {
218  /* Find the appropriate seqbase */
220  ListBase *seqbase = SEQ_get_seqbase_by_seq(scene, src_seq);
221 
222  if (dst_seqm->type != SEQ_TYPE_META) {
223  *error_str = N_("Can not move strip to non-meta strip");
224  return false;
225  }
226 
227  if (src_seq == dst_seqm) {
228  *error_str = N_("Strip can not be moved into itself");
229  return false;
230  }
231 
232  if (seqbase == &dst_seqm->seqbase) {
233  *error_str = N_("Moved strip is already inside provided meta strip");
234  return false;
235  }
236 
237  if (src_seq->type == SEQ_TYPE_META && SEQ_exists_in_seqbase(dst_seqm, &src_seq->seqbase)) {
238  *error_str = N_("Moved strip is parent of provided meta strip");
239  return false;
240  }
241 
242  if (!SEQ_exists_in_seqbase(dst_seqm, &ed->seqbase)) {
243  *error_str = N_("Can not move strip to different scene");
244  return false;
245  }
246 
247  SeqCollection *collection = SEQ_collection_create(__func__);
248  SEQ_collection_append_strip(src_seq, collection);
250 
251  Sequence *seq;
252  SEQ_ITERATOR_FOREACH (seq, collection) {
253  /* Move to meta. */
254  SEQ_edit_move_strip_to_seqbase(scene, seqbase, seq, &dst_seqm->seqbase);
255  }
256 
257  SEQ_collection_free(collection);
258 
259  return true;
260 }
261 
262 static void seq_split_set_right_hold_offset(Scene *scene, Sequence *seq, int timeline_frame)
263 {
264  const float content_start = seq->start;
265  const float content_end = seq->start + SEQ_time_strip_length_get(scene, seq);
266 
267  /* Adjust within range of extended still-frames before strip. */
268  if (timeline_frame < content_start) {
269  const float offset = content_start + 1 - timeline_frame;
270  seq->start -= offset;
271  seq->startofs += offset;
272  SEQ_time_right_handle_frame_set(scene, seq, timeline_frame);
273  }
274  /* Adjust within range of strip contents. */
275  else if ((timeline_frame >= content_start) && (timeline_frame <= content_end)) {
276  seq->endofs = 0;
277  seq->anim_endofs += (content_end - timeline_frame) * seq->speed_factor;
278  }
279  /* Adjust within range of extended still-frames after strip. */
280  else if (timeline_frame > content_end) {
281  SEQ_time_right_handle_frame_set(scene, seq, timeline_frame);
282  }
283 }
284 
285 static void seq_split_set_left_hold_offset(Scene *scene, Sequence *seq, int timeline_frame)
286 {
287  const float content_start = seq->start;
288  const float content_end = seq->start + SEQ_time_strip_length_get(scene, seq);
289 
290  /* Adjust within range of extended still-frames before strip. */
291  if (timeline_frame < content_start) {
292  SEQ_time_left_handle_frame_set(scene, seq, timeline_frame);
293  }
294  /* Adjust within range of strip contents. */
295  else if ((timeline_frame >= content_start) && (timeline_frame <= content_end)) {
296  seq->anim_startofs += (timeline_frame - content_start) * seq->speed_factor;
297  seq->start = timeline_frame;
298  seq->startofs = 0;
299  }
300  /* Adjust within range of extended still-frames after strip. */
301  else if (timeline_frame > content_end) {
302  const float offset = timeline_frame - content_end + 1;
303  seq->start += offset;
304  seq->endofs += offset;
305  SEQ_time_left_handle_frame_set(scene, seq, timeline_frame);
306  }
307 }
308 
310  const Sequence *seq,
311  const int timeline_frame)
312 {
313  return timeline_frame > SEQ_time_left_handle_frame_get(scene, seq) &&
314  timeline_frame < SEQ_time_right_handle_frame_get(scene, seq);
315 }
316 
318  Scene *scene,
319  Sequence *left_seq,
320  Sequence *right_seq,
321  const int timeline_frame,
322  const eSeqSplitMethod method)
323 {
324  if (seq_edit_split_effect_intersect_check(scene, right_seq, timeline_frame)) {
325  switch (method) {
326  case SEQ_SPLIT_SOFT:
327  SEQ_time_left_handle_frame_set(scene, right_seq, timeline_frame);
328  break;
329  case SEQ_SPLIT_HARD:
330  seq_split_set_left_hold_offset(scene, right_seq, timeline_frame);
331  SEQ_add_reload_new_file(bmain, scene, right_seq, false);
332  break;
333  }
334  }
335 
336  if (seq_edit_split_effect_intersect_check(scene, left_seq, timeline_frame)) {
337  switch (method) {
338  case SEQ_SPLIT_SOFT:
339  SEQ_time_right_handle_frame_set(scene, left_seq, timeline_frame);
340  break;
341  case SEQ_SPLIT_HARD:
342  seq_split_set_right_hold_offset(scene, left_seq, timeline_frame);
343  SEQ_add_reload_new_file(bmain, scene, left_seq, false);
344  break;
345  }
346  }
347 }
348 
350  const Sequence *seq,
351  const int timeline_frame)
352 {
353  bool input_does_intersect = false;
354  if (seq->seq1) {
355  input_does_intersect |= seq_edit_split_effect_intersect_check(
356  scene, seq->seq1, timeline_frame);
357  if ((seq->seq1->type & SEQ_TYPE_EFFECT) != 0) {
358  input_does_intersect |= seq_edit_split_effect_inputs_intersect(
359  scene, seq->seq1, timeline_frame);
360  }
361  }
362  if (seq->seq2) {
363  input_does_intersect |= seq_edit_split_effect_intersect_check(
364  scene, seq->seq2, timeline_frame);
365  if ((seq->seq1->type & SEQ_TYPE_EFFECT) != 0) {
366  input_does_intersect |= seq_edit_split_effect_inputs_intersect(
367  scene, seq->seq2, timeline_frame);
368  }
369  }
370  if (seq->seq3) {
371  input_does_intersect |= seq_edit_split_effect_intersect_check(
372  scene, seq->seq3, timeline_frame);
373  if ((seq->seq1->type & SEQ_TYPE_EFFECT) != 0) {
374  input_does_intersect |= seq_edit_split_effect_inputs_intersect(
375  scene, seq->seq3, timeline_frame);
376  }
377  }
378  return input_does_intersect;
379 }
380 
382  SeqCollection *strips,
383  const int timeline_frame,
384  const char **r_error)
385 {
386  Sequence *seq;
387  SEQ_ITERATOR_FOREACH (seq, strips) {
388  if ((seq->type & SEQ_TYPE_EFFECT) == 0) {
389  continue;
390  }
391  if (!seq_edit_split_effect_intersect_check(scene, seq, timeline_frame)) {
392  continue;
393  }
394  if (SEQ_effect_get_num_inputs(seq->type) <= 1) {
395  continue;
396  }
398  *r_error = "Splitting transition effect is not permitted.";
399  return false;
400  }
401  if (!seq_edit_split_effect_inputs_intersect(scene, seq, timeline_frame)) {
402  *r_error = "Effect inputs don't overlap. Can not split such effect.";
403  return false;
404  }
405  }
406  return true;
407 }
408 
410  Scene *scene,
411  ListBase *seqbase,
412  Sequence *seq,
413  const int timeline_frame,
414  const eSeqSplitMethod method,
415  const char **r_error)
416 {
417  if (!seq_edit_split_effect_intersect_check(scene, seq, timeline_frame)) {
418  return NULL;
419  }
420 
421  /* Whole strip chain must be duplicated in order to preserve relationships. */
422  SeqCollection *collection = SEQ_collection_create(__func__);
423  SEQ_collection_append_strip(seq, collection);
425 
426  if (!seq_edit_split_operation_permitted_check(scene, collection, timeline_frame, r_error)) {
427  SEQ_collection_free(collection);
428  return NULL;
429  }
430 
431  /* Store `F-Curves`, so original ones aren't renamed. */
432  ListBase fcurves_original_backup = {NULL, NULL};
433  SEQ_animation_backup_original(scene, &fcurves_original_backup);
434 
435  ListBase left_strips = {NULL, NULL};
436  SEQ_ITERATOR_FOREACH (seq, collection) {
437  /* Move strips in collection from seqbase to new ListBase. */
438  BLI_remlink(seqbase, seq);
439  BLI_addtail(&left_strips, seq);
440 
441  /* Duplicate curves from backup, so they can be renamed along with split strips. */
442  SEQ_animation_duplicate(scene, seq, &fcurves_original_backup);
443  }
444 
445  SEQ_collection_free(collection);
446 
447  /* Duplicate ListBase. */
448  ListBase right_strips = {NULL, NULL};
449  SEQ_sequence_base_dupli_recursive(scene, scene, &right_strips, &left_strips, SEQ_DUPE_ALL, 0);
450 
451  Sequence *left_seq = left_strips.first;
452  Sequence *right_seq = right_strips.first;
453  Sequence *return_seq = NULL;
454 
455  /* Move strips from detached `ListBase`, otherwise they can't be flagged for removal. */
456  BLI_movelisttolist(seqbase, &left_strips);
457  BLI_movelisttolist(seqbase, &right_strips);
458 
459  /* Rename duplicated strips. This has to be done immediately after adding
460  * strips to seqbase, for lookup cache to work correctly. */
461  Sequence *seq_rename = right_seq;
462  for (; seq_rename; seq_rename = seq_rename->next) {
463  SEQ_ensure_unique_name(seq_rename, scene);
464  }
465 
466  /* Split strips. */
467  while (left_seq && right_seq) {
468  if (SEQ_time_left_handle_frame_get(scene, left_seq) >= timeline_frame) {
469  SEQ_edit_flag_for_removal(scene, seqbase, left_seq);
470  }
471  else if (SEQ_time_right_handle_frame_get(scene, right_seq) <= timeline_frame) {
472  SEQ_edit_flag_for_removal(scene, seqbase, right_seq);
473  }
474  else if (return_seq == NULL) {
475  /* Store return value - pointer to strip that will not be removed. */
476  return_seq = right_seq;
477  }
478 
479  seq_edit_split_handle_strip_offsets(bmain, scene, left_seq, right_seq, timeline_frame, method);
480  left_seq = left_seq->next;
481  right_seq = right_seq->next;
482  }
483 
485  SEQ_animation_restore_original(scene, &fcurves_original_backup);
486 
487  return return_seq;
488 }
489 
491  ListBase *seqbase,
492  const int initial_frame,
493  const bool remove_all_gaps)
494 {
495  GapInfo gap_info = {0};
496  seq_time_gap_info_get(scene, seqbase, initial_frame, &gap_info);
497 
498  if (!gap_info.gap_exists) {
499  return false;
500  }
501 
502  if (remove_all_gaps) {
503  while (gap_info.gap_exists) {
505  scene, seqbase, -gap_info.gap_length, gap_info.gap_start_frame);
506  seq_time_gap_info_get(scene, seqbase, initial_frame, &gap_info);
507  }
508  }
509  else {
511  scene, seqbase, -gap_info.gap_length, gap_info.gap_start_frame);
512  }
513  return true;
514 }
515 
516 void SEQ_edit_sequence_name_set(Scene *scene, Sequence *seq, const char *new_name)
517 {
518  BLI_strncpy_utf8(seq->name + 2, new_name, MAX_NAME - 2);
519  BLI_str_utf8_invalid_strip(seq->name + 2, strlen(seq->name + 2));
521 }
void BKE_sound_mute_scene_sound(void *handle, char mute)
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:354
void void void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
int BLI_str_utf8_invalid_strip(char *str, size_t length) ATTR_NONNULL(1)
Definition: string_utf8.c:181
char * BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL(1
#define SWAP(type, a, b)
#define ELEM(...)
#define MAX_NAME
Definition: DNA_defs.h:48
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_CROSS
@ SEQ_TYPE_WIPE
@ SEQ_TYPE_META
@ SEQ_TYPE_SCENE
@ SEQ_TYPE_GAMCROSS
@ SEQ_TYPE_EFFECT
@ SEQ_FLAG_DELETE
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
eSeqSplitMethod
Definition: SEQ_edit.h:60
@ SEQ_SPLIT_SOFT
Definition: SEQ_edit.h:61
@ SEQ_SPLIT_HARD
Definition: SEQ_edit.h:62
#define SEQ_ITERATOR_FOREACH(var, collection)
Definition: SEQ_iterator.h:35
@ SEQ_LOOKUP_TAG_INVALID
#define SEQ_DUPE_ALL
Definition: SEQ_sequencer.h:39
void SEQ_free_animdata(Scene *scene, Sequence *seq)
Definition: animation.c:100
void SEQ_animation_backup_original(Scene *scene, ListBase *list)
Definition: animation.c:118
void SEQ_animation_duplicate(Scene *scene, Sequence *seq, ListBase *list)
Definition: animation.c:137
void SEQ_animation_restore_original(Scene *scene, ListBase *list)
Definition: animation.c:128
Scene scene
int SEQ_effect_get_num_inputs(int seq_type)
Definition: effects.c:3741
void SEQ_query_strip_effect_chain(const Scene *scene, Sequence *seq_reference, ListBase *seqbase, SeqCollection *collection)
Definition: iterator.c:335
void SEQ_collection_expand(const Scene *scene, ListBase *seqbase, SeqCollection *collection, void seq_query_func(const Scene *scene, Sequence *seq_reference, ListBase *seqbase, SeqCollection *collection))
Definition: iterator.c:151
SeqCollection * SEQ_collection_create(const char *name)
Definition: iterator.c:87
bool SEQ_collection_append_strip(Sequence *seq, SeqCollection *collection)
Definition: iterator.c:117
void SEQ_collection_free(SeqCollection *collection)
Definition: iterator.c:81
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
bool SEQ_render_is_muted(const ListBase *channels, const Sequence *seq)
Definition: render.c:2199
void SEQ_sequence_lookup_tag(const Scene *scene, eSequenceLookupTag tag)
void SEQ_sequence_base_dupli_recursive(const Scene *scene_src, Scene *scene_dst, ListBase *nseqbase, const ListBase *seqbase, int dupe_flag, const int flag)
Definition: sequencer.c:613
void SEQ_sequence_free(Scene *scene, Sequence *seq)
Definition: sequencer.c:224
Editing * SEQ_editing_get(const Scene *scene)
Definition: sequencer.c:241
void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const bool lock_range)
Definition: strip_add.c:506
bool SEQ_edit_move_strip_to_meta(Scene *scene, Sequence *src_seq, Sequence *dst_seqm, const char **error_str)
Definition: strip_edit.c:213
static bool seq_edit_split_effect_intersect_check(const Scene *scene, const Sequence *seq, const int timeline_frame)
Definition: strip_edit.c:309
bool SEQ_edit_remove_gaps(Scene *scene, ListBase *seqbase, const int initial_frame, const bool remove_all_gaps)
Definition: strip_edit.c:490
static void seq_update_muting_recursive(ListBase *channels, ListBase *seqbasep, Sequence *metaseq, int mute)
Definition: strip_edit.c:93
void SEQ_edit_flag_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq)
Definition: strip_edit.c:163
bool SEQ_edit_move_strip_to_seqbase(Scene *scene, ListBase *seqbase, Sequence *seq, ListBase *dst_seqbase)
Definition: strip_edit.c:195
static void seq_edit_split_handle_strip_offsets(Main *bmain, Scene *scene, Sequence *left_seq, Sequence *right_seq, const int timeline_frame, const eSeqSplitMethod method)
Definition: strip_edit.c:317
static bool seq_edit_split_effect_inputs_intersect(const Scene *scene, const Sequence *seq, const int timeline_frame)
Definition: strip_edit.c:349
static void seq_split_set_right_hold_offset(Scene *scene, Sequence *seq, int timeline_frame)
Definition: strip_edit.c:262
int SEQ_edit_sequence_swap(Scene *scene, Sequence *seq_a, Sequence *seq_b, const char **error_str)
Definition: strip_edit.c:40
void SEQ_edit_sequence_name_set(Scene *scene, Sequence *seq, const char *new_name)
Definition: strip_edit.c:516
Sequence * SEQ_edit_strip_split(Main *bmain, Scene *scene, ListBase *seqbase, Sequence *seq, const int timeline_frame, const eSeqSplitMethod method, const char **r_error)
Definition: strip_edit.c:409
void SEQ_edit_remove_flagged_sequences(Scene *scene, ListBase *seqbase)
Definition: strip_edit.c:180
static bool seq_edit_split_operation_permitted_check(const Scene *scene, SeqCollection *strips, const int timeline_frame, const char **r_error)
Definition: strip_edit.c:381
void SEQ_edit_update_muting(Editing *ed)
Definition: strip_edit.c:123
static void sequencer_flag_users_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq)
Definition: strip_edit.c:138
static void seq_split_set_left_hold_offset(Scene *scene, Sequence *seq, int timeline_frame)
Definition: strip_edit.c:285
bool SEQ_exists_in_seqbase(const Sequence *seq, const ListBase *seqbase)
bool SEQ_relation_is_effect_of_strip(const Sequence *effect, const Sequence *input)
void SEQ_relations_invalidate_cache_preprocessed(Scene *scene, Sequence *seq)
int SEQ_time_strip_length_get(const Scene *scene, const Sequence *seq)
Definition: strip_time.c:484
void SEQ_time_right_handle_frame_set(const Scene *scene, Sequence *seq, int val)
Definition: strip_time.c:539
int SEQ_time_left_handle_frame_get(const Scene *UNUSED(scene), const Sequence *seq)
Definition: strip_time.c:506
void SEQ_time_left_handle_frame_set(const Scene *scene, Sequence *seq, int val)
Definition: strip_time.c:524
void seq_time_gap_info_get(const Scene *scene, ListBase *seqbase, const int initial_frame, GapInfo *r_gap_info)
Definition: strip_time.c:392
void seq_time_effect_range_set(const Scene *scene, Sequence *seq)
Definition: strip_time.c:184
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
Definition: strip_time.c:515
bool SEQ_transform_seqbase_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
bool SEQ_transform_test_overlap(const Scene *scene, ListBase *seqbasep, Sequence *test)
void SEQ_transform_offset_after_frame(Scene *scene, ListBase *seqbase, const int delta, const int timeline_frame)
ListBase seqbase
ListBase channels
ListBase metastack
int gap_length
Definition: strip_time.h:25
int gap_start_frame
Definition: strip_time.h:24
bool gap_exists
Definition: strip_time.h:26
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
Sequence * parseq
struct Editing * ed
struct SequenceModifierData * next
struct Sequence * mask_sequence
struct Sequence * seq3
void * scene_sound
ListBase channels
struct Sequence * prev
ListBase seqbase
struct Sequence * seq1
struct Sequence * seq2
struct Sequence * next
ListBase * SEQ_get_seqbase_by_seq(const Scene *scene, Sequence *seq)
Definition: utils.c:373
void SEQ_ensure_unique_name(Sequence *seq, Scene *scene)
Definition: utils.c:523
#define N_(msgid)