1use crate::bindings::{
2 FrameCapturedStatus, FrameSourceTypes, IFrameCapturedEventArgs, IFrameDescription, TIMESPAN,
3};
4use std::ptr;
5use windows::{
6 Win32::Foundation::{E_FAIL, E_POINTER},
7 core::Error,
8};
9
10#[derive(Debug, Clone)]
11pub struct FrameDescription {
12 ptr: *mut IFrameDescription,
13}
14
15impl FrameDescription {
16 pub(crate) fn new(ptr: *mut IFrameDescription) -> Self {
17 assert!(!ptr.is_null(), "FrameDescription pointer cannot be null");
18 Self { ptr }
19 }
20
21 pub fn get_width(&self) -> Result<i32, Error> {
22 if self.ptr.is_null() {
23 return Err(Error::from_hresult(E_POINTER));
24 }
25 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
26 let get_fn = vtbl.get_Width.ok_or(E_FAIL)?;
27 let mut width: i32 = 0;
28 let hr = unsafe { get_fn(self.ptr, &mut width) };
29 if hr.is_ok() {
30 Ok(width)
31 } else {
32 Err(Error::from_hresult(hr))
33 }
34 }
35
36 pub fn get_height(&self) -> Result<i32, Error> {
37 if self.ptr.is_null() {
38 return Err(Error::from_hresult(E_POINTER));
39 }
40 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
41 let get_fn = vtbl.get_Height.ok_or(E_FAIL)?;
42 let mut height: i32 = 0;
43 let hr = unsafe { get_fn(self.ptr, &mut height) };
44 if hr.is_ok() {
45 Ok(height)
46 } else {
47 Err(Error::from_hresult(hr))
48 }
49 }
50
51 pub fn get_horizontal_field_of_view(&self) -> Result<f32, Error> {
52 if self.ptr.is_null() {
53 return Err(Error::from_hresult(E_POINTER));
54 }
55 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
56 let get_fn = vtbl.get_HorizontalFieldOfView.ok_or(E_FAIL)?;
57 let mut fov: f32 = 0.0;
58 let hr = unsafe { get_fn(self.ptr, &mut fov) };
59 if hr.is_ok() {
60 Ok(fov)
61 } else {
62 Err(Error::from_hresult(hr))
63 }
64 }
65
66 pub fn get_vertical_field_of_view(&self) -> Result<f32, Error> {
67 if self.ptr.is_null() {
68 return Err(Error::from_hresult(E_POINTER));
69 }
70 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
71 let get_fn = vtbl.get_VerticalFieldOfView.ok_or(E_FAIL)?;
72 let mut fov: f32 = 0.0;
73 let hr = unsafe { get_fn(self.ptr, &mut fov) };
74 if hr.is_ok() {
75 Ok(fov)
76 } else {
77 Err(Error::from_hresult(hr))
78 }
79 }
80
81 pub fn get_diagonal_field_of_view(&self) -> Result<f32, Error> {
82 if self.ptr.is_null() {
83 return Err(Error::from_hresult(E_POINTER));
84 }
85 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
86 let get_fn = vtbl.get_DiagonalFieldOfView.ok_or(E_FAIL)?;
87 let mut fov: f32 = 0.0;
88 let hr = unsafe { get_fn(self.ptr, &mut fov) };
89 if hr.is_ok() {
90 Ok(fov)
91 } else {
92 Err(Error::from_hresult(hr))
93 }
94 }
95
96 pub fn get_length_in_pixels(&self) -> Result<u32, Error> {
97 if self.ptr.is_null() {
98 return Err(Error::from_hresult(E_POINTER));
99 }
100 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
101 let get_fn = vtbl.get_LengthInPixels.ok_or(E_FAIL)?;
102 let mut length: u32 = 0;
103 let hr = unsafe { get_fn(self.ptr, &mut length) };
104 if hr.is_ok() {
105 Ok(length)
106 } else {
107 Err(Error::from_hresult(hr))
108 }
109 }
110
111 pub fn get_bytes_per_pixel(&self) -> Result<u32, Error> {
112 if self.ptr.is_null() {
113 return Err(Error::from_hresult(E_POINTER));
114 }
115 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
116 let get_fn = vtbl.get_BytesPerPixel.ok_or(E_FAIL)?;
117 let mut bpp: u32 = 0;
118 let hr = unsafe { get_fn(self.ptr, &mut bpp) };
119 if hr.is_ok() {
120 Ok(bpp)
121 } else {
122 Err(Error::from_hresult(hr))
123 }
124 }
125}
126
127impl Drop for FrameDescription {
128 fn drop(&mut self) {
129 if !self.ptr.is_null() {
130 unsafe {
131 let vtbl = (*self.ptr)
132 .lpVtbl
133 .as_ref()
134 .expect("VTable pointer is null in Drop");
135 let release_fn = vtbl
136 .Release
137 .expect("Release function pointer is null in Drop");
138 release_fn(self.ptr);
139 }
140 self.ptr = ptr::null_mut();
141 }
142 }
143}
144
145pub struct FrameCapturedEventArgs {
146 ptr: *mut IFrameCapturedEventArgs,
147}
148
149impl FrameCapturedEventArgs {
150 pub(crate) fn new(ptr: *mut IFrameCapturedEventArgs) -> Self {
151 assert!(
152 !ptr.is_null(),
153 "FrameCapturedEventArgs pointer cannot be null"
154 );
155 Self { ptr }
156 }
157
158 pub fn get_frame_type(&self) -> Result<FrameSourceTypes, Error> {
159 if self.ptr.is_null() {
160 return Err(Error::from_hresult(E_POINTER));
161 }
162 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
163 let get_fn = vtbl.get_FrameType.ok_or(E_FAIL)?;
164 let mut frame_type: FrameSourceTypes = FrameSourceTypes::None;
165 let hr = unsafe { get_fn(self.ptr, &mut frame_type) };
166 if hr.is_ok() {
167 Ok(frame_type)
168 } else {
169 Err(Error::from_hresult(hr))
170 }
171 }
172
173 pub fn get_frame_status(&self) -> Result<FrameCapturedStatus, Error> {
174 if self.ptr.is_null() {
175 return Err(Error::from_hresult(E_POINTER));
176 }
177 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
178 let get_fn = vtbl.get_FrameStatus.ok_or(E_FAIL)?;
179 let mut status: FrameCapturedStatus = FrameCapturedStatus::Unknown;
180 let hr = unsafe { get_fn(self.ptr, &mut status) };
181 if hr.is_ok() {
182 Ok(status)
183 } else {
184 Err(Error::from_hresult(hr))
185 }
186 }
187
188 pub fn get_relative_time(&self) -> Result<TIMESPAN, Error> {
189 if self.ptr.is_null() {
190 return Err(Error::from_hresult(E_POINTER));
191 }
192 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
193 let get_fn = vtbl.get_RelativeTime.ok_or(E_FAIL)?;
194 let mut time: TIMESPAN = 0;
195 let hr = unsafe { get_fn(self.ptr, &mut time) };
196 if hr.is_ok() {
197 Ok(time)
198 } else {
199 Err(Error::from_hresult(hr))
200 }
201 }
202}
203
204impl Drop for FrameCapturedEventArgs {
205 fn drop(&mut self) {
206 if !self.ptr.is_null() {
207 unsafe {
208 let vtbl = (*self.ptr)
209 .lpVtbl
210 .as_ref()
211 .expect("VTable pointer is null in Drop");
212 let release_fn = vtbl
213 .Release
214 .expect("Release function pointer is null in Drop");
215 release_fn(self.ptr);
216 }
217 self.ptr = ptr::null_mut();
218 }
219 }
220}