render: apply clip effect stacks in the montage path
Adding an effect to a clip did nothing: the sequence render is flattened into a montage (decode + composite), and MontageClip carried no effect data at all. - MontageClip gains an ordered effect stack (type id / enabled / effect input / parameter values); protocol v2 carries it as an additive wire field (older peers default to an empty stack). - renderops::video_montage fills the stack from the effect chain (the footage source node — the chain end without an effect input — is dropped; the montage decodes the footage itself). Export (oak-task) and the multicam single-track montage fill it too. - The worker applies the stack between decode and composite: built-in Opacity gets a CPU evaluator (C++ opacity.frag parity — whole vec4, alpha included, unity pass-through); everything else dispatches as an OFX plugin job through a new instance-factory slot (oak-plugin lazily creates + caches one instance per identifier per render process) with the montage's parameters injected. Disabled effects bypass (the C++ traverser pushes the effect input through). Unknown types warn once per type id and pass through — no silent no-ops. Not covered (explicitly): Transform/Crop and the other ~30 built-in effects have no CPU evaluator in oak-render (they pass through with a warning), keyframed parameter animation, audio effect chains, and the CLI's simplified montage. Acceptance: a real 50% Opacity on real media quarters the rendered pixels both in-process (renderops test) and through a real worker process over IPC + shared memory (procpool_integration test); disabling restores the plain render byte-for-byte.
This commit is contained in:
@@ -1936,6 +1936,7 @@ fn build_ticket_spec(
|
||||
media_in_num: c.media_in.numerator(),
|
||||
media_in_den: c.media_in.denominator(),
|
||||
gain: c.gain,
|
||||
effects: c.effects.iter().map(crate::ipc::wire_effect_from).collect(),
|
||||
})
|
||||
.collect();
|
||||
BatchTicketSpec {
|
||||
@@ -1970,6 +1971,7 @@ fn build_audio_ticket_spec(ticket: i64, slot: u32, params: &AudioTicketParams) -
|
||||
media_in_num: c.media_in.numerator(),
|
||||
media_in_den: c.media_in.denominator(),
|
||||
gain: c.gain,
|
||||
effects: c.effects.iter().map(crate::ipc::wire_effect_from).collect(),
|
||||
})
|
||||
.collect();
|
||||
AudioTicketSpec {
|
||||
|
||||
Reference in New Issue
Block a user