vapoursynth/
video_info.rs1use std::fmt::Debug;
4use std::ops::Deref;
5
6use vapoursynth_sys as ffi;
7
8use crate::format::Format;
9
10#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
12pub struct Resolution {
13 pub width: usize,
15
16 pub height: usize,
18}
19
20#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
22pub struct Framerate {
23 pub numerator: u64,
25
26 pub denominator: u64,
28}
29
30#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
33pub enum Property<T: Debug + Clone + Copy + Eq + PartialEq> {
34 Variable,
36
37 Constant(T),
39}
40
41#[derive(Debug, Copy, Clone)]
43pub struct VideoInfo<'core> {
44 pub format: Format<'core>,
46
47 pub framerate: Property<Framerate>,
49
50 pub resolution: Property<Resolution>,
52
53 pub num_frames: usize,
55}
56
57impl<'core> VideoInfo<'core> {
58 pub(crate) unsafe fn from_ptr(ptr: *const ffi::VSVideoInfo) -> Self {
63 let info = unsafe { &*ptr };
64
65 debug_assert!(info.fpsNum >= 0);
66 debug_assert!(info.fpsDen >= 0);
67 debug_assert!(info.width >= 0);
68 debug_assert!(info.height >= 0);
69 debug_assert!(info.numFrames >= 0);
70
71 let format = unsafe { Format::from_ptr(&info.format) };
72
73 let framerate = if info.fpsNum == 0 {
74 debug_assert!(info.fpsDen == 0);
75 Property::Variable
76 } else {
77 debug_assert!(info.fpsDen != 0);
78 Property::Constant(Framerate {
79 numerator: info.fpsNum as _,
80 denominator: info.fpsDen as _,
81 })
82 };
83
84 let resolution = if info.width == 0 {
85 debug_assert!(info.height == 0);
86 Property::Variable
87 } else {
88 debug_assert!(info.height != 0);
89 Property::Constant(Resolution {
90 width: info.width as _,
91 height: info.height as _,
92 })
93 };
94
95 let num_frames = {
96 debug_assert!(info.numFrames != 0);
97 info.numFrames as _
98 };
99
100 Self {
101 format,
102 framerate,
103 resolution,
104 num_frames,
105 }
106 }
107
108 pub(crate) fn ffi_type(self) -> ffi::VSVideoInfo {
110 let format = self.format.deref();
111
112 let (fps_num, fps_den) = match self.framerate {
113 Property::Variable => (0, 0),
114 Property::Constant(Framerate {
115 numerator,
116 denominator,
117 }) => (numerator as i64, denominator as i64),
118 };
119
120 let (width, height) = match self.resolution {
121 Property::Variable => (0, 0),
122 Property::Constant(Resolution { width, height }) => (width as i32, height as i32),
123 };
124
125 let num_frames = self.num_frames as i32;
126
127 ffi::VSVideoInfo {
128 format: *format,
129 fpsNum: fps_num,
130 fpsDen: fps_den,
131 width,
132 height,
133 numFrames: num_frames,
134 }
135 }
136}
137
138impl<T> From<T> for Property<T>
139where
140 T: Debug + Clone + Copy + Eq + PartialEq,
141{
142 #[inline]
143 fn from(x: T) -> Self {
144 Property::Constant(x)
145 }
146}