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:
Brandon ThomasandClaude Opus 5.5 committed 2026-10-04 02:50:16 -04:00
1 parent 27a1f78df7
commit e2afbed6c2
2 files changed
+44

No files matched your search

+17
View File
@@ -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)));
}
}
+27
View File
@@ -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");
}
}