use orbbec_sdk_sys::*;
use std::ffi::CStr;
use std::io::{self, Write};
use std::process;
use std::ptr;
unsafe fn from_c_str(ptr: *const std::os::raw::c_char) -> String {
if ptr.is_null() {
return String::from("(null)");
}
unsafe { CStr::from_ptr(ptr) }
.to_string_lossy()
.into_owned()
}
unsafe fn check_ob_error(err: *mut *mut ob_error) {
unsafe {
if !(*err).is_null() {
let msg_ptr = ob_error_get_message(*err);
let error_message = from_c_str(msg_ptr);
eprintln!("Error: {}", error_message);
ob_delete_error(*err);
process::exit(-1);
}
*err = ptr::null_mut();
}
}
fn select_index(prompt: &str, min_value: u32, max_value: u32) -> Option<u32> {
print!("\n{} (Input device index or 'q' to exit program): ", prompt);
io::stdout().flush().unwrap();
loop {
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap();
let input = input.trim();
if input.eq_ignore_ascii_case("q") {
return None;
}
match input.parse::<u32>() {
Ok(num) if num >= min_value && num <= max_value => {
return Some(num);
}
_ => {
print!(
"Invalid input, please input a number between {} and {} or 'q' to exit program: ",
min_value, max_value
);
io::stdout().flush().unwrap();
}
}
}
}
unsafe fn enumerate_stream_info(sensor: *mut ob_sensor) {
unsafe {
let mut error: *mut ob_error = ptr::null_mut();
let sensor_type = ob_sensor_get_type(sensor, &mut error);
check_ob_error(&mut error);
let stream_profile_list = ob_sensor_get_stream_profile_list(sensor, &mut error);
check_ob_error(&mut error);
let stream_profile_count =
ob_stream_profile_list_get_count(stream_profile_list, &mut error);
check_ob_error(&mut error);
println!("Available stream profiles: ");
for index in 0..stream_profile_count {
let stream_profile =
ob_stream_profile_list_get_profile(stream_profile_list, index as i32, &mut error);
check_ob_error(&mut error);
if sensor_type == OBSensorType_OB_SENSOR_IR
|| sensor_type == OBSensorType_OB_SENSOR_COLOR
|| sensor_type == OBSensorType_OB_SENSOR_DEPTH
|| sensor_type == OBSensorType_OB_SENSOR_IR_LEFT
|| sensor_type == OBSensorType_OB_SENSOR_IR_RIGHT
{
let stream_type = ob_stream_profile_get_type(stream_profile, &mut error);
check_ob_error(&mut error);
let stream_type_str = from_c_str(ob_stream_type_to_string(stream_type));
let stream_format = ob_stream_profile_get_format(stream_profile, &mut error);
check_ob_error(&mut error);
let stream_format_str = from_c_str(ob_format_to_string(stream_format));
let stream_width = ob_video_stream_profile_get_width(stream_profile, &mut error);
check_ob_error(&mut error);
let stream_height = ob_video_stream_profile_get_height(stream_profile, &mut error);
check_ob_error(&mut error);
let stream_fps = ob_video_stream_profile_get_fps(stream_profile, &mut error);
check_ob_error(&mut error);
println!(
" {} - type: {:>4}, format: {:>4}, width: {:>4}, height: {:>4}, fps: {:>4}",
index,
stream_type_str,
stream_format_str,
stream_width,
stream_height,
stream_fps
);
} else if sensor_type == OBSensorType_OB_SENSOR_ACCEL {
let stream_format = ob_stream_profile_get_format(stream_profile, &mut error);
check_ob_error(&mut error);
let acc_fps = ob_accel_stream_profile_get_sample_rate(stream_profile, &mut error);
check_ob_error(&mut error);
println!(
" {} - type: {}, fps: {}",
index,
from_c_str(ob_format_to_string(stream_format)),
from_c_str(ob_imu_rate_type_to_string(acc_fps))
);
} else if sensor_type == OBSensorType_OB_SENSOR_GYRO {
let stream_format = ob_stream_profile_get_format(stream_profile, &mut error);
check_ob_error(&mut error);
let gyro_fps = ob_gyro_stream_profile_get_sample_rate(stream_profile, &mut error);
check_ob_error(&mut error);
println!(
" {} - type: {}, fps: {}",
index,
from_c_str(ob_format_to_string(stream_format)),
from_c_str(ob_imu_rate_type_to_string(gyro_fps))
);
}
ob_delete_stream_profile(stream_profile, &mut error);
check_ob_error(&mut error);
}
ob_delete_stream_profile_list(stream_profile_list, &mut error);
check_ob_error(&mut error);
}
}
unsafe fn enumerate_sensor_info(device: *mut ob_device) {
unsafe {
let mut error: *mut ob_error = ptr::null_mut();
let sensor_list = ob_device_get_sensor_list(device, &mut error);
check_ob_error(&mut error);
let sensor_count = ob_sensor_list_get_count(sensor_list, &mut error);
check_ob_error(&mut error);
if sensor_count == 0 {
println!("No sensor found for the selected device!");
ob_delete_sensor_list(sensor_list, &mut error);
check_ob_error(&mut error);
return;
}
loop {
println!("Available sensors: ");
for i in 0..sensor_count {
let sensor = ob_sensor_list_get_sensor(sensor_list, i, &mut error);
check_ob_error(&mut error);
let sensor_type = ob_sensor_get_type(sensor, &mut error);
check_ob_error(&mut error);
let sensor_name = from_c_str(ob_sensor_type_to_string(sensor_type));
println!(" {} - sensor name: {}", i, sensor_name);
ob_delete_sensor(sensor, &mut error);
check_ob_error(&mut error);
}
if let Some(index) = select_index(
"Select a sensor to enumerate its stream profiles",
0,
sensor_count - 1,
) {
let sensor = ob_sensor_list_get_sensor(sensor_list, index as u32, &mut error);
check_ob_error(&mut error);
enumerate_stream_info(sensor);
ob_delete_sensor(sensor, &mut error);
check_ob_error(&mut error);
} else {
break;
}
}
ob_delete_sensor_list(sensor_list, &mut error);
check_ob_error(&mut error);
}
}
unsafe fn print_device_info(device: *mut ob_device, index: u32) {
unsafe {
let mut error: *mut ob_error = ptr::null_mut();
let dev_inf = ob_device_get_device_info(device, &mut error);
check_ob_error(&mut error);
let dev_name = from_c_str(ob_device_info_get_name(dev_inf, &mut error));
check_ob_error(&mut error);
let dev_pid = ob_device_info_get_pid(dev_inf, &mut error);
check_ob_error(&mut error);
let dev_sn = from_c_str(ob_device_info_get_serial_number(dev_inf, &mut error));
check_ob_error(&mut error);
let conn_type = from_c_str(ob_device_info_get_connection_type(dev_inf, &mut error));
check_ob_error(&mut error);
println!(
" {} - device name: {}, device pid: {:#06x}, device sn: {}, connection type: {}",
index, dev_name, dev_pid, dev_sn, conn_type
);
ob_delete_device_info(dev_inf, &mut error);
check_ob_error(&mut error);
}
}
fn main() {
unsafe {
let mut error: *mut ob_error = ptr::null_mut();
let major = ob_get_major_version();
let minor = ob_get_minor_version();
let patch = ob_get_patch_version();
println!("Orbbec SDK version: {}.{}.{}", major, minor, patch);
let ctx = ob_create_context(&mut error);
check_ob_error(&mut error);
let dev_list = ob_query_device_list(ctx, &mut error);
check_ob_error(&mut error);
let dev_count = ob_device_list_get_count(dev_list, &mut error);
check_ob_error(&mut error);
if dev_count == 0 {
println!("No device found! Please connect a supported device and retry this program.");
ob_delete_device_list(dev_list, &mut error);
check_ob_error(&mut error);
ob_delete_context(ctx, &mut error);
check_ob_error(&mut error);
println!("\nPress Enter to exit.");
let _ = io::stdin().read_line(&mut String::new());
return;
}
loop {
println!("Connected devices: ");
for index in 0..dev_count {
let dev = ob_device_list_get_device(dev_list, index, &mut error);
check_ob_error(&mut error);
print_device_info(dev, index);
ob_delete_device(dev, &mut error);
check_ob_error(&mut error);
}
let device_index =
select_index("Select a device to enumerate its sensors", 0, dev_count - 1);
if let Some(device_index) = device_index {
let device = ob_device_list_get_device(dev_list, device_index as u32, &mut error);
check_ob_error(&mut error);
enumerate_sensor_info(device);
ob_delete_device(device, &mut error);
check_ob_error(&mut error);
} else {
break;
}
}
ob_delete_device_list(dev_list, &mut error);
check_ob_error(&mut error);
ob_delete_context(ctx, &mut error);
check_ob_error(&mut error);
println!("\nProgram ended successfully. Press Enter to exit.");
let _ = io::stdin().read_line(&mut String::new());
}
}