Blender  V2.93
strip_time.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 
33 #include "BKE_movieclip.h"
34 #include "BKE_scene.h"
35 #include "BKE_sound.h"
36 
37 #include "DNA_sound_types.h"
38 #include "IMB_imbuf.h"
39 
40 #include "SEQ_render.h"
41 #include "SEQ_sequencer.h"
42 #include "SEQ_time.h"
43 #include "SEQ_transform.h"
44 
45 #include "strip_time.h"
46 #include "utils.h"
47 
48 float seq_give_frame_index(Sequence *seq, float timeline_frame)
49 {
50  float frame_index;
51  int sta = seq->start;
52  int end = seq->start + seq->len - 1;
53 
54  if (seq->type & SEQ_TYPE_EFFECT) {
55  end = seq->enddisp;
56  }
57 
58  if (end < sta) {
59  return -1;
60  }
61 
62  if (seq->flag & SEQ_REVERSE_FRAMES) {
63  /*reverse frame in this sequence */
64  if (timeline_frame <= sta) {
65  frame_index = end - sta;
66  }
67  else if (timeline_frame >= end) {
68  frame_index = 0;
69  }
70  else {
71  frame_index = end - timeline_frame;
72  }
73  }
74  else {
75  if (timeline_frame <= sta) {
76  frame_index = 0;
77  }
78  else if (timeline_frame >= end) {
79  frame_index = end - sta;
80  }
81  else {
82  frame_index = timeline_frame - sta;
83  }
84  }
85 
86  if (seq->strobe < 1.0f) {
87  seq->strobe = 1.0f;
88  }
89 
90  if (seq->strobe > 1.0f) {
91  frame_index -= fmodf((double)frame_index, (double)seq->strobe);
92  }
93 
94  return frame_index;
95 }
96 
97 static int metaseq_start(Sequence *metaseq)
98 {
99  return metaseq->start + metaseq->startofs;
100 }
101 
102 static int metaseq_end(Sequence *metaseq)
103 {
104  return metaseq->start + metaseq->len - metaseq->endofs;
105 }
106 
108  Sequence *metaseq,
109  int start,
110  int end)
111 {
112  Sequence *seq;
113 
114  /* for sound we go over full meta tree to update bounds of the sound strips,
115  * since sound is played outside of evaluating the imbufs, */
116  for (seq = metaseq->seqbase.first; seq; seq = seq->next) {
117  if (seq->type == SEQ_TYPE_META) {
119  scene, seq, max_ii(start, metaseq_start(seq)), min_ii(end, metaseq_end(seq)));
120  }
121  else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
122  if (seq->scene_sound) {
123  int startofs = seq->startofs;
124  int endofs = seq->endofs;
125  if (seq->startofs + seq->start < start) {
126  startofs = start - seq->start;
127  }
128 
129  if (seq->start + seq->len - seq->endofs > end) {
130  endofs = seq->start + seq->len - end;
131  }
132 
134  seq->scene_sound,
135  seq->start + startofs,
136  seq->start + seq->len - endofs,
137  startofs + seq->anim_startofs,
138  seq->sound->offset_time);
139  }
140  }
141  }
142 }
143 
145 {
147  scene, metaseq, metaseq_start(metaseq), metaseq_end(metaseq));
148 }
149 
151 {
152  if (seq->startofs && seq->startstill) {
153  seq->startstill = 0;
154  }
155  if (seq->endofs && seq->endstill) {
156  seq->endstill = 0;
157  }
158 
159  seq->startdisp = seq->start + seq->startofs - seq->startstill;
160  seq->enddisp = seq->start + seq->len - seq->endofs + seq->endstill;
161 
162  if (seq->type == SEQ_TYPE_META) {
164  }
165 }
166 
168 {
169  if (BLI_listbase_is_empty(&seq_meta->seqbase)) {
170  return;
171  }
172 
173  int min = MAXFRAME * 2;
174  int max = -MAXFRAME * 2;
175  LISTBASE_FOREACH (Sequence *, seq, &seq_meta->seqbase) {
176  min = min_ii(seq->startdisp, min);
177  max = max_ii(seq->enddisp, max);
178  }
179 
180  seq_meta->start = min + seq_meta->anim_startofs;
181  seq_meta->len = max - min;
182  seq_meta->len -= seq_meta->anim_startofs;
183  seq_meta->len -= seq_meta->anim_endofs;
184 
186 }
187 
189 {
191 
192  /* Prevent metastrip to move in timeline. */
193  SEQ_transform_set_left_handle_frame(seq_meta, seq_meta->startdisp);
194  SEQ_transform_set_right_handle_frame(seq_meta, seq_meta->enddisp);
195 }
196 
198 {
199  Sequence *seqm;
200 
201  /* check all metas recursively */
202  seqm = seq->seqbase.first;
203  while (seqm) {
204  if (seqm->seqbase.first) {
206  }
207  seqm = seqm->next;
208  }
209 
210  /* effects and meta: automatic start and end */
211  if (seq->type & SEQ_TYPE_EFFECT) {
212  if (seq->seq1) {
213  seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
214  if (seq->seq3) {
215  seq->start = seq->startdisp = max_iii(
216  seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
217  seq->enddisp = min_iii(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
218  }
219  else if (seq->seq2) {
220  seq->start = seq->startdisp = max_ii(seq->seq1->startdisp, seq->seq2->startdisp);
221  seq->enddisp = min_ii(seq->seq1->enddisp, seq->seq2->enddisp);
222  }
223  else {
224  seq->start = seq->startdisp = seq->seq1->startdisp;
225  seq->enddisp = seq->seq1->enddisp;
226  }
227  /* we cant help if strips don't overlap, it wont give useful results.
228  * but at least ensure 'len' is never negative which causes bad bugs elsewhere. */
229  if (seq->enddisp < seq->startdisp) {
230  /* simple start/end swap */
231  seq->start = seq->enddisp;
232  seq->enddisp = seq->startdisp;
233  seq->startdisp = seq->start;
234  seq->flag |= SEQ_INVALID_EFFECT;
235  }
236  else {
237  seq->flag &= ~SEQ_INVALID_EFFECT;
238  }
239 
240  seq->len = seq->enddisp - seq->startdisp;
241  }
242  else {
244  }
245  }
246  else {
247  if (seq->type == SEQ_TYPE_META) {
249  }
250 
251  Editing *ed = SEQ_editing_get(scene, false);
253  if (ms != NULL) {
255  }
256 
258  }
259 }
260 
262 int SEQ_time_cmp_time_startdisp(const void *a, const void *b)
263 {
264  const Sequence *seq_a = a;
265  const Sequence *seq_b = b;
266 
267  return (seq_a->startdisp > seq_b->startdisp);
268 }
269 
271  int timeline_frame,
272  const short side,
273  const bool do_skip_mute,
274  const bool do_center,
275  const bool do_unselected)
276 {
277  Editing *ed = SEQ_editing_get(scene, false);
278  Sequence *seq;
279 
280  int dist, best_dist, best_frame = timeline_frame;
281  int seq_frames[2], seq_frames_tot;
282 
283  /* In case where both is passed,
284  * frame just finds the nearest end while frame_left the nearest start. */
285 
286  best_dist = MAXFRAME * 2;
287 
288  if (ed == NULL) {
289  return timeline_frame;
290  }
291 
292  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
293  int i;
294 
295  if (do_skip_mute && (seq->flag & SEQ_MUTE)) {
296  continue;
297  }
298 
299  if (do_unselected && (seq->flag & SELECT)) {
300  continue;
301  }
302 
303  if (do_center) {
304  seq_frames[0] = (seq->startdisp + seq->enddisp) / 2;
305  seq_frames_tot = 1;
306  }
307  else {
308  seq_frames[0] = seq->startdisp;
309  seq_frames[1] = seq->enddisp;
310 
311  seq_frames_tot = 2;
312  }
313 
314  for (i = 0; i < seq_frames_tot; i++) {
315  const int seq_frame = seq_frames[i];
316 
317  dist = MAXFRAME * 2;
318 
319  switch (side) {
320  case SEQ_SIDE_LEFT:
321  if (seq_frame < timeline_frame) {
322  dist = timeline_frame - seq_frame;
323  }
324  break;
325  case SEQ_SIDE_RIGHT:
326  if (seq_frame > timeline_frame) {
327  dist = seq_frame - timeline_frame;
328  }
329  break;
330  case SEQ_SIDE_BOTH:
331  dist = abs(seq_frame - timeline_frame);
332  break;
333  }
334 
335  if (dist < best_dist) {
336  best_frame = seq_frame;
337  best_dist = dist;
338  }
339  }
340  }
341 
342  return best_frame;
343 }
344 
346 {
347  switch (seq->type) {
348  case SEQ_TYPE_MOVIE: {
349  seq_open_anim_file(scene, seq, true);
350  if (BLI_listbase_is_empty(&seq->anims)) {
351  return 0.0f;
352  }
353  StripAnim *strip_anim = seq->anims.first;
354  if (strip_anim->anim == NULL) {
355  return 0.0f;
356  }
357  short frs_sec;
358  float frs_sec_base;
359  if (IMB_anim_get_fps(strip_anim->anim, &frs_sec, &frs_sec_base, true)) {
360  return (float)frs_sec / frs_sec_base;
361  }
362  break;
363  }
364  case SEQ_TYPE_MOVIECLIP:
365  if (seq->clip != NULL) {
366  return BKE_movieclip_get_fps(seq->clip);
367  }
368  break;
369  case SEQ_TYPE_SCENE:
370  if (seq->scene != NULL) {
371  return (float)seq->scene->r.frs_sec / seq->scene->r.frs_sec_base;
372  }
373  break;
374  }
375  return 0.0f;
376 }
377 
385 void SEQ_timeline_boundbox(const Scene *scene, const ListBase *seqbase, rctf *rect)
386 {
387  rect->xmin = scene->r.sfra;
388  rect->xmax = scene->r.efra + 1;
389  rect->ymin = 0.0f;
390  rect->ymax = 8.0f;
391 
392  if (seqbase == NULL) {
393  return;
394  }
395 
396  LISTBASE_FOREACH (Sequence *, seq, seqbase) {
397  if (rect->xmin > seq->startdisp - 1) {
398  rect->xmin = seq->startdisp - 1;
399  }
400  if (rect->xmax < seq->enddisp + 1) {
401  rect->xmax = seq->enddisp + 1;
402  }
403  if (rect->ymax < seq->machine + 2) {
404  rect->ymax = seq->machine + 2;
405  }
406  }
407 }
408 
418  ListBase *seqbase,
419  const int initial_frame,
420  GapInfo *r_gap_info)
421 {
422  rctf rectf;
423  /* Get first and last frame. */
424  SEQ_timeline_boundbox(scene, seqbase, &rectf);
425  const int sfra = (int)rectf.xmin;
426  const int efra = (int)rectf.xmax;
427  int timeline_frame = initial_frame;
428  r_gap_info->gap_exists = false;
429 
430  if (SEQ_render_evaluate_frame(seqbase, initial_frame) == 0) {
431  /* Search backward for gap_start_frame. */
432  for (; timeline_frame >= sfra; timeline_frame--) {
433  if (SEQ_render_evaluate_frame(seqbase, timeline_frame) != 0) {
434  break;
435  }
436  }
437  r_gap_info->gap_start_frame = timeline_frame + 1;
438  timeline_frame = initial_frame;
439  }
440  else {
441  /* Search forward for gap_start_frame. */
442  for (; timeline_frame <= efra; timeline_frame++) {
443  if (SEQ_render_evaluate_frame(seqbase, timeline_frame) == 0) {
444  r_gap_info->gap_start_frame = timeline_frame;
445  break;
446  }
447  }
448  }
449  /* Search forward for gap_end_frame. */
450  for (; timeline_frame <= efra; timeline_frame++) {
451  if (SEQ_render_evaluate_frame(seqbase, timeline_frame) != 0) {
452  const int gap_end_frame = timeline_frame;
453  r_gap_info->gap_length = gap_end_frame - r_gap_info->gap_start_frame;
454  r_gap_info->gap_exists = true;
455  break;
456  }
457  }
458 }
float BKE_movieclip_get_fps(struct MovieClip *clip)
Definition: movieclip.c:1591
void BKE_sound_move_scene_sound(struct Scene *scene, void *handle, int startframe, int endframe, int frameskip, double audio_offset)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
MINLINE int min_iii(int a, int b, int c)
MINLINE int max_iii(int a, int b, int c)
#define ELEM(...)
#define MAXFRAME
@ SEQ_MUTE
@ SEQ_INVALID_EFFECT
@ SEQ_REVERSE_FRAMES
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_META
@ SEQ_TYPE_SCENE
@ SEQ_TYPE_MOVIECLIP
@ SEQ_TYPE_EFFECT
@ SEQ_TYPE_MOVIE
bool IMB_anim_get_fps(struct anim *anim, short *frs_sec, float *frs_sec_base, bool no_av_base)
Definition: anim_movie.c:1691
@ SEQ_SIDE_RIGHT
Definition: SEQ_sequencer.h:42
@ SEQ_SIDE_BOTH
Definition: SEQ_sequencer.h:43
@ SEQ_SIDE_LEFT
Definition: SEQ_sequencer.h:41
#define SELECT
Scene scene
#define fmodf(x, y)
static unsigned a[3]
Definition: RandGen.cpp:92
int SEQ_render_evaluate_frame(ListBase *seqbase, int timeline_frame)
Definition: render.c:324
MetaStack * SEQ_meta_stack_active_get(const Editing *ed)
Definition: sequencer.c:405
Editing * SEQ_editing_get(Scene *scene, bool alloc)
Definition: sequencer.c:232
#define min(a, b)
Definition: sort.c:51
static int metaseq_end(Sequence *metaseq)
Definition: strip_time.c:102
static void seq_time_update_meta_strip(Scene *scene, Sequence *seq_meta)
Definition: strip_time.c:167
int SEQ_time_cmp_time_startdisp(const void *a, const void *b)
Definition: strip_time.c:262
void SEQ_timeline_boundbox(const Scene *scene, const ListBase *seqbase, rctf *rect)
Definition: strip_time.c:385
void seq_time_gap_info_get(const Scene *scene, ListBase *seqbase, const int initial_frame, GapInfo *r_gap_info)
Definition: strip_time.c:417
static int metaseq_start(Sequence *metaseq)
Definition: strip_time.c:97
float SEQ_time_sequence_get_fps(Scene *scene, Sequence *seq)
Definition: strip_time.c:345
int SEQ_time_find_next_prev_edit(Scene *scene, int timeline_frame, const short side, const bool do_skip_mute, const bool do_center, const bool do_unselected)
Definition: strip_time.c:270
static void seq_update_sound_bounds_recursive_impl(Scene *scene, Sequence *metaseq, int start, int end)
Definition: strip_time.c:107
float seq_give_frame_index(Sequence *seq, float timeline_frame)
Definition: strip_time.c:48
void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
Definition: strip_time.c:144
static void seq_time_update_meta_strip_range(Scene *scene, Sequence *seq_meta)
Definition: strip_time.c:188
void SEQ_time_update_sequence_bounds(Scene *scene, Sequence *seq)
Definition: strip_time.c:150
void SEQ_time_update_sequence(Scene *scene, Sequence *seq)
Definition: strip_time.c:197
void SEQ_transform_set_right_handle_frame(Sequence *seq, int val)
void SEQ_transform_set_left_handle_frame(Sequence *seq, int val)
ListBase * seqbasep
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 * first
Definition: DNA_listBase.h:47
Sequence * parseq
float frs_sec_base
struct RenderData r
struct MovieClip * clip
struct Scene * scene
ListBase anims
struct Sequence * seq3
void * scene_sound
ListBase seqbase
struct bSound * sound
struct Sequence * seq1
struct Sequence * seq2
struct Sequence * next
struct anim * anim
double offset_time
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
float max
__forceinline const avxi abs(const avxi &a)
Definition: util_avxi.h:186
void seq_open_anim_file(Scene *scene, Sequence *seq, bool openfile)
Definition: utils.c:266