Blender  V2.93
strip_edit.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_listbase.h"
31 #include "BLI_math.h"
32 #include "BLI_string.h"
33 
34 #include "BLT_translation.h"
35 
36 #include "BKE_main.h"
37 #include "BKE_movieclip.h"
38 #include "BKE_scene.h"
39 #include "BKE_sound.h"
40 
41 #include "strip_time.h"
42 
43 #include "SEQ_add.h"
44 #include "SEQ_edit.h"
45 #include "SEQ_effects.h"
46 #include "SEQ_relations.h"
47 #include "SEQ_sequencer.h"
48 #include "SEQ_time.h"
49 #include "SEQ_transform.h"
50 #include "SEQ_utils.h"
51 
52 int SEQ_edit_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str)
53 {
54  char name[sizeof(seq_a->name)];
55 
56  if (seq_a->len != seq_b->len) {
57  *error_str = N_("Strips must be the same length");
58  return 0;
59  }
60 
61  /* type checking, could be more advanced but disallow sound vs non-sound copy */
62  if (seq_a->type != seq_b->type) {
63  if (seq_a->type == SEQ_TYPE_SOUND_RAM || seq_b->type == SEQ_TYPE_SOUND_RAM) {
64  *error_str = N_("Strips were not compatible");
65  return 0;
66  }
67 
68  /* disallow effects to swap with non-effects strips */
69  if ((seq_a->type & SEQ_TYPE_EFFECT) != (seq_b->type & SEQ_TYPE_EFFECT)) {
70  *error_str = N_("Strips were not compatible");
71  return 0;
72  }
73 
74  if ((seq_a->type & SEQ_TYPE_EFFECT) && (seq_b->type & SEQ_TYPE_EFFECT)) {
76  *error_str = N_("Strips must have the same number of inputs");
77  return 0;
78  }
79  }
80  }
81 
82  SWAP(Sequence, *seq_a, *seq_b);
83 
84  /* swap back names so animation fcurves don't get swapped */
85  BLI_strncpy(name, seq_a->name + 2, sizeof(name));
86  BLI_strncpy(seq_a->name + 2, seq_b->name + 2, sizeof(seq_b->name) - 2);
87  BLI_strncpy(seq_b->name + 2, name, sizeof(seq_b->name) - 2);
88 
89  /* swap back opacity, and overlay mode */
90  SWAP(int, seq_a->blend_mode, seq_b->blend_mode);
91  SWAP(float, seq_a->blend_opacity, seq_b->blend_opacity);
92 
93  SWAP(Sequence *, seq_a->prev, seq_b->prev);
94  SWAP(Sequence *, seq_a->next, seq_b->next);
95  SWAP(int, seq_a->start, seq_b->start);
96  SWAP(int, seq_a->startofs, seq_b->startofs);
97  SWAP(int, seq_a->endofs, seq_b->endofs);
98  SWAP(int, seq_a->startstill, seq_b->startstill);
99  SWAP(int, seq_a->endstill, seq_b->endstill);
100  SWAP(int, seq_a->machine, seq_b->machine);
101  SWAP(int, seq_a->startdisp, seq_b->startdisp);
102  SWAP(int, seq_a->enddisp, seq_b->enddisp);
103 
104  return 1;
105 }
106 
107 static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute)
108 {
109  Sequence *seq;
110  int seqmute;
111 
112  /* for sound we go over full meta tree to update muted state,
113  * since sound is played outside of evaluating the imbufs, */
114  for (seq = seqbasep->first; seq; seq = seq->next) {
115  seqmute = (mute || (seq->flag & SEQ_MUTE));
116 
117  if (seq->type == SEQ_TYPE_META) {
118  /* if this is the current meta sequence, unmute because
119  * all sequences above this were set to mute */
120  if (seq == metaseq) {
121  seqmute = 0;
122  }
123 
124  seq_update_muting_recursive(&seq->seqbase, metaseq, seqmute);
125  }
126  else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
127  if (seq->scene_sound) {
129  }
130  }
131  }
132 }
133 
135 {
136  if (ed) {
137  /* mute all sounds up to current metastack list */
138  MetaStack *ms = ed->metastack.last;
139 
140  if (ms) {
142  }
143  else {
145  }
146  }
147 }
148 
150 {
151  LISTBASE_FOREACH (Sequence *, user_seq, seqbase) {
152  /* Look in metas for usage of seq. */
153  if (user_seq->type == SEQ_TYPE_META) {
154  sequencer_flag_users_for_removal(scene, &user_seq->seqbase, seq);
155  }
156 
157  /* Clear seq from modifiers. */
159  for (smd = user_seq->modifiers.first; smd; smd = smd->next) {
160  if (smd->mask_sequence == seq) {
161  smd->mask_sequence = NULL;
162  }
163  }
164 
165  /* Remove effects, that use seq. */
166  if ((user_seq->seq1 && user_seq->seq1 == seq) || (user_seq->seq2 && user_seq->seq2 == seq) ||
167  (user_seq->seq3 && user_seq->seq3 == seq)) {
168  user_seq->flag |= SEQ_FLAG_DELETE;
169  /* Strips can be used as mask even if not in same seqbase. */
171  }
172  }
173 }
174 
175 /* Flag seq and its users (effects) for removal. */
177 {
178  if (seq == NULL || (seq->flag & SEQ_FLAG_DELETE) != 0) {
179  return;
180  }
181 
182  /* Flag and remove meta children. */
183  if (seq->type == SEQ_TYPE_META) {
184  LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) {
185  SEQ_edit_flag_for_removal(scene, &seq->seqbase, meta_child);
186  }
187  }
188 
189  seq->flag |= SEQ_FLAG_DELETE;
191 }
192 
193 /* Remove all flagged sequences, return true if sequence is removed. */
195 {
196  LISTBASE_FOREACH_MUTABLE (Sequence *, seq, seqbase) {
197  if (seq->flag & SEQ_FLAG_DELETE) {
198  if (seq->type == SEQ_TYPE_META) {
200  }
201  BLI_remlink(seqbase, seq);
202  SEQ_sequence_free(scene, seq, true);
203  }
204  }
205 }
206 
207 static bool seq_exists_in_seqbase(Sequence *seq, ListBase *seqbase)
208 {
209  LISTBASE_FOREACH (Sequence *, seq_test, seqbase) {
210  if (seq_test->type == SEQ_TYPE_META && seq_exists_in_seqbase(seq, &seq_test->seqbase)) {
211  return true;
212  }
213  if (seq_test == seq) {
214  return true;
215  }
216  }
217  return false;
218 }
219 
221  Sequence *src_seq,
222  Sequence *dst_seqm,
223  const char **error_str)
224 {
225  /* Find the appropriate seqbase */
226  Editing *ed = SEQ_editing_get(scene, false);
227  ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, src_seq);
228 
229  if (dst_seqm->type != SEQ_TYPE_META) {
230  *error_str = N_("Can not move strip to non-meta strip");
231  return false;
232  }
233 
234  if (src_seq == dst_seqm) {
235  *error_str = N_("Strip can not be moved into itself");
236  return false;
237  }
238 
239  if (seqbase == &dst_seqm->seqbase) {
240  *error_str = N_("Moved strip is already inside provided meta strip");
241  return false;
242  }
243 
244  if (src_seq->type == SEQ_TYPE_META && seq_exists_in_seqbase(dst_seqm, &src_seq->seqbase)) {
245  *error_str = N_("Moved strip is parent of provided meta strip");
246  return false;
247  }
248 
249  if (!seq_exists_in_seqbase(dst_seqm, &ed->seqbase)) {
250  *error_str = N_("Can not move strip to different scene");
251  return false;
252  }
253 
254  /* Remove users of src_seq. Ideally these could be moved into meta as well, but this would be
255  * best to do with generalized iterator as described in D10337. */
256  sequencer_flag_users_for_removal(scene, seqbase, src_seq);
258 
259  /* Move to meta. */
260  BLI_remlink(seqbase, src_seq);
261  BLI_addtail(&dst_seqm->seqbase, src_seq);
263 
264  /* Update meta. */
265  SEQ_time_update_sequence(scene, dst_seqm);
266  if (SEQ_transform_test_overlap(&dst_seqm->seqbase, src_seq)) {
267  SEQ_transform_seqbase_shuffle(&dst_seqm->seqbase, src_seq, scene);
268  }
269 
270  return true;
271 }
272 
273 static void seq_split_set_left_hold_offset(Sequence *seq, int timeline_frame)
274 {
275  /* Adjust within range of extended stillframes before strip. */
276  if (timeline_frame < seq->start) {
277  seq->start = timeline_frame - 1;
278  seq->anim_endofs += seq->len - 1;
279  seq->startstill = timeline_frame - seq->startdisp - 1;
280  seq->endstill = 0;
281  }
282  /* Adjust within range of strip contents. */
283  else if ((timeline_frame >= seq->start) && (timeline_frame <= (seq->start + seq->len))) {
284  seq->endofs = 0;
285  seq->endstill = 0;
286  seq->anim_endofs += (seq->start + seq->len) - timeline_frame;
287  }
288  /* Adjust within range of extended stillframes after strip. */
289  else if ((seq->start + seq->len) < timeline_frame) {
290  seq->endstill = timeline_frame - seq->start - seq->len;
291  }
292 }
293 
294 static void seq_split_set_right_hold_offset(Sequence *seq, int timeline_frame)
295 {
296  /* Adjust within range of extended stillframes before strip. */
297  if (timeline_frame < seq->start) {
298  seq->startstill = seq->start - timeline_frame;
299  }
300  /* Adjust within range of strip contents. */
301  else if ((timeline_frame >= seq->start) && (timeline_frame <= (seq->start + seq->len))) {
302  seq->anim_startofs += timeline_frame - seq->start;
303  seq->start = timeline_frame;
304  seq->startstill = 0;
305  seq->startofs = 0;
306  }
307  /* Adjust within range of extended stillframes after strip. */
308  else if ((seq->start + seq->len) < timeline_frame) {
309  seq->start = timeline_frame;
310  seq->startofs = 0;
311  seq->anim_startofs += seq->len - 1;
312  seq->endstill = seq->enddisp - timeline_frame - 1;
313  seq->startstill = 0;
314  }
315 }
316 
317 static void seq_split_set_right_offset(Sequence *seq, int timeline_frame)
318 {
319  /* Adjust within range of extended stillframes before strip. */
320  if (timeline_frame < seq->start) {
321  seq->start = timeline_frame - 1;
322  seq->startstill = timeline_frame - seq->startdisp - 1;
323  seq->endofs = seq->len - 1;
324  }
325  /* Adjust within range of extended stillframes after strip. */
326  else if ((seq->start + seq->len) < timeline_frame) {
327  seq->endstill -= seq->enddisp - timeline_frame;
328  }
329  SEQ_transform_set_right_handle_frame(seq, timeline_frame);
330 }
331 
332 static void seq_split_set_left_offset(Sequence *seq, int timeline_frame)
333 {
334  /* Adjust within range of extended stillframes before strip. */
335  if (timeline_frame < seq->start) {
336  seq->startstill = seq->start - timeline_frame;
337  }
338  /* Adjust within range of extended stillframes after strip. */
339  if ((seq->start + seq->len) < timeline_frame) {
340  seq->start = timeline_frame - seq->len + 1;
341  seq->endstill = seq->enddisp - timeline_frame - 1;
342  }
343  SEQ_transform_set_left_handle_frame(seq, timeline_frame);
344 }
345 
358  Scene *scene,
359  ListBase *seqbase,
360  Sequence *seq,
361  const int timeline_frame,
362  const eSeqSplitMethod method)
363 {
364  if (timeline_frame <= seq->startdisp || timeline_frame >= seq->enddisp) {
365  return NULL;
366  }
367 
368  if (method == SEQ_SPLIT_HARD) {
369  /* Precaution, needed because the length saved on-disk may not match the length saved in the
370  * blend file, or our code may have minor differences reading file length between versions.
371  * This causes hard-split to fail, see: T47862. */
372  SEQ_add_reload_new_file(bmain, scene, seq, true);
374  }
375 
376  Sequence *left_seq = seq;
378  scene, scene, seqbase, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
379 
380  switch (method) {
381  case SEQ_SPLIT_SOFT:
382  seq_split_set_left_offset(right_seq, timeline_frame);
383  seq_split_set_right_offset(left_seq, timeline_frame);
384  break;
385  case SEQ_SPLIT_HARD:
386  seq_split_set_right_hold_offset(left_seq, timeline_frame);
387  seq_split_set_left_hold_offset(right_seq, timeline_frame);
388  SEQ_add_reload_new_file(bmain, scene, left_seq, false);
389  SEQ_add_reload_new_file(bmain, scene, right_seq, false);
390  break;
391  }
392  SEQ_time_update_sequence(scene, left_seq);
393  SEQ_time_update_sequence(scene, right_seq);
394  return right_seq;
395 }
396 
407  ListBase *seqbase,
408  const int initial_frame,
409  const bool remove_all_gaps)
410 {
411  GapInfo gap_info = {0};
412  seq_time_gap_info_get(scene, seqbase, initial_frame, &gap_info);
413 
414  if (!gap_info.gap_exists) {
415  return false;
416  }
417 
418  if (remove_all_gaps) {
419  while (gap_info.gap_exists) {
421  scene, seqbase, -gap_info.gap_length, gap_info.gap_start_frame);
422  seq_time_gap_info_get(scene, seqbase, initial_frame, &gap_info);
423  }
424  }
425  else {
427  scene, seqbase, -gap_info.gap_length, gap_info.gap_start_frame);
428  }
429  return true;
430 }
void BKE_sound_mute_scene_sound(void *handle, char mute)
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:188
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define SWAP(type, a, b)
#define ELEM(...)
#define N_(msgid)
@ SEQ_MUTE
@ SEQ_FLAG_DELETE
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_META
@ SEQ_TYPE_SCENE
@ SEQ_TYPE_EFFECT
eSeqSplitMethod
Definition: SEQ_edit.h:46
@ SEQ_SPLIT_SOFT
Definition: SEQ_edit.h:47
@ SEQ_SPLIT_HARD
Definition: SEQ_edit.h:48
#define SEQ_DUPE_UNIQUE_NAME
Definition: SEQ_sequencer.h:50
#define SEQ_DUPE_ANIM
Definition: SEQ_sequencer.h:52
Scene scene
int SEQ_effect_get_num_inputs(int seq_type)
Definition: effects.c:4328
Sequence * SEQ_sequence_dupli_recursive(const Scene *scene_src, Scene *scene_dst, ListBase *new_seq_list, Sequence *seq, int dupe_flag)
Definition: sequencer.c:548
void SEQ_sequence_free(Scene *scene, Sequence *seq, const bool do_clean_animdata)
Definition: sequencer.c:213
Editing * SEQ_editing_get(Scene *scene, bool alloc)
Definition: sequencer.c:232
void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const bool lock_range)
Definition: strip_add.c:623
bool SEQ_edit_move_strip_to_meta(Scene *scene, Sequence *src_seq, Sequence *dst_seqm, const char **error_str)
Definition: strip_edit.c:220
bool SEQ_edit_remove_gaps(Scene *scene, ListBase *seqbase, const int initial_frame, const bool remove_all_gaps)
Definition: strip_edit.c:406
static void seq_split_set_left_hold_offset(Sequence *seq, int timeline_frame)
Definition: strip_edit.c:273
void SEQ_edit_flag_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq)
Definition: strip_edit.c:176
static bool seq_exists_in_seqbase(Sequence *seq, ListBase *seqbase)
Definition: strip_edit.c:207
static void seq_split_set_right_hold_offset(Sequence *seq, int timeline_frame)
Definition: strip_edit.c:294
static void seq_split_set_left_offset(Sequence *seq, int timeline_frame)
Definition: strip_edit.c:332
int SEQ_edit_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str)
Definition: strip_edit.c:52
Sequence * SEQ_edit_strip_split(Main *bmain, Scene *scene, ListBase *seqbase, Sequence *seq, const int timeline_frame, const eSeqSplitMethod method)
Definition: strip_edit.c:357
void SEQ_edit_remove_flagged_sequences(Scene *scene, ListBase *seqbase)
Definition: strip_edit.c:194
static void seq_split_set_right_offset(Sequence *seq, int timeline_frame)
Definition: strip_edit.c:317
static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute)
Definition: strip_edit.c:107
void SEQ_edit_update_muting(Editing *ed)
Definition: strip_edit.c:134
static void sequencer_flag_users_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq)
Definition: strip_edit.c:149
void SEQ_relations_invalidate_cache_preprocessed(Scene *scene, Sequence *seq)
void seq_time_gap_info_get(const Scene *scene, ListBase *seqbase, const int initial_frame, GapInfo *r_gap_info)
Definition: strip_time.c:417
void SEQ_time_update_sequence(Scene *scene, Sequence *seq)
Definition: strip_time.c:197
bool SEQ_transform_seqbase_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
bool SEQ_transform_test_overlap(ListBase *seqbasep, Sequence *test)
void SEQ_transform_set_right_handle_frame(Sequence *seq, int val)
void SEQ_transform_set_left_handle_frame(Sequence *seq, int val)
void SEQ_transform_offset_after_frame(Scene *scene, ListBase *seqbase, const int delta, const int timeline_frame)
ListBase seqbase
ListBase metastack
int gap_length
Definition: strip_time.h:40
int gap_start_frame
Definition: strip_time.h:39
bool gap_exists
Definition: strip_time.h:41
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
Sequence * parseq
struct Editing * ed
struct SequenceModifierData * next
struct Sequence * mask_sequence
void * scene_sound
struct Sequence * prev
ListBase seqbase
struct Sequence * next
ListBase * SEQ_get_seqbase_by_seq(ListBase *seqbase, Sequence *seq)
Definition: utils.c:428