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
10
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) {
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);
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.
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 Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves 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 Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
@ 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
float max
ccl_device_inline int abs(int x)
Definition util/math.h:120