kinect_v2_sys/
body_index.rs

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