realsense_rust/processing_blocks/
disparity_transform.rs

1//! Processing block for depth<->disparity domain transformation
2//!
3//! Provides depth<->disparity domain transformation for stereo-based depth modules
4
5use crate::{
6    check_rs2_error,
7    frame::{DepthFrame, FrameEx},
8    processing_blocks::errors::{ProcessFrameError, ProcessingBlockConstructionError},
9};
10use anyhow::Result;
11use realsense_sys as sys;
12use std::{convert::TryFrom, ptr::NonNull, task::Poll, time::Duration};
13
14/// Creates a post processing block that provides for depth<->disparity domain transformation
15/// for stereo-based depth modules
16#[derive(Debug, Clone)]
17pub struct DisparityTransform {
18    /// The processing block for disparity transformation
19    processing_block: NonNull<sys::rs2_processing_block>,
20    /// The frame queue upon which the processing block will deposit transformed frames
21    processing_queue: NonNull<sys::rs2_frame_queue>,
22}
23
24impl Drop for DisparityTransform {
25    fn drop(&mut self) {
26        unsafe {
27            sys::rs2_delete_frame_queue(self.processing_queue.as_ptr());
28            sys::rs2_delete_processing_block(self.processing_block.as_ptr());
29        }
30    }
31}
32
33impl DisparityTransform {
34    /// Create a new DisparityTransform processing block
35    ///
36    /// # Arguments
37    ///
38    /// * `transform_to_disparity` - true = depth->disparity, false = disparity->depth
39    /// * `processing_queue_size` - Size of the processing queue
40    pub fn new(
41        transform_to_disparity: bool,
42        processing_queue_size: i32,
43    ) -> Result<Self, ProcessingBlockConstructionError> {
44        let (processing_block, processing_queue) = unsafe {
45            let mut err = std::ptr::null_mut::<sys::rs2_error>();
46
47            let ptr = sys::rs2_create_disparity_transform_block(
48                if transform_to_disparity { 1 } else { 0 },
49                &mut err,
50            );
51            check_rs2_error!(
52                err,
53                ProcessingBlockConstructionError::CouldNotCreateProcessingBlock
54            )?;
55
56            let queue_ptr = sys::rs2_create_frame_queue(processing_queue_size, &mut err);
57            check_rs2_error!(
58                err,
59                ProcessingBlockConstructionError::CouldNotCreateProcessingQueue
60            )?;
61
62            sys::rs2_start_processing_queue(ptr, queue_ptr, &mut err);
63            check_rs2_error!(
64                err,
65                ProcessingBlockConstructionError::CouldNotStartProcessingQueue
66            )?;
67            (NonNull::new(ptr).unwrap(), NonNull::new(queue_ptr).unwrap())
68        };
69
70        Ok(Self {
71            processing_block,
72            processing_queue,
73        })
74    }
75
76    /// Process a depth frame with disparity transformation
77    pub fn queue(&mut self, frame: DepthFrame) -> Result<(), ProcessFrameError> {
78        unsafe {
79            let mut err = std::ptr::null_mut::<sys::rs2_error>();
80            sys::rs2_process_frame(
81                self.processing_block.as_ptr(),
82                frame.get_owned_raw().as_ptr(),
83                &mut err,
84            );
85            check_rs2_error!(err, |kind, context| { ProcessFrameError { kind, context } })?;
86            Ok(())
87        }
88    }
89
90    /// Wait to receive the transformed results
91    pub fn wait(&mut self, timeout: Duration) -> Result<DepthFrame, ProcessFrameError> {
92        unsafe {
93            let mut err = std::ptr::null_mut::<sys::rs2_error>();
94            let timeout_millis = u32::try_from(timeout.as_millis()).unwrap_or(u32::MAX);
95
96            let transformed_frame =
97                sys::rs2_wait_for_frame(self.processing_queue.as_ptr(), timeout_millis, &mut err);
98            check_rs2_error!(err, |kind, context| { ProcessFrameError { kind, context } })?;
99            Ok(DepthFrame::try_from(NonNull::new(transformed_frame).unwrap()).unwrap())
100        }
101    }
102
103    /// Poll to receive the transformed results
104    pub fn poll(&mut self) -> Result<Poll<DepthFrame>, ProcessFrameError> {
105        unsafe {
106            let mut err = std::ptr::null_mut::<sys::rs2_error>();
107            let mut frame = std::ptr::null_mut::<sys::rs2_frame>();
108            let is_ready =
109                sys::rs2_poll_for_frame(self.processing_queue.as_ptr(), &mut frame, &mut err);
110
111            // Check for errors
112            check_rs2_error!(err, |kind, context| { ProcessFrameError { kind, context } })?;
113
114            // Check for queue readiness
115            if is_ready == 0 {
116                Ok(Poll::Pending)
117            } else {
118                Ok(Poll::Ready(
119                    DepthFrame::try_from(NonNull::new(frame).unwrap()).unwrap(),
120                ))
121            }
122        }
123    }
124}