mirror of
https://github.com/storytold/filmcraft.git
synced 2026-10-14 19:26:59 -04:00
Tests for display rotation: Matroska roll → quarter turns (incl. flips, odd and malformed angles), MP4 mirrored/scaled matrices
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
27a1f78df7
commit
e2afbed6c2
2 files changed
+44
No files matched your search
@@ -552,4 +552,21 @@ mod tests {
|
||||
let s = Mp4Source::open("180.mov", rotated_mov([-ONE, 0, 0, 0, -ONE, 0, 64 * ONE, 32 * ONE, W])).expect("open");
|
||||
assert_eq!(s.info().video.as_ref().map(|v| (v.width, v.height)), Some((64, 32)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mirrored_or_scaled_matrices_are_not_mistaken_for_rotations() {
|
||||
const ONE: i32 = 0x10000;
|
||||
const W: i32 = 0x4000_0000;
|
||||
// horizontal mirror: not a pure rotation, so the frame is left as stored
|
||||
let s = Mp4Source::open("mirror.mov", rotated_mov([-ONE, 0, 0, 0, ONE, 0, 64 * ONE, 0, W])).expect("open");
|
||||
let (w, h, top, bottom) = halves(&s);
|
||||
assert_eq!((w, h), (64, 32));
|
||||
assert!(top.abs_diff(bottom) < 4);
|
||||
// a 2× scaled identity is still upright (only the signs decide the rotation)
|
||||
let s = Mp4Source::open("scaled.mov", rotated_mov([2 * ONE, 0, 0, 0, 2 * ONE, 0, 0, 0, W])).expect("open");
|
||||
assert_eq!(s.info().video.as_ref().map(|v| (v.width, v.height)), Some((64, 32)));
|
||||
// a scaled quarter turn is still a quarter turn
|
||||
let s = Mp4Source::open("cw2.mov", rotated_mov([0, 2 * ONE, 0, -2 * ONE, 0, 0, 64 * ONE, 0, W])).expect("open");
|
||||
assert_eq!(s.info().video.as_ref().map(|v| (v.width, v.height)), Some((32, 64)));
|
||||
}
|
||||
}
|
||||
@@ -318,3 +318,30 @@ impl Track {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod rotation_tests {
|
||||
use super::{Projection, VideoInfo};
|
||||
|
||||
fn with_roll(projection_type: u64, yaw: f64, pitch: f64, roll: f64) -> VideoInfo {
|
||||
VideoInfo { projection: Some(Projection { projection_type, yaw, pitch, roll }), ..Default::default() }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_rotation_maps_rectangular_roll_to_clockwise_quarter_turns() {
|
||||
assert_eq!(VideoInfo::default().display_rotation(), Some(0), "no Projection: as stored");
|
||||
// ProjectionPoseRoll is counter-clockwise: -90 is a quarter turn clockwise
|
||||
for (roll, turns) in [(0.0, 0), (-90.0, 1), (180.0, 2), (-180.0, 2), (90.0, 3), (-270.0, 3), (270.0, 1), (360.0, 0)] {
|
||||
assert_eq!(with_roll(0, 0.0, 0.0, roll).display_rotation(), Some(turns), "roll {roll}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_rotation_leaves_non_rectangular_flipped_and_odd_angles_alone() {
|
||||
assert_eq!(with_roll(1, 0.0, 0.0, -90.0).display_rotation(), None, "equirectangular");
|
||||
assert_eq!(with_roll(0, 180.0, 0.0, 0.0).display_rotation(), None, "yaw flip");
|
||||
assert_eq!(with_roll(0, 0.0, 180.0, 0.0).display_rotation(), None, "pitch flip");
|
||||
assert_eq!(with_roll(0, 0.0, 0.0, 45.0).display_rotation(), None, "not a quarter turn");
|
||||
assert_eq!(with_roll(0, 0.0, 0.0, f64::NAN).display_rotation(), None, "malformed angle");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user