G5: a still asked for at its own size is the unsized frame (#1812)

Review: frame_at_size at a still's native size made a second cache key, so the pool decoded
and kept a second full-size copy of a frame thumbnail() or frame() already had.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ded
2026-10-20 04:01:07 +03:00
co-authored by Claude Opus 5.5
parent fd1250d224
commit c33d5c20df
2 changed files with 7 additions and 1 deletions
+2 -1
View File
@@ -716,7 +716,8 @@ impl Inner {
}
let mut loc = Self::locate(footage, t, float);
let movie = loc.media_t.is_some();
if let Some(size) = size {
// A still asked for at its own size is the unsized frame (one decode, one entry).
if let Some(size) = size.filter(|s| movie || *s != (footage.width, footage.height)) {
loc.key.size = size;
}
let mut c = lock(&self.cache);
+5
View File
@@ -595,6 +595,11 @@ fn stills_at_reduced_sizes_are_resampled_once() {
let f = probe(&p).expect("probe");
let pool = MediaPool::new();
let full = pool.frame(ItemId(1), &f, Tick::ZERO).expect("frame");
// At its own size it is the unsized frame: no second decode, no second full-size copy.
let misses = pool.stats().misses;
let native = pool.frame_at_size(ItemId(1), &f, Tick::ZERO, f.width, f.height).expect("frame");
assert!(Arc::ptr_eq(&full, &native), "the native size reuses the unsized frame");
assert_eq!(pool.stats().misses, misses);
for (w, h) in [(306, 48), (153, 24), (77, 12)] {
let sized = pool.frame_at_size(ItemId(1), &f, Tick::ZERO, w, h).expect("frame");
assert_eq!(*sized, effectcraft_raster::resample(&full, w, h), "{w}×{h}: the renderer's resample");