Blender V4.3
strip_time.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 * SPDX-FileCopyrightText: 2003-2009 Blender Authors
3 * SPDX-FileCopyrightText: 2005-2006 Peter Schlaile <peter [at] schlaile [dot] de>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later */
6
11#include "MEM_guardedalloc.h"
12
13#include "DNA_scene_types.h"
14#include "DNA_sequence_types.h"
15
16#include "BLI_listbase.h"
17#include "BLI_math_base.h"
18
19#include "BKE_movieclip.h"
20#include "BKE_sound.h"
21
22#include "DNA_sound_types.h"
23
24#include "IMB_imbuf.hh"
25
26#include "SEQ_channels.hh"
27#include "SEQ_iterator.hh"
28#include "SEQ_render.hh"
29#include "SEQ_retiming.hh"
30#include "SEQ_sequencer.hh"
31#include "SEQ_time.hh"
32#include "SEQ_transform.hh"
33
34#include "sequencer.hh"
35#include "strip_time.hh"
36#include "utils.hh"
37
39{
40 if ((seq->flag & SEQ_AUTO_PLAYBACK_RATE) == 0) {
41 return 1.0f;
42 }
43 if (seq->media_playback_rate == 0.0f) {
44 return 1.0f;
45 }
46
47 float scene_playback_rate = float(scene->r.frs_sec) / scene->r.frs_sec_base;
48 return seq->media_playback_rate / scene_playback_rate;
49}
50
52{
53 if (seq->type == SEQ_TYPE_SOUND_RAM) {
54 return seq->len;
55 }
56
57 return seq->len / SEQ_time_media_playback_rate_factor_get(scene, seq);
58}
59
60float SEQ_give_frame_index(const Scene *scene, const Sequence *seq, float timeline_frame)
61{
62 float frame_index;
63 float sta = SEQ_time_start_frame_get(seq);
64 float end = SEQ_time_content_end_frame_get(scene, seq) - 1;
65 float frame_index_max = seq->len - 1;
66
67 if (seq->type & SEQ_TYPE_EFFECT) {
68 end = SEQ_time_right_handle_frame_get(scene, seq);
69 frame_index_max = end - sta;
70 }
71
72 if (end < sta) {
73 return -1;
74 }
75
77 return 0;
78 }
79
80 if (seq->flag & SEQ_REVERSE_FRAMES) {
81 frame_index = end - timeline_frame;
82 }
83 else {
84 frame_index = timeline_frame - sta;
85 }
86
87 frame_index = max_ff(frame_index, 0);
88
89 frame_index *= SEQ_time_media_playback_rate_factor_get(scene, seq);
90
91 if (SEQ_retiming_is_active(seq)) {
92 const float retiming_factor = seq_retiming_evaluate(seq, frame_index);
93 frame_index = retiming_factor * frame_index_max;
94 }
95 /* Clamp frame index to strip content frame range. */
96 frame_index = clamp_f(frame_index, 0, frame_index_max);
97
98 if (seq->strobe > 1.0f) {
99 frame_index -= fmodf(double(frame_index), double(seq->strobe));
100 }
101
102 return frame_index;
103}
104
105static int metaseq_start(Sequence *metaseq)
106{
107 return metaseq->start + metaseq->startofs;
108}
109
110static int metaseq_end(Sequence *metaseq)
111{
112 return metaseq->start + metaseq->len - metaseq->endofs;
113}
114
116 Sequence *metaseq,
117 int start,
118 int end)
119{
120 /* For sound we go over full meta tree to update bounds of the sound strips,
121 * since sound is played outside of evaluating the image-buffers (#ImBuf). */
122 LISTBASE_FOREACH (Sequence *, seq, &metaseq->seqbase) {
123 if (seq->type == SEQ_TYPE_META) {
125 scene, seq, max_ii(start, metaseq_start(seq)), min_ii(end, metaseq_end(seq)));
126 }
127 else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
128 if (seq->scene_sound) {
129 int startofs = seq->startofs;
130 int endofs = seq->endofs;
131 if (seq->startofs + seq->start < start) {
132 startofs = start - seq->start;
133 }
134
135 if (seq->start + seq->len - seq->endofs > end) {
136 endofs = seq->start + seq->len - end;
137 }
138
139 double offset_time = 0.0f;
140 if (seq->sound != nullptr) {
141 offset_time = seq->sound->offset_time + seq->sound_offset;
142 }
143
145 seq->scene_sound,
146 seq->start + startofs,
147 seq->start + seq->len - endofs,
148 startofs + seq->anim_startofs,
149 offset_time);
150 }
151 }
152 }
153}
154
156{
158 scene, metaseq, metaseq_start(metaseq), metaseq_end(metaseq));
159}
160
162{
163 if (seq_meta == nullptr) {
164 return;
165 }
166
167 if (BLI_listbase_is_empty(&seq_meta->seqbase)) {
168 return;
169 }
170
171 const int strip_start = SEQ_time_left_handle_frame_get(scene, seq_meta);
172 const int strip_end = SEQ_time_right_handle_frame_get(scene, seq_meta);
173
174 int min = MAXFRAME * 2;
175 int max = -MAXFRAME * 2;
176 LISTBASE_FOREACH (Sequence *, seq, &seq_meta->seqbase) {
178 max = max_ii(SEQ_time_right_handle_frame_get(scene, seq), max);
179 }
180
181 seq_meta->start = min + seq_meta->anim_startofs;
182 seq_meta->len = max - min;
183 seq_meta->len -= seq_meta->anim_startofs;
184 seq_meta->len -= seq_meta->anim_endofs;
185
186 /* Functions `SEQ_time_*_handle_frame_set()` can not be used here, because they are clamped, so
187 * change must be done at once. */
188 seq_meta->startofs = strip_start - seq_meta->start;
189 seq_meta->startdisp = strip_start; /* Only to make files usable in older versions. */
190 seq_meta->endofs = seq_meta->start + SEQ_time_strip_length_get(scene, seq_meta) - strip_end;
191 seq_meta->enddisp = strip_end; /* Only to make files usable in older versions. */
192
193 seq_update_sound_bounds_recursive(scene, seq_meta);
194 blender::Span effects = seq_sequence_lookup_effects_by_seq(scene, seq_meta);
197}
198
200{
201 if (seq->seq1 == nullptr && seq->seq2 == nullptr) {
202 return;
203 }
204
205 if (seq->seq1 && seq->seq2) { /* 2 - input effect. */
210 }
211 else if (seq->seq1) { /* Single input effect. */
213 seq->enddisp = SEQ_time_left_handle_frame_get(scene, seq->seq1);
214 }
215 else if (seq->seq2) { /* Strip may be missing one of inputs. */
217 seq->enddisp = SEQ_time_left_handle_frame_get(scene, seq->seq2);
218 }
219
220 if (seq->startdisp > seq->enddisp) {
221 std::swap(seq->startdisp, seq->enddisp);
222 }
223
224 /* Values unusable for effects, these should be always 0. */
225 seq->startofs = seq->endofs = seq->anim_startofs = seq->anim_endofs = 0;
226 seq->start = seq->startdisp;
227 seq->len = seq->enddisp - seq->startdisp;
228}
229
231 const blender::Span<Sequence *> effects)
232{
233 /* First pass: Update length of immediate effects. */
234 for (Sequence *seq : effects) {
235 seq_time_effect_range_set(scene, seq);
236 }
237
238 /* Second pass: Recursive call to update effects in chain and in order, so they inherit length
239 * correctly. */
240 for (Sequence *seq : effects) {
241 blender::Span effects_recurse = seq_sequence_lookup_effects_by_seq(scene, seq);
242 seq_time_update_effects_strip_range(scene, effects_recurse);
243 }
244}
245
247 int timeline_frame,
248 const short side,
249 const bool do_skip_mute,
250 const bool do_center,
251 const bool do_unselected)
252{
253 Editing *ed = SEQ_editing_get(scene);
254 ListBase *channels = SEQ_channels_displayed_get(ed);
255
256 int dist, best_dist, best_frame = timeline_frame;
257 int seq_frames[2], seq_frames_tot;
258
259 /* In case where both is passed,
260 * frame just finds the nearest end while frame_left the nearest start. */
261
262 best_dist = MAXFRAME * 2;
263
264 if (ed == nullptr) {
265 return timeline_frame;
266 }
267
268 LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) {
269 int i;
270
271 if (do_skip_mute && SEQ_render_is_muted(channels, seq)) {
272 continue;
273 }
274
275 if (do_unselected && (seq->flag & SELECT)) {
276 continue;
277 }
278
279 if (do_center) {
280 seq_frames[0] = (SEQ_time_left_handle_frame_get(scene, seq) +
282 2;
283 seq_frames_tot = 1;
284 }
285 else {
286 seq_frames[0] = SEQ_time_left_handle_frame_get(scene, seq);
287 seq_frames[1] = SEQ_time_right_handle_frame_get(scene, seq);
288
289 seq_frames_tot = 2;
290 }
291
292 for (i = 0; i < seq_frames_tot; i++) {
293 const int seq_frame = seq_frames[i];
294
295 dist = MAXFRAME * 2;
296
297 switch (side) {
298 case SEQ_SIDE_LEFT:
299 if (seq_frame < timeline_frame) {
300 dist = timeline_frame - seq_frame;
301 }
302 break;
303 case SEQ_SIDE_RIGHT:
304 if (seq_frame > timeline_frame) {
305 dist = seq_frame - timeline_frame;
306 }
307 break;
308 case SEQ_SIDE_BOTH:
309 dist = abs(seq_frame - timeline_frame);
310 break;
311 }
312
313 if (dist < best_dist) {
314 best_frame = seq_frame;
315 best_dist = dist;
316 }
317 }
318 }
319
320 return best_frame;
321}
322
324{
325 switch (seq->type) {
326 case SEQ_TYPE_MOVIE: {
327 seq_open_anim_file(scene, seq, true);
328 if (BLI_listbase_is_empty(&seq->anims)) {
329 return 0.0f;
330 }
331 StripAnim *strip_anim = static_cast<StripAnim *>(seq->anims.first);
332 if (strip_anim->anim == nullptr) {
333 return 0.0f;
334 }
335 short frs_sec;
336 float frs_sec_base;
337 if (IMB_anim_get_fps(strip_anim->anim, true, &frs_sec, &frs_sec_base)) {
338 return float(frs_sec) / frs_sec_base;
339 }
340 break;
341 }
343 if (seq->clip != nullptr) {
344 return BKE_movieclip_get_fps(seq->clip);
345 }
346 break;
347 case SEQ_TYPE_SCENE:
348 if (seq->scene != nullptr) {
349 return float(seq->scene->r.frs_sec) / seq->scene->r.frs_sec_base;
350 }
351 break;
352 }
353 return 0.0f;
354}
355
356void SEQ_timeline_init_boundbox(const Scene *scene, rctf *r_rect)
357{
358 r_rect->xmin = scene->r.sfra;
359 r_rect->xmax = scene->r.efra + 1;
360 r_rect->ymin = 1.0f; /* The first strip is drawn at y == 1.0f */
361 r_rect->ymax = 8.0f;
362}
363
364void SEQ_timeline_expand_boundbox(const Scene *scene, const ListBase *seqbase, rctf *rect)
365{
366 if (seqbase == nullptr) {
367 return;
368 }
369
370 LISTBASE_FOREACH (Sequence *, seq, seqbase) {
371 if (rect->xmin > SEQ_time_left_handle_frame_get(scene, seq) - 1) {
372 rect->xmin = SEQ_time_left_handle_frame_get(scene, seq) - 1;
373 }
374 if (rect->xmax < SEQ_time_right_handle_frame_get(scene, seq) + 1) {
375 rect->xmax = SEQ_time_right_handle_frame_get(scene, seq) + 1;
376 }
377 if (rect->ymax < seq->machine + 1.0f) {
378 /* We do +1 here to account for the channel thickness. Channel n has range of <n, n+1>. */
379 rect->ymax = seq->machine + 1.0f;
380 }
381 }
382}
383
384void SEQ_timeline_boundbox(const Scene *scene, const ListBase *seqbase, rctf *r_rect)
385{
386 SEQ_timeline_init_boundbox(scene, r_rect);
387 SEQ_timeline_expand_boundbox(scene, seqbase, r_rect);
388}
389
390static bool strip_exists_at_frame(const Scene *scene,
392 const int timeline_frame)
393{
394 for (Sequence *seq : strips) {
395 if (SEQ_time_strip_intersects_frame(scene, seq, timeline_frame)) {
396 return true;
397 }
398 }
399 return false;
400}
401
402void seq_time_gap_info_get(const Scene *scene,
403 ListBase *seqbase,
404 const int initial_frame,
405 GapInfo *r_gap_info)
406{
407 rctf rectf;
408 /* Get first and last frame. */
409 SEQ_timeline_boundbox(scene, seqbase, &rectf);
410 const int sfra = int(rectf.xmin);
411 const int efra = int(rectf.xmax);
412 int timeline_frame = initial_frame;
413 r_gap_info->gap_exists = false;
414
416
417 if (!strip_exists_at_frame(scene, strips, initial_frame)) {
418 /* Search backward for gap_start_frame. */
419 for (; timeline_frame >= sfra; timeline_frame--) {
420 if (strip_exists_at_frame(scene, strips, timeline_frame)) {
421 break;
422 }
423 }
424 r_gap_info->gap_start_frame = timeline_frame + 1;
425 timeline_frame = initial_frame;
426 }
427 else {
428 /* Search forward for gap_start_frame. */
429 for (; timeline_frame <= efra; timeline_frame++) {
430 if (!strip_exists_at_frame(scene, strips, timeline_frame)) {
431 r_gap_info->gap_start_frame = timeline_frame;
432 break;
433 }
434 }
435 }
436 /* Search forward for gap_end_frame. */
437 for (; timeline_frame <= efra; timeline_frame++) {
438 if (strip_exists_at_frame(scene, strips, timeline_frame)) {
439 const int gap_end_frame = timeline_frame;
440 r_gap_info->gap_length = gap_end_frame - r_gap_info->gap_start_frame;
441 r_gap_info->gap_exists = true;
442 break;
443 }
444 }
445}
446
448 const Sequence *seq,
449 const int timeline_frame)
450{
451 return (SEQ_time_left_handle_frame_get(scene, seq) <= timeline_frame) &&
452 (SEQ_time_right_handle_frame_get(scene, seq) > timeline_frame);
453}
454
455bool SEQ_time_has_left_still_frames(const Scene *scene, const Sequence *seq)
456{
458}
459
460bool SEQ_time_has_right_still_frames(const Scene *scene, const Sequence *seq)
461{
463}
464
465bool SEQ_time_has_still_frames(const Scene *scene, const Sequence *seq)
466{
467 return SEQ_time_has_right_still_frames(scene, seq) || SEQ_time_has_left_still_frames(scene, seq);
468}
469
470int SEQ_time_strip_length_get(const Scene *scene, const Sequence *seq)
471{
472 if (SEQ_retiming_is_active(seq)) {
473 const int last_key_frame = SEQ_retiming_key_timeline_frame_get(
474 scene, seq, SEQ_retiming_last_key_get(seq));
475 /* Last key is mapped to last frame index. Numbering starts from 0. */
476 int sound_offset = SEQ_time_get_rounded_sound_offset(scene, seq);
477 return last_key_frame + 1 - SEQ_time_start_frame_get(seq) - sound_offset;
478 }
479
480 return seq->len / SEQ_time_media_playback_rate_factor_get(scene, seq);
481}
482
484{
485 return seq->start;
486}
487
488void SEQ_time_start_frame_set(const Scene *scene, Sequence *seq, int timeline_frame)
489{
490 seq->start = timeline_frame;
494}
495
496float SEQ_time_content_end_frame_get(const Scene *scene, const Sequence *seq)
497{
498 return SEQ_time_start_frame_get(seq) + SEQ_time_strip_length_get(scene, seq);
499}
500
501int SEQ_time_left_handle_frame_get(const Scene * /*scene*/, const Sequence *seq)
502{
503 if (seq->seq1 || seq->seq2) {
504 return seq->startdisp;
505 }
506
507 return seq->start + seq->startofs;
508}
509
510int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
511{
512 if (seq->seq1 || seq->seq2) {
513 return seq->enddisp;
514 }
515
516 return SEQ_time_content_end_frame_get(scene, seq) - seq->endofs;
517}
518
519void SEQ_time_left_handle_frame_set(const Scene *scene, Sequence *seq, int timeline_frame)
520{
521 const float right_handle_orig_frame = SEQ_time_right_handle_frame_get(scene, seq);
522
523 if (timeline_frame >= right_handle_orig_frame) {
524 timeline_frame = right_handle_orig_frame - 1;
525 }
526
527 float offset = timeline_frame - SEQ_time_start_frame_get(seq);
528
530 /* This strip has only 1 frame of content, that is always stretched to whole strip length.
531 * Therefore, strip start should be moved instead of adjusting offset. */
532 SEQ_time_start_frame_set(scene, seq, timeline_frame);
533 seq->endofs += offset;
534 }
535 else {
536 seq->startofs = offset;
537 }
538
539 seq->startdisp = timeline_frame; /* Only to make files usable in older versions. */
540
544}
545
546void SEQ_time_right_handle_frame_set(const Scene *scene, Sequence *seq, int timeline_frame)
547{
548 const float left_handle_orig_frame = SEQ_time_left_handle_frame_get(scene, seq);
549
550 if (timeline_frame <= left_handle_orig_frame) {
551 timeline_frame = left_handle_orig_frame + 1;
552 }
553
554 seq->endofs = SEQ_time_content_end_frame_get(scene, seq) - timeline_frame;
555 seq->enddisp = timeline_frame; /* Only to make files usable in older versions. */
556
560}
561
562void seq_time_translate_handles(const Scene *scene, Sequence *seq, const int offset)
563{
564 seq->startofs += offset;
565 seq->endofs -= offset;
566 seq->startdisp += offset; /* Only to make files usable in older versions. */
567 seq->enddisp -= offset; /* Only to make files usable in older versions. */
568
572}
573
575 const Scene *scene, Sequence *seq, int delta, float subframe_delta, bool recursed)
576{
577 if (seq->type == SEQ_TYPE_SOUND_RAM && subframe_delta != 0.0f) {
578 seq->sound_offset += subframe_delta / FPS;
579 }
580
581 if (delta == 0) {
582 return;
583 }
584
585 /* Skip effect strips where the length is dependent on another strip,
586 * as they are calculated with #seq_time_update_effects_strip_range. */
587 if (seq->seq1 != nullptr || seq->seq2 != nullptr) {
588 return;
589 }
590
591 /* Effects only have a start frame and a length, so unless we're inside
592 * a meta strip, there's no need to do anything. */
593 if (!recursed && (seq->type & SEQ_TYPE_EFFECT)) {
594 return;
595 }
596
597 /* Move strips inside meta strip. */
598 if (seq->type == SEQ_TYPE_META) {
599 /* If the meta strip has no contents, don't do anything. */
600 if (BLI_listbase_is_empty(&seq->seqbase)) {
601 return;
602 }
603 LISTBASE_FOREACH (Sequence *, seq_child, &seq->seqbase) {
604 seq_time_slip_strip_ex(scene, seq_child, delta, subframe_delta, true);
605 }
606 }
607
608 seq->start = seq->start + delta;
609 if (!recursed) {
610 seq->startofs = seq->startofs - delta;
611 seq->endofs = seq->endofs + delta;
612 }
613
614 /* Only to make files usable in older versions. */
615 seq->startdisp = SEQ_time_left_handle_frame_get(scene, seq);
616 seq->enddisp = SEQ_time_right_handle_frame_get(scene, seq);
617
620}
621
622void SEQ_time_slip_strip(const Scene *scene, Sequence *seq, int delta, float subframe_delta)
623{
624 seq_time_slip_strip_ex(scene, seq, delta, subframe_delta, false);
625}
626
628{
629 int sound_offset = 0;
630 if (seq->type == SEQ_TYPE_SOUND_RAM && seq->sound != nullptr) {
631 sound_offset = round_fl_to_int((seq->sound->offset_time + seq->sound_offset) * FPS);
632 }
633 return sound_offset;
634}
float BKE_movieclip_get_fps(struct MovieClip *clip)
void BKE_sound_move_scene_sound(const 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)
#define LISTBASE_FOREACH(type, var, list)
MINLINE int round_fl_to_int(float a)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float clamp_f(float value, float min, float max)
MINLINE int max_ii(int a, int b)
#define ELEM(...)
#define FPS
#define MAXFRAME
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_META
@ SEQ_TYPE_SCENE
@ SEQ_TYPE_MOVIECLIP
@ SEQ_TYPE_IMAGE
@ SEQ_TYPE_EFFECT
@ SEQ_TYPE_MOVIE
@ SEQ_REVERSE_FRAMES
@ SEQ_AUTO_PLAYBACK_RATE
bool IMB_anim_get_fps(const ImBufAnim *anim, bool no_av_base, short *r_frs_sec, float *r_frs_sec_base)
Read Guarded memory(de)allocation.
@ SEQ_SIDE_RIGHT
@ SEQ_SIDE_BOTH
@ SEQ_SIDE_LEFT
ListBase * SEQ_channels_displayed_get(Editing *ed)
Definition channels.cc:23
#define SELECT
#define fmodf(x, y)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
VectorSet< Sequence * > SEQ_query_all_strips(ListBase *seqbase)
Definition iterator.cc:97
bool SEQ_render_is_muted(const ListBase *channels, const Sequence *seq)
Definition render.cc:2154
Sequence * seq_sequence_lookup_meta_by_seq(const Scene *scene, const Sequence *key)
blender::Span< Sequence * > seq_sequence_lookup_effects_by_seq(const Scene *scene, const Sequence *key)
void seq_open_anim_file(Scene *scene, Sequence *seq, bool openfile)
Editing * SEQ_editing_get(const Scene *scene)
Definition sequencer.cc:262
#define min(a, b)
Definition sort.c:32
bool SEQ_retiming_is_active(const Sequence *seq)
SeqRetimingKey * SEQ_retiming_last_key_get(const Sequence *seq)
int SEQ_retiming_key_timeline_frame_get(const Scene *scene, const Sequence *seq, const SeqRetimingKey *key)
float seq_retiming_evaluate(const Sequence *seq, const float frame_index)
float SEQ_give_frame_index(const Scene *scene, const Sequence *seq, float timeline_frame)
Definition strip_time.cc:60
void SEQ_time_start_frame_set(const Scene *scene, Sequence *seq, int timeline_frame)
int SEQ_time_strip_length_get(const Scene *scene, const Sequence *seq)
static int metaseq_end(Sequence *metaseq)
int seq_time_strip_original_content_length_get(const Scene *scene, const Sequence *seq)
Definition strip_time.cc:51
bool SEQ_time_has_right_still_frames(const Scene *scene, const Sequence *seq)
bool SEQ_time_has_left_still_frames(const Scene *scene, const Sequence *seq)
bool SEQ_time_has_still_frames(const Scene *scene, const Sequence *seq)
void SEQ_time_right_handle_frame_set(const Scene *scene, Sequence *seq, int timeline_frame)
void SEQ_time_update_meta_strip_range(const Scene *scene, Sequence *seq_meta)
void SEQ_time_left_handle_frame_set(const Scene *scene, Sequence *seq, int timeline_frame)
void seq_update_sound_bounds_recursive(const Scene *scene, Sequence *metaseq)
int SEQ_time_get_rounded_sound_offset(const Scene *scene, const Sequence *seq)
static void seq_time_slip_strip_ex(const Scene *scene, Sequence *seq, int delta, float subframe_delta, bool recursed)
int SEQ_time_left_handle_frame_get(const Scene *, const Sequence *seq)
void SEQ_timeline_expand_boundbox(const Scene *scene, const ListBase *seqbase, rctf *rect)
float SEQ_time_content_end_frame_get(const Scene *scene, const Sequence *seq)
void seq_time_translate_handles(const Scene *scene, Sequence *seq, const int offset)
void SEQ_time_slip_strip(const Scene *scene, Sequence *seq, int delta, float subframe_delta)
void seq_time_gap_info_get(const Scene *scene, ListBase *seqbase, const int initial_frame, GapInfo *r_gap_info)
static int metaseq_start(Sequence *metaseq)
void seq_time_effect_range_set(const Scene *scene, Sequence *seq)
float SEQ_time_sequence_get_fps(Scene *scene, Sequence *seq)
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)
void SEQ_timeline_init_boundbox(const Scene *scene, rctf *r_rect)
bool SEQ_time_strip_intersects_frame(const Scene *scene, const Sequence *seq, const int timeline_frame)
void SEQ_timeline_boundbox(const Scene *scene, const ListBase *seqbase, rctf *r_rect)
void seq_time_update_effects_strip_range(const Scene *scene, const blender::Span< Sequence * > effects)
static bool strip_exists_at_frame(const Scene *scene, blender::Span< Sequence * > strips, const int timeline_frame)
float SEQ_time_start_frame_get(const Sequence *seq)
float SEQ_time_media_playback_rate_factor_get(const Scene *scene, const Sequence *seq)
Definition strip_time.cc:38
static void seq_update_sound_bounds_recursive_impl(const Scene *scene, Sequence *metaseq, int start, int end)
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
bool SEQ_transform_single_image_check(const Sequence *seq)
ListBase * seqbasep
int gap_length
Definition strip_time.hh:22
int gap_start_frame
Definition strip_time.hh:21
bool gap_exists
Definition strip_time.hh:23
void * first
struct RenderData r
float media_playback_rate
struct MovieClip * clip
struct Scene * scene
struct bSound * sound
struct Sequence * seq1
struct Sequence * seq2
struct ImBufAnim * anim
double offset_time
float xmax
float xmin
float ymax
float ymin
ccl_device_inline int abs(int x)
Definition util/math.h:120