mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-31 21:48:20 -06:00
S2.4: effectcraft-sam2 crate skeleton
Native-only, Apache-2.0, forbid(unsafe_code), panic lints denied, NOTICE, layer 3. Empty on wasm32. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
48997fcd3d
commit
36a22733a2
Generated
+4
@@ -1765,6 +1765,10 @@ dependencies = [
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "effectcraft-sam2"
|
||||
version = "0.9.2"
|
||||
|
||||
[[package]]
|
||||
name = "effectcraft-script"
|
||||
version = "0.18.0"
|
||||
|
||||
@@ -28,6 +28,7 @@ effectcraft-text = { path = "crates/text" }
|
||||
effectcraft-effects = { path = "crates/effects" }
|
||||
effectcraft-track = { path = "crates/track" }
|
||||
effectcraft-segment = { path = "crates/segment" }
|
||||
effectcraft-sam2 = { path = "crates/sam2" }
|
||||
effectcraft-model = { path = "crates/model" }
|
||||
effectcraft-render = { path = "crates/render" }
|
||||
effectcraft-gpu = { path = "crates/gpu" }
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "effectcraft-sam2"
|
||||
description = "SAM 2.1 (Hiera) video object tracker for the Roto Brush: a Rust port of the Hugging Face transformers implementation, native only, weights downloaded by the user"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license = "Apache-2.0"
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
@@ -0,0 +1,11 @@
|
||||
EffectCraft SAM 2 (effectcraft-sam2)
|
||||
Copyright the EffectCraft contributors.
|
||||
|
||||
This crate is a Rust port of the SAM 2 implementation in Hugging Face `transformers`
|
||||
(`models/sam2` and `models/sam2_video`), Copyright 2025 The HuggingFace Inc. team, which in turn
|
||||
implements "SAM 2: Segment Anything in Images and Videos" by Meta AI (facebookresearch/sam2).
|
||||
Both are licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0).
|
||||
|
||||
Each ported source file states that it is a modified work (Apache-2.0 section 4(b)).
|
||||
Model weights are not part of this crate; they are downloaded by the user from the official
|
||||
`facebook/sam2.1-hiera-*` repositories (Apache-2.0).
|
||||
@@ -0,0 +1,78 @@
|
||||
//! SAM 2.1 video object tracker (Hiera backbone) for the Roto Brush.
|
||||
//!
|
||||
//! A Rust port of the Hugging Face `transformers` SAM 2 implementation (Apache-2.0; see
|
||||
//! `NOTICE`). Native only: the crate is empty on wasm32 so L0–L4 still build for the web.
|
||||
//! Nothing here loads weights unless asked to; weights are never bundled.
|
||||
//!
|
||||
//! Modules are added stage by stage, each checked against reference tensors produced by
|
||||
//! `tools/sam2_reference.py`.
|
||||
#![cfg(not(target_arch = "wasm32"))]
|
||||
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
|
||||
|
||||
use std::fmt;
|
||||
|
||||
/// Everything that can go wrong in this crate. Never a panic.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Error {
|
||||
/// The weights file is missing a tensor, has the wrong shape, or contains non-finite values.
|
||||
Weights(String),
|
||||
/// The input (frame size, prompt, frame index) is unusable.
|
||||
Input(String),
|
||||
/// The work was cancelled by the caller.
|
||||
Cancelled,
|
||||
/// A time or memory budget was exceeded.
|
||||
Budget(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Error::Weights(m) => write!(f, "SAM 2 weights: {m}"),
|
||||
Error::Input(m) => write!(f, "SAM 2 input: {m}"),
|
||||
Error::Cancelled => write!(f, "SAM 2: cancelled"),
|
||||
Error::Budget(m) => write!(f, "SAM 2 budget: {m}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
/// The released SAM 2.1 sizes. Only Tiny is wired up first; the others are configuration.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum Size {
|
||||
Tiny,
|
||||
Small,
|
||||
BasePlus,
|
||||
Large,
|
||||
}
|
||||
|
||||
impl Size {
|
||||
/// The Hugging Face repository the official weights come from.
|
||||
pub fn repo(self) -> &'static str {
|
||||
match self {
|
||||
Size::Tiny => "facebook/sam2.1-hiera-tiny",
|
||||
Size::Small => "facebook/sam2.1-hiera-small",
|
||||
Size::BasePlus => "facebook/sam2.1-hiera-base-plus",
|
||||
Size::Large => "facebook/sam2.1-hiera-large",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn sizes_name_their_official_repositories() {
|
||||
assert_eq!(Size::Tiny.repo(), "facebook/sam2.1-hiera-tiny");
|
||||
assert!(Size::Large.repo().ends_with("large"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errors_say_what_failed() {
|
||||
assert!(Error::Input("empty frame".into()).to_string().contains("empty frame"));
|
||||
assert_eq!(Error::Cancelled.to_string(), "SAM 2: cancelled");
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,7 @@ const LAYERS: &[(&str, u8)] = &[
|
||||
("expr", 3),
|
||||
("export", 3),
|
||||
("gpu", 3),
|
||||
("sam2", 3),
|
||||
("lottie", 3),
|
||||
("format", 3),
|
||||
("plugin", 3),
|
||||
|
||||
Reference in New Issue
Block a user