realsense_rust/processing_blocks/
colorizer.rs1use crate::{
6 check_rs2_error,
7 frame::{ColorFrame, DepthFrame, FrameEx},
8 processing_blocks::{
9 errors::{ProcessFrameError, ProcessingBlockConstructionError},
10 options::{
11 get_processing_block_option, get_processing_block_option_range,
12 set_processing_block_option, ColorizerOptions, OptionsExt, ProcessingBlockOptionError,
13 },
14 },
15};
16use anyhow::Result;
17use realsense_sys as sys;
18use std::{convert::TryFrom, ptr::NonNull, task::Poll, time::Duration};
19
20#[derive(Debug, Clone)]
24pub struct Colorizer {
25 processing_block: NonNull<sys::rs2_processing_block>,
27 processing_queue: NonNull<sys::rs2_frame_queue>,
29}
30
31impl Drop for Colorizer {
32 fn drop(&mut self) {
33 unsafe {
34 sys::rs2_delete_frame_queue(self.processing_queue.as_ptr());
35 sys::rs2_delete_processing_block(self.processing_block.as_ptr());
36 }
37 }
38}
39
40impl Colorizer {
41 pub fn new(processing_queue_size: i32) -> Result<Self, ProcessingBlockConstructionError> {
43 let (processing_block, processing_queue) = unsafe {
44 let mut err = std::ptr::null_mut::<sys::rs2_error>();
45
46 let ptr = sys::rs2_create_colorizer(&mut err);
47 check_rs2_error!(
48 err,
49 ProcessingBlockConstructionError::CouldNotCreateProcessingBlock
50 )?;
51
52 let queue_ptr = sys::rs2_create_frame_queue(processing_queue_size, &mut err);
53 check_rs2_error!(
54 err,
55 ProcessingBlockConstructionError::CouldNotCreateProcessingQueue
56 )?;
57
58 sys::rs2_start_processing_queue(ptr, queue_ptr, &mut err);
59 check_rs2_error!(
60 err,
61 ProcessingBlockConstructionError::CouldNotStartProcessingQueue
62 )?;
63 (NonNull::new(ptr).unwrap(), NonNull::new(queue_ptr).unwrap())
64 };
65
66 Ok(Self {
67 processing_block,
68 processing_queue,
69 })
70 }
71
72 pub fn queue(&mut self, frame: DepthFrame) -> Result<(), ProcessFrameError> {
74 unsafe {
75 let mut err = std::ptr::null_mut::<sys::rs2_error>();
76 sys::rs2_process_frame(
77 self.processing_block.as_ptr(),
78 frame.get_owned_raw().as_ptr(),
79 &mut err,
80 );
81 check_rs2_error!(err, |kind, context| { ProcessFrameError { kind, context } })?;
82 Ok(())
83 }
84 }
85
86 pub fn wait(&mut self, timeout: Duration) -> Result<ColorFrame, ProcessFrameError> {
88 unsafe {
89 let mut err = std::ptr::null_mut::<sys::rs2_error>();
90 let timeout_millis = u32::try_from(timeout.as_millis()).unwrap_or(u32::MAX);
91
92 let colorized_frame =
93 sys::rs2_wait_for_frame(self.processing_queue.as_ptr(), timeout_millis, &mut err);
94 check_rs2_error!(err, |kind, context| { ProcessFrameError { kind, context } })?;
95 Ok(ColorFrame::try_from(NonNull::new(colorized_frame).unwrap()).unwrap())
96 }
97 }
98
99 pub fn poll(&mut self) -> Result<Poll<ColorFrame>, ProcessFrameError> {
101 unsafe {
102 let mut err = std::ptr::null_mut::<sys::rs2_error>();
103 let mut frame = std::ptr::null_mut::<sys::rs2_frame>();
104 let is_ready =
105 sys::rs2_poll_for_frame(self.processing_queue.as_ptr(), &mut frame, &mut err);
106
107 check_rs2_error!(err, |kind, context| { ProcessFrameError { kind, context } })?;
109
110 if is_ready == 0 {
112 Ok(Poll::Pending)
113 } else {
114 Ok(Poll::Ready(
115 ColorFrame::try_from(NonNull::new(frame).unwrap()).unwrap(),
116 ))
117 }
118 }
119 }
120
121 pub fn apply_options(
123 &mut self,
124 options: &ColorizerOptions,
125 ) -> Result<(), ProcessingBlockOptionError> {
126 if let Some(color_scheme) = options.color_scheme {
127 self.set_option(sys::rs2_option_RS2_OPTION_COLOR_SCHEME, color_scheme)?;
128 }
129 if let Some(histogram_equalization) = options.histogram_equalization {
130 self.set_option(
131 sys::rs2_option_RS2_OPTION_HISTOGRAM_EQUALIZATION_ENABLED,
132 histogram_equalization,
133 )?;
134 }
135 if let Some(min_distance) = options.min_distance {
136 self.set_option(sys::rs2_option_RS2_OPTION_MIN_DISTANCE, min_distance)?;
137 }
138 if let Some(max_distance) = options.max_distance {
139 self.set_option(sys::rs2_option_RS2_OPTION_MAX_DISTANCE, max_distance)?;
140 }
141 Ok(())
142 }
143}
144
145impl OptionsExt for Colorizer {
146 fn set_option(
147 &mut self,
148 option: sys::rs2_option,
149 value: f32,
150 ) -> Result<(), ProcessingBlockOptionError> {
151 set_processing_block_option(self.processing_block, option, value)
152 }
153
154 fn get_option(&self, option: sys::rs2_option) -> Result<f32, ProcessingBlockOptionError> {
155 get_processing_block_option(self.processing_block, option)
156 }
157
158 fn supports_option(&self, option: sys::rs2_option) -> bool {
159 unsafe {
160 let mut err = std::ptr::null_mut::<sys::rs2_error>();
161 let is_supported = sys::rs2_supports_option(
162 self.processing_block.as_ptr() as *const sys::rs2_options,
163 option,
164 &mut err,
165 );
166 err.is_null() && is_supported != 0
167 }
168 }
169
170 fn get_option_range(
171 &self,
172 option: sys::rs2_option,
173 ) -> Result<(f32, f32, f32, f32), ProcessingBlockOptionError> {
174 get_processing_block_option_range(self.processing_block, option)
175 }
176}