Skip to main content

talw_timecode/
convert.rs

1use crate::framerate::FrameRate;
2
3pub fn convert_frames(total_frames: i64, from: FrameRate, to: FrameRate) -> i64 {
4    if from == to {
5        return total_frames;
6    }
7
8    let from_r = from.rational();
9    let to_r = to.rational();
10
11    // frames * (from_den / from_num) gives seconds
12    // seconds * (to_num / to_den) gives target frames
13    // Combined: frames * from_den * to_num / (from_num * to_den)
14    let numerator = total_frames as i128 * from_r.den as i128 * to_r.num as i128;
15    let denominator = from_r.num as i128 * to_r.den as i128;
16
17    (numerator / denominator) as i64
18}
19
20#[cfg(test)]
21mod tests {
22    use super::*;
23
24    #[test]
25    fn same_rate() {
26        assert_eq!(convert_frames(100, FrameRate::Fps24, FrameRate::Fps24), 100);
27    }
28
29    #[test]
30    fn fps24_to_fps30() {
31        assert_eq!(convert_frames(24, FrameRate::Fps24, FrameRate::Fps30), 30);
32    }
33
34    #[test]
35    fn fps24_to_fps25() {
36        assert_eq!(convert_frames(24, FrameRate::Fps24, FrameRate::Fps25), 25);
37    }
38
39    #[test]
40    fn fps30_to_fps24() {
41        assert_eq!(convert_frames(30, FrameRate::Fps30, FrameRate::Fps24), 24);
42    }
43
44    #[test]
45    fn large_value() {
46        // 1 hour at 24fps = 86400 frames -> 1 hour at 60fps = 216000 frames
47        assert_eq!(
48            convert_frames(86400, FrameRate::Fps24, FrameRate::Fps60),
49            216000
50        );
51    }
52}