kinect_v2_sys/
long_exposure_infrared.rs

1use crate::bindings::{
2    BOOLEAN, IFrameCapturedEventArgs, IFrameDescription, IKinectSensor, ILongExposureInfraredFrame,
3    ILongExposureInfraredFrameArrivedEventArgs, ILongExposureInfraredFrameReader,
4    ILongExposureInfraredFrameReference, ILongExposureInfraredFrameSource, TIMESPAN, UINT, UINT16,
5    WAITABLE_HANDLE,
6};
7use crate::frame::{FrameCapturedEventArgs, FrameDescription};
8use crate::kinect::KinectSensor;
9use std::ptr;
10use windows::Win32::Foundation::{E_FAIL, E_POINTER};
11use windows::core::Error;
12
13pub struct LongExposureInfraredFrame {
14    ptr: *mut ILongExposureInfraredFrame,
15}
16
17impl LongExposureInfraredFrame {
18    pub(crate) fn new(ptr: *mut ILongExposureInfraredFrame) -> Self {
19        assert!(!ptr.is_null());
20        Self { ptr }
21    }
22    pub fn copy_frame_data_to_array(&self, frame_data: &mut [u16]) -> Result<(), Error> {
23        if self.ptr.is_null() {
24            return Err(Error::from(E_POINTER));
25        }
26        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
27        let copy_data_fn = vtbl
28            .CopyFrameDataToArray
29            .ok_or_else(|| Error::from(E_FAIL))?;
30        let capacity = frame_data.len() as UINT;
31        let hr = unsafe { copy_data_fn(self.ptr, capacity, frame_data.as_mut_ptr()) };
32        if hr.is_err() {
33            Err(Error::from_hresult(hr))
34        } else {
35            Ok(())
36        }
37    }
38    pub fn access_underlying_buffer(&self) -> Result<&[u16], Error> {
39        if self.ptr.is_null() {
40            return Err(Error::from(E_POINTER));
41        }
42        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
43        let access_buffer_fn = vtbl
44            .AccessUnderlyingBuffer
45            .ok_or_else(|| Error::from(E_FAIL))?;
46        let mut capacity: UINT = 0;
47        let mut buffer: *mut UINT16 = ptr::null_mut();
48        let hr = unsafe { access_buffer_fn(self.ptr, &mut capacity, &mut buffer) };
49        if hr.is_err() {
50            Err(Error::from_hresult(hr))
51        } else if buffer.is_null() || capacity == 0 {
52            Err(Error::from(E_POINTER))
53        } else {
54            // Create a safe slice from the raw pointer
55            let slice =
56                unsafe { std::slice::from_raw_parts(buffer as *const u16, capacity as usize) };
57            Ok(slice)
58        }
59    }
60    pub fn get_relative_time(&self) -> Result<TIMESPAN, Error> {
61        if self.ptr.is_null() {
62            return Err(Error::from(E_POINTER));
63        }
64        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
65        let get_time_fn = vtbl.get_RelativeTime.ok_or_else(|| Error::from(E_FAIL))?;
66        let mut relative_time: TIMESPAN = 0;
67        let hr = unsafe { get_time_fn(self.ptr, &mut relative_time) };
68        if hr.is_err() {
69            Err(Error::from_hresult(hr))
70        } else {
71            Ok(relative_time)
72        }
73    }
74
75    pub fn get_frame_description(&self) -> Result<FrameDescription, Error> {
76        if self.ptr.is_null() {
77            return Err(Error::from(E_POINTER));
78        }
79        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
80        let get_description_fn = vtbl
81            .get_FrameDescription
82            .ok_or_else(|| Error::from(E_FAIL))?;
83        let mut frame_description_ptr: *mut IFrameDescription = ptr::null_mut();
84        let hr = unsafe { get_description_fn(self.ptr, &mut frame_description_ptr) };
85        if hr.is_err() {
86            Err(Error::from_hresult(hr))
87        } else {
88            Ok(FrameDescription::new(frame_description_ptr))
89        }
90    }
91
92    pub fn get_long_exposure_infrared_frame_source(
93        &self,
94    ) -> Result<LongExposureInfraredFrameSource, Error> {
95        if self.ptr.is_null() {
96            return Err(Error::from(E_POINTER));
97        }
98        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
99        let get_source_fn = vtbl
100            .get_LongExposureInfraredFrameSource
101            .ok_or_else(|| Error::from(E_FAIL))?;
102        let mut source_ptr: *mut ILongExposureInfraredFrameSource = ptr::null_mut();
103        let hr = unsafe { get_source_fn(self.ptr, &mut source_ptr) };
104        if hr.is_err() {
105            Err(Error::from_hresult(hr))
106        } else if source_ptr.is_null() {
107            Err(Error::from(E_POINTER))
108        } else {
109            Ok(LongExposureInfraredFrameSource::new(source_ptr))
110        }
111    }
112}
113
114impl Drop for LongExposureInfraredFrame {
115    fn drop(&mut self) {
116        if !self.ptr.is_null() {
117            unsafe {
118                if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
119                    && let Some(release_fn) = vtbl.Release
120                {
121                    release_fn(self.ptr);
122                }
123            }
124            self.ptr = ptr::null_mut();
125        }
126    }
127}
128
129pub struct LongExposureInfraredFrameSource {
130    ptr: *mut ILongExposureInfraredFrameSource,
131}
132impl LongExposureInfraredFrameSource {
133    pub(crate) fn new(ptr: *mut ILongExposureInfraredFrameSource) -> Self {
134        assert!(!ptr.is_null());
135        Self { ptr }
136    }
137
138    pub fn subscribe_frame_captured(&self) -> Result<WAITABLE_HANDLE, Error> {
139        if self.ptr.is_null() {
140            return Err(Error::from(E_POINTER));
141        }
142        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
143        let subscribe_fn = vtbl
144            .SubscribeFrameCaptured
145            .ok_or_else(|| Error::from(E_FAIL))?;
146        let mut waitable_handle: WAITABLE_HANDLE = windows::Win32::Foundation::HANDLE::default();
147        let hr = unsafe { subscribe_fn(self.ptr, &mut waitable_handle) };
148        if hr.is_err() {
149            Err(Error::from_hresult(hr))
150        } else {
151            Ok(waitable_handle)
152        }
153    }
154
155    pub fn unsubscribe_frame_captured(
156        &self,
157        waitable_handle: WAITABLE_HANDLE,
158    ) -> Result<(), Error> {
159        if self.ptr.is_null() {
160            return Err(Error::from(E_POINTER));
161        }
162        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
163        let unsubscribe_fn = vtbl
164            .UnsubscribeFrameCaptured
165            .ok_or_else(|| Error::from(E_FAIL))?;
166        let hr = unsafe { unsubscribe_fn(self.ptr, waitable_handle) };
167        if hr.is_err() {
168            Err(Error::from_hresult(hr))
169        } else {
170            Ok(())
171        }
172    }
173
174    pub fn get_frame_captured_event_data(
175        &self,
176        waitable_handle: WAITABLE_HANDLE,
177    ) -> Result<FrameCapturedEventArgs, Error> {
178        if self.ptr.is_null() {
179            return Err(Error::from(E_POINTER));
180        }
181        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
182        let get_data_fn = vtbl
183            .GetFrameCapturedEventData
184            .ok_or_else(|| Error::from(E_FAIL))?;
185        let mut event_args_ptr: *mut IFrameCapturedEventArgs = ptr::null_mut();
186        let hr = unsafe { get_data_fn(self.ptr, waitable_handle, &mut event_args_ptr) };
187        if hr.is_err() {
188            Err(Error::from_hresult(hr))
189        } else {
190            Ok(FrameCapturedEventArgs::new(event_args_ptr))
191        }
192    }
193
194    pub fn get_is_active(&self) -> Result<bool, Error> {
195        if self.ptr.is_null() {
196            return Err(Error::from(E_POINTER));
197        }
198        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
199        let get_active_fn = vtbl.get_IsActive.ok_or_else(|| Error::from(E_FAIL))?;
200        let mut is_active: BOOLEAN = 0;
201        let hr = unsafe { get_active_fn(self.ptr, &mut is_active) };
202        if hr.is_err() {
203            Err(Error::from_hresult(hr))
204        } else {
205            Ok(is_active != 0)
206        }
207    }
208
209    pub fn open_reader(&self) -> Result<LongExposureInfraredFrameReader, Error> {
210        if self.ptr.is_null() {
211            return Err(Error::from(E_POINTER));
212        }
213        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
214        let open_reader_fn = vtbl.OpenReader.ok_or_else(|| Error::from(E_FAIL))?;
215        let mut reader_ptr: *mut ILongExposureInfraredFrameReader = ptr::null_mut();
216        let hr = unsafe { open_reader_fn(self.ptr, &mut reader_ptr) };
217        if hr.is_err() {
218            Err(Error::from_hresult(hr))
219        } else if reader_ptr.is_null() {
220            Err(Error::from(E_POINTER))
221        } else {
222            Ok(LongExposureInfraredFrameReader::new(reader_ptr))
223        }
224    }
225
226    pub fn get_frame_description(&self) -> Result<FrameDescription, Error> {
227        if self.ptr.is_null() {
228            return Err(Error::from(E_POINTER));
229        }
230        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
231        let get_description_fn = vtbl
232            .get_FrameDescription
233            .ok_or_else(|| Error::from(E_FAIL))?;
234        let mut frame_description_ptr: *mut IFrameDescription = ptr::null_mut();
235        let hr = unsafe { get_description_fn(self.ptr, &mut frame_description_ptr) };
236        if hr.is_err() {
237            Err(Error::from_hresult(hr))
238        } else {
239            Ok(FrameDescription::new(frame_description_ptr))
240        }
241    }
242
243    pub fn get_kinect_sensor(&self) -> Result<KinectSensor, Error> {
244        if self.ptr.is_null() {
245            return Err(Error::from(E_POINTER));
246        }
247        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
248        let get_sensor_fn = vtbl.get_KinectSensor.ok_or_else(|| Error::from(E_FAIL))?;
249        let mut sensor_ptr: *mut IKinectSensor = ptr::null_mut();
250        let hr = unsafe { get_sensor_fn(self.ptr, &mut sensor_ptr) };
251        if hr.is_err() {
252            Err(Error::from_hresult(hr))
253        } else {
254            Ok(KinectSensor::new(sensor_ptr))
255        }
256    }
257}
258impl Drop for LongExposureInfraredFrameSource {
259    fn drop(&mut self) {
260        if !self.ptr.is_null() {
261            unsafe {
262                if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
263                    && let Some(release_fn) = vtbl.Release
264                {
265                    release_fn(self.ptr);
266                }
267            }
268            self.ptr = ptr::null_mut();
269        }
270    }
271}
272
273pub struct LongExposureInfraredFrameReader {
274    ptr: *mut ILongExposureInfraredFrameReader,
275}
276
277impl LongExposureInfraredFrameReader {
278    pub(crate) fn new(ptr: *mut ILongExposureInfraredFrameReader) -> Self {
279        assert!(!ptr.is_null());
280        Self { ptr }
281    }
282
283    pub fn subscribe_frame_arrived(&self) -> Result<WAITABLE_HANDLE, Error> {
284        if self.ptr.is_null() {
285            return Err(Error::from(E_POINTER));
286        }
287        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
288        let subscribe_fn = vtbl
289            .SubscribeFrameArrived
290            .ok_or_else(|| Error::from(E_FAIL))?;
291        let mut waitable_handle: WAITABLE_HANDLE = windows::Win32::Foundation::HANDLE::default();
292        let hr = unsafe { subscribe_fn(self.ptr, &mut waitable_handle) };
293        if hr.is_err() {
294            Err(Error::from_hresult(hr))
295        } else {
296            Ok(waitable_handle)
297        }
298    }
299
300    pub fn unsubscribe_frame_arrived(&self, waitable_handle: WAITABLE_HANDLE) -> Result<(), Error> {
301        if self.ptr.is_null() {
302            return Err(Error::from(E_POINTER));
303        }
304        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
305        let unsubscribe_fn = vtbl
306            .UnsubscribeFrameArrived
307            .ok_or_else(|| Error::from(E_FAIL))?;
308        let hr = unsafe { unsubscribe_fn(self.ptr, waitable_handle) };
309        if hr.is_err() {
310            Err(Error::from_hresult(hr))
311        } else {
312            Ok(())
313        }
314    }
315
316    pub fn get_frame_arrived_event_data(
317        &self,
318        waitable_handle: WAITABLE_HANDLE,
319    ) -> Result<LongExposureInfraredFrameArrivedEventArgs, Error> {
320        if self.ptr.is_null() {
321            return Err(Error::from(E_POINTER));
322        }
323        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
324        let get_data_fn = vtbl
325            .GetFrameArrivedEventData
326            .ok_or_else(|| Error::from(E_FAIL))?;
327        let mut event_data: *mut ILongExposureInfraredFrameArrivedEventArgs = ptr::null_mut();
328        let hr = unsafe { get_data_fn(self.ptr, waitable_handle, &mut event_data) };
329        if hr.is_err() {
330            Err(Error::from_hresult(hr))
331        } else if event_data.is_null() {
332            Err(Error::from(E_POINTER))
333        } else {
334            Ok(LongExposureInfraredFrameArrivedEventArgs::new(event_data))
335        }
336    }
337
338    pub fn acquire_latest_frame(&self) -> Result<LongExposureInfraredFrame, Error> {
339        if self.ptr.is_null() {
340            return Err(Error::from(E_POINTER));
341        }
342        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
343        let acquire_fn = vtbl.AcquireLatestFrame.ok_or_else(|| Error::from(E_FAIL))?;
344        let mut frame_ptr: *mut ILongExposureInfraredFrame = ptr::null_mut();
345        let hr = unsafe { acquire_fn(self.ptr, &mut frame_ptr) };
346        if hr.is_err() {
347            Err(Error::from_hresult(hr))
348        } else if frame_ptr.is_null() {
349            Err(Error::from(E_POINTER))
350        } else {
351            Ok(LongExposureInfraredFrame::new(frame_ptr))
352        }
353    }
354
355    pub fn get_is_paused(&self) -> Result<bool, Error> {
356        if self.ptr.is_null() {
357            return Err(Error::from(E_POINTER));
358        }
359        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
360        let get_paused_fn = vtbl.get_IsPaused.ok_or_else(|| Error::from(E_FAIL))?;
361        let mut is_paused: BOOLEAN = 0;
362        let hr = unsafe { get_paused_fn(self.ptr, &mut is_paused) };
363        if hr.is_err() {
364            Err(Error::from_hresult(hr))
365        } else {
366            Ok(is_paused != 0)
367        }
368    }
369
370    pub fn put_is_paused(&self, is_paused: bool) -> Result<(), Error> {
371        if self.ptr.is_null() {
372            return Err(Error::from(E_POINTER));
373        }
374        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
375        let put_paused_fn = vtbl.put_IsPaused.ok_or_else(|| Error::from(E_FAIL))?;
376        let paused_value: BOOLEAN = if is_paused { 1 } else { 0 };
377        let hr = unsafe { put_paused_fn(self.ptr, paused_value) };
378        if hr.is_err() {
379            Err(Error::from_hresult(hr))
380        } else {
381            Ok(())
382        }
383    }
384
385    pub fn get_long_exposure_infrared_frame_source(
386        &self,
387    ) -> Result<LongExposureInfraredFrameSource, Error> {
388        if self.ptr.is_null() {
389            return Err(Error::from(E_POINTER));
390        }
391        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
392        let get_source_fn = vtbl
393            .get_LongExposureInfraredFrameSource
394            .ok_or_else(|| Error::from(E_FAIL))?;
395        let mut source_ptr: *mut ILongExposureInfraredFrameSource = ptr::null_mut();
396        let hr = unsafe { get_source_fn(self.ptr, &mut source_ptr) };
397        if hr.is_err() {
398            Err(Error::from_hresult(hr))
399        } else if source_ptr.is_null() {
400            Err(Error::from(E_POINTER))
401        } else {
402            Ok(LongExposureInfraredFrameSource::new(source_ptr))
403        }
404    }
405}
406
407impl Drop for LongExposureInfraredFrameReader {
408    fn drop(&mut self) {
409        if !self.ptr.is_null() {
410            unsafe {
411                if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
412                    && let Some(release_fn) = vtbl.Release
413                {
414                    release_fn(self.ptr);
415                }
416            }
417            self.ptr = ptr::null_mut();
418        }
419    }
420}
421
422pub struct LongExposureInfraredFrameReference {
423    ptr: *mut ILongExposureInfraredFrameReference,
424}
425
426impl LongExposureInfraredFrameReference {
427    pub(crate) fn new(ptr: *mut ILongExposureInfraredFrameReference) -> Self {
428        assert!(!ptr.is_null());
429        Self { ptr }
430    }
431
432    pub fn acquire_frame(&self) -> Result<LongExposureInfraredFrame, Error> {
433        if self.ptr.is_null() {
434            return Err(Error::from(E_POINTER));
435        }
436        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
437        let acquire_frame_fn = vtbl.AcquireFrame.ok_or_else(|| Error::from(E_FAIL))?;
438        let mut frame_ptr: *mut ILongExposureInfraredFrame = ptr::null_mut();
439        let hr = unsafe { acquire_frame_fn(self.ptr, &mut frame_ptr) };
440        if hr.is_err() {
441            Err(Error::from_hresult(hr))
442        } else if frame_ptr.is_null() {
443            Err(Error::from(E_POINTER))
444        } else {
445            Ok(LongExposureInfraredFrame::new(frame_ptr))
446        }
447    }
448
449    pub fn get_relative_time(&self) -> Result<TIMESPAN, Error> {
450        if self.ptr.is_null() {
451            return Err(Error::from(E_POINTER));
452        }
453        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
454        let get_time_fn = vtbl.get_RelativeTime.ok_or_else(|| Error::from(E_FAIL))?;
455        let mut relative_time: TIMESPAN = 0;
456        let hr = unsafe { get_time_fn(self.ptr, &mut relative_time) };
457        if hr.is_err() {
458            Err(Error::from_hresult(hr))
459        } else {
460            Ok(relative_time)
461        }
462    }
463}
464
465impl Drop for LongExposureInfraredFrameReference {
466    fn drop(&mut self) {
467        if !self.ptr.is_null() {
468            unsafe {
469                if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
470                    && let Some(release_fn) = vtbl.Release
471                {
472                    release_fn(self.ptr);
473                }
474            }
475            self.ptr = ptr::null_mut();
476        }
477    }
478}
479
480pub struct LongExposureInfraredFrameArrivedEventArgs {
481    ptr: *mut ILongExposureInfraredFrameArrivedEventArgs,
482}
483
484impl LongExposureInfraredFrameArrivedEventArgs {
485    pub(crate) fn new(ptr: *mut ILongExposureInfraredFrameArrivedEventArgs) -> Self {
486        assert!(!ptr.is_null());
487        Self { ptr }
488    }
489
490    pub fn get_frame_reference(&self) -> Result<LongExposureInfraredFrameReference, Error> {
491        if self.ptr.is_null() {
492            return Err(Error::from(E_POINTER));
493        }
494        let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
495        let get_frame_reference_fn = vtbl.get_FrameReference.ok_or_else(|| Error::from(E_FAIL))?;
496        let mut frame_reference_ptr: *mut ILongExposureInfraredFrameReference = ptr::null_mut();
497        let hr = unsafe { get_frame_reference_fn(self.ptr, &mut frame_reference_ptr) };
498        if hr.is_err() {
499            Err(Error::from_hresult(hr))
500        } else if frame_reference_ptr.is_null() {
501            Err(Error::from(E_POINTER))
502        } else {
503            Ok(LongExposureInfraredFrameReference::new(frame_reference_ptr))
504        }
505    }
506}
507
508impl Drop for LongExposureInfraredFrameArrivedEventArgs {
509    fn drop(&mut self) {
510        if !self.ptr.is_null() {
511            unsafe {
512                if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
513                    && let Some(release_fn) = vtbl.Release
514                {
515                    release_fn(self.ptr);
516                }
517            }
518            self.ptr = ptr::null_mut();
519        }
520    }
521}