1use crate::playback::Playback;
2use crate::record::Record;
3use crate::*;
4use azure_kinect_sys::k4a::{k4a_calibration_t, k4a_capture_t, k4a_image_t};
5use std::ffi::CString;
6use std::os::raw;
7use std::ptr;
8
9pub type DebugMessageHandler = dyn FnMut(LogLevel, &str, raw::c_int, &str);
10pub type MemoryDestroyCallback = extern "C" fn(buffer: *mut (), context: *mut ());
11
12pub trait PreAllocatedBufferInfo {
13 fn format(&self) -> ImageFormat;
14 fn width_pixels(&self) -> i32;
15 fn height_pixels(&self) -> i32;
16 fn stride_bytes(&self) -> i32;
17 fn buffer(&mut self) -> *mut u8;
18 fn buffer_size(&self) -> usize;
19}
20
21pub struct Factory {
22 pub(crate) api: azure_kinect_sys::api::Api,
23 debug_message_handler: Option<Box<DebugMessageHandler>>,
24}
25
26impl Factory {
27 pub fn new() -> Result<Factory, Error> {
28 Ok(Factory {
29 api: azure_kinect_sys::api::Api::new()?,
30 debug_message_handler: None,
31 })
32 }
33
34 pub fn with_library_directory(lib_dir: &str) -> Result<Factory, Error> {
35 Ok(Factory {
36 api: azure_kinect_sys::api::Api::with_library_directory(lib_dir)?,
37 debug_message_handler: None,
38 })
39 }
40
41 pub(crate) fn with_get_module() -> Result<Factory, Error> {
42 Ok(Factory {
43 api: azure_kinect_sys::api::Api::with_get_module()?,
44 debug_message_handler: None,
45 })
46 }
47
48 pub fn set_debug_message_handler(
50 mut self,
51 debug_message_handler: Box<DebugMessageHandler>,
52 min_level: LogLevel,
53 ) -> Self {
54 self.set_debug_message_handler_internal(debug_message_handler, min_level);
55 self
56 }
57
58 pub fn reset_debug_message_handler(mut self) -> Self {
60 self.reset_debug_message_handler_internal();
61 self
62 }
63
64 pub(crate) fn set_debug_message_handler_internal(
65 &mut self,
66 debug_message_handler: Box<DebugMessageHandler>,
67 min_level: LogLevel,
68 ) {
69 self.debug_message_handler = Some(debug_message_handler);
70 unsafe {
71 (self.api.funcs.k4a_set_debug_message_handler)(
72 Some(Self::debug_message_handler_func),
73 std::mem::transmute(self.debug_message_handler.as_mut()),
74 min_level.into(),
75 );
76 }
77 }
78
79 pub(crate) fn reset_debug_message_handler_internal(&mut self) {
80 self.debug_message_handler = None;
81 unsafe {
82 (self.api.funcs.k4a_set_debug_message_handler)(
83 None,
84 ptr::null_mut(),
85 azure_kinect_sys::k4a::k4a_log_level_t_K4A_LOG_LEVEL_OFF,
86 );
87 }
88 }
89
90 pub fn device_get_installed_count(&self) -> u32 {
92 unsafe { (self.api.funcs.k4a_device_get_installed_count)() }
93 }
94
95 pub fn device_open(&self, index: u32) -> Result<Device, Error> {
97 let mut handle: azure_kinect_sys::k4a::k4a_device_t = ptr::null_mut();
98 Error::from_k4a_result_t(unsafe { (self.api.funcs.k4a_device_open)(index, &mut handle) })
99 .to_result_fn(|| Device::from_handle(&self.api, handle))
100 }
101
102 pub fn calibration_get_from_raw(
104 &self,
105 raw_calibration: &Vec<u8>,
106 target_depth_mode: DepthMode,
107 target_color_resolution: ColorResolution,
108 ) -> Result<Calibration, Error> {
109 let mut calibration = k4a_calibration_t::default();
110 Error::from_k4a_result_t(unsafe {
111 (self.api.funcs.k4a_calibration_get_from_raw)(
112 raw_calibration.as_ptr() as *mut i8,
113 raw_calibration.len(),
114 target_depth_mode.into(),
115 target_color_resolution.into(),
116 &mut calibration,
117 )
118 })
119 .to_result_fn(|| Calibration::from_handle(&self.api, calibration))
120 }
121
122 pub fn capture_create(&self) -> Result<Capture, Error> {
123 let mut handle: k4a_capture_t = ptr::null_mut();
124 Error::from_k4a_result_t(unsafe { (self.api.funcs.k4a_capture_create)(&mut handle) })
125 .to_result_fn(|| Capture::from_handle(&self.api, handle))
126 }
127
128 pub fn image_create(
130 &self,
131 format: ImageFormat,
132 width_pixels: i32,
133 height_pixels: i32,
134 stride_bytes: i32,
135 ) -> Result<Image, Error> {
136 let mut handle: k4a_image_t = ptr::null_mut();
137 Error::from_k4a_result_t(unsafe {
138 (self.api.funcs.k4a_image_create)(
139 format.into(),
140 width_pixels,
141 height_pixels,
142 stride_bytes,
143 &mut handle,
144 )
145 })
146 .to_result_fn(|| Image::from_handle(&self.api, handle))
147 }
148
149 pub fn image_create_from_buffer_native(
151 &self,
152 format: ImageFormat,
153 width_pixels: i32,
154 height_pixels: i32,
155 stride_bytes: i32,
156 buffer: *mut u8,
157 buffer_size: usize,
158 buffer_release_cb: Option<MemoryDestroyCallback>,
159 buffer_release_cb_context: *mut (),
160 ) -> Result<Image, Error> {
161 let mut handle: k4a_image_t = ptr::null_mut();
162 Error::from_k4a_result_t(unsafe {
163 (self.api.funcs.k4a_image_create_from_buffer)(
164 format.into(),
165 width_pixels,
166 height_pixels,
167 stride_bytes,
168 buffer,
169 buffer_size,
170 std::mem::transmute(buffer_release_cb),
171 buffer_release_cb_context as _,
172 &mut handle,
173 )
174 })
175 .to_result_fn(|| Image::from_handle(&self.api, handle))
176 }
177
178 pub fn image_create_from_buffer<T: FnOnce(*mut ())>(
180 &self,
181 format: ImageFormat,
182 width_pixels: i32,
183 height_pixels: i32,
184 stride_bytes: i32,
185 buffer: *mut u8,
186 buffer_size: usize,
187 buffer_release_cb: Box<T>,
188 ) -> Result<Image, Error> {
189 self.image_create_from_buffer_native(
190 format.into(),
191 width_pixels,
192 height_pixels,
193 stride_bytes,
194 buffer,
195 buffer_size,
196 Some(Self::buffer_release_callback::<T>),
197 Box::<T>::into_raw(buffer_release_cb) as _,
198 )
199 }
200
201 pub fn image_create_from_buffer_with_info<T: PreAllocatedBufferInfo + Drop>(
203 &self,
204 mut buffer_info: Box<T>,
205 ) -> Result<Image, Error> {
206 self.image_create_from_buffer(
207 buffer_info.format().into(),
208 buffer_info.width_pixels(),
209 buffer_info.height_pixels(),
210 buffer_info.stride_bytes(),
211 buffer_info.buffer(),
212 buffer_info.buffer_size(),
213 Box::new(move |_| {
214 let _ = buffer_info;
215 }),
216 )
217 }
218
219 pub fn transformation_create<'a>(&'a self, calibration: &'a Calibration) -> Transformation<'a> {
221 let handle =
222 unsafe { (self.api.funcs.k4a_transformation_create)(&calibration.calibration) };
223 Transformation::from_handle(&self, handle, calibration)
224 }
225
226 extern "C" fn debug_message_handler_func(
227 context: *mut ::std::os::raw::c_void,
228 level: azure_kinect_sys::k4a::k4a_log_level_t,
229 file: *const ::std::os::raw::c_char,
230 line: ::std::os::raw::c_int,
231 message: *const ::std::os::raw::c_char,
232 ) {
233 unsafe {
234 let f = std::mem::transmute::<_, &mut Box<DebugMessageHandler>>(context);
235 f(
236 LogLevel::from_primitive(level),
237 std::ffi::CStr::from_ptr(file).to_str().unwrap_or_default(),
238 line,
239 std::ffi::CStr::from_ptr(message)
240 .to_str()
241 .unwrap_or_default(),
242 );
243 }
244 }
245
246 extern "C" fn buffer_release_callback<T: FnOnce(*mut ())>(buffer: *mut (), context: *mut ()) {
247 unsafe {
248 let f = Box::<T>::from_raw(context as _);
249 f(buffer);
250 }
251 }
252}
253
254pub struct FactoryRecord {
255 core: Factory,
256 pub(crate) api_record: azure_kinect_sys::api::ApiRecord,
257}
258
259impl FactoryRecord {
260 pub fn new() -> Result<FactoryRecord, Error> {
261 FactoryRecord::with_api_record(azure_kinect_sys::api::ApiRecord::new()?)
262 }
263
264 pub fn with_library_directory(lib_dir: &str) -> Result<FactoryRecord, Error> {
265 FactoryRecord::with_api_record(azure_kinect_sys::api::ApiRecord::with_library_directory(
266 lib_dir,
267 )?)
268 }
269
270 fn with_api_record(
271 api_record: azure_kinect_sys::api::ApiRecord,
272 ) -> Result<FactoryRecord, Error> {
273 Ok(FactoryRecord {
274 core: Factory::with_get_module()?,
275 api_record,
276 })
277 }
278
279 pub fn set_debug_message_handler(
281 mut self,
282 debug_message_handler: Box<DebugMessageHandler>,
283 min_level: LogLevel,
284 ) -> Self {
285 self.core
286 .set_debug_message_handler_internal(debug_message_handler, min_level);
287 self
288 }
289
290 pub fn reset_debug_message_handler(mut self) -> Self {
292 self.core.reset_debug_message_handler_internal();
293 self
294 }
295
296 pub fn core(&self) -> &Factory {
297 &self.core
298 }
299
300 pub fn playback_open(&self, path: &str) -> Result<Playback, Error> {
302 let mut handle: azure_kinect_sys::k4arecord::k4a_playback_t = ptr::null_mut();
303 let path = CString::new(path).unwrap_or_default();
304 Error::from_k4a_result_t(unsafe {
305 (self.api_record.funcs.k4a_playback_open)(path.as_ptr(), &mut handle)
306 })
307 .to_result_fn(|| Playback::from_handle(&self, handle))
308 }
309
310 pub fn record_create(
312 &self,
313 path: &str,
314 device: &Device,
315 device_configuration: &DeviceConfiguration,
316 ) -> Result<Record, Error> {
317 let mut handle: azure_kinect_sys::k4arecord::k4a_record_t = ptr::null_mut();
318 let path = CString::new(path).unwrap_or_default();
319 Error::from_k4a_result_t(unsafe {
320 (self.api_record.funcs.k4a_record_create)(
321 path.as_ptr(),
322 device.handle as _,
323 *device_configuration.for_k4arecord(),
324 &mut handle,
325 )
326 })
327 .to_result_fn(|| Record::from_handle(&self.api_record, handle))
328 }
329}
330
331#[cfg(test)]
332mod tests {
333 use crate::factory::PreAllocatedBufferInfo;
334 use crate::*;
335
336 #[test]
337 fn test() -> std::result::Result<(), Box<dyn std::error::Error>> {
338 let manager = Factory::with_library_directory(
339 std::env::current_dir()?.to_str().ok_or(Error::Failed)?,
340 );
341 assert!(manager.is_ok());
342 let manager2 = manager.unwrap();
343 let c = unsafe { (manager2.api.funcs.k4a_device_get_installed_count)() };
344 println!("device count = {}", c);
345 Ok(())
346 }
347
348 #[test]
349 fn test_image_create_from_buffer() -> std::result::Result<(), Box<dyn std::error::Error>> {
350 let factory = Factory::with_library_directory(
351 std::env::current_dir()?.to_str().ok_or(Error::Failed)?,
352 );
353 assert!(factory.is_ok());
354
355 let mut mem = Vec::<u8>::with_capacity(256 * 4 * 256);
356 unsafe {
357 mem.set_len(mem.capacity());
358 }
359
360 let factory = factory.unwrap();
361 let _ = factory.image_create_from_buffer(
362 ImageFormat::BGRA32,
363 255,
364 256,
365 256 * 4,
366 &mut mem[0] as _,
367 mem.len(),
368 Box::new(|x| {
369 assert_eq!(x as *const u8, &mem[0] as *const u8);
370 }),
371 )?;
372
373 Ok(())
374 }
375
376 pub struct BufferInfo {
377 mem: Vec<u8>,
378 }
379
380 impl BufferInfo {
381 pub fn new() -> BufferInfo {
382 let mut mem = Vec::<u8>::with_capacity(256 * 4 * 256);
383 unsafe {
384 mem.set_len(mem.capacity());
385 }
386
387 BufferInfo { mem }
388 }
389 }
390
391 impl PreAllocatedBufferInfo for BufferInfo {
392 fn format(&self) -> ImageFormat {
393 ImageFormat::BGRA32
394 }
395
396 fn width_pixels(&self) -> i32 {
397 256
398 }
399
400 fn height_pixels(&self) -> i32 {
401 256
402 }
403
404 fn stride_bytes(&self) -> i32 {
405 256 * 4
406 }
407
408 fn buffer(&mut self) -> *mut u8 {
409 &mut self.mem[0]
410 }
411
412 fn buffer_size(&self) -> usize {
413 self.mem.len()
414 }
415 }
416
417 impl Drop for BufferInfo {
418 fn drop(&mut self) {
419 println!("drop BufferInfo");
420 }
421 }
422
423 #[test]
424 fn test_image_create_from_buffer_with_info(
425 ) -> std::result::Result<(), Box<dyn std::error::Error>> {
426 let factory = Factory::with_library_directory(
427 std::env::current_dir()?.to_str().ok_or(Error::Failed)?,
428 );
429 assert!(factory.is_ok());
430
431 let factory = factory.unwrap();
432 let buffer_info = Box::new(BufferInfo::new());
433 let _ = factory.image_create_from_buffer_with_info(buffer_info)?;
434
435 Ok(())
436 }
437}