Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Antalik <richardantalik@gmail.com>2022-06-29 13:45:59 +0300
committerRichard Antalik <richardantalik@gmail.com>2022-06-29 13:48:34 +0300
commit302b04a5a3fc0e767ac784424f78ce2edf5d2844 (patch)
treedef4de621fbb0a194b350da781f054c6aefbab35 /source/blender/sequencer/intern/render.c
parentc51b8ec86364585c4088837c603b39752065bc34 (diff)
VSE: Improved Retiming system
Patch implements better way to control playback speed than it is possible to do with speed effect. Speed factor property can be set in Time panel. There are 2 layers of control: Option to retime movie to match scene FPS rate. Custom speed factor to control playback rate. Since playback rate is strip property, it is now possible to manipulate strip as normal one even if it is retimed. To facilitate manipulation, some functions need to consider speed factor and apply necessary corrections to strip offset or strip start. These corrections may need to be float numbers, so start and offsets must be float as well. Sound strips now use speed factor instead of pitch. This means, that strips will change length to match usable length. In addition, it is possible to group movie and sound strip and change speed of meta strip.
Diffstat (limited to 'source/blender/sequencer/intern/render.c')
-rw-r--r--source/blender/sequencer/intern/render.c65
1 files changed, 38 insertions, 27 deletions
diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c
index e7a1bbeb9d0..15487a597d1 100644
--- a/source/blender/sequencer/intern/render.c
+++ b/source/blender/sequencer/intern/render.c
@@ -233,7 +233,7 @@ void seq_render_state_init(SeqRenderState *state)
state->scene_parents = NULL;
}
-StripElem *SEQ_render_give_stripelem(Sequence *seq, int timeline_frame)
+StripElem *SEQ_render_give_stripelem(const Scene *scene, Sequence *seq, int timeline_frame)
{
StripElem *se = seq->strip->stripdata;
@@ -242,7 +242,7 @@ StripElem *SEQ_render_give_stripelem(Sequence *seq, int timeline_frame)
* all other strips don't use this...
*/
- int frame_index = (int)seq_give_frame_index(seq, timeline_frame);
+ int frame_index = (int)seq_give_frame_index(scene, seq, timeline_frame);
if (frame_index == -1 || se == NULL) {
return NULL;
@@ -258,14 +258,15 @@ static int seq_channel_cmp_fn(const void *a, const void *b)
return (*(Sequence **)a)->machine - (*(Sequence **)b)->machine;
}
-int seq_get_shown_sequences(ListBase *channels,
+int seq_get_shown_sequences(const Scene *scene,
+ ListBase *channels,
ListBase *seqbase,
const int timeline_frame,
const int chanshown,
Sequence **r_seq_arr)
{
SeqCollection *collection = SEQ_query_rendered_strips(
- channels, seqbase, timeline_frame, chanshown);
+ scene, channels, seqbase, timeline_frame, chanshown);
const int strip_count = BLI_gset_len(collection->set);
if (strip_count > MAXSEQ) {
@@ -795,7 +796,7 @@ static ImBuf *seq_render_effect_strip_impl(const SeqRenderData *context,
}
if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
- sh.get_default_fac(seq, timeline_frame, &fac);
+ sh.get_default_fac(scene, seq, timeline_frame, &fac);
}
else {
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "effect_fader", 0, NULL);
@@ -936,7 +937,7 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context,
char prefix[FILE_MAX];
ImBuf *ibuf = NULL;
- StripElem *s_elem = SEQ_render_give_stripelem(seq, timeline_frame);
+ StripElem *s_elem = SEQ_render_give_stripelem(context->scene, seq, timeline_frame);
if (s_elem == NULL) {
return NULL;
}
@@ -1024,7 +1025,8 @@ static ImBuf *seq_render_movie_strip_custom_file_proxy(const SeqRenderData *cont
}
}
- int frameno = (int)seq_give_frame_index(seq, timeline_frame) + seq->anim_startofs;
+ int frameno = (int)seq_give_frame_index(context->scene, seq, timeline_frame) +
+ seq->anim_startofs;
return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE);
}
@@ -1622,7 +1624,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context,
bool *r_is_proxy_image)
{
ImBuf *ibuf = NULL;
- float frame_index = seq_give_frame_index(seq, timeline_frame);
+ float frame_index = seq_give_frame_index(context->scene, seq, timeline_frame);
int type = (seq->type & SEQ_TYPE_EFFECT) ? SEQ_TYPE_EFFECT : seq->type;
switch (type) {
case SEQ_TYPE_META: {
@@ -1826,7 +1828,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
ImBuf *out = NULL;
count = seq_get_shown_sequences(
- channels, seqbasep, timeline_frame, chanshown, (Sequence **)&seq_arr);
+ context->scene, channels, seqbasep, timeline_frame, chanshown, (Sequence **)&seq_arr);
if (count == 0) {
return NULL;
@@ -1940,7 +1942,7 @@ ImBuf *SEQ_render_give_ibuf(const SeqRenderData *context, float timeline_frame,
Sequence *seq_arr[MAXSEQ + 1];
int count;
- count = seq_get_shown_sequences(channels, seqbasep, timeline_frame, chanshown, seq_arr);
+ count = seq_get_shown_sequences(scene, channels, seqbasep, timeline_frame, chanshown, seq_arr);
if (count) {
out = seq_cache_get(context, seq_arr[count - 1], timeline_frame, SEQ_CACHE_STORE_FINAL_OUT);
@@ -1992,14 +1994,17 @@ ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context,
return ibuf;
}
-float SEQ_render_thumbnail_first_frame_get(Sequence *seq, float frame_step, rctf *view_area)
+float SEQ_render_thumbnail_first_frame_get(const Scene *scene,
+ Sequence *seq,
+ float frame_step,
+ rctf *view_area)
{
int first_drawable_frame = max_iii(
- SEQ_time_left_handle_frame_get(seq), seq->start, view_area->xmin);
+ SEQ_time_left_handle_frame_get(scene, seq), seq->start, view_area->xmin);
/* First frame should correspond to handle position. */
- if (first_drawable_frame == SEQ_time_left_handle_frame_get(seq)) {
- return SEQ_time_left_handle_frame_get(seq);
+ if (first_drawable_frame == SEQ_time_left_handle_frame_get(scene, seq)) {
+ return SEQ_time_left_handle_frame_get(scene, seq);
}
float aligned_frame_offset = (int)((first_drawable_frame - seq->start) / frame_step) *
@@ -2007,12 +2012,15 @@ float SEQ_render_thumbnail_first_frame_get(Sequence *seq, float frame_step, rctf
return seq->start + aligned_frame_offset;
}
-float SEQ_render_thumbnail_next_frame_get(Sequence *seq, float last_frame, float frame_step)
+float SEQ_render_thumbnail_next_frame_get(const Scene *scene,
+ Sequence *seq,
+ float last_frame,
+ float frame_step)
{
float next_frame = last_frame + frame_step;
/* If handle position was displayed, align next frame with `seq->start`. */
- if (last_frame == SEQ_time_left_handle_frame_get(seq)) {
+ if (last_frame == SEQ_time_left_handle_frame_get(scene, seq)) {
next_frame = seq->start + ((int)((last_frame - seq->start) / frame_step) + 1) * frame_step;
}
@@ -2086,22 +2094,23 @@ void SEQ_render_thumbnails(const SeqRenderData *context,
{
SeqRenderState state;
seq_render_state_init(&state);
+ const Scene *scene = context->scene;
/* Adding the hold offset value (seq->anim_startofs) to the start frame. Position of image not
* affected, but frame loaded affected. */
- float upper_thumb_bound = SEQ_time_has_right_still_frames(seq) ?
+ float upper_thumb_bound = SEQ_time_has_right_still_frames(scene, seq) ?
(seq->start + seq->len) :
- SEQ_time_right_handle_frame_get(seq);
+ SEQ_time_right_handle_frame_get(scene, seq);
upper_thumb_bound = (upper_thumb_bound > view_area->xmax) ? view_area->xmax + frame_step :
upper_thumb_bound;
- float timeline_frame = SEQ_render_thumbnail_first_frame_get(seq, frame_step, view_area);
+ float timeline_frame = SEQ_render_thumbnail_first_frame_get(scene, seq, frame_step, view_area);
while ((timeline_frame < upper_thumb_bound) & !*stop) {
ImBuf *ibuf = seq_cache_get(
context, seq_orig, round_fl_to_int(timeline_frame), SEQ_CACHE_STORE_THUMBNAIL);
if (ibuf) {
IMB_freeImBuf(ibuf);
- timeline_frame = SEQ_render_thumbnail_next_frame_get(seq, timeline_frame, frame_step);
+ timeline_frame = SEQ_render_thumbnail_next_frame_get(scene, seq, timeline_frame, frame_step);
continue;
}
@@ -2118,14 +2127,15 @@ void SEQ_render_thumbnails(const SeqRenderData *context,
return;
}
- timeline_frame = SEQ_render_thumbnail_next_frame_get(seq, timeline_frame, frame_step);
+ timeline_frame = SEQ_render_thumbnail_next_frame_get(scene, seq, timeline_frame, frame_step);
}
}
-int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const Sequence *seq)
+int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const Scene *scene, const Sequence *seq)
{
- const int content_start = max_ii(SEQ_time_left_handle_frame_get(seq), seq->start);
- const int content_end = min_ii(SEQ_time_right_handle_frame_get(seq), seq->start + seq->len);
+ const int content_start = max_ii(SEQ_time_left_handle_frame_get(scene, seq), seq->start);
+ const int content_end = min_ii(SEQ_time_right_handle_frame_get(scene, seq),
+ seq->start + seq->len);
const int content_len = content_end - content_start;
/* Arbitrary, but due to performance reasons should be as low as possible. */
@@ -2144,11 +2154,12 @@ void SEQ_render_thumbnails_base_set(const SeqRenderData *context,
{
SeqRenderState state;
seq_render_state_init(&state);
+ const Scene *scene = context->scene;
- int timeline_frame = SEQ_time_left_handle_frame_get(seq);
- const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(seq);
+ int timeline_frame = SEQ_time_left_handle_frame_get(scene, seq);
+ const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(scene, seq);
- while (timeline_frame < SEQ_time_right_handle_frame_get(seq) && !*stop) {
+ while (timeline_frame < SEQ_time_right_handle_frame_get(scene, seq) && !*stop) {
ImBuf *ibuf = seq_cache_get(
context, seq_orig, roundf(timeline_frame), SEQ_CACHE_STORE_THUMBNAIL);
if (ibuf) {