Files
test2/source/blender/sequencer/intern/effects/vse_effect_multi_camera.cc
Richard Antalik 97297bd167 Fix #146484: Stack overflow due to recursive strip rendering
When effect of adjustment layer strip is moved below the adjustment
layer, this causes infinite loop in strip rendering. Same happens when
you use multicam strip and set source channel to one of its effects.

This is fixed by passing `SeqRenderState` to the effects. If any strip
renders "seqbase" pointer of strip is stored in set in the render state
struct. If the pointer exists in this set, function returns without
rendering anything. In other words, The strip must never render itself.

Pull Request: https://projects.blender.org/blender/blender/pulls/146624
2025-09-25 08:48:56 +02:00

72 lines
1.7 KiB
C++

/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup sequencer
*/
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "SEQ_channels.hh"
#include "SEQ_render.hh"
#include "SEQ_utils.hh"
#include "effects.hh"
#include "render.hh"
namespace blender::seq {
/* No effect inputs for multi-camera, we use #give_ibuf_seq. */
static int num_inputs_multicam()
{
return 0;
}
static StripEarlyOut early_out_multicam(const Strip * /*strip*/, float /*fac*/)
{
return StripEarlyOut::NoInput;
}
static ImBuf *do_multicam(const RenderData *context,
SeqRenderState *state,
Strip *strip,
float timeline_frame,
float /*fac*/,
ImBuf * /*ibuf1*/,
ImBuf * /*ibuf2*/)
{
ImBuf *out;
Editing *ed;
if (strip->multicam_source == 0 || strip->multicam_source >= strip->channel) {
return nullptr;
}
ed = context->scene->ed;
if (!ed || state->strips_rendering_seqbase.contains(strip)) {
return nullptr;
}
ListBase *seqbasep = get_seqbase_by_strip(context->scene, strip);
ListBase *channels = get_channels_by_strip(ed, strip);
if (!seqbasep) {
return nullptr;
}
state->strips_rendering_seqbase.add(strip);
out = seq_render_give_ibuf_seqbase(
context, state, timeline_frame, strip->multicam_source, channels, seqbasep);
return out;
}
void multi_camera_effect_get_handle(EffectHandle &rval)
{
rval.num_inputs = num_inputs_multicam;
rval.early_out = early_out_multicam;
rval.execute = do_multicam;
}
} // namespace blender::seq