1use crate::bindings::{
2 BOOLEAN, IFrameCapturedEventArgs, IFrameDescription, IInfraredFrame,
3 IInfraredFrameArrivedEventArgs, IInfraredFrameReader, IInfraredFrameReference,
4 IInfraredFrameSource, IKinectSensor, TIMESPAN, UINT, UINT16, 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 InfraredFrame {
14 ptr: *mut IInfraredFrame,
15}
16
17impl InfraredFrame {
18 pub(crate) fn new(ptr: *mut IInfraredFrame) -> 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 let slice =
56 unsafe { std::slice::from_raw_parts(buffer as *const u16, capacity as usize) };
57 Ok(slice)
58 }
59 }
60
61 pub fn get_frame_description(&self) -> Result<FrameDescription, Error> {
62 if self.ptr.is_null() {
63 return Err(Error::from(E_POINTER));
64 }
65 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
66 let get_description_fn = vtbl
67 .get_FrameDescription
68 .ok_or_else(|| Error::from(E_FAIL))?;
69 let mut frame_description_ptr: *mut IFrameDescription = ptr::null_mut();
70 let hr = unsafe { get_description_fn(self.ptr, &mut frame_description_ptr) };
71 if hr.is_err() {
72 Err(Error::from_hresult(hr))
73 } else {
74 Ok(FrameDescription::new(frame_description_ptr))
75 }
76 }
77
78 pub fn get_relative_time(&self) -> Result<TIMESPAN, Error> {
79 if self.ptr.is_null() {
80 return Err(Error::from(E_POINTER));
81 }
82 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
83 let get_time_fn = vtbl.get_RelativeTime.ok_or_else(|| Error::from(E_FAIL))?;
84 let mut relative_time: TIMESPAN = 0;
85 let hr = unsafe { get_time_fn(self.ptr, &mut relative_time) };
86 if hr.is_err() {
87 Err(Error::from_hresult(hr))
88 } else {
89 Ok(relative_time)
90 }
91 }
92
93 pub fn get_infrared_frame_source(&self) -> Result<InfraredFrameSource, Error> {
94 if self.ptr.is_null() {
95 return Err(Error::from(E_POINTER));
96 }
97 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
98 let get_source_fn = vtbl
99 .get_InfraredFrameSource
100 .ok_or_else(|| Error::from(E_FAIL))?;
101 let mut infrared_frame_source_ptr: *mut IInfraredFrameSource = ptr::null_mut();
102 let hr = unsafe { get_source_fn(self.ptr, &mut infrared_frame_source_ptr) };
103 if hr.is_err() {
104 Err(Error::from_hresult(hr))
105 } else if infrared_frame_source_ptr.is_null() {
106 Err(Error::from(E_POINTER))
107 } else {
108 Ok(InfraredFrameSource::new(infrared_frame_source_ptr))
109 }
110 }
111}
112
113impl Drop for InfraredFrame {
114 fn drop(&mut self) {
115 if !self.ptr.is_null() {
116 unsafe {
117 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
118 if let Some(release_fn) = vtbl.Release {
119 release_fn(self.ptr);
120 }
121 }
122 }
123 self.ptr = ptr::null_mut();
124 }
125 }
126}
127
128pub struct InfraredFrameSource {
129 ptr: *mut IInfraredFrameSource,
130}
131impl InfraredFrameSource {
132 pub(crate) fn new(ptr: *mut IInfraredFrameSource) -> Self {
133 assert!(!ptr.is_null());
134 Self { ptr }
135 }
136
137 pub fn subscribe_frame_captured(&self) -> Result<WAITABLE_HANDLE, Error> {
138 if self.ptr.is_null() {
139 return Err(Error::from(E_POINTER));
140 }
141 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
142 let subscribe_fn = vtbl
143 .SubscribeFrameCaptured
144 .ok_or_else(|| Error::from(E_FAIL))?;
145 let mut waitable_handle: WAITABLE_HANDLE = windows::Win32::Foundation::HANDLE::default();
146 let hr = unsafe { subscribe_fn(self.ptr, &mut waitable_handle) };
147 if hr.is_err() {
148 Err(Error::from_hresult(hr))
149 } else {
150 Ok(waitable_handle)
151 }
152 }
153
154 pub fn unsubscribe_frame_captured(
155 &self,
156 waitable_handle: WAITABLE_HANDLE,
157 ) -> Result<(), Error> {
158 if self.ptr.is_null() {
159 return Err(Error::from(E_POINTER));
160 }
161 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
162 let unsubscribe_fn = vtbl
163 .UnsubscribeFrameCaptured
164 .ok_or_else(|| Error::from(E_FAIL))?;
165 let hr = unsafe { unsubscribe_fn(self.ptr, waitable_handle) };
166 if hr.is_err() {
167 Err(Error::from_hresult(hr))
168 } else {
169 Ok(())
170 }
171 }
172
173 pub fn get_frame_captured_event_data(
174 &self,
175 waitable_handle: WAITABLE_HANDLE,
176 ) -> Result<FrameCapturedEventArgs, Error> {
177 if self.ptr.is_null() {
178 return Err(Error::from(E_POINTER));
179 }
180 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
181 let get_data_fn = vtbl
182 .GetFrameCapturedEventData
183 .ok_or_else(|| Error::from(E_FAIL))?;
184 let mut event_args_ptr: *mut IFrameCapturedEventArgs = ptr::null_mut();
185 let hr = unsafe { get_data_fn(self.ptr, waitable_handle, &mut event_args_ptr) };
186 if hr.is_err() {
187 Err(Error::from_hresult(hr))
188 } else {
189 Ok(FrameCapturedEventArgs::new(event_args_ptr))
190 }
191 }
192
193 pub fn get_is_active(&self) -> Result<bool, Error> {
194 if self.ptr.is_null() {
195 return Err(Error::from(E_POINTER));
196 }
197 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
198 let get_active_fn = vtbl.get_IsActive.ok_or_else(|| Error::from(E_FAIL))?;
199 let mut is_active: BOOLEAN = 0;
200 let hr = unsafe { get_active_fn(self.ptr, &mut is_active) };
201 if hr.is_err() {
202 Err(Error::from_hresult(hr))
203 } else {
204 Ok(is_active != 0)
205 }
206 }
207
208 pub fn open_reader(&self) -> Result<InfraredFrameReader, Error> {
209 if self.ptr.is_null() {
210 return Err(Error::from(E_POINTER));
211 }
212 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
213 let open_reader_fn = vtbl.OpenReader.ok_or_else(|| Error::from(E_FAIL))?;
214 let mut reader_ptr: *mut IInfraredFrameReader = ptr::null_mut();
215 let hr = unsafe { open_reader_fn(self.ptr, &mut reader_ptr) };
216 if hr.is_err() {
217 Err(Error::from_hresult(hr))
218 } else if reader_ptr.is_null() {
219 Err(Error::from(E_POINTER))
220 } else {
221 Ok(InfraredFrameReader::new(reader_ptr))
222 }
223 }
224
225 pub fn get_frame_description(&self) -> Result<FrameDescription, Error> {
226 if self.ptr.is_null() {
227 return Err(Error::from(E_POINTER));
228 }
229 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
230 let get_description_fn = vtbl
231 .get_FrameDescription
232 .ok_or_else(|| Error::from(E_FAIL))?;
233 let mut frame_description_ptr: *mut IFrameDescription = ptr::null_mut();
234 let hr = unsafe { get_description_fn(self.ptr, &mut frame_description_ptr) };
235 if hr.is_err() {
236 Err(Error::from_hresult(hr))
237 } else {
238 Ok(FrameDescription::new(frame_description_ptr))
239 }
240 }
241
242 pub fn get_kinect_sensor(&self) -> Result<KinectSensor, Error> {
243 if self.ptr.is_null() {
244 return Err(Error::from(E_POINTER));
245 }
246 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
247 let get_sensor_fn = vtbl.get_KinectSensor.ok_or_else(|| Error::from(E_FAIL))?;
248 let mut sensor: *mut IKinectSensor = ptr::null_mut();
249 let hr = unsafe { get_sensor_fn(self.ptr, &mut sensor) };
250 if hr.is_err() {
251 Err(Error::from_hresult(hr))
252 } else {
253 Ok(KinectSensor::new(sensor))
254 }
255 }
256}
257
258impl Drop for InfraredFrameSource {
259 fn drop(&mut self) {
260 if !self.ptr.is_null() {
261 unsafe {
262 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
263 if let Some(release_fn) = vtbl.Release {
264 release_fn(self.ptr);
265 }
266 }
267 }
268 self.ptr = ptr::null_mut();
269 }
270 }
271}
272
273pub struct InfraredFrameReader {
274 ptr: *mut IInfraredFrameReader,
275}
276
277impl InfraredFrameReader {
278 pub(crate) fn new(ptr: *mut IInfraredFrameReader) -> 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 pub fn get_frame_arrived_event_data(
316 &self,
317 waitable_handle: WAITABLE_HANDLE,
318 ) -> Result<InfraredFrameArrivedEventArgs, Error> {
319 if self.ptr.is_null() {
320 return Err(Error::from(E_POINTER));
321 }
322 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
323 let get_data_fn = vtbl
324 .GetFrameArrivedEventData
325 .ok_or_else(|| Error::from(E_FAIL))?;
326 let mut event_data: *mut IInfraredFrameArrivedEventArgs = ptr::null_mut();
327 let hr = unsafe { get_data_fn(self.ptr, waitable_handle, &mut event_data) };
328 if hr.is_err() {
329 Err(Error::from_hresult(hr))
330 } else if event_data.is_null() {
331 Err(Error::from(E_POINTER))
332 } else {
333 Ok(InfraredFrameArrivedEventArgs::new(event_data))
334 }
335 }
336
337 pub fn acquire_latest_frame(&self) -> Result<InfraredFrame, Error> {
338 if self.ptr.is_null() {
339 return Err(Error::from(E_POINTER));
340 }
341 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
342 let acquire_fn = vtbl.AcquireLatestFrame.ok_or_else(|| Error::from(E_FAIL))?;
343 let mut frame_ptr: *mut IInfraredFrame = ptr::null_mut();
344 let hr = unsafe { acquire_fn(self.ptr, &mut frame_ptr) };
345 if hr.is_err() {
346 Err(Error::from_hresult(hr))
347 } else if frame_ptr.is_null() {
348 Err(Error::from(E_POINTER))
349 } else {
350 Ok(InfraredFrame::new(frame_ptr))
351 }
352 }
353
354 pub fn get_is_paused(&self) -> Result<bool, Error> {
355 if self.ptr.is_null() {
356 return Err(Error::from(E_POINTER));
357 }
358 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
359 let get_paused_fn = vtbl.get_IsPaused.ok_or_else(|| Error::from(E_FAIL))?;
360 let mut is_paused: BOOLEAN = 0;
361 let hr = unsafe { get_paused_fn(self.ptr, &mut is_paused) };
362 if hr.is_err() {
363 Err(Error::from_hresult(hr))
364 } else {
365 Ok(is_paused != 0)
366 }
367 }
368
369 pub fn put_is_paused(&self, is_paused: bool) -> Result<(), Error> {
370 if self.ptr.is_null() {
371 return Err(Error::from(E_POINTER));
372 }
373 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
374 let put_paused_fn = vtbl.put_IsPaused.ok_or_else(|| Error::from(E_FAIL))?;
375 let paused_value: BOOLEAN = if is_paused { 1 } else { 0 };
376 let hr = unsafe { put_paused_fn(self.ptr, paused_value) };
377 if hr.is_err() {
378 Err(Error::from_hresult(hr))
379 } else {
380 Ok(())
381 }
382 }
383
384 pub fn get_infrared_frame_source(&self) -> Result<InfraredFrameSource, Error> {
385 if self.ptr.is_null() {
386 return Err(Error::from(E_POINTER));
387 }
388 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
389 let get_source_fn = vtbl
390 .get_InfraredFrameSource
391 .ok_or_else(|| Error::from(E_FAIL))?;
392 let mut source_ptr: *mut IInfraredFrameSource = ptr::null_mut();
393 let hr = unsafe { get_source_fn(self.ptr, &mut source_ptr) };
394 if hr.is_err() {
395 Err(Error::from_hresult(hr))
396 } else if source_ptr.is_null() {
397 Err(Error::from(E_POINTER))
398 } else {
399 Ok(InfraredFrameSource::new(source_ptr))
400 }
401 }
402}
403
404impl Drop for InfraredFrameReader {
405 fn drop(&mut self) {
406 if !self.ptr.is_null() {
407 unsafe {
408 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
409 if let Some(release_fn) = vtbl.Release {
410 release_fn(self.ptr);
411 }
412 }
413 }
414 self.ptr = ptr::null_mut();
415 }
416 }
417}
418
419pub struct InfraredFrameReference {
420 ptr: *mut IInfraredFrameReference,
421}
422
423impl InfraredFrameReference {
424 pub(crate) fn new(ptr: *mut IInfraredFrameReference) -> Self {
425 assert!(!ptr.is_null());
426 Self { ptr }
427 }
428
429 pub fn acquire_frame(&self) -> Result<InfraredFrame, Error> {
430 if self.ptr.is_null() {
431 return Err(Error::from(E_POINTER));
432 }
433 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
434 let acquire_frame_fn = vtbl.AcquireFrame.ok_or_else(|| Error::from(E_FAIL))?;
435 let mut frame_ptr: *mut IInfraredFrame = ptr::null_mut();
436 let hr = unsafe { acquire_frame_fn(self.ptr, &mut frame_ptr) };
437 if hr.is_err() {
438 Err(Error::from_hresult(hr))
439 } else if frame_ptr.is_null() {
440 Err(Error::from(E_POINTER))
441 } else {
442 Ok(InfraredFrame::new(frame_ptr))
443 }
444 }
445
446 pub fn get_relative_time(&self) -> Result<TIMESPAN, Error> {
447 if self.ptr.is_null() {
448 return Err(Error::from(E_POINTER));
449 }
450 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
451 let get_time_fn = vtbl.get_RelativeTime.ok_or_else(|| Error::from(E_FAIL))?;
452 let mut relative_time: TIMESPAN = 0;
453 let hr = unsafe { get_time_fn(self.ptr, &mut relative_time) };
454 if hr.is_err() {
455 Err(Error::from_hresult(hr))
456 } else {
457 Ok(relative_time)
458 }
459 }
460}
461
462impl Drop for InfraredFrameReference {
463 fn drop(&mut self) {
464 if !self.ptr.is_null() {
465 unsafe {
466 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
467 if let Some(release_fn) = vtbl.Release {
468 release_fn(self.ptr);
469 }
470 }
471 }
472 self.ptr = ptr::null_mut();
473 }
474 }
475}
476
477pub struct InfraredFrameArrivedEventArgs {
478 ptr: *mut IInfraredFrameArrivedEventArgs,
479}
480
481impl InfraredFrameArrivedEventArgs {
482 pub(crate) fn new(ptr: *mut IInfraredFrameArrivedEventArgs) -> Self {
483 assert!(!ptr.is_null());
484 Self { ptr }
485 }
486
487 pub fn get_frame_reference(&self) -> Result<InfraredFrameReference, Error> {
488 if self.ptr.is_null() {
489 return Err(Error::from(E_POINTER));
490 }
491 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
492 let get_frame_reference_fn = vtbl.get_FrameReference.ok_or_else(|| Error::from(E_FAIL))?;
493 let mut frame_reference_ptr: *mut IInfraredFrameReference = ptr::null_mut();
494 let hr = unsafe { get_frame_reference_fn(self.ptr, &mut frame_reference_ptr) };
495 if hr.is_err() {
496 Err(Error::from_hresult(hr))
497 } else if frame_reference_ptr.is_null() {
498 Err(Error::from(E_POINTER))
499 } else {
500 Ok(InfraredFrameReference::new(frame_reference_ptr))
501 }
502 }
503}
504
505impl Drop for InfraredFrameArrivedEventArgs {
506 fn drop(&mut self) {
507 if !self.ptr.is_null() {
508 unsafe {
509 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
510 if let Some(release_fn) = vtbl.Release {
511 release_fn(self.ptr);
512 }
513 }
514 }
515 self.ptr = ptr::null_mut();
516 }
517 }
518}
519
520#[cfg(test)]
522mod tests {
523 use crate::kinect;
524 use std::{thread, time::Duration};
525 use windows::Win32::{
526 Foundation::{WAIT_OBJECT_0, WAIT_TIMEOUT},
527 System::{Com::Urlmon::E_PENDING, Threading::WaitForSingleObject},
528 };
529
530 #[test]
531 fn get_latest_infrared_frame() -> anyhow::Result<()> {
532 let kinect = kinect::get_default_kinect_sensor()?;
533 kinect.open()?;
534 let infrared_frame_source = kinect.infrared_frame_source()?;
535 let infrared_frame_reader = infrared_frame_source.open_reader()?;
536
537 let mut frame_count = 0;
538 loop {
539 match infrared_frame_reader.acquire_latest_frame() {
540 Ok(infrared_frame) => {
541 let frame_description = infrared_frame.get_frame_description()?;
542 let width = frame_description.get_width()?;
543 let height = frame_description.get_height()?;
544 let relative_time = infrared_frame.get_relative_time()?;
545 assert_eq!(width, 512);
546 assert_eq!(height, 424);
547 assert!(relative_time > 0);
548 frame_count += 1;
549 if frame_count > 10 {
550 break; }
552 }
553 Err(e) => {
554 if e.code() == E_PENDING {
555 thread::sleep(Duration::from_millis(100));
557 } else {
558 return Err(anyhow::Error::new(e));
560 }
561 }
562 }
563 }
564
565 Ok(())
566 }
567
568 #[test]
569 fn subscribe_infrared_frame_arrived_event() -> anyhow::Result<()> {
570 let kinect = kinect::get_default_kinect_sensor()?;
571 kinect.open()?;
572 let infrared_frame_source = kinect.infrared_frame_source()?;
573 let infrared_frame_reader = infrared_frame_source.open_reader()?;
574 let waitable_handle = infrared_frame_reader.subscribe_frame_arrived()?;
575 let mut frame_count = 0;
576 let is_active = infrared_frame_source.get_is_active()?;
577 assert!(is_active, "Color frame source should be active");
578 loop {
579 let result = unsafe { WaitForSingleObject(waitable_handle, 100) };
580 if result == WAIT_OBJECT_0 {
581 let event_args =
582 infrared_frame_reader.get_frame_arrived_event_data(waitable_handle)?;
583
584 let frame_reference = event_args.get_frame_reference()?;
585 let infrared_frame = frame_reference.acquire_frame()?;
586 let frame_description = infrared_frame.get_frame_description()?;
587 let width = frame_description.get_width()?;
588 let height = frame_description.get_height()?;
589 let relative_time = frame_reference.get_relative_time()?;
590 let bytes_per_pixel = frame_description.get_bytes_per_pixel()?;
591 assert_eq!(width, 512);
592 assert_eq!(height, 424);
593 assert!(relative_time > 0);
594 assert_eq!(bytes_per_pixel, 2);
595 let capacity = (width * height) as u32;
596 let mut frame_data: Vec<u16> = vec![0; capacity as usize];
597 infrared_frame.copy_frame_data_to_array(&mut frame_data)?;
598 println!(
599 "Infrared frame dimensions: {}x{}, time: {}, data length: {}",
600 width,
601 height,
602 relative_time,
603 frame_data.len()
604 );
605
606 frame_count += 1;
607 if frame_count > 10 {
608 break; }
610 } else if result == WAIT_TIMEOUT {
611 println!("No new infrared frame available, waiting...");
612 } else {
613 return Err(anyhow::anyhow!(
614 "WaitForSingleObject failed with result: {:?}",
615 result
616 ));
617 }
618 }
619
620 Ok(())
621 }
622}