perf(media): tell the media pool which EXR footage effects read (#474)

The pool learned that an effect reads a footage item's channels only at the
first aux() call, so the first frame was decoded twice (picture, then in
full), and the hint was never cleared after the effect was removed.

The session now gives the footage source the whole set of files read by
enabled 3D Channel effects (FootageSource::set_aux_footage) with every
project change (Session::bump: edits, undo, redo, history jumps, rollbacks,
project open), sending it only when it changed. The pool keeps that set and,
as a safety net, what aux() learns; a new set drops what was learned.

Refs #474

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
vangel76
2026-11-03 03:21:40 +01:00
co-authored by Claude Opus 5.5
parent 00a15d847e
commit 5b31b96cde
14 changed files with 412 additions and 12 deletions
+9
View File
@@ -48,6 +48,12 @@ pub trait FootageSource: Send + Sync {
fn aux(&self, _item: ItemId, _footage: &Footage, _t: Tick) -> Option<Arc<effectcraft_raster::AuxChannels>> {
None
}
/// The footage files (by [`Footage::path`]) whose channels effects of the project read
/// through [`FootageSource::aux`] (EXtractoR, Cryptomatte and the other 3D Channel effects),
/// replacing the set given before. A source that decodes a file's picture and its channels
/// separately can decode both at once for these from the first frame on. Sources that don't
/// ignore it.
fn set_aux_footage(&self, _paths: &[String]) {}
/// The parsed 3D model of a [`effectcraft_project::FootageKind::Model`] item (Advanced 3D).
fn model(&self, _item: ItemId, _footage: &Footage) -> Option<Arc<effectcraft_model::Model>> {
None
@@ -140,6 +146,9 @@ impl FootageSource for CancellableFootage<'_> {
fn aux(&self, item: ItemId, footage: &Footage, t: Tick) -> Option<Arc<effectcraft_raster::AuxChannels>> {
self.inner.aux(item, footage, t)
}
fn set_aux_footage(&self, paths: &[String]) {
self.inner.set_aux_footage(paths)
}
fn model(&self, item: ItemId, footage: &Footage) -> Option<Arc<effectcraft_model::Model>> {
self.inner.model(item, footage)
}