mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-20 17:02:53 -04:00
fix lossy margins
This commit is contained in:
+25
-25
@@ -15,7 +15,7 @@ use crate::generate::generate_video::video_generation_cost_estimate::VideoGenera
|
||||
/// Kept as f64 because per-second rates are fractional; rounding happens
|
||||
/// once at the end after multiplying by duration × batch.
|
||||
const CENTS_PER_SECOND_480P: f64 = 7.772;
|
||||
const CENTS_PER_SECOND_720P: f64 = 16.0;
|
||||
const CENTS_PER_SECOND_720P: f64 = 18.5;
|
||||
const CENTS_PER_SECOND_1080P: f64 = 46.632;
|
||||
|
||||
/// USD cents per second, in hundredths of a cent, when one or more
|
||||
@@ -131,32 +131,32 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn batch_1() {
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 4, 1), 64);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 5, 1), 80);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 6, 1), 96);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 10, 1), 160);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 15, 1), 240);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 4, 1), 74);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 5, 1), 93);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 6, 1), 111);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 10, 1), 185);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 15, 1), 278);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn batch_2() {
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 4, 2), 128);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 5, 2), 160);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 15, 2), 480);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 4, 2), 148);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 5, 2), 185);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 15, 2), 555);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn batch_3() {
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 4, 3), 192);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 5, 3), 240);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 15, 3), 720);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 4, 3), 222);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 5, 3), 278);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 15, 3), 833);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn batch_4() {
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 4, 4), 256);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 5, 4), 320);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 15, 4), 960);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 4, 4), 296);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 5, 4), 370);
|
||||
assert_eq!(cost_cents(Some(RouterResolution::SevenTwentyP), 15, 4), 1110);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -242,10 +242,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn explicit_4k_without_video_reference() {
|
||||
assert_eq!(artcraft_4k_cents(4, 1, false), 358);
|
||||
assert_eq!(artcraft_4k_cents(5, 1, false), 447);
|
||||
assert_eq!(artcraft_4k_cents(10, 1, false), 893);
|
||||
assert_eq!(artcraft_4k_cents(15, 1, false), 1340);
|
||||
assert_eq!(artcraft_4k_cents(4, 1, false), 370);
|
||||
assert_eq!(artcraft_4k_cents(5, 1, false), 463);
|
||||
assert_eq!(artcraft_4k_cents(10, 1, false), 925);
|
||||
assert_eq!(artcraft_4k_cents(15, 1, false), 1388);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -499,9 +499,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn refs_cost_more_at_720p() {
|
||||
assert_ref_delta(CommonResolution::SevenTwentyP, 5, 80, 111, 31);
|
||||
assert_ref_delta(CommonResolution::SevenTwentyP, 10, 160, 221, 61);
|
||||
assert_ref_delta(CommonResolution::SevenTwentyP, 15, 240, 331, 91);
|
||||
assert_ref_delta(CommonResolution::SevenTwentyP, 5, 93, 111, 18);
|
||||
assert_ref_delta(CommonResolution::SevenTwentyP, 10, 185, 221, 36);
|
||||
assert_ref_delta(CommonResolution::SevenTwentyP, 15, 278, 331, 53);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -513,9 +513,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn refs_cost_more_at_4k() {
|
||||
assert_ref_delta(CommonResolution::FourK, 5, 447, 569, 122);
|
||||
assert_ref_delta(CommonResolution::FourK, 10, 893, 1138, 245);
|
||||
assert_ref_delta(CommonResolution::FourK, 15, 1340, 1707, 367);
|
||||
assert_ref_delta(CommonResolution::FourK, 5, 463, 569, 106);
|
||||
assert_ref_delta(CommonResolution::FourK, 10, 925, 1138, 213);
|
||||
assert_ref_delta(CommonResolution::FourK, 15, 1388, 1707, 319);
|
||||
}
|
||||
|
||||
/// Price the same generation with and without a reference video; pin
|
||||
|
||||
+8
-8
@@ -11,8 +11,8 @@ use kinovi_web_client::generate::video::generate_seedance_2p5::{
|
||||
// in hundredths of a USD cent per second so the math is exact integer arithmetic
|
||||
// (no floating point), then rounded up to whole cents.
|
||||
|
||||
/// 4K output price, in hundredths of a USD cent per second (89.30 ¢/s).
|
||||
const FOUR_K_CENTI_CENTS_PER_SECOND: u64 = 8930;
|
||||
/// 4K output price, in hundredths of a USD cent per second (92.50 ¢/s).
|
||||
const FOUR_K_CENTI_CENTS_PER_SECOND: u64 = 9250;
|
||||
|
||||
/// ArtCraft's price (USD cents) for Seedance 2.0 at 4K with no reference
|
||||
/// videos attached. Each model prices reference videos through its own
|
||||
@@ -273,16 +273,16 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn four_k_base_prices() {
|
||||
assert_eq!(seedance_2p0_four_k_usd_cents(4, 1), 358);
|
||||
assert_eq!(seedance_2p0_four_k_usd_cents(5, 1), 447);
|
||||
assert_eq!(seedance_2p0_four_k_usd_cents(10, 1), 893);
|
||||
assert_eq!(seedance_2p0_four_k_usd_cents(15, 1), 1340);
|
||||
assert_eq!(seedance_2p0_four_k_usd_cents(4, 1), 370);
|
||||
assert_eq!(seedance_2p0_four_k_usd_cents(5, 1), 463);
|
||||
assert_eq!(seedance_2p0_four_k_usd_cents(10, 1), 925);
|
||||
assert_eq!(seedance_2p0_four_k_usd_cents(15, 1), 1388);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn batch_count_multiplies() {
|
||||
assert_eq!(seedance_2p0_four_k_usd_cents(5, 2), 893);
|
||||
assert_eq!(seedance_2p0_four_k_usd_cents(5, 4), 1786);
|
||||
assert_eq!(seedance_2p0_four_k_usd_cents(5, 2), 925);
|
||||
assert_eq!(seedance_2p0_four_k_usd_cents(5, 4), 1850);
|
||||
}
|
||||
|
||||
// ── Seedance 2.0 Mini ──
|
||||
|
||||
+5
-5
@@ -955,8 +955,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn prices_720p_and_unset_identically() {
|
||||
assert_eq!(estimate_cost_upfront(Some(KinoviOutputResolution::SevenTwentyP), KinoviBatchCount::One, 5, false), 80);
|
||||
assert_eq!(estimate_cost_upfront(None, KinoviBatchCount::One, 5, false), 80);
|
||||
assert_eq!(estimate_cost_upfront(Some(KinoviOutputResolution::SevenTwentyP), KinoviBatchCount::One, 5, false), 93);
|
||||
assert_eq!(estimate_cost_upfront(None, KinoviBatchCount::One, 5, false), 93);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -975,13 +975,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn batch_count_multiplies() {
|
||||
assert_eq!(estimate_cost_upfront(Some(KinoviOutputResolution::SevenTwentyP), KinoviBatchCount::Two, 5, false), 160);
|
||||
assert_eq!(estimate_cost_upfront(Some(KinoviOutputResolution::SevenTwentyP), KinoviBatchCount::Four, 5, false), 320);
|
||||
assert_eq!(estimate_cost_upfront(Some(KinoviOutputResolution::SevenTwentyP), KinoviBatchCount::Two, 5, false), 185);
|
||||
assert_eq!(estimate_cost_upfront(Some(KinoviOutputResolution::SevenTwentyP), KinoviBatchCount::Four, 5, false), 370);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ten_seconds_720p() {
|
||||
assert_eq!(estimate_cost_upfront(Some(KinoviOutputResolution::SevenTwentyP), KinoviBatchCount::One, 10, false), 160);
|
||||
assert_eq!(estimate_cost_upfront(Some(KinoviOutputResolution::SevenTwentyP), KinoviBatchCount::One, 10, false), 185);
|
||||
assert_eq!(estimate_cost_upfront(Some(KinoviOutputResolution::SevenTwentyP), KinoviBatchCount::One, 10, true), 221);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ mod billing_parity {
|
||||
CommonVideoModel::Seedance2p0,
|
||||
Some(CommonResolution::SevenTwentyP),
|
||||
Seconds(5),
|
||||
ExpectedCredits(80),
|
||||
ExpectedCredits(93),
|
||||
).await;
|
||||
}
|
||||
|
||||
|
||||
+80
-80
@@ -22,7 +22,7 @@ use crate::http_server::endpoints::omni_gen::generate::video::tests::support::{
|
||||
};
|
||||
|
||||
// ── Seedance 2.0 (Volcengine) ──
|
||||
// Rates: 480p 7.772 ¢/s, 720p 16 ¢/s, 1080p 46.632 ¢/s, 4K 86.6 ¢/s
|
||||
// Rates: 480p 7.772 ¢/s, 720p 18.5 ¢/s, 1080p 46.632 ¢/s, 4K 92.50 ¢/s
|
||||
// (4K ceil-rounds; the rest round once after duration × batch).
|
||||
mod seedance_2p0 {
|
||||
use super::*;
|
||||
@@ -46,18 +46,18 @@ mod seedance_2p0 {
|
||||
(Some(CommonResolution::FourEightyP), Seconds(13), Batch(1), ExpectedCredits(101)),
|
||||
(Some(CommonResolution::FourEightyP), Seconds(14), Batch(1), ExpectedCredits(109)),
|
||||
(Some(CommonResolution::FourEightyP), Seconds(15), Batch(1), ExpectedCredits(117)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(4), Batch(1), ExpectedCredits(64)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(1), ExpectedCredits(80)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(6), Batch(1), ExpectedCredits(96)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(7), Batch(1), ExpectedCredits(112)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(8), Batch(1), ExpectedCredits(128)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(9), Batch(1), ExpectedCredits(144)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(10), Batch(1), ExpectedCredits(160)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(11), Batch(1), ExpectedCredits(176)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(12), Batch(1), ExpectedCredits(192)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(13), Batch(1), ExpectedCredits(208)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(14), Batch(1), ExpectedCredits(224)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(15), Batch(1), ExpectedCredits(240)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(4), Batch(1), ExpectedCredits(74)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(1), ExpectedCredits(93)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(6), Batch(1), ExpectedCredits(111)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(7), Batch(1), ExpectedCredits(130)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(8), Batch(1), ExpectedCredits(148)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(9), Batch(1), ExpectedCredits(167)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(10), Batch(1), ExpectedCredits(185)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(11), Batch(1), ExpectedCredits(204)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(12), Batch(1), ExpectedCredits(222)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(13), Batch(1), ExpectedCredits(241)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(14), Batch(1), ExpectedCredits(259)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(15), Batch(1), ExpectedCredits(278)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(4), Batch(1), ExpectedCredits(187)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(5), Batch(1), ExpectedCredits(233)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(6), Batch(1), ExpectedCredits(280)),
|
||||
@@ -70,18 +70,18 @@ mod seedance_2p0 {
|
||||
(Some(CommonResolution::TenEightyP), Seconds(13), Batch(1), ExpectedCredits(606)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(14), Batch(1), ExpectedCredits(653)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(15), Batch(1), ExpectedCredits(699)),
|
||||
(Some(CommonResolution::FourK), Seconds(4), Batch(1), ExpectedCredits(358)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(1), ExpectedCredits(447)),
|
||||
(Some(CommonResolution::FourK), Seconds(6), Batch(1), ExpectedCredits(536)),
|
||||
(Some(CommonResolution::FourK), Seconds(7), Batch(1), ExpectedCredits(626)),
|
||||
(Some(CommonResolution::FourK), Seconds(8), Batch(1), ExpectedCredits(715)),
|
||||
(Some(CommonResolution::FourK), Seconds(9), Batch(1), ExpectedCredits(804)),
|
||||
(Some(CommonResolution::FourK), Seconds(10), Batch(1), ExpectedCredits(893)),
|
||||
(Some(CommonResolution::FourK), Seconds(11), Batch(1), ExpectedCredits(983)),
|
||||
(Some(CommonResolution::FourK), Seconds(12), Batch(1), ExpectedCredits(1072)),
|
||||
(Some(CommonResolution::FourK), Seconds(13), Batch(1), ExpectedCredits(1161)),
|
||||
(Some(CommonResolution::FourK), Seconds(14), Batch(1), ExpectedCredits(1251)),
|
||||
(Some(CommonResolution::FourK), Seconds(15), Batch(1), ExpectedCredits(1340)),
|
||||
(Some(CommonResolution::FourK), Seconds(4), Batch(1), ExpectedCredits(370)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(1), ExpectedCredits(463)),
|
||||
(Some(CommonResolution::FourK), Seconds(6), Batch(1), ExpectedCredits(555)),
|
||||
(Some(CommonResolution::FourK), Seconds(7), Batch(1), ExpectedCredits(648)),
|
||||
(Some(CommonResolution::FourK), Seconds(8), Batch(1), ExpectedCredits(740)),
|
||||
(Some(CommonResolution::FourK), Seconds(9), Batch(1), ExpectedCredits(833)),
|
||||
(Some(CommonResolution::FourK), Seconds(10), Batch(1), ExpectedCredits(925)),
|
||||
(Some(CommonResolution::FourK), Seconds(11), Batch(1), ExpectedCredits(1018)),
|
||||
(Some(CommonResolution::FourK), Seconds(12), Batch(1), ExpectedCredits(1110)),
|
||||
(Some(CommonResolution::FourK), Seconds(13), Batch(1), ExpectedCredits(1203)),
|
||||
(Some(CommonResolution::FourK), Seconds(14), Batch(1), ExpectedCredits(1295)),
|
||||
(Some(CommonResolution::FourK), Seconds(15), Batch(1), ExpectedCredits(1388)),
|
||||
];
|
||||
|
||||
for (resolution, seconds, batch, expected) in cases {
|
||||
@@ -109,16 +109,16 @@ mod seedance_2p0 {
|
||||
(Some(CommonResolution::FourEightyP), Seconds(5), Batch(8), ExpectedCredits(155)),
|
||||
(Some(CommonResolution::FourEightyP), Seconds(5), Batch(9), ExpectedCredits(155)),
|
||||
(Some(CommonResolution::FourEightyP), Seconds(5), Batch(10), ExpectedCredits(155)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(1), ExpectedCredits(80)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(2), ExpectedCredits(160)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(3), ExpectedCredits(240)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(4), ExpectedCredits(320)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(5), ExpectedCredits(320)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(6), ExpectedCredits(320)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(7), ExpectedCredits(320)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(8), ExpectedCredits(320)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(9), ExpectedCredits(320)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(10), ExpectedCredits(320)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(1), ExpectedCredits(93)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(2), ExpectedCredits(185)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(3), ExpectedCredits(278)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(4), ExpectedCredits(370)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(5), ExpectedCredits(370)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(6), ExpectedCredits(370)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(7), ExpectedCredits(370)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(8), ExpectedCredits(370)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(9), ExpectedCredits(370)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(10), ExpectedCredits(370)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(5), Batch(1), ExpectedCredits(233)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(5), Batch(2), ExpectedCredits(466)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(5), Batch(3), ExpectedCredits(699)),
|
||||
@@ -129,16 +129,16 @@ mod seedance_2p0 {
|
||||
(Some(CommonResolution::TenEightyP), Seconds(5), Batch(8), ExpectedCredits(933)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(5), Batch(9), ExpectedCredits(933)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(5), Batch(10), ExpectedCredits(933)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(1), ExpectedCredits(447)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(2), ExpectedCredits(893)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(3), ExpectedCredits(1340)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(4), ExpectedCredits(1786)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(5), ExpectedCredits(1786)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(6), ExpectedCredits(1786)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(7), ExpectedCredits(1786)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(8), ExpectedCredits(1786)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(9), ExpectedCredits(1786)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(10), ExpectedCredits(1786)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(1), ExpectedCredits(463)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(2), ExpectedCredits(925)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(3), ExpectedCredits(1388)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(4), ExpectedCredits(1850)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(5), ExpectedCredits(1850)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(6), ExpectedCredits(1850)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(7), ExpectedCredits(1850)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(8), ExpectedCredits(1850)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(9), ExpectedCredits(1850)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(10), ExpectedCredits(1850)),
|
||||
];
|
||||
|
||||
for (resolution, seconds, batch, expected) in cases {
|
||||
@@ -161,24 +161,24 @@ mod seedance_2p0 {
|
||||
(Some(CommonResolution::FourEightyP), Seconds(11), Batch(5), ExpectedCredits(342)),
|
||||
(Some(CommonResolution::FourEightyP), Seconds(13), Batch(8), ExpectedCredits(404)),
|
||||
(Some(CommonResolution::FourEightyP), Seconds(15), Batch(10), ExpectedCredits(466)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(6), Batch(2), ExpectedCredits(192)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(7), Batch(3), ExpectedCredits(336)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(9), Batch(4), ExpectedCredits(576)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(11), Batch(5), ExpectedCredits(704)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(13), Batch(8), ExpectedCredits(832)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(15), Batch(10), ExpectedCredits(960)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(6), Batch(2), ExpectedCredits(222)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(7), Batch(3), ExpectedCredits(389)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(9), Batch(4), ExpectedCredits(666)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(11), Batch(5), ExpectedCredits(814)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(13), Batch(8), ExpectedCredits(962)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(15), Batch(10), ExpectedCredits(1110)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(6), Batch(2), ExpectedCredits(560)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(7), Batch(3), ExpectedCredits(979)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(9), Batch(4), ExpectedCredits(1679)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(11), Batch(5), ExpectedCredits(2052)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(13), Batch(8), ExpectedCredits(2425)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(15), Batch(10), ExpectedCredits(2798)),
|
||||
(Some(CommonResolution::FourK), Seconds(6), Batch(2), ExpectedCredits(1072)),
|
||||
(Some(CommonResolution::FourK), Seconds(7), Batch(3), ExpectedCredits(1876)),
|
||||
(Some(CommonResolution::FourK), Seconds(9), Batch(4), ExpectedCredits(3215)),
|
||||
(Some(CommonResolution::FourK), Seconds(11), Batch(5), ExpectedCredits(3930)),
|
||||
(Some(CommonResolution::FourK), Seconds(13), Batch(8), ExpectedCredits(4644)),
|
||||
(Some(CommonResolution::FourK), Seconds(15), Batch(10), ExpectedCredits(5358)),
|
||||
(Some(CommonResolution::FourK), Seconds(6), Batch(2), ExpectedCredits(1110)),
|
||||
(Some(CommonResolution::FourK), Seconds(7), Batch(3), ExpectedCredits(1943)),
|
||||
(Some(CommonResolution::FourK), Seconds(9), Batch(4), ExpectedCredits(3330)),
|
||||
(Some(CommonResolution::FourK), Seconds(11), Batch(5), ExpectedCredits(4070)),
|
||||
(Some(CommonResolution::FourK), Seconds(13), Batch(8), ExpectedCredits(4810)),
|
||||
(Some(CommonResolution::FourK), Seconds(15), Batch(10), ExpectedCredits(5550)),
|
||||
];
|
||||
|
||||
for (resolution, seconds, batch, expected) in cases {
|
||||
@@ -394,7 +394,7 @@ mod seedance_2p0 {
|
||||
// ── Seedance 2.0 BytePlus (+ its PreviewModel alias) ──
|
||||
// THE collapse-bug regression pins. These variants are FULFILLED by the
|
||||
// base Seedance 2.0 request but must be PRICED as themselves: 480p 10 ¢/s,
|
||||
// 720p 25 ¢/s, 1080p 50 ¢/s, 4K 86.6 ¢/s. The shipped bug billed them at
|
||||
// 720p 25 ¢/s, 1080p 50 ¢/s, 4K 95 ¢/s. The shipped bug billed them at
|
||||
// the base rate (720p 5s: 80 instead of 125).
|
||||
mod seedance_2p0_bp {
|
||||
use super::*;
|
||||
@@ -560,7 +560,7 @@ mod seedance_2p0_bp {
|
||||
}
|
||||
}
|
||||
|
||||
/// The BytePlus rate cards are flat below 4K: reference videos only change the 4K price (a 17.20 cents/s surcharge). Charges are asserted on the refunded ledger entry (the fixture media is unreachable).
|
||||
/// The BytePlus rate cards are flat below 4K: reference videos only change the 4K price (a 23.00 cents/s surcharge). Charges are asserted on the refunded ledger entry (the fixture media is unreachable).
|
||||
/// Every duration 4-15s at every resolution, single video.
|
||||
#[tokio::test]
|
||||
#[cfg_attr(feature = "skip_database_tests", ignore)]
|
||||
@@ -625,7 +625,7 @@ mod seedance_2p0_bp {
|
||||
}
|
||||
}
|
||||
|
||||
/// The BytePlus rate cards are flat below 4K: reference videos only change the 4K price (a 17.20 cents/s surcharge). Charges are asserted on the refunded ledger entry (the fixture media is unreachable).
|
||||
/// The BytePlus rate cards are flat below 4K: reference videos only change the 4K price (a 23.00 cents/s surcharge). Charges are asserted on the refunded ledger entry (the fixture media is unreachable).
|
||||
/// Every batch size 1-10 at every resolution (5s).
|
||||
/// Batches over the platform max of 4 downgrade to 4 (3 upgrades to 4); execution and billing agree.
|
||||
#[tokio::test]
|
||||
@@ -683,7 +683,7 @@ mod seedance_2p0_bp {
|
||||
}
|
||||
}
|
||||
|
||||
/// The BytePlus rate cards are flat below 4K: reference videos only change the 4K price (a 17.20 cents/s surcharge). Charges are asserted on the refunded ledger entry (the fixture media is unreachable).
|
||||
/// The BytePlus rate cards are flat below 4K: reference videos only change the 4K price (a 23.00 cents/s surcharge). Charges are asserted on the refunded ledger entry (the fixture media is unreachable).
|
||||
/// Spot checks across duration x batch x resolution.
|
||||
/// References must be CHARGED more than the identical no-reference
|
||||
/// request, at every resolution and across durations.
|
||||
@@ -925,7 +925,7 @@ mod seedance_2p0_bpu {
|
||||
}
|
||||
}
|
||||
|
||||
/// The BytePlus rate cards are flat below 4K: reference videos only change the 4K price (a 17.20 cents/s surcharge). Charges are asserted on the refunded ledger entry (the fixture media is unreachable).
|
||||
/// The BytePlus rate cards are flat below 4K: reference videos only change the 4K price (a 23.00 cents/s surcharge). Charges are asserted on the refunded ledger entry (the fixture media is unreachable).
|
||||
/// Every duration 4-15s at every resolution, single video.
|
||||
#[tokio::test]
|
||||
#[cfg_attr(feature = "skip_database_tests", ignore)]
|
||||
@@ -990,7 +990,7 @@ mod seedance_2p0_bpu {
|
||||
}
|
||||
}
|
||||
|
||||
/// The BytePlus rate cards are flat below 4K: reference videos only change the 4K price (a 17.20 cents/s surcharge). Charges are asserted on the refunded ledger entry (the fixture media is unreachable).
|
||||
/// The BytePlus rate cards are flat below 4K: reference videos only change the 4K price (a 23.00 cents/s surcharge). Charges are asserted on the refunded ledger entry (the fixture media is unreachable).
|
||||
/// Every batch size 1-10 at every resolution (5s).
|
||||
/// Batches over the platform max of 4 downgrade to 4 (3 upgrades to 4); execution and billing agree.
|
||||
#[tokio::test]
|
||||
@@ -1048,7 +1048,7 @@ mod seedance_2p0_bpu {
|
||||
}
|
||||
}
|
||||
|
||||
/// The BytePlus rate cards are flat below 4K: reference videos only change the 4K price (a 17.20 cents/s surcharge). Charges are asserted on the refunded ledger entry (the fixture media is unreachable).
|
||||
/// The BytePlus rate cards are flat below 4K: reference videos only change the 4K price (a 23.00 cents/s surcharge). Charges are asserted on the refunded ledger entry (the fixture media is unreachable).
|
||||
/// Spot checks across duration x batch x resolution.
|
||||
/// References must be CHARGED more than the identical no-reference
|
||||
/// request, at every resolution and across durations.
|
||||
@@ -1139,18 +1139,18 @@ mod premium {
|
||||
|
||||
let cases: &[(Option<CommonResolution>, Seconds, Batch, ExpectedCredits, ExpectedCredits, CreditsDelta)] = &[
|
||||
(Some(CommonResolution::FourEightyP), Seconds(5), Batch(1), ExpectedCredits(39), ExpectedCredits(50), CreditsDelta(11)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(1), ExpectedCredits(80), ExpectedCredits(125), CreditsDelta(45)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(10), Batch(1), ExpectedCredits(160), ExpectedCredits(250), CreditsDelta(90)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(1), ExpectedCredits(93), ExpectedCredits(125), CreditsDelta(32)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(10), Batch(1), ExpectedCredits(185), ExpectedCredits(250), CreditsDelta(65)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(5), Batch(1), ExpectedCredits(233), ExpectedCredits(250), CreditsDelta(17)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(15), Batch(1), ExpectedCredits(240), ExpectedCredits(375), CreditsDelta(135)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(4), ExpectedCredits(320), ExpectedCredits(500), CreditsDelta(180)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(15), Batch(1), ExpectedCredits(278), ExpectedCredits(375), CreditsDelta(97)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(4), ExpectedCredits(370), ExpectedCredits(500), CreditsDelta(130)),
|
||||
// Batch 8 is accepted but downgrades to the platform max of 4 on both
|
||||
// execution and billing, so it prices identically to batch 4.
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(8), ExpectedCredits(320), ExpectedCredits(500), CreditsDelta(180)),
|
||||
// 4K premium: the base tier prices at 89.3 cents/s while the BytePlus
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(8), ExpectedCredits(370), ExpectedCredits(500), CreditsDelta(130)),
|
||||
// 4K premium: the base tier prices at 92.50 cents/s while the BytePlus
|
||||
// tiers price at 95.0 cents/s.
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(1), ExpectedCredits(447), ExpectedCredits(475), CreditsDelta(28)),
|
||||
(Some(CommonResolution::FourK), Seconds(15), Batch(4), ExpectedCredits(5358), ExpectedCredits(5700), CreditsDelta(342)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(1), ExpectedCredits(463), ExpectedCredits(475), CreditsDelta(12)),
|
||||
(Some(CommonResolution::FourK), Seconds(15), Batch(4), ExpectedCredits(5550), ExpectedCredits(5700), CreditsDelta(150)),
|
||||
];
|
||||
|
||||
for (resolution, seconds, batch, base, variant, delta) in cases {
|
||||
@@ -1170,18 +1170,18 @@ mod premium {
|
||||
|
||||
let cases: &[(Option<CommonResolution>, Seconds, Batch, ExpectedCredits, ExpectedCredits, CreditsDelta)] = &[
|
||||
(Some(CommonResolution::FourEightyP), Seconds(5), Batch(1), ExpectedCredits(39), ExpectedCredits(50), CreditsDelta(11)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(1), ExpectedCredits(80), ExpectedCredits(125), CreditsDelta(45)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(10), Batch(1), ExpectedCredits(160), ExpectedCredits(250), CreditsDelta(90)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(1), ExpectedCredits(93), ExpectedCredits(125), CreditsDelta(32)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(10), Batch(1), ExpectedCredits(185), ExpectedCredits(250), CreditsDelta(65)),
|
||||
(Some(CommonResolution::TenEightyP), Seconds(5), Batch(1), ExpectedCredits(233), ExpectedCredits(250), CreditsDelta(17)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(15), Batch(1), ExpectedCredits(240), ExpectedCredits(375), CreditsDelta(135)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(4), ExpectedCredits(320), ExpectedCredits(500), CreditsDelta(180)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(15), Batch(1), ExpectedCredits(278), ExpectedCredits(375), CreditsDelta(97)),
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(4), ExpectedCredits(370), ExpectedCredits(500), CreditsDelta(130)),
|
||||
// Batch 8 is accepted but downgrades to the platform max of 4 on both
|
||||
// execution and billing, so it prices identically to batch 4.
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(8), ExpectedCredits(320), ExpectedCredits(500), CreditsDelta(180)),
|
||||
// 4K premium: the base tier prices at 89.3 cents/s while the BytePlus
|
||||
(Some(CommonResolution::SevenTwentyP), Seconds(5), Batch(8), ExpectedCredits(370), ExpectedCredits(500), CreditsDelta(130)),
|
||||
// 4K premium: the base tier prices at 92.50 cents/s while the BytePlus
|
||||
// tiers price at 95.0 cents/s.
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(1), ExpectedCredits(447), ExpectedCredits(475), CreditsDelta(28)),
|
||||
(Some(CommonResolution::FourK), Seconds(15), Batch(4), ExpectedCredits(5358), ExpectedCredits(5700), CreditsDelta(342)),
|
||||
(Some(CommonResolution::FourK), Seconds(5), Batch(1), ExpectedCredits(463), ExpectedCredits(475), CreditsDelta(12)),
|
||||
(Some(CommonResolution::FourK), Seconds(15), Batch(4), ExpectedCredits(5550), ExpectedCredits(5700), CreditsDelta(150)),
|
||||
];
|
||||
|
||||
for (resolution, seconds, batch, base, variant, delta) in cases {
|
||||
|
||||
Reference in New Issue
Block a user