kinect_v2_sys/
multi_source_frame.rs

1use crate::bindings::{
2    BOOLEAN, IBodyFrameReference, IBodyIndexFrameReference, IColorFrameReference,
3    IDepthFrameReference, IInfraredFrameReference, IKinectSensor,
4    ILongExposureInfraredFrameReference, IMultiSourceFrame, IMultiSourceFrameArrivedEventArgs,
5    IMultiSourceFrameReader, IMultiSourceFrameReference, ULONG, WAITABLE_HANDLE,
6};
7use crate::body::BodyFrameReference;
8use crate::body_index::BodyIndexFrameReference;
9use crate::depth::DepthFrameReference;
10use crate::kinect::KinectSensor;
11use crate::{
12    color::ColorFrameReference, infrared::InfraredFrameReference,
13    long_exposure_infrared::LongExposureInfraredFrameReference,
14};
15use std::ptr;
16use windows::{
17    Win32::Foundation::{E_FAIL, E_POINTER},
18    core::Error,
19};
20
21pub struct MultiSourceFrameReader {
22    ptr: *mut IMultiSourceFrameReader,
23}
24
25impl MultiSourceFrameReader {
26    pub(crate) fn new(ptr: *mut IMultiSourceFrameReader) -> Self {
27        assert!(!ptr.is_null());
28        Self { ptr }
29    }
30
31    pub fn subscribe_multi_source_frame_arrived(
32        &self,
33        waitable_handle: &mut WAITABLE_HANDLE,
34    ) -> Result<(), Error> {
35        if self.ptr.is_null() {
36            return Err(Error::from_hresult(E_POINTER));
37        }
38        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
39        let subscribe_fn = vtbl.SubscribeMultiSourceFrameArrived.ok_or(E_FAIL)?;
40        let hr = unsafe { subscribe_fn(self.ptr, waitable_handle) };
41        if hr.is_ok() {
42            Ok(())
43        } else {
44            Err(Error::from_hresult(hr))
45        }
46    }
47
48    pub fn unsubscribe_multi_source_frame_arrived(
49        &self,
50        waitable_handle: WAITABLE_HANDLE,
51    ) -> Result<(), 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 unsubscribe_fn = vtbl.UnsubscribeMultiSourceFrameArrived.ok_or(E_FAIL)?;
57        let hr = unsafe { unsubscribe_fn(self.ptr, waitable_handle) };
58        if hr.is_ok() {
59            Ok(())
60        } else {
61            Err(Error::from_hresult(hr))
62        }
63    }
64
65    pub fn get_multi_source_frame_arrived_event_data(
66        &self,
67        waitable_handle: WAITABLE_HANDLE,
68    ) -> Result<MultiSourceFrameArrivedEventArgs, Error> {
69        if self.ptr.is_null() {
70            return Err(Error::from_hresult(E_POINTER));
71        }
72        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
73        let get_data_fn = vtbl.GetMultiSourceFrameArrivedEventData.ok_or(E_FAIL)?;
74        let mut event_data: *mut IMultiSourceFrameArrivedEventArgs = ptr::null_mut();
75        let hr = unsafe { get_data_fn(self.ptr, waitable_handle, &mut event_data) };
76        if hr.is_ok() {
77            Ok(MultiSourceFrameArrivedEventArgs::new(event_data))
78        } else {
79            Err(Error::from_hresult(hr))
80        }
81    }
82
83    pub fn acquire_latest_frame(&self) -> Result<MultiSourceFrame, Error> {
84        if self.ptr.is_null() {
85            return Err(Error::from_hresult(E_POINTER));
86        }
87        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
88        let acquire_fn = vtbl.AcquireLatestFrame.ok_or(E_FAIL)?;
89        let mut frame_ptr: *mut IMultiSourceFrame = ptr::null_mut();
90        let hr = unsafe { acquire_fn(self.ptr, &mut frame_ptr) };
91        if hr.is_ok() {
92            Ok(MultiSourceFrame::new(frame_ptr))
93        } else {
94            Err(Error::from_hresult(hr))
95        }
96    }
97
98    pub fn get_frame_source_types(&self) -> Result<ULONG, Error> {
99        if self.ptr.is_null() {
100            return Err(Error::from_hresult(E_POINTER));
101        }
102        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
103        let get_fn = vtbl.get_FrameSourceTypes.ok_or(E_FAIL)?;
104        let mut frame_source_types: ULONG = 0;
105        let hr = unsafe { get_fn(self.ptr, &mut frame_source_types) };
106        if hr.is_ok() {
107            Ok(frame_source_types)
108        } else {
109            Err(Error::from_hresult(hr))
110        }
111    }
112
113    pub fn get_is_paused(&self) -> Result<bool, Error> {
114        if self.ptr.is_null() {
115            return Err(Error::from_hresult(E_POINTER));
116        }
117        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
118        let get_fn = vtbl.get_IsPaused.ok_or(E_FAIL)?;
119        let mut is_paused: BOOLEAN = 0;
120        let hr = unsafe { get_fn(self.ptr, &mut is_paused) };
121        if hr.is_ok() {
122            Ok(is_paused != 0)
123        } else {
124            Err(Error::from_hresult(hr))
125        }
126    }
127
128    pub fn set_is_paused(&self, is_paused: bool) -> Result<(), Error> {
129        if self.ptr.is_null() {
130            return Err(Error::from_hresult(E_POINTER));
131        }
132        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
133        let put_fn = vtbl.put_IsPaused.ok_or(E_FAIL)?;
134        let paused_value: BOOLEAN = if is_paused { 1 } else { 0 };
135        let hr = unsafe { put_fn(self.ptr, paused_value) };
136        if hr.is_ok() {
137            Ok(())
138        } else {
139            Err(Error::from_hresult(hr))
140        }
141    }
142
143    pub fn get_kinect_sensor(&self) -> Result<KinectSensor, Error> {
144        if self.ptr.is_null() {
145            return Err(Error::from_hresult(E_POINTER));
146        }
147        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
148        let get_fn = vtbl.get_KinectSensor.ok_or(E_FAIL)?;
149        let mut sensor_ptr: *mut IKinectSensor = ptr::null_mut();
150        let hr = unsafe { get_fn(self.ptr, &mut sensor_ptr) };
151        if hr.is_ok() {
152            Ok(KinectSensor::new(sensor_ptr))
153        } else {
154            Err(Error::from_hresult(hr))
155        }
156    }
157}
158
159impl Drop for MultiSourceFrameReader {
160    fn drop(&mut self) {
161        if !self.ptr.is_null() {
162            unsafe {
163                if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
164                    if let Some(release_fn) = vtbl.Release {
165                        release_fn(self.ptr);
166                    }
167                }
168            }
169            self.ptr = ptr::null_mut();
170        }
171    }
172}
173
174pub struct MultiSourceFrameArrivedEventArgs {
175    ptr: *mut IMultiSourceFrameArrivedEventArgs,
176}
177
178impl MultiSourceFrameArrivedEventArgs {
179    pub(crate) fn new(ptr: *mut IMultiSourceFrameArrivedEventArgs) -> Self {
180        assert!(!ptr.is_null());
181        Self { ptr }
182    }
183
184    pub fn get_frame_reference(&self) -> Result<MultiSourceFrameReference, Error> {
185        if self.ptr.is_null() {
186            return Err(Error::from_hresult(E_POINTER));
187        }
188        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
189        let get_fn = vtbl.get_FrameReference.ok_or(E_FAIL)?;
190        let mut ref_ptr: *mut IMultiSourceFrameReference = ptr::null_mut();
191        let hr = unsafe { get_fn(self.ptr, &mut ref_ptr) };
192        if hr.is_ok() {
193            Ok(MultiSourceFrameReference::new(ref_ptr))
194        } else {
195            Err(Error::from_hresult(hr))
196        }
197    }
198}
199
200impl Drop for MultiSourceFrameArrivedEventArgs {
201    fn drop(&mut self) {
202        if !self.ptr.is_null() {
203            unsafe {
204                if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
205                    if let Some(release_fn) = vtbl.Release {
206                        release_fn(self.ptr);
207                    }
208                }
209            }
210            self.ptr = ptr::null_mut();
211        }
212    }
213}
214
215pub struct MultiSourceFrameReference {
216    ptr: *mut IMultiSourceFrameReference,
217}
218
219impl MultiSourceFrameReference {
220    pub(crate) fn new(ptr: *mut IMultiSourceFrameReference) -> Self {
221        assert!(!ptr.is_null());
222        Self { ptr }
223    }
224
225    pub fn acquire_frame(&self) -> Result<MultiSourceFrame, Error> {
226        if self.ptr.is_null() {
227            return Err(Error::from_hresult(E_POINTER));
228        }
229        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
230        let acquire_fn = vtbl.AcquireFrame.ok_or(E_FAIL)?;
231        let mut frame_ptr: *mut IMultiSourceFrame = ptr::null_mut();
232        let hr = unsafe { acquire_fn(self.ptr, &mut frame_ptr) };
233        if hr.is_ok() {
234            Ok(MultiSourceFrame::new(frame_ptr))
235        } else {
236            Err(Error::from_hresult(hr))
237        }
238    }
239}
240
241impl Drop for MultiSourceFrameReference {
242    fn drop(&mut self) {
243        if !self.ptr.is_null() {
244            unsafe {
245                if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
246                    if let Some(release_fn) = vtbl.Release {
247                        release_fn(self.ptr);
248                    }
249                }
250            }
251            self.ptr = ptr::null_mut();
252        }
253    }
254}
255
256pub struct MultiSourceFrame {
257    ptr: *mut IMultiSourceFrame,
258}
259
260impl MultiSourceFrame {
261    pub(crate) fn new(ptr: *mut IMultiSourceFrame) -> Self {
262        assert!(!ptr.is_null());
263        Self { ptr }
264    }
265
266    pub fn get_color_frame_reference(&self) -> Result<ColorFrameReference, Error> {
267        if self.ptr.is_null() {
268            return Err(Error::from_hresult(E_POINTER));
269        }
270        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
271        let get_fn = vtbl.get_ColorFrameReference.ok_or(E_FAIL)?;
272        let mut ref_ptr: *mut IColorFrameReference = ptr::null_mut();
273        let hr = unsafe { get_fn(self.ptr, &mut ref_ptr) };
274        if hr.is_ok() {
275            Ok(ColorFrameReference::new(ref_ptr))
276        } else {
277            Err(Error::from_hresult(hr))
278        }
279    }
280
281    pub fn get_depth_frame_reference(&self) -> Result<DepthFrameReference, Error> {
282        if self.ptr.is_null() {
283            return Err(Error::from_hresult(E_POINTER));
284        }
285        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
286        let get_fn = vtbl.get_DepthFrameReference.ok_or(E_FAIL)?;
287        let mut ref_ptr: *mut IDepthFrameReference = ptr::null_mut();
288        let hr = unsafe { get_fn(self.ptr, &mut ref_ptr) };
289        if hr.is_ok() {
290            Ok(DepthFrameReference::new(ref_ptr))
291        } else {
292            Err(Error::from_hresult(hr))
293        }
294    }
295
296    pub fn get_body_frame_reference(&self) -> Result<BodyFrameReference, Error> {
297        if self.ptr.is_null() {
298            return Err(Error::from_hresult(E_POINTER));
299        }
300        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
301        let get_fn = vtbl.get_BodyFrameReference.ok_or(E_FAIL)?;
302        let mut ref_ptr: *mut IBodyFrameReference = ptr::null_mut();
303        let hr = unsafe { get_fn(self.ptr, &mut ref_ptr) };
304        if hr.is_ok() {
305            Ok(BodyFrameReference::new(ref_ptr))
306        } else {
307            Err(Error::from_hresult(hr))
308        }
309    }
310
311    pub fn get_body_index_frame_reference(&self) -> Result<BodyIndexFrameReference, Error> {
312        if self.ptr.is_null() {
313            return Err(Error::from_hresult(E_POINTER));
314        }
315        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
316        let get_fn = vtbl.get_BodyIndexFrameReference.ok_or(E_FAIL)?;
317        let mut ref_ptr: *mut IBodyIndexFrameReference = ptr::null_mut();
318        let hr = unsafe { get_fn(self.ptr, &mut ref_ptr) };
319        if hr.is_ok() {
320            Ok(BodyIndexFrameReference::new(ref_ptr))
321        } else {
322            Err(Error::from_hresult(hr))
323        }
324    }
325
326    pub fn get_infrared_frame_reference(&self) -> Result<InfraredFrameReference, Error> {
327        if self.ptr.is_null() {
328            return Err(Error::from_hresult(E_POINTER));
329        }
330        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
331        let get_fn = vtbl.get_InfraredFrameReference.ok_or(E_FAIL)?;
332        let mut ref_ptr: *mut IInfraredFrameReference = ptr::null_mut();
333        let hr = unsafe { get_fn(self.ptr, &mut ref_ptr) };
334        if hr.is_ok() {
335            Ok(InfraredFrameReference::new(ref_ptr))
336        } else {
337            Err(Error::from_hresult(hr))
338        }
339    }
340
341    pub fn get_long_exposure_infrared_frame_reference(
342        &self,
343    ) -> Result<LongExposureInfraredFrameReference, Error> {
344        if self.ptr.is_null() {
345            return Err(Error::from_hresult(E_POINTER));
346        }
347        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
348        let get_fn = vtbl.get_LongExposureInfraredFrameReference.ok_or(E_FAIL)?;
349        let mut ref_ptr: *mut ILongExposureInfraredFrameReference = ptr::null_mut();
350        let hr = unsafe { get_fn(self.ptr, &mut ref_ptr) };
351        if hr.is_ok() {
352            Ok(LongExposureInfraredFrameReference::new(ref_ptr))
353        } else {
354            Err(Error::from_hresult(hr))
355        }
356    }
357}
358
359impl Drop for MultiSourceFrame {
360    fn drop(&mut self) {
361        if !self.ptr.is_null() {
362            unsafe {
363                if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
364                    if let Some(release_fn) = vtbl.Release {
365                        release_fn(self.ptr);
366                    }
367                }
368            }
369            self.ptr = ptr::null_mut();
370        }
371    }
372}