mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-12 21:32:52 +00:00
Export: Skip Existing keeps a frame already in the overflow folder
* Export: Skip Existing keeps a frame already in the overflow folder * Export: Skip Existing checks every overflow folder before a frame is placed
This commit is contained in:
1 parent
bdc56ca75e
commit
2b30f53e7a
3 files changed
+63
-1
No files matched your search
@@ -321,7 +321,7 @@ async fn sequence(cx: &Cx<'_>, comp: &Comp, w: u32, h: u32, st: &mut State<'_>)
|
||||
let mut i = 0;
|
||||
while i < st.total {
|
||||
let end = (i + batch).min(st.total);
|
||||
let ks: Vec<u64> = (i..end).filter(|k| !(cx.settings.skip_existing && out::exists(cx.sink, &sequence_path(cx.path, f0 + *k as i64)))).collect();
|
||||
let ks: Vec<u64> = (i..end).filter(|k| !(cx.settings.skip_existing && cx.frame_exists(&sequence_path(cx.path, f0 + *k as i64)))).collect();
|
||||
let written: Vec<Result<u64>> = cx
|
||||
.frames(comp, ks, |k, img| {
|
||||
let path = sequence_path(cx.path, f0 + k as i64);
|
||||
|
||||
@@ -894,6 +894,20 @@ impl<'a> Cx<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether Skip Existing finds `path` already written: at its own place or, with Use Storage
|
||||
/// Overflow, in any overflow folder (checked before a frame is placed, so a skipped frame
|
||||
/// reserves no quota).
|
||||
pub fn frame_exists(&self, path: &str) -> bool {
|
||||
if out::exists(self.sink, path) {
|
||||
return true;
|
||||
}
|
||||
if !self.job.settings.storage_overflow {
|
||||
return false;
|
||||
}
|
||||
let Some(name) = std::path::Path::new(path).file_name() else { return false };
|
||||
self.job.options.overflow.iter().any(|dir| out::exists(self.sink, &std::path::Path::new(dir).join(name).to_string_lossy()))
|
||||
}
|
||||
|
||||
/// Where a file goes: `path`, or (Use Storage Overflow) the first overflow folder with room
|
||||
/// for `bytes` when the quota hook says the output volume is full.
|
||||
pub fn place(&self, path: &str, bytes: u64) -> String {
|
||||
|
||||
@@ -444,6 +444,54 @@ fn cancelled_export_removes_only_files_it_opened() {
|
||||
std::fs::remove_dir_all(dir).unwrap();
|
||||
}
|
||||
|
||||
/// Skip Existing keeps a frame that is already in the overflow folder the frame is placed in
|
||||
/// (it checked only the primary destination, then truncated the overflow file).
|
||||
#[test]
|
||||
fn skip_existing_keeps_a_frame_in_the_overflow_folder() {
|
||||
use std::path::PathBuf;
|
||||
// Room only in the second overflow folder; the frame already sits in the first (which is full).
|
||||
struct Overflow(PathBuf);
|
||||
impl StorageQuota for Overflow {
|
||||
fn has_room(&self, path: &str, _: u64) -> bool {
|
||||
std::path::Path::new(path).starts_with(&self.0)
|
||||
}
|
||||
}
|
||||
let guard = tempfile::tempdir().unwrap();
|
||||
let (dir, full, over) = (guard.path().to_path_buf(), guard.path().join("full"), guard.path().join("over"));
|
||||
std::fs::create_dir_all(&full).unwrap();
|
||||
std::fs::create_dir_all(&over).unwrap();
|
||||
std::fs::write(full.join("clip_00000.png"), b"keep").unwrap();
|
||||
let quota = Overflow(over.clone());
|
||||
let (p, cid) = project(FrameRate::new(25, 1), |_, _| {});
|
||||
let settings = RenderSettings { skip_existing: true, storage_overflow: true, ..Default::default() };
|
||||
let om = OutputModule::for_format(OutputFormat::PngSequence);
|
||||
let path = dir.join("clip_[#####].png");
|
||||
let result = export(
|
||||
&Job {
|
||||
project: &p,
|
||||
footage: &NoFootage,
|
||||
expr: None,
|
||||
accel: None,
|
||||
comp: cid,
|
||||
settings: &settings,
|
||||
output: &om,
|
||||
path: path.to_str().unwrap(),
|
||||
sink: None,
|
||||
nested_switches: true,
|
||||
options: JobOptions {
|
||||
storage: Some("a),
|
||||
overflow: vec![full.to_string_lossy().into_owned(), over.to_string_lossy().into_owned()],
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
&mut |_| true,
|
||||
);
|
||||
assert!(result.is_ok(), "{result:?}");
|
||||
assert_eq!(std::fs::read(full.join("clip_00000.png")).unwrap(), b"keep");
|
||||
assert!(!over.join("clip_00000.png").exists(), "no duplicate in another overflow folder");
|
||||
assert!(over.join("clip_00001.png").exists(), "the other frames are still written");
|
||||
}
|
||||
|
||||
/// A GPU compositor stand-in that renders every frame solid green (the CPU draws the bar and the
|
||||
/// block on black) and keeps Auto's timing history.
|
||||
#[derive(Default)]
|
||||
|
||||
Reference in new issue
Block a user