diff --git a/.gitignore b/.gitignore index 1851f67a5..a273f1e84 100644 --- a/.gitignore +++ b/.gitignore @@ -304,3 +304,4 @@ __pycache__/ /.settings *.project *.cproject +/doxygen/Doxyfile.in.modified diff --git a/docs/refactor.md b/docs/refactor.md new file mode 100644 index 000000000..ea593047f --- /dev/null +++ b/docs/refactor.md @@ -0,0 +1,299 @@ +# Changes to the Kinect SDK API surface + + The following changes have been made to the Kinect SDK API surface (k4a.h, k4atypes.h) so camera manufacturers may provide + their own implementation of the Kinect SDK that will work with their cameras. The key change is switching from enums that identify + color resolution, depth mode and framerate, to structs that contain information about color mode, depth mode and fps mode. All + devices must support a depth sensor, but color, microphone and IMU sensors are not required. + +## Changes to k4atypes.h + + 1. The following enums have been changed: + + k4a_result_t Added K4A_RESULT_UNSUPPORTED Returned when function requires unsupported sensor. + k4a_buffer_result_t Added K4A_BUFFER_RESULT_UNSUPPORTED Returned when buffer function requires unsupported sensor. + k4a_wait_result_t Added K4A_WAIT_RESULT_UNSUPPORTED Returned when wait function requires unsupported sensor. + + + 2. The following enums have been moved: + + k4a_color_resolution_t Moved to include/k4ainternal/modes.h Is no longer a part of the API surface. + k4a_depth_mode_t Moved to include/k4ainternal/modes.h Is no longer a part of the API surface. + k4a_fps_t Moved to include/k4ainternal/modes.h Is no longer a part of the API surface. + + + 3. The following enum has been added: + + k4a_device_capabilities_t Indicates which sensors(color, depth, IMU, microphone) are supported by a device. + + + 4. The following structs have been added: + + k4a_device_info_t Contains the size and version of the struct as well as vendor id, device id and + capabilities(color, depth, IMU, microphone). + + k4a_color_mode_info_t Contains the size and version of the struct as well as mode id, width, height, native format, + horizontal/vertical fov and min/max fps. + + k4a_depth_mode_info_t Contains the size and version of the struct as well as mode id, whether to capture passive IR only, + width, height, native format, horizontal/vertical fov, min/max fps and min/max range. + + k4a_fps_mode_info_t Contains the size and version of the struct as well as mode id and fps. + + + 5. The following structs have been changed: + + k4a_calibration_t k4a_color_resolution_t color_resolution is now uint32_t color_mode_id. + k4a_depth_mode_t depth_mode is now uint32_t depth_mode_id. + + k4a_device_configuration_t k4a_color_resolution_t color_resolution is now uint32_t color_mode_id. + k4a_depth_mode_t depth_mode is now uint32_t depth_mode_id. + k4a_fps_t camera_fps is now uint32_t fps_mode_id. + + + 4. The following #define have been added: + + K4A_INIT_STRUCT(T, S) Used to safely init the new device info and color/depth/fps mode info structs. + K4A_ABI_VERSION Indicates the ABI version that is used in the new device info and color/depth/fps mode info structs. + + + 5. The following static const has been changed: + + K4A_DEVICE_CONFIG_INIT_DISABLE_ALL The fps_mode_id is set to 0, which means off. The color_mode_id and depth_mode_id is + also set to 0, which means they are also both off. To start a device, either the + color_mode_id or the depth_mode_id must not be set to 0 and the fps_mode_id must not be + set to 0. To set the color_mode_id, depth_mode_id and fps_mode_id, use the new device get mode and + modes count functions added to k4a.h. + + +### Changes to k4a.h + + 1. The following functions have been added: + + k4a_result_t k4a_device_get_info(k4a_device_t device_handle, k4a_device_info_t *device_info) + + k4a_result_t k4a_device_get_color_mode_count(k4a_device_t device_handle, uint32_t *mode_count) + k4a_result_t k4a_device_get_depth_mode_count(k4a_device_t device_handle, uint32_t *mode_count) + k4a_result_t k4a_device_get_fps_mode_count(k4a_device_t device_handle, uint32_t *mode_count) + + k4a_result_t k4a_device_get_color_mode(k4a_device_t device_handle, uint32_t mode_index, k4a_color_mode_info_t *mode_info) + k4a_result_t k4a_device_get_depth_mode(k4a_device_t device_handle, uint32_t mode_index, k4a_depth_mode_info_t *mode_info) + k4a_result_t k4a_device_get_fps_mode(k4a_device_t device_handle, uint32_t mode_index, k4a_fps_mode_info_t *mode_info) + + 2. The following functions have been changed: + + k4a_result_t k4a_device_get_calibration(k4a_device_t device_handle, + const k4a_depth_mode_t depth_mode is now const uint32_t depth_mode_id, + const k4a_color_resolution_t color_resolution is now const uint32_t color_mode_id, + k4a_calibration_t *calibration) + + k4a_result_t k4a_calibration_get_from_raw(char *raw_calibration, + size_t raw_calibration_size, + const k4a_depth_mode_t depth_mode is now const uint32_t depth_mode_id, + const k4a_color_resolution_t color_resolution is now const uint32_t color_mode_id, + k4a_calibration_t *calibration) + +#### Using the new get device info and get color/depth/fps mode info functions added to k4a.h. + + 1. Using k4a_device_get_info: + + int main(int argc, char **argv) + { + k4a_device_t device = NULL; + if (K4A_RESULT_SUCCEEDED != k4a_device_open(0, &device)) + { + printf("0: Failed to open device"); + exit(-1); + } + + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + + if (!k4a_device_get_info(device, &device_info) == K4A_RESULT_SUCCEEDED) + { + printf("Failed to get device info\n"); + exit(-1); + } + + bool hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + bool hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + + if(hasDepthDevice) + { + printf("The device has a depth sensor.\n"); + } + + if(hasColorDevice) + { + printf("The device has a color sensor.\n"); + } + } + + + 2. Using k4a_device_get_color_mode with k4a_device_get_color_mode_count: + + int math_get_common_factor(int width, int height) + { + return (height == 0) ? width : math_get_common_factor(height, width % height); + } + + int main(int argc, char **argv) + { + k4a_device_t device = NULL; + if (K4A_RESULT_SUCCEEDED != k4a_device_open(0, &device)) + { + printf("0: Failed to open device"); + exit(-1); + } + + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + + if (!k4a_device_get_info(device, &device_info) == K4A_RESULT_SUCCEEDED) + { + printf("Failed to get device info\n"); + exit(-1); + } + + bool hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + + if(!hasColorDevice) + { + printf("The device does not have a color sensor.\n"); + exit(-1); + } + + uint32_t color_mode_count = 0; + + if (!K4A_SUCCEEDED(k4a_device_get_color_mode_count(device, &color_mode_count))) + { + printf("Failed to get color mode count.\n"); + exit(-1); + } + + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + + for (uint32_t c = 0; c < color_mode_count; c++) + { + if (k4a_device_get_color_mode(device, c, &color_mode_info) == K4A_RESULT_SUCCEEDED) + { + int width = static_cast(color_mode_info.width); + int height = static_cast(color_mode_info.height); + int common_factor = math_get_common_factor(width, height); + + printf("\t"); + printf("[%u] = ", c); + printf("\t"); + if(height < 1000) + { + printf(" "); + } + printf("%up", height); + printf("\t"); + printf("%i:", width/common_factor); + printf("%i", height/common_factor); + printf("\n"); + } + } + } + + + 3. Using k4a_device_get_depth_mode with k4a_device_get_depth_mode_count: + + int main(int argc, char **argv) + { + k4a_device_t device = NULL; + if (K4A_RESULT_SUCCEEDED != k4a_device_open(0, &device)) + { + printf("0: Failed to open device"); + exit(-1); + } + + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + + if (!k4a_device_get_info(device, &device_info) == K4A_RESULT_SUCCEEDED) + { + printf("Failed to get device info\n"); + exit(-1); + } + + bool hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + + if(!hasDepthDevice) + { + printf("The device does not have a depth sensor.\n"); + exit(-1); + } + + uint32_t depth_mode_count = 0; + + if (!K4A_SUCCEEDED(k4a_device_get_depth_mode_count(device, &depth_mode_count))) + { + printf("Failed to get depth mode count.\n"); + exit(-1); + } + + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + + for (uint32_t d = 0; d < depth_mode_count; d++) + { + if (k4a_device_get_depth_mode(device, d, &depth_mode_info) == K4A_RESULT_SUCCEEDED) + { + int width = static_cast(depth_mode_info.width); + int height = static_cast(depth_mode_info.height); + float fov = depth_mode_info.horizontal_fov; + + printf("\t"); + printf("[%u] = ", d); + printf("\t"); + if (depth_mode_info.passive_ir_only) + { + printf("Passive IR"); + printf("\n"); + } + else + { + if (width < 1000) + { + printf(" "); + } + printf("%ix", width); + if (height < 1000) + { + printf(" "); + } + printf("%i, ", height); + printf("%f Deg", fov); + } + } + } + } + + + 4. Using k4a_device_get_fps_mode with k4a_device_get_fps_mode_count: + + int main(int argc, char **argv) + { + k4a_device_t device = NULL; + if (K4A_RESULT_SUCCEEDED != k4a_device_open(0, &device)) + { + printf("0: Failed to open device"); + exit(-1); + } + + uint32_t fps_mode_count = 0; + + if (!K4A_SUCCEEDED(k4a_device_get_fps_mode_count(device, &fps_mode_count))) + { + printf("Failed to get fps mode count.\n"); + exit(-1); + } + + k4a_fps_mode_info_t fps_mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + + for (uint32_t f = 0; f < fps_mode_count; f++) + { + if (k4a_device_get_fps_mode(device, f, &fps_mode_info) == K4A_RESULT_SUCCEEDED) + { + printf("\t%up\n", fps_mode_info.fps); + } + } + } + \ No newline at end of file diff --git a/doxygen/k4a.tagfile b/doxygen/k4a.tagfile new file mode 100644 index 000000000..1a9d3dcd6 --- /dev/null +++ b/doxygen/k4a.tagfile @@ -0,0 +1,3103 @@ + + + + k4a_calibration_intrinsic_parameters_t::_param + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + + float + cx + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + acdaf3c374353bc3347551b379ee4f83c + + + + float + cy + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + a033e90a9b862dddffc0e4e5f6d1f02b3 + + + + float + fx + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + a8069e7da60119d09b9c7a37cf9f65d6a + + + + float + fy + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + a88fcdda1ec2d887b03be4011d8442c6a + + + + float + k1 + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + a37e8c8a30e851f28a008c415504b92ed + + + + float + k2 + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + af543f06407c571b7329c3e35653db4aa + + + + float + k3 + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + a7ec939246110c28e7bfb2f0b7004a208 + + + + float + k4 + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + a30f9b667e6661b737f98afa38ac47fd2 + + + + float + k5 + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + ac5d1ce28acdba0f35cd3bbcc6a174f41 + + + + float + k6 + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + a3b36721c7c58ec9f3228809c2a92b263 + + + + float + codx + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + a11b533b26b38b6cfd0e3b69c9aeade55 + + + + float + cody + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + a0e3edc5180a9323a5f7d28c7f3cd7f65 + + + + float + p2 + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + a80718603ed70e762dfe9aa01eccbcc6b + + + + float + p1 + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + a0967d84ba1f4ce82b47bfa2fa13a8360 + + + + float + metric_radius + structk4a__calibration__intrinsic__parameters__t_1_1__param.html + a91b39ee152b891ae79641ad8e6137adb + + + + + k4a_float2_t::_xy + structk4a__float2__t_1_1__xy.html + + float + x + structk4a__float2__t_1_1__xy.html + a045e7ea3933e7c0b2c21b3b362f9e9b0 + + + + float + y + structk4a__float2__t_1_1__xy.html + a741293a6bb2362c9aa506ca793599707 + + + + + k4a_float3_t::_xyz + structk4a__float3__t_1_1__xyz.html + + float + x + structk4a__float3__t_1_1__xyz.html + a21c7d10afe5ba22922607083c9fc6625 + + + + float + y + structk4a__float3__t_1_1__xyz.html + a8d0daad684174757630f64ce84f142b4 + + + + float + z + structk4a__float3__t_1_1__xyz.html + ac48d96dc75aa3a2a59386fcfd08474de + + + + + k4a::calibration + structk4a_1_1calibration.html + k4a_calibration_t + + k4a_float3_t + convert_3d_to_3d + structk4a_1_1calibration_a44fbcadffdbef6fa2be0e076afcfb470.html + a44fbcadffdbef6fa2be0e076afcfb470 + (const k4a_float3_t &source_point3d, k4a_calibration_type_t source_camera, k4a_calibration_type_t target_camera) const + + + bool + convert_2d_to_3d + structk4a_1_1calibration_a84577df64d47642d0b8f1fee11b21a96.html + a84577df64d47642d0b8f1fee11b21a96 + (const k4a_float2_t &source_point2d, float source_depth, k4a_calibration_type_t source_camera, k4a_calibration_type_t target_camera, k4a_float3_t *target_point3d) const + + + bool + convert_3d_to_2d + structk4a_1_1calibration_a74a6fef25540e9cdf18ed06ff1cfdc2e.html + a74a6fef25540e9cdf18ed06ff1cfdc2e + (const k4a_float3_t &source_point3d, k4a_calibration_type_t source_camera, k4a_calibration_type_t target_camera, k4a_float2_t *target_point2d) const + + + bool + convert_2d_to_2d + structk4a_1_1calibration_afd343e2419c2a3437559aa90fcf2a4f0.html + afd343e2419c2a3437559aa90fcf2a4f0 + (const k4a_float2_t &source_point2d, float source_depth, k4a_calibration_type_t source_camera, k4a_calibration_type_t target_camera, k4a_float2_t *target_point2d) const + + + bool + convert_color_2d_to_depth_2d + structk4a_1_1calibration_ab72a37ed466a41d68c522678fa57ff4f.html + ab72a37ed466a41d68c522678fa57ff4f + (const k4a_float2_t &source_point2d, const image &depth_image, k4a_float2_t *target_point2d) const + + + static calibration + get_from_raw + structk4a_1_1calibration_afa00ccc1e2fa237c17220385c49ed7be.html + afa00ccc1e2fa237c17220385c49ed7be + (char *raw_calibration, size_t raw_calibration_size, uint32_t depth_mode_id, uint32_t color_mode_id) + + + static calibration + get_from_raw + structk4a_1_1calibration_a16c8644a560372d08819f14cef2e16a3.html + a16c8644a560372d08819f14cef2e16a3 + (uint8_t *raw_calibration, size_t raw_calibration_size, uint32_t depth_mode_id, uint32_t color_mode_id) + + + static calibration + get_from_raw + structk4a_1_1calibration_a664b3159be937252240e7d5baa638837.html + a664b3159be937252240e7d5baa638837 + (std::vector< uint8_t > &raw_calibration, uint32_t depth_mode_id, uint32_t color_mode_id) + + + + k4a::capture + classk4a_1_1capture.html + + + capture + classk4a_1_1capture_a713dcb3e3539e8d08f30be67b23b6ea8.html + a713dcb3e3539e8d08f30be67b23b6ea8 + (k4a_capture_t handle=nullptr) noexcept + + + + capture + classk4a_1_1capture.html + a6da3c95c4331e4c25a8379f8e1feb97e + (const capture &other) noexcept + + + + capture + classk4a_1_1capture.html + aa06ed4ed8711325935e906a0414c1009 + (capture &&other) noexcept + + + capture & + operator= + classk4a_1_1capture.html + acda82ae99269039a2671ec29c7f7fa55 + (const capture &other) noexcept + + + capture & + operator= + classk4a_1_1capture.html + ad297433d44328b7b2a60a90bd2f80268 + (capture &&other) noexcept + + + capture & + operator= + classk4a_1_1capture.html + a766690e9c9f045b552892971903bf578 + (std::nullptr_t) noexcept + + + bool + operator== + classk4a_1_1capture.html + aa25047bfa3d41a3e350b93dbead41b58 + (const capture &other) const noexcept + + + bool + operator== + classk4a_1_1capture.html + a650a8677ba836694aac75a22683f3d9d + (std::nullptr_t) const noexcept + + + bool + operator!= + classk4a_1_1capture.html + a34e5cc8621b5c782f79e8ad7a6d667b1 + (const capture &other) const noexcept + + + bool + operator!= + classk4a_1_1capture.html + a1a5b1eac81bfd22a978f5c2ccbfc38a4 + (std::nullptr_t) const noexcept + + + + operator bool + classk4a_1_1capture.html + a9b195bd62ed46c3138b88942ca8b6447 + () const noexcept + + + bool + is_valid + classk4a_1_1capture.html + ab35642daed5d6d74f44b69806665573e + () const noexcept + + + k4a_capture_t + handle + classk4a_1_1capture_a5e5a361b96542cc0206524b03ddaf95d.html + a5e5a361b96542cc0206524b03ddaf95d + () const noexcept + + + void + reset + classk4a_1_1capture.html + aa922aa6bae17310b4d73464a2486be92 + () noexcept + + + image + get_color_image + classk4a_1_1capture_a885c87e3fdd40c567350bfece9c6969c.html + a885c87e3fdd40c567350bfece9c6969c + () const noexcept + + + image + get_depth_image + classk4a_1_1capture_a36de50df5f36391e7ed606c0cb5607a2.html + a36de50df5f36391e7ed606c0cb5607a2 + () const noexcept + + + image + get_ir_image + classk4a_1_1capture_aa19b3af5fefbb2dc4dabd4a31c94d6fc.html + aa19b3af5fefbb2dc4dabd4a31c94d6fc + () const noexcept + + + void + set_color_image + classk4a_1_1capture_ac97e202cb82abcbd95cf584045233d64.html + ac97e202cb82abcbd95cf584045233d64 + (const image &color_image) noexcept + + + void + set_depth_image + classk4a_1_1capture_a6136c6d7369ebccbee2a65ef4d800f9e.html + a6136c6d7369ebccbee2a65ef4d800f9e + (const image &depth_image) noexcept + + + void + set_ir_image + classk4a_1_1capture_aba19a0d0ff58f841223832422415c790.html + aba19a0d0ff58f841223832422415c790 + (const image &ir_image) noexcept + + + void + set_temperature_c + classk4a_1_1capture_a462b292bdb1f7a525e461bc8a7d94510.html + a462b292bdb1f7a525e461bc8a7d94510 + (float temperature_c) noexcept + + + float + get_temperature_c + classk4a_1_1capture_a48bbcd6a4e69cf1c5574162d2d0f0d33.html + a48bbcd6a4e69cf1c5574162d2d0f0d33 + () const noexcept + + + static capture + create + classk4a_1_1capture_a92b8f943cef424490692fc6e76bfe3ec.html + a92b8f943cef424490692fc6e76bfe3ec + () + + + + k4a::device + classk4a_1_1device.html + + + device + classk4a_1_1device_a060093e3ad034aaeb05ea9dc69958a58.html + a060093e3ad034aaeb05ea9dc69958a58 + (k4a_device_t handle=nullptr) noexcept + + + + device + classk4a_1_1device.html + a7543679a25b5761293869d1856d219aa + (device &&dev) noexcept + + + device & + operator= + classk4a_1_1device.html + aed3433182911420149e64721764df383 + (device &&dev) noexcept + + + + operator bool + classk4a_1_1device.html + a015a45ab5362697ef77ec4be2f387e31 + () const noexcept + + + bool + is_valid + classk4a_1_1device.html + aece422ef7b2e662ceccebb4a990ed613 + () const noexcept + + + k4a_device_t + handle + classk4a_1_1device_a67c4cbd2cf6113228b5dfed56fef987b.html + a67c4cbd2cf6113228b5dfed56fef987b + () const noexcept + + + void + close + classk4a_1_1device_a1060f1cee688cbb125d112259b7b0739.html + a1060f1cee688cbb125d112259b7b0739 + () noexcept + + + bool + get_capture + classk4a_1_1device_a591d2f9a0a1a25eaf7f2fc9cfc5b7c7e.html + a591d2f9a0a1a25eaf7f2fc9cfc5b7c7e + (capture *cap, std::chrono::milliseconds timeout) + + + bool + get_capture + classk4a_1_1device_a14c9e31b77fa4fc8e55054276e580cf8.html + a14c9e31b77fa4fc8e55054276e580cf8 + (capture *cap) + + + bool + get_imu_sample + classk4a_1_1device_a59acd51c256b17441c6a2a4e335bc982.html + a59acd51c256b17441c6a2a4e335bc982 + (k4a_imu_sample_t *imu_sample, std::chrono::milliseconds timeout) + + + bool + get_imu_sample + classk4a_1_1device_a5957d37c22bca085fe4a8da3d7444999.html + a5957d37c22bca085fe4a8da3d7444999 + (k4a_imu_sample_t *imu_sample) + + + void + start_cameras + classk4a_1_1device_a52c94d759b88a19421f9fce558c44c7b.html + a52c94d759b88a19421f9fce558c44c7b + (const k4a_device_configuration_t *configuration) + + + void + stop_cameras + classk4a_1_1device_a54390cae2a759ad9e36f47a30c223fd5.html + a54390cae2a759ad9e36f47a30c223fd5 + () noexcept + + + void + start_imu + classk4a_1_1device_abc8bb828de9b48b10fefa5ca6b8482c7.html + abc8bb828de9b48b10fefa5ca6b8482c7 + () + + + void + stop_imu + classk4a_1_1device_a18f23e91f38643520228d784435938e5.html + a18f23e91f38643520228d784435938e5 + () noexcept + + + std::string + get_serialnum + classk4a_1_1device_a452df45f6aa4ce3d8ae442bc1f2e7e7d.html + a452df45f6aa4ce3d8ae442bc1f2e7e7d + () const + + + void + get_color_control + classk4a_1_1device_a4a0757363fc3e7937908f90b30f3666d.html + a4a0757363fc3e7937908f90b30f3666d + (k4a_color_control_command_t command, k4a_color_control_mode_t *mode, int32_t *value) const + + + void + set_color_control + classk4a_1_1device_af257d6c8181222823c7cfbdf57e032d7.html + af257d6c8181222823c7cfbdf57e032d7 + (k4a_color_control_command_t command, k4a_color_control_mode_t mode, int32_t value) + + + std::vector< uint8_t > + get_raw_calibration + classk4a_1_1device_a9d2c806f63893cb9486bd42bb634747f.html + a9d2c806f63893cb9486bd42bb634747f + () const + + + calibration + get_calibration + classk4a_1_1device_a9d98c69e3202a347001630904d24f824.html + a9d98c69e3202a347001630904d24f824 + (uint32_t depth_mode_id, uint32_t color_mode_id) const + + + bool + is_sync_in_connected + classk4a_1_1device_acaba6c5d8a28965882a4703e8806810a.html + acaba6c5d8a28965882a4703e8806810a + () const + + + bool + is_sync_out_connected + classk4a_1_1device_aec0191ecf75549f650af7ac61d0afbef.html + aec0191ecf75549f650af7ac61d0afbef + () const + + + k4a_hardware_version_t + get_version + classk4a_1_1device_a56dd0f20dcc26c014cdd8b47145a523b.html + a56dd0f20dcc26c014cdd8b47145a523b + () const + + + k4a_device_info_t + get_info + classk4a_1_1device_a29e30ddb733c36c78b9cba1158a2f048.html + a29e30ddb733c36c78b9cba1158a2f048 + () + + + std::vector< k4a_color_mode_info_t > + get_color_modes + classk4a_1_1device.html + a5b5b320308f45e5a9f0a6c6187caf50c + () + + + k4a_color_mode_info_t + get_color_mode + classk4a_1_1device_a6c4fcd4d9a5157294fd9e353f415c839.html + a6c4fcd4d9a5157294fd9e353f415c839 + (int color_mode_id) + + + std::vector< k4a_depth_mode_info_t > + get_depth_modes + classk4a_1_1device.html + a5e2efe03105ccd328fb3469d3330fc96 + () + + + k4a_depth_mode_info_t + get_depth_mode + classk4a_1_1device_ab820baaa31768c2afb312a5da7d1b241.html + ab820baaa31768c2afb312a5da7d1b241 + (int depth_mode_id) + + + std::vector< k4a_fps_mode_info_t > + get_fps_modes + classk4a_1_1device.html + a99627d618809010f9804577bbc57810a + () + + + k4a_fps_mode_info_t + get_fps_mode + classk4a_1_1device_a1b7bb6d6a9c9a57872051a043784b92f.html + a1b7bb6d6a9c9a57872051a043784b92f + (int fps_mode_id) + + + static device + open + classk4a_1_1device_a0094acf44bc68ab3d48f0851619d3467.html + a0094acf44bc68ab3d48f0851619d3467 + (uint32_t index) + + + static uint32_t + get_installed_count + classk4a_1_1device_a8e55f0b0001b72db094aaf613eb48c15.html + a8e55f0b0001b72db094aaf613eb48c15 + () noexcept + + + + k4a::error + classk4a_1_1error.html + + + k4a::image + classk4a_1_1image.html + + + image + classk4a_1_1image_ac9f26e8ea2dc561d64de0cabe004967e.html + ac9f26e8ea2dc561d64de0cabe004967e + (k4a_image_t handle=nullptr) noexcept + + + + image + classk4a_1_1image.html + aff608c45cc2a141c71a448607741df34 + (const image &other) noexcept + + + + image + classk4a_1_1image.html + adb337f5ae0c5428a7d34876affdb5ae8 + (image &&other) noexcept + + + image & + operator= + classk4a_1_1image.html + a08a32ff87256a778ce77bfffb6568beb + (const image &other) noexcept + + + image & + operator= + classk4a_1_1image.html + a6a4670119bd9a2b91f243c343d312a90 + (image &&other) noexcept + + + image & + operator= + classk4a_1_1image.html + aa52fed26cdd34b9f63f3b219f7c1bc6d + (std::nullptr_t) noexcept + + + bool + operator== + classk4a_1_1image.html + afcc26100d131a15edb5f4f87501c37bc + (const image &other) const noexcept + + + bool + operator== + classk4a_1_1image.html + aac0490a29722a1377564cbcc7642c0b4 + (std::nullptr_t) const noexcept + + + bool + operator!= + classk4a_1_1image.html + aa000850be81fbda9b9bbfdde0283ec7a + (const image &other) const noexcept + + + bool + operator!= + classk4a_1_1image.html + a76be4cef7e6661f3940f9b9adcc16840 + (std::nullptr_t) const noexcept + + + + operator bool + classk4a_1_1image.html + a32b1ba1b4dc1f1190fa456250ee0e4a0 + () const noexcept + + + bool + is_valid + classk4a_1_1image.html + a94f398595ba9086533e9d6afe74b38b5 + () const noexcept + + + k4a_image_t + handle + classk4a_1_1image_a88a5e67e8dd75677502e2421b3ba7c2c.html + a88a5e67e8dd75677502e2421b3ba7c2c + () const noexcept + + + void + reset + classk4a_1_1image.html + a5654ce02204e255e11350c14cf1f4b89 + () noexcept + + + uint8_t * + get_buffer + classk4a_1_1image_af088c323209fecac22012e253dc3d9d1.html + af088c323209fecac22012e253dc3d9d1 + () noexcept + + + const uint8_t * + get_buffer + classk4a_1_1image_a6b68d771858ff5d1878f6f0c314a669e.html + a6b68d771858ff5d1878f6f0c314a669e + () const noexcept + + + size_t + get_size + classk4a_1_1image_a681ade955c81f42d967d41dcbaf065d4.html + a681ade955c81f42d967d41dcbaf065d4 + () const noexcept + + + k4a_image_format_t + get_format + classk4a_1_1image_aad5e858608f4109d7c3c8fa0f58cd6ac.html + aad5e858608f4109d7c3c8fa0f58cd6ac + () const noexcept + + + int + get_width_pixels + classk4a_1_1image_a2ed85b2247946a21251c790071612904.html + a2ed85b2247946a21251c790071612904 + () const noexcept + + + int + get_height_pixels + classk4a_1_1image_a806880f3fe29f7b4833813138d40c0fa.html + a806880f3fe29f7b4833813138d40c0fa + () const noexcept + + + int + get_stride_bytes + classk4a_1_1image_a5e22c7875e15ecf102cc4cf4accb27c2.html + a5e22c7875e15ecf102cc4cf4accb27c2 + () const noexcept + + + std::chrono::microseconds + get_device_timestamp + classk4a_1_1image_a2d45cb5d26b004d0f93be7b3c130aabe.html + a2d45cb5d26b004d0f93be7b3c130aabe + () const noexcept + + + std::chrono::nanoseconds + get_system_timestamp + classk4a_1_1image_aa691f71650646a9183352cae0c993e40.html + aa691f71650646a9183352cae0c993e40 + () const noexcept + + + std::chrono::microseconds + get_exposure + classk4a_1_1image_a02849afc366ccb6e01d8a15ef284bea3.html + a02849afc366ccb6e01d8a15ef284bea3 + () const noexcept + + + uint32_t + get_white_balance + classk4a_1_1image_a98fc61c44d56d183125ddd1f519f4cc8.html + a98fc61c44d56d183125ddd1f519f4cc8 + () const noexcept + + + uint32_t + get_iso_speed + classk4a_1_1image_a666dca56f2e7224488b95ac3b6ae8a6b.html + a666dca56f2e7224488b95ac3b6ae8a6b + () const noexcept + + + void + set_timestamp + classk4a_1_1image_a867e09f47781f3f3dee0dac1d7dcc6d7.html + a867e09f47781f3f3dee0dac1d7dcc6d7 + (std::chrono::microseconds timestamp) noexcept + + + void + set_exposure_time + classk4a_1_1image_aee70ef70051ec0ec28021e528c427758.html + aee70ef70051ec0ec28021e528c427758 + (std::chrono::microseconds exposure) noexcept + + + void + set_white_balance + classk4a_1_1image_a4b6b1f96c49dbdf90b083181e4839c39.html + a4b6b1f96c49dbdf90b083181e4839c39 + (uint32_t white_balance) noexcept + + + void + set_iso_speed + classk4a_1_1image_ab5857c281c7bafb0c14c1ecdc068280c.html + ab5857c281c7bafb0c14c1ecdc068280c + (uint32_t iso_speed) noexcept + + + static image + create + classk4a_1_1image_a7a92d9119d57b57039946f6f7220d9a9.html + a7a92d9119d57b57039946f6f7220d9a9 + (k4a_image_format_t format, int width_pixels, int height_pixels, int stride_bytes) + + + static image + create_from_buffer + classk4a_1_1image_a2885ff39ce74f193d5fe9fd1e92072ce.html + a2885ff39ce74f193d5fe9fd1e92072ce + (k4a_image_format_t format, int width_pixels, int height_pixels, int stride_bytes, uint8_t *buffer, size_t buffer_size, k4a_memory_destroy_cb_t *buffer_release_cb, void *buffer_release_cb_context) + + + + k4a_calibration_camera_t + structk4a__calibration__camera__t.html + + k4a_calibration_extrinsics_t + extrinsics + structk4a__calibration__camera__t.html + ace9c34429fcaa1a5c3be9aca9ba01f3d + + + + k4a_calibration_intrinsics_t + intrinsics + structk4a__calibration__camera__t.html + a0c2ddd100f986b0a5a604abaf67e8e44 + + + + int + resolution_width + structk4a__calibration__camera__t.html + a3e45105675a0b95f139f3ecae1e46427 + + + + int + resolution_height + structk4a__calibration__camera__t.html + ac47d2146081bca338ddf9d71cccdb2b8 + + + + float + metric_radius + structk4a__calibration__camera__t.html + ac9ba89cf72b237cb8ce7cdcbaca0c6a5 + + + + + k4a_calibration_extrinsics_t + structk4a__calibration__extrinsics__t.html + + float + rotation + structk4a__calibration__extrinsics__t.html + a2227d500bc6f240628774be2503c20a7 + [9] + + + float + translation + structk4a__calibration__extrinsics__t.html + a9246edc779148b57fb90efa283e65fcf + [3] + + + + k4a_calibration_intrinsic_parameters_t + unionk4a__calibration__intrinsic__parameters__t.html + k4a_calibration_intrinsic_parameters_t::_param + + struct k4a_calibration_intrinsic_parameters_t::_param + param + unionk4a__calibration__intrinsic__parameters__t.html + aba32dd57ef2dbbfec9c6f11c285d3c41 + + + + float + v + unionk4a__calibration__intrinsic__parameters__t.html + ac61b843bb57e4c345b010e6fa5c10cd3 + [15] + + + + k4a_calibration_intrinsics_t + structk4a__calibration__intrinsics__t.html + + k4a_calibration_model_type_t + type + structk4a__calibration__intrinsics__t.html + abf7247b67cdc839e09ab226498f22294 + + + + unsigned int + parameter_count + structk4a__calibration__intrinsics__t.html + a2e0654444a6d350ce3e5e19ffdb3c7f6 + + + + k4a_calibration_intrinsic_parameters_t + parameters + structk4a__calibration__intrinsics__t.html + a0b48309440647746ea36015cd618bbba + + + + + k4a_calibration_t + structk4a__calibration__t.html + + k4a_calibration_camera_t + depth_camera_calibration + structk4a__calibration__t.html + afb9c6f1ed401107b0f65a7fa6a5af910 + + + + k4a_calibration_camera_t + color_camera_calibration + structk4a__calibration__t.html + a3adc45fd59f6c8df46bec9848d70c565 + + + + k4a_calibration_extrinsics_t + extrinsics + structk4a__calibration__t_a03f4b1600f8088739ffeea818a5df890.html + a03f4b1600f8088739ffeea818a5df890 + [K4A_CALIBRATION_TYPE_NUM][K4A_CALIBRATION_TYPE_NUM] + + + uint32_t + depth_mode_id + structk4a__calibration__t.html + a1b206641693220f43836e40b74585028 + + + + uint32_t + color_mode_id + structk4a__calibration__t.html + a1fc290d07999eda51ddbe6765e4a4223 + + + + k4a_result_t + k4a_calibration_3d_to_3d + group___functions_gaacd1eab997ef964b5e436afa5295726e.html + gaacd1eab997ef964b5e436afa5295726e + (const k4a_calibration_t *calibration, const k4a_float3_t *source_point3d_mm, const k4a_calibration_type_t source_camera, const k4a_calibration_type_t target_camera, k4a_float3_t *target_point3d_mm) + + + k4a_result_t + k4a_calibration_2d_to_3d + group___functions_ga664602bdb48dab38117a6c1d14b880de.html + ga664602bdb48dab38117a6c1d14b880de + (const k4a_calibration_t *calibration, const k4a_float2_t *source_point2d, const float source_depth_mm, const k4a_calibration_type_t source_camera, const k4a_calibration_type_t target_camera, k4a_float3_t *target_point3d_mm, int *valid) + + + k4a_result_t + k4a_calibration_3d_to_2d + group___functions_ga2ed8b51d727425caa942aab190fc2ba9.html + ga2ed8b51d727425caa942aab190fc2ba9 + (const k4a_calibration_t *calibration, const k4a_float3_t *source_point3d_mm, const k4a_calibration_type_t source_camera, const k4a_calibration_type_t target_camera, k4a_float2_t *target_point2d, int *valid) + + + k4a_result_t + k4a_calibration_2d_to_2d + group___functions_ga3b6bf6dedbfe67468e2f895dcce68ed4.html + ga3b6bf6dedbfe67468e2f895dcce68ed4 + (const k4a_calibration_t *calibration, const k4a_float2_t *source_point2d, const float source_depth_mm, const k4a_calibration_type_t source_camera, const k4a_calibration_type_t target_camera, k4a_float2_t *target_point2d, int *valid) + + + k4a_result_t + k4a_calibration_color_2d_to_depth_2d + group___functions_ga18bc3138d6cc68af6c49902853fda9b5.html + ga18bc3138d6cc68af6c49902853fda9b5 + (const k4a_calibration_t *calibration, const k4a_float2_t *source_point2d, const k4a_image_t depth_image, k4a_float2_t *target_point2d, int *valid) + + + k4a_transformation_t + k4a_transformation_create + group___functions_ga853a1a5b6d521bbdf523a69e890c4f10.html + ga853a1a5b6d521bbdf523a69e890c4f10 + (const k4a_calibration_t *calibration) + + + + k4a_capture_t + structk4a__capture__t.html + + k4a_result_t + k4a_capture_create + group___functions_gaffbf32b4d014c31826d52de1c0c932cc.html + gaffbf32b4d014c31826d52de1c0c932cc + (k4a_capture_t *capture_handle) + + + void + k4a_capture_release + group___functions_ga0ed6f74ec403c3eac1b8ef3afb32cee6.html + ga0ed6f74ec403c3eac1b8ef3afb32cee6 + (k4a_capture_t capture_handle) + + + void + k4a_capture_reference + group___functions_gab15293d2e452470fff8d5109472c7350.html + gab15293d2e452470fff8d5109472c7350 + (k4a_capture_t capture_handle) + + + k4a_image_t + k4a_capture_get_color_image + group___functions_ga683e440b5f22215a2de58d7fa140488c.html + ga683e440b5f22215a2de58d7fa140488c + (k4a_capture_t capture_handle) + + + k4a_image_t + k4a_capture_get_depth_image + group___functions_gafa03513da96bf6b8c254fc11a04ee6d6.html + gafa03513da96bf6b8c254fc11a04ee6d6 + (k4a_capture_t capture_handle) + + + k4a_image_t + k4a_capture_get_ir_image + group___functions_ga1531c3fa76a7c174b8f2eab24de91794.html + ga1531c3fa76a7c174b8f2eab24de91794 + (k4a_capture_t capture_handle) + + + void + k4a_capture_set_color_image + group___functions_ga28824350a175d8eeba7c7a7d2753c2cf.html + ga28824350a175d8eeba7c7a7d2753c2cf + (k4a_capture_t capture_handle, k4a_image_t image_handle) + + + void + k4a_capture_set_depth_image + group___functions_gad28b520b45096dd430d2a14b6052ebae.html + gad28b520b45096dd430d2a14b6052ebae + (k4a_capture_t capture_handle, k4a_image_t image_handle) + + + void + k4a_capture_set_ir_image + group___functions_ga473abb7de733bf5f53329f3b1a86594c.html + ga473abb7de733bf5f53329f3b1a86594c + (k4a_capture_t capture_handle, k4a_image_t image_handle) + + + void + k4a_capture_set_temperature_c + group___functions_ga262b1df45e7b33dd4ea95e81d52a3a9c.html + ga262b1df45e7b33dd4ea95e81d52a3a9c + (k4a_capture_t capture_handle, float temperature_c) + + + float + k4a_capture_get_temperature_c + group___functions_gacc45836ed4a9cd055c37f51ffca4f992.html + gacc45836ed4a9cd055c37f51ffca4f992 + (k4a_capture_t capture_handle) + + + + k4a_color_mode_info_t + structk4a__color__mode__info__t.html + + uint32_t + struct_size + structk4a__color__mode__info__t.html + a4895521e1b7853fa109f879ce50987e8 + + + + uint32_t + struct_version + structk4a__color__mode__info__t_a1e8e8a6f3366b24fec3c19e7d8840235.html + a1e8e8a6f3366b24fec3c19e7d8840235 + + + + uint32_t + mode_id + structk4a__color__mode__info__t_a9fef69bfa46d06807078769a4b2a0edc.html + a9fef69bfa46d06807078769a4b2a0edc + + + + uint32_t + width + structk4a__color__mode__info__t.html + a05fc49b96a51e6b50163300d598da05a + + + + uint32_t + height + structk4a__color__mode__info__t.html + af86d62b6640ebf61a3285d4a3557cd89 + + + + k4a_image_format_t + native_format + structk4a__color__mode__info__t.html + a3d30e445ba9c7760d64678a0b1b84234 + + + + float + horizontal_fov + structk4a__color__mode__info__t.html + a782f8b3d400a467bf7a2f030aa11e44a + + + + float + vertical_fov + structk4a__color__mode__info__t.html + a1415e159824be7758b44706886c8988f + + + + int + min_fps + structk4a__color__mode__info__t.html + ac5512dba7c946f9ff9fedd93efd7ab5b + + + + int + max_fps + structk4a__color__mode__info__t.html + ac1256451ac7cf8c7a8836d2e4b490428 + + + + + k4a_depth_mode_info_t + structk4a__depth__mode__info__t.html + + uint32_t + struct_size + structk4a__depth__mode__info__t.html + a9ec6ee2d22176e8014afed4d963df74e + + + + uint32_t + struct_version + structk4a__depth__mode__info__t_afcbfb4faaca9e687bd2c42f9136ef291.html + afcbfb4faaca9e687bd2c42f9136ef291 + + + + uint32_t + mode_id + structk4a__depth__mode__info__t_a17ad844ed8e299fb00cb9ef17acafaf7.html + a17ad844ed8e299fb00cb9ef17acafaf7 + + + + bool + passive_ir_only + structk4a__depth__mode__info__t.html + a0257e3cdd457132534b468a6979a4c78 + + + + uint32_t + width + structk4a__depth__mode__info__t.html + a16da38c2f40e63b65f61442cdad420d1 + + + + uint32_t + height + structk4a__depth__mode__info__t.html + ab3490f6e4ebb2a67941682954318c56b + + + + k4a_image_format_t + native_format + structk4a__depth__mode__info__t.html + aa05ecf7b3b9d610cf050823a15e1b7e2 + + + + float + horizontal_fov + structk4a__depth__mode__info__t.html + aff9fb75449f496324397c9c6adf3e565 + + + + float + vertical_fov + structk4a__depth__mode__info__t.html + a93ed5718ce50dbd48f9cb468d6d2ca1d + + + + int + min_fps + structk4a__depth__mode__info__t.html + a7b1fe64bd337df9e602ff17cbef27cd6 + + + + int + max_fps + structk4a__depth__mode__info__t.html + a7b8cc91260c1f2861f184c0b766d8ea2 + + + + int + min_range + structk4a__depth__mode__info__t.html + a967aec3ad67765bd0d0725f6059861a0 + + + + int + max_range + structk4a__depth__mode__info__t.html + a1b7a5f0667524df08e9d66008ba44e60 + + + + + k4a_device_configuration_t + structk4a__device__configuration__t.html + + k4a_image_format_t + color_format + structk4a__device__configuration__t_a89d4e4703550d607e4fc3a8cce5b30ed.html + a89d4e4703550d607e4fc3a8cce5b30ed + + + + uint32_t + color_mode_id + structk4a__device__configuration__t.html + afeb238dbdceb6d061678ad4b9d40183e + + + + uint32_t + depth_mode_id + structk4a__device__configuration__t.html + a3ec12e21314c28686a8f806608cdb745 + + + + uint32_t + fps_mode_id + structk4a__device__configuration__t.html + a3e476faea863c6bd039831cd066d88b3 + + + + bool + synchronized_images_only + structk4a__device__configuration__t_a8208974f05d89fc1362c6a0900bdef4d.html + a8208974f05d89fc1362c6a0900bdef4d + + + + int32_t + depth_delay_off_color_usec + structk4a__device__configuration__t_a65f787c15d6b0a75119c2179054b5db4.html + a65f787c15d6b0a75119c2179054b5db4 + + + + k4a_wired_sync_mode_t + wired_sync_mode + structk4a__device__configuration__t.html + ab2b227f0d1ae58e8d59ff89fd27504b3 + + + + uint32_t + subordinate_delay_off_master_usec + structk4a__device__configuration__t_a85928bddb1fd92882d604678b648eea5.html + a85928bddb1fd92882d604678b648eea5 + + + + bool + disable_streaming_indicator + structk4a__device__configuration__t_a1fcc00f1a70f9cc28caeac306ba61253.html + a1fcc00f1a70f9cc28caeac306ba61253 + + + + + k4a_device_info_t + structk4a__device__info__t.html + + uint32_t + struct_size + structk4a__device__info__t.html + ad53910168cf32c55b79c554d526bff57 + + + + uint32_t + struct_version + structk4a__device__info__t.html + a673fc689adb403043b13e7be4c2c81ce + + + + uint32_t + vendor_id + structk4a__device__info__t.html + adf0b99f08dcd6e0973304759ee4aff5d + + + + uint32_t + device_id + structk4a__device__info__t.html + a2e9eecc6a6d77d82c3b6290f1085f41b + + + + uint32_t + capabilities + structk4a__device__info__t.html + a22faf124ad41b02359ca1ae33888f20b + + + + + k4a_device_t + structk4a__device__t.html + + uint32_t + k4a_device_get_installed_count + group___functions_gaf7d19df0f73f8e4dfaa21e1b4b719ecc.html + gaf7d19df0f73f8e4dfaa21e1b4b719ecc + (void) + + + k4a_result_t + k4a_device_open + group___functions_ga3d4eb5dfbf4d576d4978b66ea419f113.html + ga3d4eb5dfbf4d576d4978b66ea419f113 + (uint32_t index, k4a_device_t *device_handle) + + + void + k4a_device_close + group___functions_ga7a3931d9a690b3971caaac83b43f9423.html + ga7a3931d9a690b3971caaac83b43f9423 + (k4a_device_t device_handle) + + + k4a_wait_result_t + k4a_device_get_capture + group___functions_ga4dac757a33657f4d3dbf1ae8b21c158a.html + ga4dac757a33657f4d3dbf1ae8b21c158a + (k4a_device_t device_handle, k4a_capture_t *capture_handle, int32_t timeout_in_ms) + + + k4a_wait_result_t + k4a_device_get_imu_sample + group___functions_ga8e5913b3bb94a453c7143bbd6e399a0e.html + ga8e5913b3bb94a453c7143bbd6e399a0e + (k4a_device_t device_handle, k4a_imu_sample_t *imu_sample, int32_t timeout_in_ms) + + + k4a_result_t + k4a_device_start_cameras + group___functions_gaad7a85e1e5471810262442fc4a8e217a.html + gaad7a85e1e5471810262442fc4a8e217a + (k4a_device_t device_handle, const k4a_device_configuration_t *config) + + + void + k4a_device_stop_cameras + group___functions_ga4fa0e0a011a7105309ad97f081a5d6b8.html + ga4fa0e0a011a7105309ad97f081a5d6b8 + (k4a_device_t device_handle) + + + k4a_result_t + k4a_device_start_imu + group___functions_gaa855688659a69c0098ce9e0b2ffcc152.html + gaa855688659a69c0098ce9e0b2ffcc152 + (k4a_device_t device_handle) + + + void + k4a_device_stop_imu + group___functions_ga731c3ddd0833ce86d31e278992cf3453.html + ga731c3ddd0833ce86d31e278992cf3453 + (k4a_device_t device_handle) + + + k4a_buffer_result_t + k4a_device_get_serialnum + group___functions_ga798489af207ff1c99f2285ff6b08bc22.html + ga798489af207ff1c99f2285ff6b08bc22 + (k4a_device_t device_handle, char *serial_number, size_t *serial_number_size) + + + k4a_result_t + k4a_device_get_version + group___functions_gaea1def0a70bfa64ba275534be945669e.html + gaea1def0a70bfa64ba275534be945669e + (k4a_device_t device_handle, k4a_hardware_version_t *version) + + + k4a_result_t + k4a_device_get_color_control_capabilities + group___functions_ga70968e31e13aed0e2bef2009f169b901.html + ga70968e31e13aed0e2bef2009f169b901 + (k4a_device_t device_handle, k4a_color_control_command_t command, bool *supports_auto, int32_t *min_value, int32_t *max_value, int32_t *step_value, int32_t *default_value, k4a_color_control_mode_t *default_mode) + + + k4a_result_t + k4a_device_get_color_control + group___functions_ga5cb97bc0db4ab28ad98c44e323da1cce.html + ga5cb97bc0db4ab28ad98c44e323da1cce + (k4a_device_t device_handle, k4a_color_control_command_t command, k4a_color_control_mode_t *mode, int32_t *value) + + + k4a_result_t + k4a_device_set_color_control + group___functions_gae81269489170b26b7f0bbe1a7f9d31d6.html + gae81269489170b26b7f0bbe1a7f9d31d6 + (k4a_device_t device_handle, k4a_color_control_command_t command, k4a_color_control_mode_t mode, int32_t value) + + + k4a_buffer_result_t + k4a_device_get_raw_calibration + group___functions_ga8c4e46642cee3115aeb0b33e2b43b24f.html + ga8c4e46642cee3115aeb0b33e2b43b24f + (k4a_device_t device_handle, uint8_t *data, size_t *data_size) + + + k4a_result_t + k4a_device_get_calibration + group___functions_ga2d9b1bea66eecbbf7b2d2868f913292b.html + ga2d9b1bea66eecbbf7b2d2868f913292b + (k4a_device_t device_handle, const uint32_t depth_mode_id, const uint32_t color_mode_id, k4a_calibration_t *calibration) + + + k4a_result_t + k4a_device_get_sync_jack + group___functions_ga0209ac87bfd055163677321b0304e962.html + ga0209ac87bfd055163677321b0304e962 + (k4a_device_t device_handle, bool *sync_in_jack_connected, bool *sync_out_jack_connected) + + + k4a_result_t + k4a_calibration_get_from_raw + group___functions_ga3efe518a3de8c75c174cb97c84e12735.html + ga3efe518a3de8c75c174cb97c84e12735 + (char *raw_calibration, size_t raw_calibration_size, const uint32_t depth_mode_id, const uint32_t color_mode_id, k4a_calibration_t *calibration) + + + + k4a_float2_t + unionk4a__float2__t.html + k4a_float2_t::_xy + + struct k4a_float2_t::_xy + xy + unionk4a__float2__t.html + acc0527ecc3b56531e7c29f16e33dbd40 + + + + float + v + unionk4a__float2__t.html + ab085251b8d54dd0581a4b45d19cf80d0 + [2] + + + + k4a_float3_t + unionk4a__float3__t.html + k4a_float3_t::_xyz + + struct k4a_float3_t::_xyz + xyz + unionk4a__float3__t.html + a58b13ec006f76805563722e17cb6857c + + + + float + v + unionk4a__float3__t.html + ace48a59a47986cef62c0a2e6137beacf + [3] + + + + k4a_fps_mode_info_t + structk4a__fps__mode__info__t.html + + uint32_t + struct_size + structk4a__fps__mode__info__t.html + a330141878eb081f976c307f5fe028080 + + + + uint32_t + struct_version + structk4a__fps__mode__info__t_a07bad1812a3a2ca91989632d890d5593.html + a07bad1812a3a2ca91989632d890d5593 + + + + uint32_t + mode_id + structk4a__fps__mode__info__t.html + ac45b467c4f7677162b2161af8ea15e3a + + + + int + fps + structk4a__fps__mode__info__t.html + a8e0e4fa545b99bbae76d1ac237bde48e + + + + + k4a_hardware_version_t + structk4a__hardware__version__t.html + + k4a_version_t + rgb + structk4a__hardware__version__t.html + a1fee646cb54b74f2c257ee528322f4b4 + + + + k4a_version_t + depth + structk4a__hardware__version__t.html + a0a633007ba808514d59a8b710a11db04 + + + + k4a_version_t + audio + structk4a__hardware__version__t.html + a5e84b60b8f2c73a643e9e675105a2ccf + + + + k4a_version_t + depth_sensor + structk4a__hardware__version__t.html + a5d9d2e5e0f093d7b74f483c381c06534 + + + + k4a_firmware_build_t + firmware_build + structk4a__hardware__version__t.html + ae737e359b66141852bdd26662df7f2e8 + + + + k4a_firmware_signature_t + firmware_signature + structk4a__hardware__version__t.html + a10847af1b6b417da36507e380bc5404c + + + + + k4a_image_t + structk4a__image__t.html + + k4a_result_t + k4a_image_create + group___functions_ga859554581bb97a620ff8e92a893e71ef.html + ga859554581bb97a620ff8e92a893e71ef + (k4a_image_format_t format, int width_pixels, int height_pixels, int stride_bytes, k4a_image_t *image_handle) + + + k4a_result_t + k4a_image_create_from_buffer + group___functions_gaf84f2a271bcf6afae429bbccd47071b3.html + gaf84f2a271bcf6afae429bbccd47071b3 + (k4a_image_format_t format, int width_pixels, int height_pixels, int stride_bytes, uint8_t *buffer, size_t buffer_size, k4a_memory_destroy_cb_t *buffer_release_cb, void *buffer_release_cb_context, k4a_image_t *image_handle) + + + uint8_t * + k4a_image_get_buffer + group___functions_ga2ef070cf4e543cd0f726478af332546e.html + ga2ef070cf4e543cd0f726478af332546e + (k4a_image_t image_handle) + + + size_t + k4a_image_get_size + group___functions_ga814fd12783faf624e9357bbb3655643b.html + ga814fd12783faf624e9357bbb3655643b + (k4a_image_t image_handle) + + + k4a_image_format_t + k4a_image_get_format + group___functions_ga16f663cb93d8a8fa059fd551485f1315.html + ga16f663cb93d8a8fa059fd551485f1315 + (k4a_image_t image_handle) + + + int + k4a_image_get_width_pixels + group___functions_gab3df35a307588f272665328711342c06.html + gab3df35a307588f272665328711342c06 + (k4a_image_t image_handle) + + + int + k4a_image_get_height_pixels + group___functions_ga57ef7c5ce58812e176537476e4eb1764.html + ga57ef7c5ce58812e176537476e4eb1764 + (k4a_image_t image_handle) + + + int + k4a_image_get_stride_bytes + group___functions_ga18fa129b72b89ce8d13cd3e650af88e6.html + ga18fa129b72b89ce8d13cd3e650af88e6 + (k4a_image_t image_handle) + + + K4A_DEPRECATED_EXPORT uint64_t + k4a_image_get_timestamp_usec + group___functions_ga5a0940fb8ecf418eb3a388412bd08643.html + ga5a0940fb8ecf418eb3a388412bd08643 + (k4a_image_t image_handle) + + + uint64_t + k4a_image_get_device_timestamp_usec + group___functions_ga318e115976ac441b513f6cf3c102a655.html + ga318e115976ac441b513f6cf3c102a655 + (k4a_image_t image_handle) + + + uint64_t + k4a_image_get_system_timestamp_nsec + group___functions_ga98ba229d1ee1cf3b7c27a0f95e14826b.html + ga98ba229d1ee1cf3b7c27a0f95e14826b + (k4a_image_t image_handle) + + + uint64_t + k4a_image_get_exposure_usec + group___functions_ga54568ebab477f2534b3c4c92688344d9.html + ga54568ebab477f2534b3c4c92688344d9 + (k4a_image_t image_handle) + + + uint32_t + k4a_image_get_white_balance + group___functions_ga5075f97b2de6cb0fee1725d5e9250879.html + ga5075f97b2de6cb0fee1725d5e9250879 + (k4a_image_t image_handle) + + + uint32_t + k4a_image_get_iso_speed + group___functions_ga3626cef655d79190d2e002c3c4030872.html + ga3626cef655d79190d2e002c3c4030872 + (k4a_image_t image_handle) + + + void + k4a_image_set_device_timestamp_usec + group___functions_gacc2c4bf42956687a101937b77f8dfa21.html + gacc2c4bf42956687a101937b77f8dfa21 + (k4a_image_t image_handle, uint64_t timestamp_usec) + + + K4A_DEPRECATED_EXPORT void + k4a_image_set_timestamp_usec + group___functions_ga276298132ac76f56bf2c8b7589e38d63.html + ga276298132ac76f56bf2c8b7589e38d63 + (k4a_image_t image_handle, uint64_t timestamp_usec) + + + void + k4a_image_set_system_timestamp_nsec + group___functions_gaf18827997835a77ac041d5a87203e5ef.html + gaf18827997835a77ac041d5a87203e5ef + (k4a_image_t image_handle, uint64_t timestamp_nsec) + + + void + k4a_image_set_exposure_usec + group___functions_ga617dac1d4664f8f4ead3013c1739ebb0.html + ga617dac1d4664f8f4ead3013c1739ebb0 + (k4a_image_t image_handle, uint64_t exposure_usec) + + + K4A_DEPRECATED_EXPORT void + k4a_image_set_exposure_time_usec + group___functions_ga29954cc87d1fabc8651155f7baff5c9f.html + ga29954cc87d1fabc8651155f7baff5c9f + (k4a_image_t image_handle, uint64_t exposure_usec) + + + void + k4a_image_set_white_balance + group___functions_gad8c0bbccfd5086a7330bf897ae82561b.html + gad8c0bbccfd5086a7330bf897ae82561b + (k4a_image_t image_handle, uint32_t white_balance) + + + void + k4a_image_set_iso_speed + group___functions_ga5a64f64515ff4dff317fec92a8427f45.html + ga5a64f64515ff4dff317fec92a8427f45 + (k4a_image_t image_handle, uint32_t iso_speed) + + + void + k4a_image_reference + group___functions_gae211d6b97d4ce1c752e8db9d5ea5b8b9.html + gae211d6b97d4ce1c752e8db9d5ea5b8b9 + (k4a_image_t image_handle) + + + void + k4a_image_release + group___functions_ga27c81863b13fafc3934a32935a014e9f.html + ga27c81863b13fafc3934a32935a014e9f + (k4a_image_t image_handle) + + + + k4a_imu_sample_t + structk4a__imu__sample__t.html + + float + temperature + structk4a__imu__sample__t.html + aa18dbd8281ba8f570c6717253af3b1c4 + + + + k4a_float3_t + acc_sample + structk4a__imu__sample__t.html + a9950b04962f1f796e7910594f1b90398 + + + + uint64_t + acc_timestamp_usec + structk4a__imu__sample__t.html + a7f14c94aabeea0628c423e475bb47377 + + + + k4a_float3_t + gyro_sample + structk4a__imu__sample__t.html + aacb7ac18928c86a8babea1b4691ec28a + + + + uint64_t + gyro_timestamp_usec + structk4a__imu__sample__t.html + afce6c68eff09e50fdb57e91a383c4798 + + + + + k4a_transformation_t + structk4a__transformation__t.html + + void + k4a_transformation_destroy + group___functions_ga7d3ecaae66f26c1a89da9042b1bc6d44.html + ga7d3ecaae66f26c1a89da9042b1bc6d44 + (k4a_transformation_t transformation_handle) + + + k4a_result_t + k4a_transformation_depth_image_to_color_camera + group___functions_gafacffb5f781a9c2df30d4a16241cd514.html + gafacffb5f781a9c2df30d4a16241cd514 + (k4a_transformation_t transformation_handle, const k4a_image_t depth_image, k4a_image_t transformed_depth_image) + + + k4a_result_t + k4a_transformation_depth_image_to_color_camera_custom + group___functions_gac00dd00e7612a86382e3d0a130f276bb.html + gac00dd00e7612a86382e3d0a130f276bb + (k4a_transformation_t transformation_handle, const k4a_image_t depth_image, const k4a_image_t custom_image, k4a_image_t transformed_depth_image, k4a_image_t transformed_custom_image, k4a_transformation_interpolation_type_t interpolation_type, uint32_t invalid_custom_value) + + + k4a_result_t + k4a_transformation_color_image_to_depth_camera + group___functions_gaf3a941f07bb0185cd7a72699a648fc29.html + gaf3a941f07bb0185cd7a72699a648fc29 + (k4a_transformation_t transformation_handle, const k4a_image_t depth_image, const k4a_image_t color_image, k4a_image_t transformed_color_image) + + + k4a_result_t + k4a_transformation_depth_image_to_point_cloud + group___functions_ga7385eb4beb9d8892e8a88cf4feb3be70.html + ga7385eb4beb9d8892e8a88cf4feb3be70 + (k4a_transformation_t transformation_handle, const k4a_image_t depth_image, const k4a_calibration_type_t camera, k4a_image_t xyz_image) + + + + k4a_version_t + structk4a__version__t.html + + uint32_t + major + structk4a__version__t.html + aba947b238819496adc41888de36df6e1 + + + + uint32_t + minor + structk4a__version__t.html + a52626a80e919cac31d837efa3d01abfb + + + + uint32_t + iteration + structk4a__version__t.html + a9f3ec6a118f81533c7748b9080f68acf + + + + + k4a::transformation + classk4a_1_1transformation.html + + + transformation + classk4a_1_1transformation_abc5ca125a64e9702e80e2335a4303084.html + abc5ca125a64e9702e80e2335a4303084 + (const k4a_calibration_t &calibration) noexcept + + + + transformation + classk4a_1_1transformation_a7b98768f8ee53d39f20ec1d79bfec39a.html + a7b98768f8ee53d39f20ec1d79bfec39a + (k4a_transformation_t handle=nullptr) noexcept + + + + transformation + classk4a_1_1transformation.html + a87a09b55a536a08f36233abfd5846b4f + (transformation &&other) noexcept + + + transformation & + operator= + classk4a_1_1transformation.html + a2ae48e0963e332805b28b2d8659081b5 + (transformation &&other) noexcept + + + transformation & + operator= + classk4a_1_1transformation.html + a6297f8afa4706d6c5b19727ca4d1f8a9 + (std::nullptr_t) noexcept + + + void + destroy + classk4a_1_1transformation.html + a0f938b04a6a4b3d6b15df85ec3dc0422 + () noexcept + + + void + depth_image_to_color_camera + classk4a_1_1transformation_a84d7583dff4ba83f9ed162233f860418.html + a84d7583dff4ba83f9ed162233f860418 + (const image &depth_image, image *transformed_depth_image) const + + + image + depth_image_to_color_camera + classk4a_1_1transformation_ac3511565a1eedf5e22900f1fdc71c185.html + ac3511565a1eedf5e22900f1fdc71c185 + (const image &depth_image) const + + + void + depth_image_to_color_camera_custom + classk4a_1_1transformation_a81ead7ffe1c9540a2f91c364a749827d.html + a81ead7ffe1c9540a2f91c364a749827d + (const image &depth_image, const image &custom_image, image *transformed_depth_image, image *transformed_custom_image, k4a_transformation_interpolation_type_t interpolation_type, uint32_t invalid_custom_value) const + + + std::pair< image, image > + depth_image_to_color_camera_custom + classk4a_1_1transformation_a72eaf319f56076237371651dc483603e.html + a72eaf319f56076237371651dc483603e + (const image &depth_image, const image &custom_image, k4a_transformation_interpolation_type_t interpolation_type, uint32_t invalid_custom_value) const + + + void + color_image_to_depth_camera + classk4a_1_1transformation_ae25f1d6159f91bda04e9026959f94b15.html + ae25f1d6159f91bda04e9026959f94b15 + (const image &depth_image, const image &color_image, image *transformed_color_image) const + + + image + color_image_to_depth_camera + classk4a_1_1transformation_a208b7009485b1d14ccebaade276a32dc.html + a208b7009485b1d14ccebaade276a32dc + (const image &depth_image, const image &color_image) const + + + void + depth_image_to_point_cloud + classk4a_1_1transformation_aca376c8cca0f1157c3632b4f4c1a59ab.html + aca376c8cca0f1157c3632b4f4c1a59ab + (const image &depth_image, k4a_calibration_type_t camera, image *xyz_image) const + + + image + depth_image_to_point_cloud + classk4a_1_1transformation_aeced431be8c6be8efaf8da92380dd423.html + aeced431be8c6be8efaf8da92380dd423 + (const image &depth_image, k4a_calibration_type_t camera) const + + + + Functions + Functions + group___functions.html + + k4a_result_t + k4a_set_debug_message_handler + group___functions_ga77a5f83e56a04136df1398478353193d.html + ga77a5f83e56a04136df1398478353193d + (k4a_logging_message_cb_t *message_cb, void *message_cb_context, k4a_log_level_t min_level) + + + k4a_result_t + k4a_set_allocator + group___functions_ga1d09216c8ee1a878f3e8b6045979adc1.html + ga1d09216c8ee1a878f3e8b6045979adc1 + (k4a_memory_allocate_cb_t allocate, k4a_memory_destroy_cb_t free) + + + k4a_result_t + k4a_device_get_info + group___functions_gac274ccaf0d96578072026ac314893c11.html + gac274ccaf0d96578072026ac314893c11 + (k4a_device_t device_handle, k4a_device_info_t *device_info) + + + k4a_result_t + k4a_device_get_color_mode_count + group___functions_ga20bf63f7f9a62ec27d6e52ede5d5aa9a.html + ga20bf63f7f9a62ec27d6e52ede5d5aa9a + (k4a_device_t device_handle, int *mode_count) + + + k4a_result_t + k4a_device_get_color_mode + group___functions_gae2c7f66152cf2eb2f1e9a207bce64647.html + gae2c7f66152cf2eb2f1e9a207bce64647 + (k4a_device_t device_handle, int mode_id, k4a_color_mode_info_t *mode_info) + + + k4a_result_t + k4a_device_get_depth_mode_count + group___functions_ga99493493a9d9cc6e222f9ee764ec7060.html + ga99493493a9d9cc6e222f9ee764ec7060 + (k4a_device_t device_handle, int *mode_count) + + + k4a_result_t + k4a_device_get_depth_mode + group___functions_ga0f6fb0b10b1c18fc934f70759aebbba5.html + ga0f6fb0b10b1c18fc934f70759aebbba5 + (k4a_device_t device_handle, int mode_id, k4a_depth_mode_info_t *mode_info) + + + k4a_result_t + k4a_device_get_fps_mode_count + group___functions_ga089979035d6b84e18ec792bdcf3bcd3b.html + ga089979035d6b84e18ec792bdcf3bcd3b + (k4a_device_t device_handle, int *mode_count) + + + k4a_result_t + k4a_device_get_fps_mode + group___functions_ga14956baf6db6ba2e936ae92e0413948a.html + ga14956baf6db6ba2e936ae92e0413948a + (k4a_device_t device_handle, int mode_id, k4a_fps_mode_info_t *mode_info) + + + uint32_t + k4a_device_get_installed_count + group___functions_gaf7d19df0f73f8e4dfaa21e1b4b719ecc.html + gaf7d19df0f73f8e4dfaa21e1b4b719ecc + (void) + + + k4a_result_t + k4a_device_open + group___functions_ga3d4eb5dfbf4d576d4978b66ea419f113.html + ga3d4eb5dfbf4d576d4978b66ea419f113 + (uint32_t index, k4a_device_t *device_handle) + + + void + k4a_device_close + group___functions_ga7a3931d9a690b3971caaac83b43f9423.html + ga7a3931d9a690b3971caaac83b43f9423 + (k4a_device_t device_handle) + + + k4a_wait_result_t + k4a_device_get_capture + group___functions_ga4dac757a33657f4d3dbf1ae8b21c158a.html + ga4dac757a33657f4d3dbf1ae8b21c158a + (k4a_device_t device_handle, k4a_capture_t *capture_handle, int32_t timeout_in_ms) + + + k4a_wait_result_t + k4a_device_get_imu_sample + group___functions_ga8e5913b3bb94a453c7143bbd6e399a0e.html + ga8e5913b3bb94a453c7143bbd6e399a0e + (k4a_device_t device_handle, k4a_imu_sample_t *imu_sample, int32_t timeout_in_ms) + + + k4a_result_t + k4a_capture_create + group___functions_gaffbf32b4d014c31826d52de1c0c932cc.html + gaffbf32b4d014c31826d52de1c0c932cc + (k4a_capture_t *capture_handle) + + + void + k4a_capture_release + group___functions_ga0ed6f74ec403c3eac1b8ef3afb32cee6.html + ga0ed6f74ec403c3eac1b8ef3afb32cee6 + (k4a_capture_t capture_handle) + + + void + k4a_capture_reference + group___functions_gab15293d2e452470fff8d5109472c7350.html + gab15293d2e452470fff8d5109472c7350 + (k4a_capture_t capture_handle) + + + k4a_image_t + k4a_capture_get_color_image + group___functions_ga683e440b5f22215a2de58d7fa140488c.html + ga683e440b5f22215a2de58d7fa140488c + (k4a_capture_t capture_handle) + + + k4a_image_t + k4a_capture_get_depth_image + group___functions_gafa03513da96bf6b8c254fc11a04ee6d6.html + gafa03513da96bf6b8c254fc11a04ee6d6 + (k4a_capture_t capture_handle) + + + k4a_image_t + k4a_capture_get_ir_image + group___functions_ga1531c3fa76a7c174b8f2eab24de91794.html + ga1531c3fa76a7c174b8f2eab24de91794 + (k4a_capture_t capture_handle) + + + void + k4a_capture_set_color_image + group___functions_ga28824350a175d8eeba7c7a7d2753c2cf.html + ga28824350a175d8eeba7c7a7d2753c2cf + (k4a_capture_t capture_handle, k4a_image_t image_handle) + + + void + k4a_capture_set_depth_image + group___functions_gad28b520b45096dd430d2a14b6052ebae.html + gad28b520b45096dd430d2a14b6052ebae + (k4a_capture_t capture_handle, k4a_image_t image_handle) + + + void + k4a_capture_set_ir_image + group___functions_ga473abb7de733bf5f53329f3b1a86594c.html + ga473abb7de733bf5f53329f3b1a86594c + (k4a_capture_t capture_handle, k4a_image_t image_handle) + + + void + k4a_capture_set_temperature_c + group___functions_ga262b1df45e7b33dd4ea95e81d52a3a9c.html + ga262b1df45e7b33dd4ea95e81d52a3a9c + (k4a_capture_t capture_handle, float temperature_c) + + + float + k4a_capture_get_temperature_c + group___functions_gacc45836ed4a9cd055c37f51ffca4f992.html + gacc45836ed4a9cd055c37f51ffca4f992 + (k4a_capture_t capture_handle) + + + k4a_result_t + k4a_image_create + group___functions_ga859554581bb97a620ff8e92a893e71ef.html + ga859554581bb97a620ff8e92a893e71ef + (k4a_image_format_t format, int width_pixels, int height_pixels, int stride_bytes, k4a_image_t *image_handle) + + + k4a_result_t + k4a_image_create_from_buffer + group___functions_gaf84f2a271bcf6afae429bbccd47071b3.html + gaf84f2a271bcf6afae429bbccd47071b3 + (k4a_image_format_t format, int width_pixels, int height_pixels, int stride_bytes, uint8_t *buffer, size_t buffer_size, k4a_memory_destroy_cb_t *buffer_release_cb, void *buffer_release_cb_context, k4a_image_t *image_handle) + + + uint8_t * + k4a_image_get_buffer + group___functions_ga2ef070cf4e543cd0f726478af332546e.html + ga2ef070cf4e543cd0f726478af332546e + (k4a_image_t image_handle) + + + size_t + k4a_image_get_size + group___functions_ga814fd12783faf624e9357bbb3655643b.html + ga814fd12783faf624e9357bbb3655643b + (k4a_image_t image_handle) + + + k4a_image_format_t + k4a_image_get_format + group___functions_ga16f663cb93d8a8fa059fd551485f1315.html + ga16f663cb93d8a8fa059fd551485f1315 + (k4a_image_t image_handle) + + + int + k4a_image_get_width_pixels + group___functions_gab3df35a307588f272665328711342c06.html + gab3df35a307588f272665328711342c06 + (k4a_image_t image_handle) + + + int + k4a_image_get_height_pixels + group___functions_ga57ef7c5ce58812e176537476e4eb1764.html + ga57ef7c5ce58812e176537476e4eb1764 + (k4a_image_t image_handle) + + + int + k4a_image_get_stride_bytes + group___functions_ga18fa129b72b89ce8d13cd3e650af88e6.html + ga18fa129b72b89ce8d13cd3e650af88e6 + (k4a_image_t image_handle) + + + K4A_DEPRECATED_EXPORT uint64_t + k4a_image_get_timestamp_usec + group___functions_ga5a0940fb8ecf418eb3a388412bd08643.html + ga5a0940fb8ecf418eb3a388412bd08643 + (k4a_image_t image_handle) + + + uint64_t + k4a_image_get_device_timestamp_usec + group___functions_ga318e115976ac441b513f6cf3c102a655.html + ga318e115976ac441b513f6cf3c102a655 + (k4a_image_t image_handle) + + + uint64_t + k4a_image_get_system_timestamp_nsec + group___functions_ga98ba229d1ee1cf3b7c27a0f95e14826b.html + ga98ba229d1ee1cf3b7c27a0f95e14826b + (k4a_image_t image_handle) + + + uint64_t + k4a_image_get_exposure_usec + group___functions_ga54568ebab477f2534b3c4c92688344d9.html + ga54568ebab477f2534b3c4c92688344d9 + (k4a_image_t image_handle) + + + uint32_t + k4a_image_get_white_balance + group___functions_ga5075f97b2de6cb0fee1725d5e9250879.html + ga5075f97b2de6cb0fee1725d5e9250879 + (k4a_image_t image_handle) + + + uint32_t + k4a_image_get_iso_speed + group___functions_ga3626cef655d79190d2e002c3c4030872.html + ga3626cef655d79190d2e002c3c4030872 + (k4a_image_t image_handle) + + + void + k4a_image_set_device_timestamp_usec + group___functions_gacc2c4bf42956687a101937b77f8dfa21.html + gacc2c4bf42956687a101937b77f8dfa21 + (k4a_image_t image_handle, uint64_t timestamp_usec) + + + K4A_DEPRECATED_EXPORT void + k4a_image_set_timestamp_usec + group___functions_ga276298132ac76f56bf2c8b7589e38d63.html + ga276298132ac76f56bf2c8b7589e38d63 + (k4a_image_t image_handle, uint64_t timestamp_usec) + + + void + k4a_image_set_system_timestamp_nsec + group___functions_gaf18827997835a77ac041d5a87203e5ef.html + gaf18827997835a77ac041d5a87203e5ef + (k4a_image_t image_handle, uint64_t timestamp_nsec) + + + void + k4a_image_set_exposure_usec + group___functions_ga617dac1d4664f8f4ead3013c1739ebb0.html + ga617dac1d4664f8f4ead3013c1739ebb0 + (k4a_image_t image_handle, uint64_t exposure_usec) + + + K4A_DEPRECATED_EXPORT void + k4a_image_set_exposure_time_usec + group___functions_ga29954cc87d1fabc8651155f7baff5c9f.html + ga29954cc87d1fabc8651155f7baff5c9f + (k4a_image_t image_handle, uint64_t exposure_usec) + + + void + k4a_image_set_white_balance + group___functions_gad8c0bbccfd5086a7330bf897ae82561b.html + gad8c0bbccfd5086a7330bf897ae82561b + (k4a_image_t image_handle, uint32_t white_balance) + + + void + k4a_image_set_iso_speed + group___functions_ga5a64f64515ff4dff317fec92a8427f45.html + ga5a64f64515ff4dff317fec92a8427f45 + (k4a_image_t image_handle, uint32_t iso_speed) + + + void + k4a_image_reference + group___functions_gae211d6b97d4ce1c752e8db9d5ea5b8b9.html + gae211d6b97d4ce1c752e8db9d5ea5b8b9 + (k4a_image_t image_handle) + + + void + k4a_image_release + group___functions_ga27c81863b13fafc3934a32935a014e9f.html + ga27c81863b13fafc3934a32935a014e9f + (k4a_image_t image_handle) + + + k4a_result_t + k4a_device_start_cameras + group___functions_gaad7a85e1e5471810262442fc4a8e217a.html + gaad7a85e1e5471810262442fc4a8e217a + (k4a_device_t device_handle, const k4a_device_configuration_t *config) + + + void + k4a_device_stop_cameras + group___functions_ga4fa0e0a011a7105309ad97f081a5d6b8.html + ga4fa0e0a011a7105309ad97f081a5d6b8 + (k4a_device_t device_handle) + + + k4a_result_t + k4a_device_start_imu + group___functions_gaa855688659a69c0098ce9e0b2ffcc152.html + gaa855688659a69c0098ce9e0b2ffcc152 + (k4a_device_t device_handle) + + + void + k4a_device_stop_imu + group___functions_ga731c3ddd0833ce86d31e278992cf3453.html + ga731c3ddd0833ce86d31e278992cf3453 + (k4a_device_t device_handle) + + + k4a_buffer_result_t + k4a_device_get_serialnum + group___functions_ga798489af207ff1c99f2285ff6b08bc22.html + ga798489af207ff1c99f2285ff6b08bc22 + (k4a_device_t device_handle, char *serial_number, size_t *serial_number_size) + + + k4a_result_t + k4a_device_get_version + group___functions_gaea1def0a70bfa64ba275534be945669e.html + gaea1def0a70bfa64ba275534be945669e + (k4a_device_t device_handle, k4a_hardware_version_t *version) + + + k4a_result_t + k4a_device_get_color_control_capabilities + group___functions_ga70968e31e13aed0e2bef2009f169b901.html + ga70968e31e13aed0e2bef2009f169b901 + (k4a_device_t device_handle, k4a_color_control_command_t command, bool *supports_auto, int32_t *min_value, int32_t *max_value, int32_t *step_value, int32_t *default_value, k4a_color_control_mode_t *default_mode) + + + k4a_result_t + k4a_device_get_color_control + group___functions_ga5cb97bc0db4ab28ad98c44e323da1cce.html + ga5cb97bc0db4ab28ad98c44e323da1cce + (k4a_device_t device_handle, k4a_color_control_command_t command, k4a_color_control_mode_t *mode, int32_t *value) + + + k4a_result_t + k4a_device_set_color_control + group___functions_gae81269489170b26b7f0bbe1a7f9d31d6.html + gae81269489170b26b7f0bbe1a7f9d31d6 + (k4a_device_t device_handle, k4a_color_control_command_t command, k4a_color_control_mode_t mode, int32_t value) + + + k4a_buffer_result_t + k4a_device_get_raw_calibration + group___functions_ga8c4e46642cee3115aeb0b33e2b43b24f.html + ga8c4e46642cee3115aeb0b33e2b43b24f + (k4a_device_t device_handle, uint8_t *data, size_t *data_size) + + + k4a_result_t + k4a_device_get_calibration + group___functions_ga2d9b1bea66eecbbf7b2d2868f913292b.html + ga2d9b1bea66eecbbf7b2d2868f913292b + (k4a_device_t device_handle, const uint32_t depth_mode_id, const uint32_t color_mode_id, k4a_calibration_t *calibration) + + + k4a_result_t + k4a_device_get_sync_jack + group___functions_ga0209ac87bfd055163677321b0304e962.html + ga0209ac87bfd055163677321b0304e962 + (k4a_device_t device_handle, bool *sync_in_jack_connected, bool *sync_out_jack_connected) + + + k4a_result_t + k4a_calibration_get_from_raw + group___functions_ga3efe518a3de8c75c174cb97c84e12735.html + ga3efe518a3de8c75c174cb97c84e12735 + (char *raw_calibration, size_t raw_calibration_size, const uint32_t depth_mode_id, const uint32_t color_mode_id, k4a_calibration_t *calibration) + + + k4a_result_t + k4a_calibration_3d_to_3d + group___functions_gaacd1eab997ef964b5e436afa5295726e.html + gaacd1eab997ef964b5e436afa5295726e + (const k4a_calibration_t *calibration, const k4a_float3_t *source_point3d_mm, const k4a_calibration_type_t source_camera, const k4a_calibration_type_t target_camera, k4a_float3_t *target_point3d_mm) + + + k4a_result_t + k4a_calibration_2d_to_3d + group___functions_ga664602bdb48dab38117a6c1d14b880de.html + ga664602bdb48dab38117a6c1d14b880de + (const k4a_calibration_t *calibration, const k4a_float2_t *source_point2d, const float source_depth_mm, const k4a_calibration_type_t source_camera, const k4a_calibration_type_t target_camera, k4a_float3_t *target_point3d_mm, int *valid) + + + k4a_result_t + k4a_calibration_3d_to_2d + group___functions_ga2ed8b51d727425caa942aab190fc2ba9.html + ga2ed8b51d727425caa942aab190fc2ba9 + (const k4a_calibration_t *calibration, const k4a_float3_t *source_point3d_mm, const k4a_calibration_type_t source_camera, const k4a_calibration_type_t target_camera, k4a_float2_t *target_point2d, int *valid) + + + k4a_result_t + k4a_calibration_2d_to_2d + group___functions_ga3b6bf6dedbfe67468e2f895dcce68ed4.html + ga3b6bf6dedbfe67468e2f895dcce68ed4 + (const k4a_calibration_t *calibration, const k4a_float2_t *source_point2d, const float source_depth_mm, const k4a_calibration_type_t source_camera, const k4a_calibration_type_t target_camera, k4a_float2_t *target_point2d, int *valid) + + + k4a_result_t + k4a_calibration_color_2d_to_depth_2d + group___functions_ga18bc3138d6cc68af6c49902853fda9b5.html + ga18bc3138d6cc68af6c49902853fda9b5 + (const k4a_calibration_t *calibration, const k4a_float2_t *source_point2d, const k4a_image_t depth_image, k4a_float2_t *target_point2d, int *valid) + + + k4a_transformation_t + k4a_transformation_create + group___functions_ga853a1a5b6d521bbdf523a69e890c4f10.html + ga853a1a5b6d521bbdf523a69e890c4f10 + (const k4a_calibration_t *calibration) + + + void + k4a_transformation_destroy + group___functions_ga7d3ecaae66f26c1a89da9042b1bc6d44.html + ga7d3ecaae66f26c1a89da9042b1bc6d44 + (k4a_transformation_t transformation_handle) + + + k4a_result_t + k4a_transformation_depth_image_to_color_camera + group___functions_gafacffb5f781a9c2df30d4a16241cd514.html + gafacffb5f781a9c2df30d4a16241cd514 + (k4a_transformation_t transformation_handle, const k4a_image_t depth_image, k4a_image_t transformed_depth_image) + + + k4a_result_t + k4a_transformation_depth_image_to_color_camera_custom + group___functions_gac00dd00e7612a86382e3d0a130f276bb.html + gac00dd00e7612a86382e3d0a130f276bb + (k4a_transformation_t transformation_handle, const k4a_image_t depth_image, const k4a_image_t custom_image, k4a_image_t transformed_depth_image, k4a_image_t transformed_custom_image, k4a_transformation_interpolation_type_t interpolation_type, uint32_t invalid_custom_value) + + + k4a_result_t + k4a_transformation_color_image_to_depth_camera + group___functions_gaf3a941f07bb0185cd7a72699a648fc29.html + gaf3a941f07bb0185cd7a72699a648fc29 + (k4a_transformation_t transformation_handle, const k4a_image_t depth_image, const k4a_image_t color_image, k4a_image_t transformed_color_image) + + + k4a_result_t + k4a_transformation_depth_image_to_point_cloud + group___functions_ga7385eb4beb9d8892e8a88cf4feb3be70.html + ga7385eb4beb9d8892e8a88cf4feb3be70 + (k4a_transformation_t transformation_handle, const k4a_image_t depth_image, const k4a_calibration_type_t camera, k4a_image_t xyz_image) + + + + cppsdk + C++ Reference + group__cppsdk.html + k4a::error + k4a::image + k4a::capture + k4a::calibration + k4a::transformation + k4a::device + + + csdk + C Reference + group__csdk.html + Functions + Handles + Enumerations + Macros + Prototypes + Structures + Definitions + + + Handles + Handles + group___handles.html + k4a_device_t + k4a_capture_t + k4a_image_t + k4a_transformation_t + + + Enumerations + Enumerations + group___enumerations.html + + + k4a_result_t + group___enumerations_ga4b419a99aa2220b076a4520dc2afd1e5.html + ga4b419a99aa2220b076a4520dc2afd1e5 + + + + K4A_RESULT_SUCCEEDED + group___enumerations_ga4b419a99aa2220b076a4520dc2afd1e5.html + gga4b419a99aa2220b076a4520dc2afd1e5a66d48bea75b8ddf1c568a824469da9d3 + + + + K4A_RESULT_FAILED + group___enumerations_ga4b419a99aa2220b076a4520dc2afd1e5.html + gga4b419a99aa2220b076a4520dc2afd1e5aeddb129210ca398349f6b7323f1cfbed + + + + K4A_RESULT_UNSUPPORTED + group___enumerations_ga4b419a99aa2220b076a4520dc2afd1e5.html + gga4b419a99aa2220b076a4520dc2afd1e5a7fdd637f1645c2d8ffeb9f5dfa028a13 + + + + + k4a_buffer_result_t + group___enumerations_ga71b3cf304a2cd8fbac2f86c876deda5c.html + ga71b3cf304a2cd8fbac2f86c876deda5c + + + + K4A_BUFFER_RESULT_SUCCEEDED + group___enumerations_ga71b3cf304a2cd8fbac2f86c876deda5c.html + gga71b3cf304a2cd8fbac2f86c876deda5cab28733ec2d34368fbc91a2ee25545fc3 + + + + K4A_BUFFER_RESULT_FAILED + group___enumerations_ga71b3cf304a2cd8fbac2f86c876deda5c.html + gga71b3cf304a2cd8fbac2f86c876deda5ca29305af05427c7e739e910f02f72709a + + + + K4A_BUFFER_RESULT_TOO_SMALL + group___enumerations_ga71b3cf304a2cd8fbac2f86c876deda5c.html + gga71b3cf304a2cd8fbac2f86c876deda5ca37df229f19ce567914a8b8d15fc50248 + + + + K4A_BUFFER_RESULT_UNSUPPORTED + group___enumerations_ga71b3cf304a2cd8fbac2f86c876deda5c.html + gga71b3cf304a2cd8fbac2f86c876deda5cacf0947fc3cc389914416e42c43aa102e + + + + + k4a_wait_result_t + group___enumerations_ga44c7c0c1cfba7c879e9e2da1a869e4ee.html + ga44c7c0c1cfba7c879e9e2da1a869e4ee + + + + K4A_WAIT_RESULT_SUCCEEDED + group___enumerations_ga44c7c0c1cfba7c879e9e2da1a869e4ee.html + gga44c7c0c1cfba7c879e9e2da1a869e4eea77ac95280b54f842a7735bbadc50f6ca + + + + K4A_WAIT_RESULT_FAILED + group___enumerations_ga44c7c0c1cfba7c879e9e2da1a869e4ee.html + gga44c7c0c1cfba7c879e9e2da1a869e4eea956d1d20b14de6ba0a0ed97955e75540 + + + + K4A_WAIT_RESULT_TIMEOUT + group___enumerations_ga44c7c0c1cfba7c879e9e2da1a869e4ee.html + gga44c7c0c1cfba7c879e9e2da1a869e4eea6bc6ba0069766499f7b791ba42a980c6 + + + + K4A_WAIT_RESULT_UNSUPPORTED + group___enumerations_ga44c7c0c1cfba7c879e9e2da1a869e4ee.html + gga44c7c0c1cfba7c879e9e2da1a869e4eeab95879b0cce3590b7e76255ce6f20a4a + + + + + k4a_log_level_t + group___enumerations_ga84d8f9a665773fb4e75a2ac8160444c6.html + ga84d8f9a665773fb4e75a2ac8160444c6 + + + + K4A_LOG_LEVEL_CRITICAL + group___enumerations_ga84d8f9a665773fb4e75a2ac8160444c6.html + gga84d8f9a665773fb4e75a2ac8160444c6ae7fe889b69c2046d0e053c63131d39ba + + + + K4A_LOG_LEVEL_ERROR + group___enumerations_ga84d8f9a665773fb4e75a2ac8160444c6.html + gga84d8f9a665773fb4e75a2ac8160444c6ac0ca5fc3565ffd8de299b9b856ddba21 + + + + K4A_LOG_LEVEL_WARNING + group___enumerations_ga84d8f9a665773fb4e75a2ac8160444c6.html + gga84d8f9a665773fb4e75a2ac8160444c6ad66a4a27178ad83bd17c82c49b84f8f3 + + + + K4A_LOG_LEVEL_INFO + group___enumerations_ga84d8f9a665773fb4e75a2ac8160444c6.html + gga84d8f9a665773fb4e75a2ac8160444c6acc980bd260314ea70122265107413a3d + + + + K4A_LOG_LEVEL_TRACE + group___enumerations_ga84d8f9a665773fb4e75a2ac8160444c6.html + gga84d8f9a665773fb4e75a2ac8160444c6a98a692cbdade257a83e341dfc78b4497 + + + + K4A_LOG_LEVEL_OFF + group___enumerations_ga84d8f9a665773fb4e75a2ac8160444c6.html + gga84d8f9a665773fb4e75a2ac8160444c6a9e378e25c87ede3b91dece190350aaee + + + + + k4a_image_format_t + group___enumerations_gabd9688eb20d5cb878fd22d36de882ddb.html + gabd9688eb20d5cb878fd22d36de882ddb + + + + K4A_IMAGE_FORMAT_COLOR_MJPG + group___enumerations_gabd9688eb20d5cb878fd22d36de882ddb.html + ggabd9688eb20d5cb878fd22d36de882ddbaae172e7eecc6f4adfc318c789e49aaf9 + + + + K4A_IMAGE_FORMAT_COLOR_NV12 + group___enumerations_gabd9688eb20d5cb878fd22d36de882ddb.html + ggabd9688eb20d5cb878fd22d36de882ddbaf334f6c32b6b44d1f5df02a349f05288 + + + + K4A_IMAGE_FORMAT_COLOR_YUY2 + group___enumerations_gabd9688eb20d5cb878fd22d36de882ddb.html + ggabd9688eb20d5cb878fd22d36de882ddbab6a418334cfd2018ff3b9e360c472306 + + + + K4A_IMAGE_FORMAT_COLOR_BGRA32 + group___enumerations_gabd9688eb20d5cb878fd22d36de882ddb.html + ggabd9688eb20d5cb878fd22d36de882ddbade43f3d12f5ce476be5be2b0e289d481 + + + + K4A_IMAGE_FORMAT_DEPTH16 + group___enumerations_gabd9688eb20d5cb878fd22d36de882ddb.html + ggabd9688eb20d5cb878fd22d36de882ddba5abd5fdff69181007ec79ed3087aa18e + + + + K4A_IMAGE_FORMAT_IR16 + group___enumerations_gabd9688eb20d5cb878fd22d36de882ddb.html + ggabd9688eb20d5cb878fd22d36de882ddba39a56f94523816908dbb08994e33c37f + + + + K4A_IMAGE_FORMAT_CUSTOM8 + group___enumerations_gabd9688eb20d5cb878fd22d36de882ddb.html + ggabd9688eb20d5cb878fd22d36de882ddba17dea221ecdfa136dea68f80e0397e15 + + + + K4A_IMAGE_FORMAT_CUSTOM16 + group___enumerations_gabd9688eb20d5cb878fd22d36de882ddb.html + ggabd9688eb20d5cb878fd22d36de882ddba6f2ee5c37729f9196b0cf3d3028edc42 + + + + K4A_IMAGE_FORMAT_CUSTOM + group___enumerations_gabd9688eb20d5cb878fd22d36de882ddb.html + ggabd9688eb20d5cb878fd22d36de882ddba10833e30171730f43eeff1dc8d7b0a52 + + + + + k4a_transformation_interpolation_type_t + group___enumerations_ga06f55e23e1d260b069e89e4a9cd6f4ee.html + ga06f55e23e1d260b069e89e4a9cd6f4ee + + + + K4A_TRANSFORMATION_INTERPOLATION_TYPE_NEAREST + group___enumerations_ga06f55e23e1d260b069e89e4a9cd6f4ee.html + gga06f55e23e1d260b069e89e4a9cd6f4eea9b7517e41898a208566db614bcf26cc5 + + + + K4A_TRANSFORMATION_INTERPOLATION_TYPE_LINEAR + group___enumerations_ga06f55e23e1d260b069e89e4a9cd6f4ee.html + gga06f55e23e1d260b069e89e4a9cd6f4eeac91cb5f01c87411e2980d109a7a36e56 + + + + + k4a_color_control_command_t + group___enumerations_gafba23de13b10b11e413485e421aa0468.html + gafba23de13b10b11e413485e421aa0468 + + + + K4A_COLOR_CONTROL_EXPOSURE_TIME_ABSOLUTE + group___enumerations_gafba23de13b10b11e413485e421aa0468.html + ggafba23de13b10b11e413485e421aa0468a13b21d4ea33a20633096955c966d96e5 + + + + K4A_COLOR_CONTROL_AUTO_EXPOSURE_PRIORITY + group___enumerations_gafba23de13b10b11e413485e421aa0468.html + ggafba23de13b10b11e413485e421aa0468a2dc2ccb23e64049b49a57e2a44346e46 + + + + K4A_COLOR_CONTROL_BRIGHTNESS + group___enumerations_gafba23de13b10b11e413485e421aa0468.html + ggafba23de13b10b11e413485e421aa0468a4c6d97415ef755ab4966e5952d68eb5d + + + + K4A_COLOR_CONTROL_CONTRAST + group___enumerations_gafba23de13b10b11e413485e421aa0468.html + ggafba23de13b10b11e413485e421aa0468a8adb525eccd99574d260749dc84e88a8 + + + + K4A_COLOR_CONTROL_SATURATION + group___enumerations_gafba23de13b10b11e413485e421aa0468.html + ggafba23de13b10b11e413485e421aa0468a59e8a733fcf68f06f0a887faa2cfda49 + + + + K4A_COLOR_CONTROL_SHARPNESS + group___enumerations_gafba23de13b10b11e413485e421aa0468.html + ggafba23de13b10b11e413485e421aa0468aa0348c48b612513655f4267550a9bb0a + + + + K4A_COLOR_CONTROL_WHITEBALANCE + group___enumerations_gafba23de13b10b11e413485e421aa0468.html + ggafba23de13b10b11e413485e421aa0468ad51b4d047313a5c6a778e17cce066a91 + + + + K4A_COLOR_CONTROL_BACKLIGHT_COMPENSATION + group___enumerations_gafba23de13b10b11e413485e421aa0468.html + ggafba23de13b10b11e413485e421aa0468aee6d4472b21851255ead137b43424715 + + + + K4A_COLOR_CONTROL_GAIN + group___enumerations_gafba23de13b10b11e413485e421aa0468.html + ggafba23de13b10b11e413485e421aa0468a1b519b3a91fb0a79e8638187f94f177c + + + + K4A_COLOR_CONTROL_POWERLINE_FREQUENCY + group___enumerations_gafba23de13b10b11e413485e421aa0468.html + ggafba23de13b10b11e413485e421aa0468a2faa17ccc813fda09c1172fc1a8b629e + + + + + k4a_color_control_mode_t + group___enumerations_ga3485402fc1bc5dc709e0d5859b6e8c88.html + ga3485402fc1bc5dc709e0d5859b6e8c88 + + + + K4A_COLOR_CONTROL_MODE_AUTO + group___enumerations_ga3485402fc1bc5dc709e0d5859b6e8c88.html + gga3485402fc1bc5dc709e0d5859b6e8c88a4f851ff5f566e23588abaa10ba1e9194 + + + + K4A_COLOR_CONTROL_MODE_MANUAL + group___enumerations_ga3485402fc1bc5dc709e0d5859b6e8c88.html + gga3485402fc1bc5dc709e0d5859b6e8c88a094d94f9ec0640e085a7318c92205d1b + + + + + k4a_wired_sync_mode_t + group___enumerations_ga6404c655dd8656efb745c6ee90da2505.html + ga6404c655dd8656efb745c6ee90da2505 + + + + K4A_WIRED_SYNC_MODE_STANDALONE + group___enumerations_ga6404c655dd8656efb745c6ee90da2505.html + gga6404c655dd8656efb745c6ee90da2505ad5e3a4dcef58c6d591a7d73a3a02602c + + + + K4A_WIRED_SYNC_MODE_MASTER + group___enumerations_ga6404c655dd8656efb745c6ee90da2505.html + gga6404c655dd8656efb745c6ee90da2505a014b98f7b0c962a994abe1a472bf6697 + + + + K4A_WIRED_SYNC_MODE_SUBORDINATE + group___enumerations_ga6404c655dd8656efb745c6ee90da2505.html + gga6404c655dd8656efb745c6ee90da2505a8140f817b21902d275832a1ef6c216ca + + + + + k4a_calibration_type_t + group___enumerations_ga8d5fae13125f360be86c166684cdb5c5.html + ga8d5fae13125f360be86c166684cdb5c5 + + + + K4A_CALIBRATION_TYPE_UNKNOWN + group___enumerations_ga8d5fae13125f360be86c166684cdb5c5.html + gga8d5fae13125f360be86c166684cdb5c5a1125662b013ee7624cc663a583637d79 + + + + K4A_CALIBRATION_TYPE_DEPTH + group___enumerations_ga8d5fae13125f360be86c166684cdb5c5.html + gga8d5fae13125f360be86c166684cdb5c5a5e8e2174902ceeeb16c4dc54914fcc66 + + + + K4A_CALIBRATION_TYPE_COLOR + group___enumerations_ga8d5fae13125f360be86c166684cdb5c5.html + gga8d5fae13125f360be86c166684cdb5c5a5e5062625d7c0ba242b078daf0b526c3 + + + + K4A_CALIBRATION_TYPE_GYRO + group___enumerations_ga8d5fae13125f360be86c166684cdb5c5.html + gga8d5fae13125f360be86c166684cdb5c5a632965983030d4ff2eea8375ad9ca606 + + + + K4A_CALIBRATION_TYPE_ACCEL + group___enumerations_ga8d5fae13125f360be86c166684cdb5c5.html + gga8d5fae13125f360be86c166684cdb5c5a16f265f6e61cc007d0494f778368ffc1 + + + + K4A_CALIBRATION_TYPE_NUM + group___enumerations_ga8d5fae13125f360be86c166684cdb5c5.html + gga8d5fae13125f360be86c166684cdb5c5a972984dcc30591a8f98034fb582fcfcd + + + + + k4a_calibration_model_type_t + group___enumerations_ga1c33fe57cf4e99fcfd556be60fce4d35.html + ga1c33fe57cf4e99fcfd556be60fce4d35 + + + + K4A_CALIBRATION_LENS_DISTORTION_MODEL_UNKNOWN + group___enumerations_ga1c33fe57cf4e99fcfd556be60fce4d35.html + gga1c33fe57cf4e99fcfd556be60fce4d35a09673a25321231c5966844657df659a0 + + + + K4A_CALIBRATION_LENS_DISTORTION_MODEL_THETA + group___enumerations_ga1c33fe57cf4e99fcfd556be60fce4d35.html + gga1c33fe57cf4e99fcfd556be60fce4d35ad05f33e19c0eba062f09295ae324031c + + + + K4A_CALIBRATION_LENS_DISTORTION_MODEL_POLYNOMIAL_3K + group___enumerations_ga1c33fe57cf4e99fcfd556be60fce4d35.html + gga1c33fe57cf4e99fcfd556be60fce4d35a235e0c967248f931b85854781bed9587 + + + + K4A_CALIBRATION_LENS_DISTORTION_MODEL_RATIONAL_6KT + group___enumerations_ga1c33fe57cf4e99fcfd556be60fce4d35.html + gga1c33fe57cf4e99fcfd556be60fce4d35a78505f093c54ef9496aebbf29c31ecd1 + + + + K4A_CALIBRATION_LENS_DISTORTION_MODEL_BROWN_CONRADY + group___enumerations_ga1c33fe57cf4e99fcfd556be60fce4d35.html + gga1c33fe57cf4e99fcfd556be60fce4d35a3b6f7595f39bb87da3f448385e90d7cf + + + + + k4a_firmware_build_t + group___enumerations_ga78923d8e6a782252bfb9874415ab7f82.html + ga78923d8e6a782252bfb9874415ab7f82 + + + + K4A_FIRMWARE_BUILD_RELEASE + group___enumerations_ga78923d8e6a782252bfb9874415ab7f82.html + gga78923d8e6a782252bfb9874415ab7f82ac7938e2e4432243b0030315dca40b885 + + + + K4A_FIRMWARE_BUILD_DEBUG + group___enumerations_ga78923d8e6a782252bfb9874415ab7f82.html + gga78923d8e6a782252bfb9874415ab7f82a7f0d4e41e2f700250d58dec80c8bfe87 + + + + + k4a_firmware_signature_t + group___enumerations_gaecc6d5a96577361afd83b855b59db7ab.html + gaecc6d5a96577361afd83b855b59db7ab + + + + K4A_FIRMWARE_SIGNATURE_MSFT + group___enumerations_gaecc6d5a96577361afd83b855b59db7ab.html + ggaecc6d5a96577361afd83b855b59db7aba4849e4fdbadcda82898ea4f16876aeae + + + + K4A_FIRMWARE_SIGNATURE_TEST + group___enumerations_gaecc6d5a96577361afd83b855b59db7ab.html + ggaecc6d5a96577361afd83b855b59db7aba79dbf6242833f37a6127582cb69b76e2 + + + + K4A_FIRMWARE_SIGNATURE_UNSIGNED + group___enumerations_gaecc6d5a96577361afd83b855b59db7ab.html + ggaecc6d5a96577361afd83b855b59db7abacbc20c42184a824759f5040f966892a1 + + + + + Macros + Macros + group___macros.html + + #define + K4A_SUCCEEDED + group___macros_ga8e5b48150bc243c6052793bd830c2fcd.html + ga8e5b48150bc243c6052793bd830c2fcd + (_result_) + + + #define + K4A_FAILED + group___macros_ga7c2e32349135d008b6f836c571d434b4.html + ga7c2e32349135d008b6f836c571d434b4 + (_result_) + + + #define + K4A_INIT_STRUCT + group___macros_gaeab021a840259ca3ad882bd080260224.html + gaeab021a840259ca3ad882bd080260224 + (T, S) + + + + Logging + Error and event logging + group___logging.html + + + Prototypes + Callback Function prototypes + group___prototypes.html + + void() + k4a_logging_message_cb_t + group___prototypes_gab303ae435243b852c36bc1981b96adfe.html + gab303ae435243b852c36bc1981b96adfe + (void *context, k4a_log_level_t level, const char *file, const int line, const char *message) + + + void() + k4a_memory_destroy_cb_t + group___prototypes_ga1e290c645920c7674c6d36dcbb75909b.html + ga1e290c645920c7674c6d36dcbb75909b + (void *buffer, void *context) + + + uint8_t *() + k4a_memory_allocate_cb_t + group___prototypes_ga5471d7b53e52a1c10569b2f17bb66b5d.html + ga5471d7b53e52a1c10569b2f17bb66b5d + (int size, void **context) + + + + Structures + Structures + group___structures.html + k4a_device_info_t + k4a_color_mode_info_t + k4a_depth_mode_info_t + k4a_fps_mode_info_t + k4a_device_configuration_t + k4a_calibration_extrinsics_t + k4a_calibration_intrinsic_parameters_t + k4a_calibration_intrinsics_t + k4a_calibration_camera_t + k4a_calibration_t + k4a_version_t + k4a_hardware_version_t + k4a_float2_t + k4a_float3_t + k4a_imu_sample_t + + + device_capabilities​​ + group___structures_ga9a605af3ceaab166fc896a00a64f9324.html + ga9a605af3ceaab166fc896a00a64f9324 + + + + + Definitions + Definitions + group___definitions.html + + #define + K4A_ABI_VERSION + group___definitions_ga91dde801d6ce8feecfd317e330361eee.html + ga91dde801d6ce8feecfd317e330361eee + + + + #define + K4A_DEVICE_DEFAULT + group___definitions_gaebe4c1071a8ba3b04e32d55c85cae72d.html + gaebe4c1071a8ba3b04e32d55c85cae72d + + + + #define + K4A_WAIT_INFINITE + group___definitions_gac012768169429fb54ba09f2964775cb9.html + gac012768169429fb54ba09f2964775cb9 + + + + static const k4a_device_configuration_t + K4A_DEVICE_CONFIG_INIT_DISABLE_ALL + group___definitions_ga4f693ace52a6eeec10cc6ca0350d6601.html + ga4f693ace52a6eeec10cc6ca0350d6601 + + + + diff --git a/examples/calibration/main.cpp b/examples/calibration/main.cpp index 374616f8d..f344afcfa 100644 --- a/examples/calibration/main.cpp +++ b/examples/calibration/main.cpp @@ -40,6 +40,76 @@ static string get_serial(k4a_device_t device) return s; } +static k4a_result_t get_device_mode_ids(k4a_device_t device, uint32_t *color_mode_id, uint32_t *depth_mode_id) +{ + // 1. declare device info and mode infos - note that you must instantiate info structs with struct size and abi + // version of the get methods will not succceed + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + + // 2. get device info + if (!k4a_device_get_info(device, &device_info) == K4A_RESULT_SUCCEEDED) + { + cout << "Failed to get device info" << endl; + return K4A_RESULT_FAILED; + } + + // Capabilities is a bitmask in which bit 0 is depth and bit 1 is color. + bool hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + bool hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + + // 3. get the count of modes + uint32_t color_mode_count = 0; + uint32_t depth_mode_count = 0; + + if (hasColorDevice && !K4A_SUCCEEDED(k4a_device_get_color_mode_count(device, &color_mode_count))) + { + cout << "Failed to get color mode count" << endl; + return K4A_RESULT_FAILED; + } + + if (hasDepthDevice && !K4A_SUCCEEDED(k4a_device_get_depth_mode_count(device, &depth_mode_count))) + { + cout << "Failed to get depth mode count" << endl; + return K4A_RESULT_FAILED; + } + + // 4. find the mode ids you want - for this example, let's find a color mode with a height of at least 1080 or over + // and a depth mode with a height of at least 576 or over and a vertical fov at least 65 or under + if (hasColorDevice && color_mode_count > 1) + { + for (uint32_t c = 0; c < color_mode_count; c++) + { + if (k4a_device_get_color_mode(device, c, &color_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (color_mode_info.height >= 1080) + { + *color_mode_id = color_mode_info.mode_id; + break; + } + } + } + } + + if (hasDepthDevice && depth_mode_count > 1) + { + for (uint32_t d = 0; d < depth_mode_count; d++) + { + if (k4a_device_get_depth_mode(device, d, &depth_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (depth_mode_info.height >= 576 && depth_mode_info.vertical_fov <= 65) + { + *depth_mode_id = depth_mode_info.mode_id; + break; + } + } + } + } + + return K4A_RESULT_SUCCEEDED; +} + static void print_calibration() { uint32_t device_count = k4a_device_get_installed_count(); @@ -57,17 +127,17 @@ static void print_calibration() k4a_calibration_t calibration; - k4a_device_configuration_t deviceConfig = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; - deviceConfig.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - deviceConfig.color_resolution = K4A_COLOR_RESOLUTION_1080P; - deviceConfig.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; - deviceConfig.camera_fps = K4A_FRAMES_PER_SECOND_30; - deviceConfig.wired_sync_mode = K4A_WIRED_SYNC_MODE_STANDALONE; - deviceConfig.synchronized_images_only = true; + uint32_t color_mode_id = 0; + uint32_t depth_mode_id = 0; + + if (!K4A_SUCCEEDED(get_device_mode_ids(device, &color_mode_id, &depth_mode_id))) + { + cout << "Failed to get device mode ids" << endl; + exit(-1); + } // get calibration - if (K4A_RESULT_SUCCEEDED != - k4a_device_get_calibration(device, deviceConfig.depth_mode, deviceConfig.color_resolution, &calibration)) + if (!K4A_SUCCEEDED(k4a_device_get_calibration(device, depth_mode_id, color_mode_id, &calibration))) { cout << "Failed to get calibration" << endl; exit(-1); @@ -165,4 +235,4 @@ int main(int argc, char **argv) } return 0; -} +} \ No newline at end of file diff --git a/examples/fastpointcloud/main.cpp b/examples/fastpointcloud/main.cpp index 116f7ef91..45d63336f 100644 --- a/examples/fastpointcloud/main.cpp +++ b/examples/fastpointcloud/main.cpp @@ -109,6 +109,89 @@ static void write_point_cloud(const char *file_name, const k4a_image_t point_clo ofs_text.write(ss.str().c_str(), (std::streamsize)ss.str().length()); } +static k4a_result_t get_device_mode_ids(k4a_device_t device, uint32_t *depth_mode_id, uint32_t *fps_mode_id) +{ + // 1. declare device info and depth and color modes - note that you must instantiate info structs with struct size + // and abi version of the get methods will not succceed + k4a_fps_mode_info_t fps_mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + + // 2. get the count of modes + uint32_t depth_mode_count = 0; + uint32_t fps_mode_count = 0; + + // 3. get device info + if (!k4a_device_get_info(device, &device_info) == K4A_RESULT_SUCCEEDED) + { + std::cout << "Failed to get device info" << std::endl; + return K4A_RESULT_FAILED; + } + + bool hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + + if (hasDepthDevice && !K4A_SUCCEEDED(k4a_device_get_depth_mode_count(device, &depth_mode_count))) + { + std::cout << "Failed to get depth mode count" << std::endl; + return K4A_RESULT_FAILED; + } + + if (!k4a_device_get_fps_mode_count(device, &fps_mode_count) == K4A_RESULT_SUCCEEDED) + { + std::cout << "Failed to get fps mode count" << std::endl; + return K4A_RESULT_FAILED; + } + + // 4. find the mode ids you want - for this example, let's find a color mode with a height of at least 720 or over, + // a depth mode with a height of at least 512 or over and a vertical fov at least 120 or over and the fps mode with + // the heightest fps + if (hasDepthDevice && depth_mode_count > 1) + { + for (uint32_t d = 0; d < depth_mode_count; d++) + { + k4a_depth_mode_info_t depth_mode = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + if (k4a_device_get_depth_mode(device, d, &depth_mode) == K4A_RESULT_SUCCEEDED) + { + if (depth_mode.height >= 512 && depth_mode.vertical_fov >= 120) + { + *depth_mode_id = depth_mode.mode_id; + break; + } + } + } + } + + if (fps_mode_count > 1) + { + uint32_t max_fps = 0; + for (uint32_t f = 0; f < fps_mode_count; f++) + { + if (k4a_device_get_fps_mode(device, f, &fps_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (fps_mode_info.fps >= max_fps) + { + max_fps = (uint32_t)fps_mode_info.fps; + *fps_mode_id = fps_mode_info.mode_id; + } + } + } + } + + // 5. fps mode id must not be set to 0, which is Off, and either color mode id or depth mode id must not be set to 0 + if (*fps_mode_id == 0) + { + std::cout << "Fps mode id must not be set to 0 (Off)" << std::endl; + return K4A_RESULT_FAILED; + } + + if (*depth_mode_id == 0) + { + std::cout << "Either color mode id or depth mode id must not be set to 0 (Off)" << std::endl; + return K4A_RESULT_FAILED; + } + + return K4A_RESULT_SUCCEEDED; +} + int main(int argc, char **argv) { int returnCode = 1; @@ -123,6 +206,9 @@ int main(int argc, char **argv) k4a_image_t point_cloud = NULL; int point_count = 0; + uint32_t depth_mode_id = 0; + uint32_t fps_mode_id = 0; + if (argc != 2) { printf("fastpointcloud.exe \n"); @@ -146,12 +232,18 @@ int main(int argc, char **argv) goto Exit; } - config.depth_mode = K4A_DEPTH_MODE_WFOV_2X2BINNED; - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + if (!K4A_SUCCEEDED(get_device_mode_ids(device, &depth_mode_id, &fps_mode_id))) + { + std::cout << "Failed to get device mode ids" << std::endl; + exit(-1); + } + + config.depth_mode_id = depth_mode_id; + config.fps_mode_id = fps_mode_id; k4a_calibration_t calibration; if (K4A_RESULT_SUCCEEDED != - k4a_device_get_calibration(device, config.depth_mode, config.color_resolution, &calibration)) + k4a_device_get_calibration(device, config.depth_mode_id, config.color_mode_id, &calibration)) { printf("Failed to get calibration\n"); goto Exit; @@ -186,6 +278,7 @@ int main(int argc, char **argv) printf("Timed out waiting for a capture\n"); goto Exit; case K4A_WAIT_RESULT_FAILED: + case K4A_WAIT_RESULT_UNSUPPORTED: printf("Failed to read a capture\n"); goto Exit; } @@ -215,4 +308,4 @@ int main(int argc, char **argv) } return returnCode; -} +} \ No newline at end of file diff --git a/examples/green_screen/main.cpp b/examples/green_screen/main.cpp index 74425e341..aeb8c1709 100644 --- a/examples/green_screen/main.cpp +++ b/examples/green_screen/main.cpp @@ -158,8 +158,8 @@ int main(int argc, char **argv) k4a_device_configuration_t secondary_config = get_subordinate_config(); // Construct all the things that we'll need whether or not we are running with 1 or 2 cameras - k4a::calibration main_calibration = capturer.get_master_device().get_calibration(main_config.depth_mode, - main_config.color_resolution); + k4a::calibration main_calibration = capturer.get_master_device().get_calibration(main_config.depth_mode_id, + main_config.color_mode_id); // Set up a transformation. DO THIS OUTSIDE OF YOUR MAIN LOOP! Constructing transformations involves time-intensive // hardware setup and should not change once you have a rigid setup, so only call it once or it will run very @@ -214,8 +214,8 @@ int main(int argc, char **argv) calibration_timeout); k4a::calibration secondary_calibration = - capturer.get_subordinate_device_by_index(0).get_calibration(secondary_config.depth_mode, - secondary_config.color_resolution); + capturer.get_subordinate_device_by_index(0).get_calibration(secondary_config.depth_mode_id, + secondary_config.color_mode_id); // Get the transformation from secondary depth to secondary color using its calibration object Transformation tr_secondary_depth_to_secondary_color = get_depth_to_color_transformation_from_calibration( secondary_calibration); @@ -504,6 +504,114 @@ Transformation stereo_calibration(const k4a::calibration &main_calib, return tr; } +static k4a_result_t +get_device_mode_ids(k4a_device_t device, uint32_t *color_mode_id, uint32_t *depth_mode_id, uint32_t *fps_mode_id) +{ + + // 1. declare device info and depth and color modes - note that you must instantiate info structs with struct size + // and abi version of the get methods will not succceed + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_fps_mode_info_t fps_mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + + // 1. get available modes from device info + if (!k4a_device_get_info(device, &device_info) == K4A_RESULT_SUCCEEDED) + { + cout << "Failed to get device info" << endl; + return K4A_RESULT_FAILED; + } + + bool hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + bool hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + + // 2. get the count of modes + uint32_t color_mode_count = 0; + uint32_t depth_mode_count = 0; + uint32_t fps_mode_count = 0; + + if (hasColorDevice && !K4A_SUCCEEDED(k4a_device_get_color_mode_count(device, &color_mode_count))) + { + cout << "Failed to get color mode count" << endl; + return K4A_RESULT_FAILED; + } + + if (hasDepthDevice && !K4A_SUCCEEDED(k4a_device_get_depth_mode_count(device, &depth_mode_count))) + { + cout << "Failed to get depth mode count" << endl; + return K4A_RESULT_FAILED; + } + + if (!k4a_device_get_fps_mode_count(device, &fps_mode_count) == K4A_RESULT_SUCCEEDED) + { + cout << "Failed to get fps mode count" << endl; + return K4A_RESULT_FAILED; + } + + // 3. find the mode ids you want - for this example, let's find a color mode with a height of at least 720 or over, + // a depth mode with a height of at least 1024 or over and a vertical fov at least 120 or over and the fps mode with + // an fps of at least 15 + if (hasColorDevice && color_mode_count > 1) + { + for (uint32_t c = 0; c < color_mode_count; c++) + { + if (k4a_device_get_color_mode(device, c, &color_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (color_mode_info.height >= 720) + { + *color_mode_id = color_mode_info.mode_id; + break; + } + } + } + } + + if (hasDepthDevice && depth_mode_count > 1) + { + for (uint32_t d = 0; d < depth_mode_count; d++) + { + if (k4a_device_get_depth_mode(device, d, &depth_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (depth_mode_info.height >= 1024 && depth_mode_info.vertical_fov <= 120) + { + *depth_mode_id = depth_mode_info.mode_id; + break; + } + } + } + } + + if (fps_mode_count > 1) + { + for (uint32_t f = 0; f < fps_mode_count; f++) + { + if (k4a_device_get_fps_mode(device, f, &fps_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (fps_mode_info.fps >= 15) + { + *fps_mode_id = f; + break; + } + } + } + } + + // 4. fps mode id must not be set to 0, which is Off, and either color mode id or depth mode id must not be set to 0 + if (*fps_mode_id == 0) + { + cout << "Fps mode id must not be set to 0 (Off)" << endl; + return K4A_RESULT_FAILED; + } + + if (*color_mode_id == 0 && *depth_mode_id == 0) + { + cout << "Either color mode id or depth mode id must not be set to 0 (Off)" << endl; + return K4A_RESULT_FAILED; + } + + return K4A_RESULT_SUCCEEDED; +} + // The following functions provide the configurations that should be used for each camera. // NOTE: For best results both cameras should have the same configuration (framerate, resolution, color and depth // modes). Additionally the both master and subordinate should have the same exposure and power line settings. Exposure @@ -513,12 +621,29 @@ Transformation stereo_calibration(const k4a::calibration &main_calib, // static k4a_device_configuration_t get_default_config() { + uint32_t color_mode_id = 0; + uint32_t depth_mode_id = 0; + uint32_t fps_mode_id = 0; + + k4a_device_t device = NULL; + if (K4A_RESULT_SUCCEEDED != k4a_device_open(0, &device)) + { + cout << 0 << ": Failed to open device" << endl; + exit(-1); + } + + if (!K4A_SUCCEEDED(get_device_mode_ids(device, &color_mode_id, &depth_mode_id, &fps_mode_id))) + { + cout << "Failed to get device mode ids" << endl; + exit(-1); + } + k4a_device_configuration_t camera_config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; camera_config.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32; - camera_config.color_resolution = K4A_COLOR_RESOLUTION_720P; - camera_config.depth_mode = K4A_DEPTH_MODE_WFOV_UNBINNED; // No need for depth during calibration - camera_config.camera_fps = K4A_FRAMES_PER_SECOND_15; // Don't use all USB bandwidth - camera_config.subordinate_delay_off_master_usec = 0; // Must be zero for master + camera_config.color_mode_id = color_mode_id; + camera_config.depth_mode_id = depth_mode_id; + camera_config.fps_mode_id = fps_mode_id; + camera_config.subordinate_delay_off_master_usec = 0; // Must be zero for master camera_config.synchronized_images_only = true; return camera_config; } @@ -561,12 +686,12 @@ static Transformation calibrate_devices(MultiDeviceCapturer &capturer, float chessboard_square_length, double calibration_timeout) { - k4a::calibration main_calibration = capturer.get_master_device().get_calibration(main_config.depth_mode, - main_config.color_resolution); + k4a::calibration main_calibration = capturer.get_master_device().get_calibration(main_config.depth_mode_id, + main_config.color_mode_id); k4a::calibration secondary_calibration = - capturer.get_subordinate_device_by_index(0).get_calibration(secondary_config.depth_mode, - secondary_config.color_resolution); + capturer.get_subordinate_device_by_index(0).get_calibration(secondary_config.depth_mode_id, + secondary_config.color_mode_id); vector> main_chessboard_corners_list; vector> secondary_chessboard_corners_list; std::chrono::time_point start_time = std::chrono::system_clock::now(); @@ -625,4 +750,4 @@ static k4a::image create_depth_image_like(const k4a::image &im) im.get_width_pixels(), im.get_height_pixels(), im.get_width_pixels() * static_cast(sizeof(uint16_t))); -} +} \ No newline at end of file diff --git a/examples/k4arecord_custom_track/main.c b/examples/k4arecord_custom_track/main.c index e0bbadfeb..0b1925618 100644 --- a/examples/k4arecord_custom_track/main.c +++ b/examples/k4arecord_custom_track/main.c @@ -50,6 +50,114 @@ void fill_bitmap_header(uint32_t width, uint32_t height, BITMAPINFOHEADER *out) out->biClrImportant = 0; } +static k4a_result_t +get_device_mode_ids(k4a_device_t device, uint32_t *color_mode_id, uint32_t *depth_mode_id, uint32_t *fps_mode_id) +{ + // 1. get available modes from device info - note that you must instantiate info structs with struct size and abi + // version of the get methods will not succceed + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + if (!k4a_device_get_info(device, &device_info) == K4A_RESULT_SUCCEEDED) + { + printf("Failed to get device info"); + return K4A_RESULT_FAILED; + } + + bool hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + bool hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + + // 2. declare mode infos + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_fps_mode_info_t fps_mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + + // 3. get the count of modes + uint32_t color_mode_count = 0; + uint32_t depth_mode_count = 0; + uint32_t fps_mode_count = 0; + + if (hasColorDevice && !K4A_SUCCEEDED(k4a_device_get_color_mode_count(device, &color_mode_count))) + { + printf("Failed to get color mode count\n"); + return K4A_RESULT_FAILED; + } + + if (hasDepthDevice && !K4A_SUCCEEDED(k4a_device_get_depth_mode_count(device, &depth_mode_count))) + { + printf("Failed to get depth mode count\n"); + return K4A_RESULT_FAILED; + } + + if (!k4a_device_get_fps_mode_count(device, &fps_mode_count) == K4A_RESULT_SUCCEEDED) + { + printf("Failed to get fps mode count\n"); + return K4A_RESULT_FAILED; + } + + // 4. find the mode ids you want - for this example, let's find a color mode with a mode id of 0, which is Off, a + // depth mode with a height of at least 288 or under and a vertical fov at least 65 or under and the fps mode with + // the heightest fps + if (hasColorDevice && color_mode_count > 1) + { + for (uint32_t c = 0; c < color_mode_count; c++) + { + if (k4a_device_get_color_mode(device, c, &color_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (color_mode_info.mode_id == 0) + { + *color_mode_id = color_mode_info.mode_id; + break; + } + } + } + } + + if (hasDepthDevice && depth_mode_count > 1) + { + for (uint32_t d = 0; d < depth_mode_count; d++) + { + if (k4a_device_get_depth_mode(device, d, &depth_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (depth_mode_info.height <= 288 && depth_mode_info.vertical_fov <= 65) + { + *depth_mode_id = depth_mode_info.mode_id; + break; + } + } + } + } + + if (fps_mode_count > 1) + { + uint32_t max_fps = 0; + for (uint32_t f = 0; f < fps_mode_count; f++) + { + if (k4a_device_get_fps_mode(device, f, &fps_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (fps_mode_info.fps >= max_fps) + { + max_fps = (uint32_t)fps_mode_info.fps; + *fps_mode_id = fps_mode_info.mode_id; + } + } + } + } + + // 5. fps mode id must not be set to 0, which is Off, and either color mode id or depth mode id must not be set to 0 + if (*fps_mode_id == 0) + { + printf("Fps mode id must not be set to 0 (Off)\n"); + return K4A_RESULT_FAILED; + } + + if (*color_mode_id == 0 && *depth_mode_id == 0) + { + printf("Either color mode id or depth mode id must not be set to 0 (Off)\n"); + return K4A_RESULT_FAILED; + } + + return K4A_RESULT_SUCCEEDED; +} + int main(int argc, char **argv) { if (argc < 2) @@ -60,12 +168,23 @@ int main(int argc, char **argv) char *recording_filename = argv[1]; - k4a_device_configuration_t device_config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; - device_config.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; - device_config.camera_fps = K4A_FRAMES_PER_SECOND_30; - k4a_device_t device; VERIFY(k4a_device_open(0, &device)); + + uint32_t color_mode_id = 0; + uint32_t depth_mode_id = 0; + uint32_t fps_mode_id = 0; + + if (!K4A_SUCCEEDED(get_device_mode_ids(device, &color_mode_id, &depth_mode_id, &fps_mode_id))) + { + printf("Failed to get device mode ids\n"); + exit(-1); + } + + k4a_device_configuration_t device_config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; + device_config.depth_mode_id = depth_mode_id; + device_config.fps_mode_id = fps_mode_id; + VERIFY(k4a_device_start_cameras(device, &device_config)); printf("Device started\n"); @@ -90,7 +209,7 @@ int main(int argc, char **argv) // Add a custom video track to store processed depth images. // Read the depth resolution from the camera configuration so we can create our custom track with the same size. k4a_calibration_t sensor_calibration; - VERIFY(k4a_device_get_calibration(device, device_config.depth_mode, K4A_COLOR_RESOLUTION_OFF, &sensor_calibration)); + VERIFY(k4a_device_get_calibration(device, depth_mode_id, color_mode_id, &sensor_calibration)); uint32_t depth_width = (uint32_t)sensor_calibration.depth_camera_calibration.resolution_width; uint32_t depth_height = (uint32_t)sensor_calibration.depth_camera_calibration.resolution_height; @@ -182,4 +301,4 @@ int main(int argc, char **argv) k4a_device_close(device); return 0; -} +} \ No newline at end of file diff --git a/examples/opencv_compatibility/main.cpp b/examples/opencv_compatibility/main.cpp index f8a76b24d..137f6d80b 100644 --- a/examples/opencv_compatibility/main.cpp +++ b/examples/opencv_compatibility/main.cpp @@ -2,9 +2,7 @@ // Licensed under the MIT License. #include - #include - #include using namespace std; @@ -20,12 +18,128 @@ static void clean_up(k4a_device_t device) } } +static k4a_result_t +get_device_mode_ids(k4a_device_t device, uint32_t *color_mode_id, uint32_t *depth_mode_id, uint32_t *fps_mode_id) +{ + // 1. declare device info and mode infos - note that you must instantiate info structs with struct size and abi + // version of the get methods will not succceed + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_fps_mode_info_t fps_mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + + // 2. initialize device capabilities + bool hasDepthDevice = false; + bool hasColorDevice = false; + + // 3. get the count of modes + uint32_t color_mode_count = 0; + uint32_t depth_mode_count = 0; + uint32_t fps_mode_count = 0; + + // 4. get available modes from device info + if (!k4a_device_get_info(device, &device_info) == K4A_RESULT_SUCCEEDED) + { + printf("Failed to get device info\n"); + return K4A_RESULT_FAILED; + } + + hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + + if (hasColorDevice && !K4A_SUCCEEDED(k4a_device_get_color_mode_count(device, &color_mode_count))) + { + printf("Failed to get color mode count\n"); + return K4A_RESULT_FAILED; + } + + if (hasDepthDevice && !K4A_SUCCEEDED(k4a_device_get_depth_mode_count(device, &depth_mode_count))) + { + printf("Failed to get depth mode count\n"); + return K4A_RESULT_FAILED; + } + + if (!k4a_device_get_fps_mode_count(device, &fps_mode_count) == K4A_RESULT_SUCCEEDED) + { + printf("Failed to get fps mode count\n"); + return K4A_RESULT_FAILED; + } + + // 5. find the mode ids you want - for this example, let's find a color mode with a height of at least 1080 or over, + // a depth mode with a height of at least 512 or under and a vertical fov at least 65 or under and the fps mode with + // the heightest fps + if (hasColorDevice && color_mode_count > 1) + { + for (uint32_t c = 0; c < color_mode_count; c++) + { + if (k4a_device_get_color_mode(device, c, &color_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (color_mode_info.height >= 1080) + { + *color_mode_id = color_mode_info.mode_id; + break; + } + } + } + } + + if (hasDepthDevice && depth_mode_count > 1) + { + for (uint32_t d = 0; d < depth_mode_count; d++) + { + if (k4a_device_get_depth_mode(device, d, &depth_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (depth_mode_info.height <= 512 && depth_mode_info.vertical_fov <= 65) + { + *depth_mode_id = depth_mode_info.mode_id; + break; + } + } + } + } + + if (fps_mode_count > 1) + { + uint32_t max_fps = 0; + for (uint32_t f = 0; f < fps_mode_count; f++) + { + if (k4a_device_get_fps_mode(device, f, &fps_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (fps_mode_info.fps >= max_fps) + { + max_fps = (uint32_t)fps_mode_info.fps; + *fps_mode_id = fps_mode_info.mode_id; + } + } + } + } + + // 6. fps mode id must not be set to 0, which is Off, and either color mode id or depth mode id must not be set to 0 + if (*fps_mode_id == 0) + { + printf("Fps mode id must not be set to 0 (Off)\n"); + return K4A_RESULT_FAILED; + } + + if (*color_mode_id == 0 && *depth_mode_id == 0) + { + printf("Either color mode id or depth mode id must not be set to 0 (Off)\n"); + return K4A_RESULT_FAILED; + } + + return K4A_RESULT_SUCCEEDED; +} + int main(int argc, char ** /*argv*/) { uint32_t device_count = 0; k4a_device_t device = NULL; k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; + uint32_t color_mode_id = 0; + uint32_t depth_mode_id = 0; + uint32_t fps_mode_id = 0; + if (argc != 1) { printf("Usage: opencv_example.exe\n"); @@ -47,13 +161,19 @@ int main(int argc, char ** /*argv*/) return 1; } - config.depth_mode = K4A_DEPTH_MODE_WFOV_2X2BINNED; - config.color_resolution = K4A_COLOR_RESOLUTION_1080P; - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + if (!K4A_SUCCEEDED(get_device_mode_ids(device, &color_mode_id, &depth_mode_id, &fps_mode_id))) + { + printf("Failed to get device mode ids\n"); + exit(-1); + } + + config.color_mode_id = color_mode_id; + config.depth_mode_id = depth_mode_id; + config.fps_mode_id = fps_mode_id; k4a_calibration_t calibration; if (K4A_RESULT_SUCCEEDED != - k4a_device_get_calibration(device, config.depth_mode, config.color_resolution, &calibration)) + k4a_device_get_calibration(device, config.depth_mode_id, config.color_mode_id, &calibration)) { printf("Failed to get calibration\n"); clean_up(device); @@ -117,4 +237,4 @@ int main(int argc, char ** /*argv*/) clean_up(device); return 0; -} +} \ No newline at end of file diff --git a/examples/streaming/main.c b/examples/streaming/main.c index aaff265bd..e910523f9 100644 --- a/examples/streaming/main.c +++ b/examples/streaming/main.c @@ -5,6 +5,118 @@ #include #include +static k4a_result_t +get_device_mode_ids(k4a_device_t device, uint32_t *color_mode_id, uint32_t *depth_mode_id, uint32_t *fps_mode_id) +{ + // 1. declare device info and mode infos - note that you must instantiate info structs with struct size and abi + // version of the get methods will not succceed + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_fps_mode_info_t fps_mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + + // 2. initialize device capabilities + bool hasDepthDevice = false; + bool hasColorDevice = false; + + // 3. get the count of modes + uint32_t color_mode_count = 0; + uint32_t depth_mode_count = 0; + uint32_t fps_mode_count = 0; + + // 4. get available modes from device info + if (!k4a_device_get_info(device, &device_info) == K4A_RESULT_SUCCEEDED) + { + printf("Failed to get device info"); + return K4A_RESULT_FAILED; + } + + hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + + if (hasColorDevice && !K4A_SUCCEEDED(k4a_device_get_color_mode_count(device, &color_mode_count))) + { + printf("Failed to get color mode count\n"); + return K4A_RESULT_FAILED; + } + + if (hasDepthDevice && !K4A_SUCCEEDED(k4a_device_get_depth_mode_count(device, &depth_mode_count))) + { + printf("Failed to get depth mode count\n"); + return K4A_RESULT_FAILED; + } + + if (!k4a_device_get_fps_mode_count(device, &fps_mode_count) == K4A_RESULT_SUCCEEDED) + { + printf("Failed to get fps mode count\n"); + return K4A_RESULT_FAILED; + } + + // 5. find the mode ids you want - for this example, let's find a color mode with a height of at least 2160 or over, + // a depth mode with a height of at least 576 or over and a vertical fov at least 65 or under and the fps mode with + // the heightest fps + if (hasColorDevice && color_mode_count > 1) + { + for (uint32_t c = 0; c < color_mode_count; c++) + { + if (k4a_device_get_color_mode(device, c, &color_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (color_mode_info.height >= 2160) + { + *color_mode_id = color_mode_info.mode_id; + break; + } + } + } + } + + if (hasDepthDevice && depth_mode_count > 1) + { + for (uint32_t d = 0; d < depth_mode_count; d++) + { + if (k4a_device_get_depth_mode(device, d, &depth_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (depth_mode_info.height >= 576 && depth_mode_info.vertical_fov <= 65) + { + *depth_mode_id = depth_mode_info.mode_id; + break; + } + } + } + } + + if (fps_mode_count > 1) + { + uint32_t max_fps = 0; + for (uint32_t f = 0; f < fps_mode_count; f++) + { + if (k4a_device_get_fps_mode(device, f, &fps_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (fps_mode_info.fps >= max_fps) + { + max_fps = (uint32_t)fps_mode_info.fps; + *fps_mode_id = fps_mode_info.mode_id; + } + } + } + } + + // 6. fps mode id must not be set to 0, which is Off, and either color mode id or depth mode id must not be set to 0 + if (*fps_mode_id == 0) + { + printf("Fps mode id must not be set to 0 (Off)\n"); + return K4A_RESULT_FAILED; + } + + if (*color_mode_id == 0 && *depth_mode_id == 0) + { + printf("Either color mode id or depth mode id must not be set to 0 (Off)\n"); + return K4A_RESULT_FAILED; + } + + return K4A_RESULT_SUCCEEDED; +} + int main(int argc, char **argv) { int returnCode = 1; @@ -13,6 +125,10 @@ int main(int argc, char **argv) int captureFrameCount; k4a_capture_t capture = NULL; + uint32_t color_mode_id = 0; + uint32_t depth_mode_id = 0; + uint32_t fps_mode_id = 0; + if (argc < 2) { printf("%s FRAMECOUNT\n", argv[0]); @@ -38,11 +154,17 @@ int main(int argc, char **argv) goto Exit; } + if (!K4A_SUCCEEDED(get_device_mode_ids(device, &color_mode_id, &depth_mode_id, &fps_mode_id))) + { + printf("Failed to get device mode ids\n"); + exit(-1); + } + k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config.color_resolution = K4A_COLOR_RESOLUTION_2160P; - config.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + config.color_mode_id = color_mode_id; + config.depth_mode_id = depth_mode_id; + config.fps_mode_id = fps_mode_id; if (K4A_RESULT_SUCCEEDED != k4a_device_start_cameras(device, &config)) { @@ -64,6 +186,7 @@ int main(int argc, char **argv) continue; break; case K4A_WAIT_RESULT_FAILED: + case K4A_WAIT_RESULT_UNSUPPORTED: printf("Failed to read a capture\n"); goto Exit; } @@ -128,4 +251,4 @@ int main(int argc, char **argv) } return returnCode; -} +} \ No newline at end of file diff --git a/examples/transformation/main.cpp b/examples/transformation/main.cpp index 9211c8f01..f089b962c 100644 --- a/examples/transformation/main.cpp +++ b/examples/transformation/main.cpp @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#include #include #include #include @@ -116,6 +117,118 @@ static bool point_cloud_depth_to_color(k4a_transformation_t transformation_handl return true; } +static k4a_result_t +get_device_mode_ids(k4a_device_t device, uint32_t *color_mode_id, uint32_t *depth_mode_id, uint32_t *fps_mode_id) +{ + // 1. declare device info and mode infos - note that you must instantiate info structs with struct size and abi + // version of the get methods will not succceed + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_fps_mode_info_t fps_mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + + // 2. initialize device capabilities + bool hasDepthDevice = false; + bool hasColorDevice = false; + + // 3. get the count of modes + uint32_t color_mode_count = 0; + uint32_t depth_mode_count = 0; + uint32_t fps_mode_count = 0; + + // 4. get available modes from device info + if (!k4a_device_get_info(device, &device_info) == K4A_RESULT_SUCCEEDED) + { + std::cout << "Failed to get device info" << std::endl; + exit(-1); + } + + hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + + if (hasColorDevice && !K4A_SUCCEEDED(k4a_device_get_color_mode_count(device, &color_mode_count))) + { + std::cout << "Failed to get color mode count" << std::endl; + return K4A_RESULT_FAILED; + } + + if (hasDepthDevice && !K4A_SUCCEEDED(k4a_device_get_depth_mode_count(device, &depth_mode_count))) + { + std::cout << "Failed to get depth mode count" << std::endl; + return K4A_RESULT_FAILED; + } + + if (!k4a_device_get_fps_mode_count(device, &fps_mode_count) == K4A_RESULT_SUCCEEDED) + { + std::cout << "Failed to get fps mode count" << std::endl; + return K4A_RESULT_FAILED; + } + + // 5. find the mode ids you want - for this example, let's find a color mode with a height of at least 720 or over, + // a depth mode with a height of at least 576 or over and a vertical fov at least 65 or under and the fps mode with + // the heightest fps + if (hasColorDevice && color_mode_count > 1) + { + for (uint32_t c = 0; c < color_mode_count; c++) + { + if (k4a_device_get_color_mode(device, c, &color_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (color_mode_info.height >= 720) + { + *color_mode_id = color_mode_info.mode_id; + break; + } + } + } + } + + if (hasDepthDevice && depth_mode_count > 1) + { + for (uint32_t d = 0; d < depth_mode_count; d++) + { + if (k4a_device_get_depth_mode(device, d, &depth_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (depth_mode_info.height >= 576 && depth_mode_info.vertical_fov <= 65) + { + *depth_mode_id = depth_mode_info.mode_id; + break; + } + } + } + } + + if (fps_mode_count > 1) + { + uint32_t max_fps = 0; + for (uint32_t f = 0; f < fps_mode_count; f++) + { + if (k4a_device_get_fps_mode(device, f, &fps_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (fps_mode_info.fps >= max_fps) + { + max_fps = (uint32_t)fps_mode_info.fps; + *fps_mode_id = fps_mode_info.mode_id; + } + } + } + } + + // 6. fps mode id must not be set to 0, which is Off, and either color mode id or depth mode id must not be set to 0 + if (*fps_mode_id == 0) + { + std::cout << "Fps mode id must not be set to 0 (Off)" << std::endl; + return K4A_RESULT_FAILED; + } + + if (*color_mode_id == 0 && *depth_mode_id == 0) + { + std::cout << "Either color mode id or depth mode id must not be set to 0 (Off)" << std::endl; + return K4A_RESULT_FAILED; + } + + return K4A_RESULT_SUCCEEDED; +} + static int capture(std::string output_dir, uint8_t deviceId = K4A_DEVICE_DEFAULT) { int returnCode = 1; @@ -131,6 +244,10 @@ static int capture(std::string output_dir, uint8_t deviceId = K4A_DEVICE_DEFAULT k4a_image_t color_image = NULL; k4a_image_t color_image_downscaled = NULL; + uint32_t color_mode_id = 0; + uint32_t depth_mode_id = 0; + uint32_t fps_mode_id = 0; + device_count = k4a_device_get_installed_count(); if (device_count == 0) @@ -145,15 +262,21 @@ static int capture(std::string output_dir, uint8_t deviceId = K4A_DEVICE_DEFAULT goto Exit; } + if (!K4A_SUCCEEDED(get_device_mode_ids(device, &color_mode_id, &depth_mode_id, &fps_mode_id))) + { + std::cout << "Failed to get device mode ids" << std::endl; + exit(-1); + } + config.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32; - config.color_resolution = K4A_COLOR_RESOLUTION_720P; - config.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + config.color_mode_id = color_mode_id; + config.depth_mode_id = depth_mode_id; + config.fps_mode_id = fps_mode_id; config.synchronized_images_only = true; // ensures that depth and color images are both available in the capture k4a_calibration_t calibration; if (K4A_RESULT_SUCCEEDED != - k4a_device_get_calibration(device, config.depth_mode, config.color_resolution, &calibration)) + k4a_device_get_calibration(device, config.depth_mode_id, config.color_mode_id, &calibration)) { printf("Failed to get calibration\n"); goto Exit; @@ -176,6 +299,7 @@ static int capture(std::string output_dir, uint8_t deviceId = K4A_DEVICE_DEFAULT printf("Timed out waiting for a capture\n"); goto Exit; case K4A_WAIT_RESULT_FAILED: + case K4A_WAIT_RESULT_UNSUPPORTED: printf("Failed to read a capture\n"); goto Exit; } @@ -491,4 +615,4 @@ int main(int argc, char **argv) } return returnCode; -} +} \ No newline at end of file diff --git a/examples/undistort/main.cpp b/examples/undistort/main.cpp index f2d5eb66e..cc72c4a8f 100644 --- a/examples/undistort/main.cpp +++ b/examples/undistort/main.cpp @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#include #include #include #include @@ -333,6 +334,118 @@ static void write_csv_file(const char *file_name, const k4a_image_t src) fclose(fp); } +static k4a_result_t +get_device_mode_ids(k4a_device_t device, uint32_t *color_mode_id, uint32_t *depth_mode_id, uint32_t *fps_mode_id) +{ + // 1. declare device info and mode infos - note that you must instantiate info structs with struct size and abi + // version of the get methods will not succceed + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_fps_mode_info_t fps_mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + + // 2. initialize device capabilities + bool hasDepthDevice = false; + bool hasColorDevice = false; + + // 3. get the count of modes + uint32_t color_mode_count = 0; + uint32_t depth_mode_count = 0; + uint32_t fps_mode_count = 0; + + // 5. get available modes from device info + if (!k4a_device_get_info(device, &device_info) == K4A_RESULT_SUCCEEDED) + { + printf("Failed to get device info"); + return K4A_RESULT_FAILED; + } + + hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + + if (hasColorDevice && !K4A_SUCCEEDED(k4a_device_get_color_mode_count(device, &color_mode_count))) + { + std::cout << "Failed to get color mode count" << std::endl; + return K4A_RESULT_FAILED; + } + + if (hasDepthDevice && !K4A_SUCCEEDED(k4a_device_get_depth_mode_count(device, &depth_mode_count))) + { + std::cout << "Failed to get depth mode count" << std::endl; + return K4A_RESULT_FAILED; + } + + if (!k4a_device_get_fps_mode_count(device, &fps_mode_count) == K4A_RESULT_SUCCEEDED) + { + std::cout << "Failed to get fps mode count" << std::endl; + return K4A_RESULT_FAILED; + } + + // 6. find the mode ids you want - for this example, let's find a color mode with mode id of 0, which is Off, a + // depth mode with a height under 512 and a vertical fov of at least 120 or over and the fps mode with the heightest + // fps + if (hasColorDevice && color_mode_count > 1) + { + for (uint32_t c = 0; c < color_mode_count; c++) + { + if (k4a_device_get_color_mode(device, c, &color_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (color_mode_info.mode_id == 0) + { + *color_mode_id = color_mode_info.mode_id; + break; + } + } + } + } + + if (hasDepthDevice && depth_mode_count > 1) + { + for (uint32_t d = 0; d < depth_mode_count; d++) + { + if (k4a_device_get_depth_mode(device, d, &depth_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (depth_mode_info.height <= 512 && depth_mode_info.vertical_fov >= 120) + { + *depth_mode_id = depth_mode_info.mode_id; + break; + } + } + } + } + + if (fps_mode_count > 1) + { + uint32_t max_fps = 0; + for (uint32_t f = 0; f < fps_mode_count; f++) + { + if (k4a_device_get_fps_mode(device, f, &fps_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (fps_mode_info.fps >= max_fps) + { + max_fps = (uint32_t)fps_mode_info.fps; + *fps_mode_id = fps_mode_info.mode_id; + } + } + } + } + + // 7. fps mode id must not be set to 0, which is Off, and either color mode id or depth mode id must not be set to 0 + if (*fps_mode_id == 0) + { + std::cout << "Fps mode id must not be set to 0 (Off)" << std::endl; + return K4A_RESULT_FAILED; + } + + if (*color_mode_id == 0 && *depth_mode_id == 0) + { + std::cout << "Either color mode id or depth mode id must not be set to 0 (Off)" << std::endl; + return K4A_RESULT_FAILED; + } + + return K4A_RESULT_SUCCEEDED; +} + int main(int argc, char **argv) { int returnCode = 1; @@ -348,6 +461,10 @@ int main(int argc, char **argv) interpolation_t interpolation_type = INTERPOLATION_NEARESTNEIGHBOR; pinhole_t pinhole; + uint32_t color_mode_id = 0; + uint32_t depth_mode_id = 0; + uint32_t fps_mode_id = 0; + if (argc != 3) { printf("undistort.exe \n"); @@ -377,12 +494,18 @@ int main(int argc, char **argv) goto Exit; } - config.depth_mode = K4A_DEPTH_MODE_WFOV_2X2BINNED; - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + if (!K4A_SUCCEEDED(get_device_mode_ids(device, &color_mode_id, &depth_mode_id, &fps_mode_id))) + { + std::cout << "Failed to get device mode ids" << std::endl; + exit(-1); + } + + config.depth_mode_id = depth_mode_id; + config.fps_mode_id = fps_mode_id; k4a_calibration_t calibration; if (K4A_RESULT_SUCCEEDED != - k4a_device_get_calibration(device, config.depth_mode, config.color_resolution, &calibration)) + k4a_device_get_calibration(device, config.depth_mode_id, config.color_mode_id, &calibration)) { printf("Failed to get calibration\n"); goto Exit; @@ -420,6 +543,7 @@ int main(int argc, char **argv) printf("Timed out waiting for a capture\n"); goto Exit; case K4A_WAIT_RESULT_FAILED: + case K4A_WAIT_RESULT_UNSUPPORTED: printf("Failed to read a capture\n"); goto Exit; } @@ -449,4 +573,4 @@ int main(int argc, char **argv) } return returnCode; -} +} \ No newline at end of file diff --git a/examples/viewer/opengl/k4astaticimageproperties.h b/examples/viewer/opengl/k4astaticimageproperties.h deleted file mode 100644 index 6a0c265c6..000000000 --- a/examples/viewer/opengl/k4astaticimageproperties.h +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#ifndef K4AIMAGESIZES_H -#define K4AIMAGESIZES_H - -#include -#include - -#include - -namespace viewer -{ - -// Gets the dimensions of the color images that the color camera will produce for a -// given color resolution -// -inline std::pair GetColorDimensions(const k4a_color_resolution_t resolution) -{ - switch (resolution) - { - case K4A_COLOR_RESOLUTION_720P: - return { 1280, 720 }; - case K4A_COLOR_RESOLUTION_2160P: - return { 3840, 2160 }; - case K4A_COLOR_RESOLUTION_1440P: - return { 2560, 1440 }; - case K4A_COLOR_RESOLUTION_1080P: - return { 1920, 1080 }; - case K4A_COLOR_RESOLUTION_3072P: - return { 4096, 3072 }; - case K4A_COLOR_RESOLUTION_1536P: - return { 2048, 1536 }; - - default: - throw std::logic_error("Invalid color dimensions value!"); - } -} - -// Gets the dimensions of the depth images that the depth camera will produce for a -// given depth mode -// -inline std::pair GetDepthDimensions(const k4a_depth_mode_t depthMode) -{ - switch (depthMode) - { - case K4A_DEPTH_MODE_NFOV_2X2BINNED: - return { 320, 288 }; - case K4A_DEPTH_MODE_NFOV_UNBINNED: - return { 640, 576 }; - case K4A_DEPTH_MODE_WFOV_2X2BINNED: - return { 512, 512 }; - case K4A_DEPTH_MODE_WFOV_UNBINNED: - return { 1024, 1024 }; - case K4A_DEPTH_MODE_PASSIVE_IR: - return { 1024, 1024 }; - - default: - throw std::logic_error("Invalid depth dimensions value!"); - } -} - -// Gets the range of values that we expect to see from the depth camera -// when using a given depth mode, in millimeters -// -inline std::pair GetDepthModeRange(const k4a_depth_mode_t depthMode) -{ - switch (depthMode) - { - case K4A_DEPTH_MODE_NFOV_2X2BINNED: - return { (uint16_t)500, (uint16_t)5800 }; - case K4A_DEPTH_MODE_NFOV_UNBINNED: - return { (uint16_t)500, (uint16_t)4000 }; - case K4A_DEPTH_MODE_WFOV_2X2BINNED: - return { (uint16_t)250, (uint16_t)3000 }; - case K4A_DEPTH_MODE_WFOV_UNBINNED: - return { (uint16_t)250, (uint16_t)2500 }; - - case K4A_DEPTH_MODE_PASSIVE_IR: - default: - throw std::logic_error("Invalid depth mode!"); - } -} - -// Gets the expected min/max IR brightness levels that we expect to see -// from the IR camera when using a given depth mode -// -inline std::pair GetIrLevels(const k4a_depth_mode_t depthMode) -{ - switch (depthMode) - { - case K4A_DEPTH_MODE_PASSIVE_IR: - return { (uint16_t)0, (uint16_t)100 }; - - case K4A_DEPTH_MODE_OFF: - throw std::logic_error("Invalid depth mode!"); - - default: - return { (uint16_t)0, (uint16_t)1000 }; - } -} -} // namespace viewer - -#endif \ No newline at end of file diff --git a/examples/viewer/opengl/main.cpp b/examples/viewer/opengl/main.cpp index c50366e84..fca4928fb 100644 --- a/examples/viewer/opengl/main.cpp +++ b/examples/viewer/opengl/main.cpp @@ -6,7 +6,7 @@ #include "k4adepthpixelcolorizer.h" #include "k4apixel.h" -#include "k4astaticimageproperties.h" +#include #include "texture.h" #include "viewerwindow.h" @@ -17,6 +17,87 @@ void ColorizeDepthImage(const k4a::image &depthImage, std::pair expectedValueRange, std::vector *buffer); +static k4a_result_t get_device_mode_ids(k4a::device *device, + k4a_color_mode_info_t *color_mode_info, + k4a_depth_mode_info_t *depth_mode_info, + k4a_fps_mode_info_t *fps_mode_info) +{ + + // 1. get available modes from device info - note that you must instantiate info structs with struct size and abi + // version of the get methods will not succceed + k4a_device_info_t device_info = device->get_info(); + bool hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + bool hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + + // 3. get the device modes + std::vector color_modes = device->get_color_modes(); + std::vector depth_modes = device->get_depth_modes(); + std::vector fps_modes = device->get_fps_modes(); + + // 4. get the size of modes + uint32_t color_mode_size = (uint32_t)color_modes.size(); + uint32_t depth_mode_size = (uint32_t)depth_modes.size(); + uint32_t fps_mode_size = (uint32_t)fps_modes.size(); + + // 5. find the mode ids you want - for this example, let's find a color mode with a height of at least 720 or over, + // a depth mode with a height under 512 and a vertical fov of at least 120 or over and the fps mode with the + // heightest fps + if (hasColorDevice && color_mode_size > 1) + { + for (uint32_t c = 0; c < color_mode_size; c++) + { + if (color_modes[c].height >= 720) + { + *color_mode_info = color_modes[c]; + break; + } + } + } + + if (hasDepthDevice && depth_mode_size > 1) + { + for (uint32_t d = 0; d < depth_mode_size; d++) + { + if (depth_modes[d].height <= 512 && depth_modes[d].vertical_fov >= 120) + { + *depth_mode_info = depth_modes[d]; + break; + } + } + } + + if (fps_mode_size > 1) + { + uint32_t max_fps = 0; + uint32_t fps_mode_id = 0; + for (uint32_t f = 0; f < fps_mode_size; f++) + { + if (fps_modes[f].fps >= max_fps) + { + max_fps = (uint32_t)fps_modes[f].fps; + fps_mode_id = f; + } + } + *fps_mode_info = fps_modes[fps_mode_id]; + } + + // 6. fps mode id must not be set to 0, which is Off, and either color mode id or depth mode id must not be set + // to 0 + if (fps_mode_info->mode_id == 0) + { + std::cout << "Fps mode id must not be set to 0 (Off)" << std::endl; + exit(-1); + } + + if (color_mode_info->mode_id == 0 && depth_mode_info->mode_id == 0) + { + std::cout << "Either color mode id or depth mode id must not be set to 0 (Off)" << std::endl; + exit(-1); + } + + return K4A_RESULT_SUCCEEDED; +} + int main() { try @@ -29,13 +110,26 @@ int main() throw std::runtime_error("No Azure Kinect devices detected!"); } + std::cout << "Started opening K4A device..." << std::endl; + + k4a::device dev = k4a::device::open(K4A_DEVICE_DEFAULT); + + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_fps_mode_info_t fps_mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + + if (!K4A_SUCCEEDED(get_device_mode_ids(&dev, &color_mode_info, &depth_mode_info, &fps_mode_info))) + { + std::cout << "Failed to get device mode ids" << std::endl; + exit(-1); + } + // Start the device - // k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; - config.camera_fps = K4A_FRAMES_PER_SECOND_30; - config.depth_mode = K4A_DEPTH_MODE_WFOV_2X2BINNED; config.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32; - config.color_resolution = K4A_COLOR_RESOLUTION_720P; + config.color_mode_id = color_mode_info.mode_id; + config.depth_mode_id = depth_mode_info.mode_id; + config.fps_mode_id = fps_mode_info.mode_id; // This means that we'll only get captures that have both color and // depth images, so we don't need to check if the capture contains @@ -43,9 +137,6 @@ int main() // config.synchronized_images_only = true; - std::cout << "Started opening K4A device..." << std::endl; - - k4a::device dev = k4a::device::open(K4A_DEVICE_DEFAULT); dev.start_cameras(&config); std::cout << "Finished opening K4A device." << std::endl; @@ -56,9 +147,8 @@ int main() window.Initialize("Simple Azure Kinect Viewer", 1440, 900); // Textures we can give to OpenGL / the viewer window to render. - // - Texture depthTexture = window.CreateTexture(GetDepthDimensions(config.depth_mode)); - Texture colorTexture = window.CreateTexture(GetColorDimensions(config.color_resolution)); + Texture depthTexture = window.CreateTexture({ depth_mode_info.width, depth_mode_info.height }); + Texture colorTexture = window.CreateTexture({ color_mode_info.width, color_mode_info.height }); // A buffer containing a BGRA color representation of the depth image. // This is what we'll end up giving to depthTexture as an image source. @@ -97,7 +187,7 @@ int main() // ColorizeDepthImage(depthImage, K4ADepthPixelColorizer::ColorizeBlueToRed, - GetDepthModeRange(config.depth_mode), + { (uint16_t)depth_mode_info.min_range, (uint16_t)depth_mode_info.max_range }, &depthTextureBuffer); depthTexture.Update(&depthTextureBuffer[0]); @@ -165,4 +255,4 @@ void ColorizeDepthImage(const k4a::image &depthImage, expectedValueRange.second); } } -} +} \ No newline at end of file diff --git a/include/k4a/k4a.h b/include/k4a/k4a.h index e7a99494b..f1743ce0c 100644 --- a/include/k4a/k4a.h +++ b/include/k4a/k4a.h @@ -60,7 +60,8 @@ K4A_EXPORT uint32_t k4a_device_get_installed_count(void); * The least critical error the user wants to be notified about. * * \return ::K4A_RESULT_SUCCEEDED if the callback function was set or cleared successfully. ::K4A_RESULT_FAILED if an - * error is encountered or the callback function has already been set. + * error is encountered or the callback function has already been set. ::K4A_RESULT_UNSUPPORTED if the operation is + * not supported. * * \remarks * Call this function to set or clear the callback function that is used to deliver debug messages to the caller. This @@ -107,7 +108,8 @@ K4A_EXPORT k4a_result_t k4a_set_debug_message_handler(k4a_logging_message_cb_t * * is no longer needed. * * \return ::K4A_RESULT_SUCCEEDED if the callback function was set or cleared successfully. ::K4A_RESULT_FAILED if an - * error is encountered or the callback function has already been set. + * error is encountered or the callback function has already been set. ::K4A_RESULT_UNSUPPORTED if the operation is + * not supported. * * \remarks * Call this function to hook memory allocation by the SDK. Calling with both \p allocate and \p free as NULL will @@ -132,6 +134,216 @@ K4A_EXPORT k4a_result_t k4a_set_debug_message_handler(k4a_logging_message_cb_t * */ K4A_EXPORT k4a_result_t k4a_set_allocator(k4a_memory_allocate_cb_t allocate, k4a_memory_destroy_cb_t free); +/** Get the device info and capabilities. + * + * \param device_handle + * Handle obtained by k4a_device_open(). + * + * \param device_info + * Location to write the device info. + * + * \returns + * ::K4A_RESULT_SUCCEEDED if \p device info was successfully written. ::K4A_RESULT_FAILED otherwise. + * + * \remarks + * The device info output contains the vendor id, the device id and available capabilities. + * + * \sa k4a_device_t + * + * \xmlonly + * + * k4a.h (include k4a/k4a.h) + * k4a.lib + * k4a.dll + * + * \endxmlonly + */ +K4A_EXPORT k4a_result_t k4a_device_get_info(k4a_device_t device_handle, k4a_device_info_t *device_info); + +/** Get the number of valid color modes. + * + * \param device_handle + * Handle obtained by k4a_device_open(). + * + * \param mode_count + * Location to write the color mode count. + * + * \returns + * ::K4A_RESULT_SUCCEEDED if \p mode count was successfully retrieved. ::K4A_RESULT_FAILED otherwise. + * + * \remarks + * The mode count output is the number of available color modes for the device specified by device_handle. + * + * \xmlonly + * + * k4a.h (include k4a/k4a.h) + * k4a.lib + * k4a.dll + * + * \endxmlonly + */ +K4A_EXPORT k4a_result_t k4a_device_get_color_mode_count(k4a_device_t device_handle, uint32_t *mode_count); + +/** Get the color mode info for a specified index. + * + * \param device_handle + * Handle obtained by k4a_device_open(). + * + * \param mode_index + * The index of the color mode to get. + * + * \param mode_info + * Location to write the color mode info. + * + * \returns + * ::K4A_RESULT_SUCCEEDED if \p mode info was successfully retrieved. ::K4A_RESULT_FAILED otherwise. + * + * \sa k4a_color_mode_info_t + * + * \sa k4a_device_get_color_mode_count + * + * \remarks + * The mode_index parameter has valid values [0, N-1] where N is the value returned by + * k4a_device_get_color_mode_count(). + * + * \remarks + * The color mode info output contains image resolution, native image format, horizontal and vertical fov and min and + * max fps. + * + * \xmlonly + * + * k4a.h (include k4a/k4a.h) + * k4a.lib + * k4a.dll + * + * \endxmlonly + */ +K4A_EXPORT k4a_result_t k4a_device_get_color_mode(k4a_device_t device_handle, + uint32_t mode_index, + k4a_color_mode_info_t *mode_info); + +/** Get the number of valid depth modes. + * + * \param device_handle + * Handle obtained by k4a_device_open(). + * + * \param mode_count + * Location to write the depth mode count. + * + * \returns + * ::K4A_RESULT_SUCCEEDED if \p mode count was successfully retrieved. ::K4A_RESULT_FAILED otherwise. + * + * \remarks + * The mode count output is the number of available depth modes for the device specified by device_handle. + * + * \xmlonly + * + * k4a.h (include k4a/k4a.h) + * k4a.lib + * k4a.dll + * + * \endxmlonly + */ +K4A_EXPORT k4a_result_t k4a_device_get_depth_mode_count(k4a_device_t device_handle, uint32_t *mode_count); + +/** Get the depth mode info for a specified index. + * + * \param device_handle + * Handle obtained by k4a_device_open(). + * + * \param mode_index + * The index of the color mode to get. + * + * \param mode_info + * Location to write the depth mode info. + * + * \returns + * ::K4A_RESULT_SUCCEEDED if \p mode info was successfully retrieved. ::K4A_RESULT_FAILED otherwise. + * + * \sa k4a_depth_mode_info_t + * + * \sa k4a_device_get_depth_mode_count + * + * \remarks + * The mode_index parameter has valid values [0, N-1] where N is the value returned by + * k4a_device_get_depth_mode_count(). + * + * \remarks + * The depth mode info output contains image resolution, image native format, horizontal and vertical fov, min and max + * fps, min and max range and whether it is passive ir only. + * + * \xmlonly + * + * k4a.h (include k4a/k4a.h) + * k4a.lib + * k4a.dll + * + * \endxmlonly + */ +K4A_EXPORT k4a_result_t k4a_device_get_depth_mode(k4a_device_t device_handle, + uint32_t mode_index, + k4a_depth_mode_info_t *mode_info); + +/** Get the number of valid fps modes. + * + * \param device_handle + * Handle obtained by k4a_device_open(). + * + * \param mode_count + * Location to write the fps mode count. + * + * \returns + * ::K4A_RESULT_SUCCEEDED if \p mode count was successfully retrieved. ::K4A_RESULT_FAILED otherwise. + * + * \remarks + * The mode count output is the number of available fps modes for the device specified by device_handle. + * + * \xmlonly + * + * k4a.h (include k4a/k4a.h) + * k4a.lib + * k4a.dll + * + * \endxmlonly + */ +K4A_EXPORT k4a_result_t k4a_device_get_fps_mode_count(k4a_device_t device_handle, uint32_t *mode_count); + +/** Get the fps mode info for a specified index. + * + * \param device_handle + * Handle obtained by k4a_device_open(). + * + * \param mode_index + * The index of the color mode to get. + * + * \param mode_info + * Location to write the fps mode info. + * + * \returns + * ::K4A_RESULT_SUCCEEDED if \p mode info was successfully retrieved. ::K4A_RESULT_FAILED otherwise. + * + * \sa k4a_fps_mode_info_t + * + * \sa k4a_device_get_fps_mode_count + * + * \remarks + * The mode_index parameter has valid values [0, N-1] where N is the value returned by k4a_device_get_fps_mode_count(). + * + * \remarks + * The fps mode info contains the frame rate per second. + * + * \xmlonly + * + * k4a.h (include k4a/k4a.h) + * k4a.lib + * k4a.dll + * + * \endxmlonly + */ +K4A_EXPORT k4a_result_t k4a_device_get_fps_mode(k4a_device_t device_handle, + uint32_t mode_index, + k4a_fps_mode_info_t *mode_info); + /** Open an Azure Kinect device. * * \param index @@ -142,7 +354,8 @@ K4A_EXPORT k4a_result_t k4a_set_allocator(k4a_memory_allocate_cb_t allocate, k4a * * \relates k4a_device_t * - * \return ::K4A_RESULT_SUCCEEDED if the device was opened successfully. + * \return ::K4A_RESULT_SUCCEEDED if the device was opened successfully. ::K4A_RESULT_FAILED if the device was + * not opened successfully. * * \remarks * If successful, k4a_device_open() will return a device handle in the device_handle parameter. @@ -261,7 +474,8 @@ K4A_EXPORT k4a_wait_result_t k4a_device_get_capture(k4a_device_t device_handle, * * \returns * ::K4A_WAIT_RESULT_SUCCEEDED if a sample is returned. If a sample is not available before the timeout elapses, the - * function will return ::K4A_WAIT_RESULT_TIMEOUT. All other failures will return ::K4A_WAIT_RESULT_FAILED. + * function will return ::K4A_WAIT_RESULT_TIMEOUT. If a device does not support an IMU, then + * ::K4A_WAIT_RESULT_UNSUPPORTED is returned. All other failures will return ::K4A_WAIT_RESULT_FAILED. * * \relates k4a_device_t * @@ -1240,7 +1454,7 @@ K4A_EXPORT void k4a_image_release(k4a_image_t image_handle); * The configuration we want to run the device in. This can be initialized with ::K4A_DEVICE_CONFIG_INIT_DISABLE_ALL. * * \returns - * ::K4A_RESULT_SUCCEEDED is returned on success. + * ::K4A_RESULT_SUCCEEDED is returned on success, ::K4A_RESULT_FAILED otherwise. * * \relates k4a_device_t * @@ -1293,7 +1507,7 @@ K4A_EXPORT void k4a_device_stop_cameras(k4a_device_t device_handle); * * \returns * ::K4A_RESULT_SUCCEEDED is returned on success. ::K4A_RESULT_FAILED if the sensor is already running or a failure is - * encountered + * encountered. If a device does not support an IMU, ::K4A_RESULT_UNSUPPORTED is returned. * * \relates k4a_device_t * @@ -1433,7 +1647,8 @@ K4A_EXPORT k4a_result_t k4a_device_get_version(k4a_device_t device_handle, k4a_h * Location to store the color sensor's control default mode of /p command. * * \returns - * ::K4A_RESULT_SUCCEEDED if the value was successfully returned, ::K4A_RESULT_FAILED if an error occurred + * ::K4A_RESULT_SUCCEEDED if the value was successfully returned, ::K4A_RESULT_FAILED if an error occurred. + * ::K4A_RESULT_UNSUPPORTED if the device does not support this operation. * * \relates k4a_device_t * @@ -1472,7 +1687,8 @@ K4A_EXPORT k4a_result_t k4a_device_get_color_control_capabilities(k4a_device_t d * mode returned is ::K4A_COLOR_CONTROL_MODE_MANUAL for the current \p command. * * \returns - * ::K4A_RESULT_SUCCEEDED if the value was successfully returned, ::K4A_RESULT_FAILED if an error occurred + * ::K4A_RESULT_SUCCEEDED if the value was successfully returned, ::K4A_RESULT_FAILED if an error occurred. + * ::K4A_RESULT_UNSUPPORTED if the device does not support this operation. * * \remarks * Each control command may be set to manual or automatic. See the definition of \ref k4a_color_control_command_t on @@ -1517,7 +1733,8 @@ K4A_EXPORT k4a_result_t k4a_device_get_color_control(k4a_device_t device_handle, * is set to ::K4A_COLOR_CONTROL_MODE_MANUAL, and is otherwise ignored. * * \returns - * ::K4A_RESULT_SUCCEEDED if the value was successfully set, ::K4A_RESULT_FAILED if an error occurred + * ::K4A_RESULT_SUCCEEDED if the value was successfully set, ::K4A_RESULT_FAILED if an error occurred. + * ::K4A_RESULT_UNSUPPORTED if the device does not support this operation. * * \remarks * Each control command may be set to manual or automatic. See the definition of \ref k4a_color_control_command_t on how @@ -1584,11 +1801,11 @@ K4A_EXPORT k4a_buffer_result_t k4a_device_get_raw_calibration(k4a_device_t devic * \param device_handle * Handle obtained by k4a_device_open(). * - * \param depth_mode + * \param depth_mode_id * Mode in which depth camera is operated. * - * \param color_resolution - * Resolution in which color camera is operated. + * \param color_mode_id + * Mode in which color camera is operated. * * \param calibration * Location to write the calibration @@ -1598,7 +1815,7 @@ K4A_EXPORT k4a_buffer_result_t k4a_device_get_raw_calibration(k4a_device_t devic * * \remarks * The \p calibration represents the data needed to transform between the camera views and may be - * different for each operating \p depth_mode and \p color_resolution the device is configured to operate in. + * different for each operating \p depth_mode_id and \p color_mode_id the device is configured to operate in. * * \remarks * The \p calibration output is used as input to all calibration and transformation functions. @@ -1619,8 +1836,8 @@ K4A_EXPORT k4a_buffer_result_t k4a_device_get_raw_calibration(k4a_device_t devic * \endxmlonly */ K4A_EXPORT k4a_result_t k4a_device_get_calibration(k4a_device_t device_handle, - const k4a_depth_mode_t depth_mode, - const k4a_color_resolution_t color_resolution, + const uint32_t depth_mode_id, + const uint32_t color_mode_id, k4a_calibration_t *calibration); /** Get the device jack status for the synchronization in and synchronization out connectors. @@ -1636,6 +1853,7 @@ K4A_EXPORT k4a_result_t k4a_device_get_calibration(k4a_device_t device_handle, * * \returns * ::K4A_RESULT_SUCCEEDED if the connector status was successfully read. + * ::K4A_RESULT_UNSUPPORTED if the device does not support this operation. * * \relates k4a_device_t * @@ -1667,10 +1885,10 @@ K4A_EXPORT k4a_result_t k4a_device_get_sync_jack(k4a_device_t device_handle, * \param raw_calibration_size * The size, in bytes, of raw_calibration including the NULL termination. * - * \param depth_mode + * \param depth_mode_id * Mode in which depth camera is operated. * - * \param color_resolution + * \param color_mode_id * Resolution in which color camera is operated. * * \param calibration @@ -1681,7 +1899,7 @@ K4A_EXPORT k4a_result_t k4a_device_get_sync_jack(k4a_device_t device_handle, * * \remarks * The \p calibration represents the data needed to transform between the camera views and is - * different for each operating \p depth_mode and \p color_resolution the device is configured to operate in. + * different for each operating \p depth_mode_id and \p color_mode_id the device is configured to operate in. * * \remarks * The \p calibration output is used as input to all transformation functions. @@ -1703,8 +1921,8 @@ K4A_EXPORT k4a_result_t k4a_device_get_sync_jack(k4a_device_t device_handle, */ K4A_EXPORT k4a_result_t k4a_calibration_get_from_raw(char *raw_calibration, size_t raw_calibration_size, - const k4a_depth_mode_t depth_mode, - const k4a_color_resolution_t color_resolution, + const uint32_t depth_mode_id, + const uint32_t color_mode_id, k4a_calibration_t *calibration); /** Transform a 3D point of a source coordinate system into a 3D point of the target coordinate system @@ -1727,7 +1945,7 @@ K4A_EXPORT k4a_result_t k4a_calibration_get_from_raw(char *raw_calibration, * * \returns * ::K4A_RESULT_SUCCEEDED if \p target_point3d_mm was successfully written. ::K4A_RESULT_FAILED if \p calibration - * contained invalid transformation parameters. + * contained invalid transformation parameters. ::K4A_RESULT_UNSUPPORTED if the device does not support this operation. * * \remarks * This function is used to transform 3D points between depth and color camera coordinate systems. The function uses the @@ -1782,7 +2000,7 @@ K4A_EXPORT k4a_result_t k4a_calibration_3d_to_3d(const k4a_calibration_t *calibr * ::K4A_RESULT_SUCCEEDED if \p target_point3d_mm was successfully written. ::K4A_RESULT_FAILED if \p calibration * contained invalid transformation parameters. If the function returns ::K4A_RESULT_SUCCEEDED, but \p valid is 0, * the transformation was computed, but the results in \p target_point3d_mm are outside of the range of valid - * calibration and should be ignored. + * calibration and should be ignored. ::K4A_RESULT_UNSUPPORTED if the device does not support this operation. * * \remarks * This function applies the intrinsic calibration of \p source_camera to compute the 3D ray from the focal point of the @@ -1839,7 +2057,7 @@ K4A_EXPORT k4a_result_t k4a_calibration_2d_to_3d(const k4a_calibration_t *calibr * ::K4A_RESULT_SUCCEEDED if \p target_point2d was successfully written. ::K4A_RESULT_FAILED if \p calibration * contained invalid transformation parameters. If the function returns ::K4A_RESULT_SUCCEEDED, but \p valid is 0, * the transformation was computed, but the results in \p target_point2d are outside of the range of valid calibration - * and should be ignored. + * and should be ignored. ::K4A_RESULT_UNSUPPORTED if the device does not support this operation. * * \remarks * If \p target_camera is different from \p source_camera, \p source_point3d_mm is transformed to \p target_camera using @@ -1899,7 +2117,7 @@ K4A_EXPORT k4a_result_t k4a_calibration_3d_to_2d(const k4a_calibration_t *calibr * ::K4A_RESULT_SUCCEEDED if \p target_point2d was successfully written. ::K4A_RESULT_FAILED if \p calibration * contained invalid transformation parameters. If the function returns ::K4A_RESULT_SUCCEEDED, but \p valid is 0, * the transformation was computed, but the results in \p target_point2d are outside of the range of valid calibration - * and should be ignored. + * and should be ignored. ::K4A_RESULT_UNSUPPORTED if the device does not support this operation. * * \remarks * This function maps a pixel between the coordinate systems of the depth and color cameras. It is equivalent to calling @@ -1956,7 +2174,7 @@ K4A_EXPORT k4a_result_t k4a_calibration_2d_to_2d(const k4a_calibration_t *calibr * ::K4A_RESULT_SUCCEEDED if \p target_point2d was successfully written. ::K4A_RESULT_FAILED if \p calibration * contained invalid transformation parameters. If the function returns ::K4A_RESULT_SUCCEEDED, but \p valid is 0, * the transformation was computed, but the results in \p target_point2d are outside of the range of valid calibration - * and should be ignored. + * and should be ignored. ::K4A_RESULT_UNSUPPORTED if the device does not support this operation. * * \remarks * This function represents an alternative to k4a_calibration_2d_to_2d() if the number of pixels that need to be @@ -2062,6 +2280,7 @@ K4A_EXPORT void k4a_transformation_destroy(k4a_transformation_t transformation_h * * \returns * ::K4A_RESULT_SUCCEEDED if \p transformed_depth_image was successfully written and ::K4A_RESULT_FAILED otherwise. + * ::K4A_RESULT_UNSUPPORTED if the device does not support this operation. * * \relates k4a_transformation_t * @@ -2141,7 +2360,7 @@ K4A_EXPORT k4a_result_t k4a_transformation_depth_image_to_color_camera(k4a_trans * * \returns * ::K4A_RESULT_SUCCEEDED if \p transformed_depth_image and \p transformed_custom_image were successfully written and - * ::K4A_RESULT_FAILED otherwise. + * ::K4A_RESULT_FAILED otherwise. ::K4A_RESULT_UNSUPPORTED if the device does not support this operation. * * \relates k4a_transformation_t * @@ -2198,6 +2417,7 @@ k4a_transformation_depth_image_to_color_camera_custom(k4a_transformation_t trans * * \returns * ::K4A_RESULT_SUCCEEDED if \p transformed_color_image was successfully written and ::K4A_RESULT_FAILED otherwise. + * ::K4A_RESULT_UNSUPPORTED if the device does not support this operation. * * \relates k4a_transformation_t * @@ -2250,6 +2470,7 @@ K4A_EXPORT k4a_result_t k4a_transformation_color_image_to_depth_camera(k4a_trans * * \returns * ::K4A_RESULT_SUCCEEDED if \p xyz_image was successfully written and ::K4A_RESULT_FAILED otherwise. + * ::K4A_RESULT_UNSUPPORTED if the device does not support this operation. * * \relates k4a_transformation_t * diff --git a/include/k4a/k4a.hpp b/include/k4a/k4a.hpp index c86299882..d2d3706f9 100644 --- a/include/k4a/k4a.hpp +++ b/include/k4a/k4a.hpp @@ -764,17 +764,12 @@ struct calibration : public k4a_calibration_t * * \sa k4a_calibration_get_from_raw */ - static calibration get_from_raw(char *raw_calibration, - size_t raw_calibration_size, - k4a_depth_mode_t target_depth_mode, - k4a_color_resolution_t target_color_resolution) + static calibration + get_from_raw(char *raw_calibration, size_t raw_calibration_size, uint32_t depth_mode_id, uint32_t color_mode_id) { calibration calib; - k4a_result_t result = k4a_calibration_get_from_raw(raw_calibration, - raw_calibration_size, - target_depth_mode, - target_color_resolution, - &calib); + k4a_result_t result = + k4a_calibration_get_from_raw(raw_calibration, raw_calibration_size, depth_mode_id, color_mode_id, &calib); if (K4A_RESULT_SUCCEEDED != result) { @@ -788,15 +783,13 @@ struct calibration : public k4a_calibration_t * * \sa k4a_calibration_get_from_raw */ - static calibration get_from_raw(uint8_t *raw_calibration, - size_t raw_calibration_size, - k4a_depth_mode_t target_depth_mode, - k4a_color_resolution_t target_color_resolution) + static calibration + get_from_raw(uint8_t *raw_calibration, size_t raw_calibration_size, uint32_t depth_mode_id, uint32_t color_mode_id) { return get_from_raw(reinterpret_cast(raw_calibration), raw_calibration_size, - target_depth_mode, - target_color_resolution); + depth_mode_id, + color_mode_id); } /** Get the camera calibration for a device from a raw calibration blob. @@ -805,13 +798,13 @@ struct calibration : public k4a_calibration_t * \sa k4a_calibration_get_from_raw */ static calibration get_from_raw(std::vector &raw_calibration, - k4a_depth_mode_t target_depth_mode, - k4a_color_resolution_t target_color_resolution) + uint32_t depth_mode_id, + uint32_t color_mode_id) { return get_from_raw(reinterpret_cast(raw_calibration.data()), raw_calibration.size(), - target_depth_mode, - target_color_resolution); + depth_mode_id, + color_mode_id); } }; @@ -1360,10 +1353,10 @@ class device * * \sa k4a_device_get_calibration */ - calibration get_calibration(k4a_depth_mode_t depth_mode, k4a_color_resolution_t color_resolution) const + calibration get_calibration(uint32_t depth_mode_id, uint32_t color_mode_id) const { calibration calib; - k4a_result_t result = k4a_device_get_calibration(m_handle, depth_mode, color_resolution, &calib); + k4a_result_t result = k4a_device_get_calibration(m_handle, depth_mode_id, color_mode_id, &calib); if (K4A_RESULT_SUCCEEDED != result) { @@ -1449,6 +1442,165 @@ class device return k4a_device_get_installed_count(); } + /** Gets info about a device + * + * \sa k4a_device_get_info + */ + k4a_device_info_t get_info() const + { + K4A_INIT_STRUCT(k4a_device_info_t, info); + k4a_device_get_info(m_handle, &info); + + return info; + } + + /** Gets the available device color modes. + * + */ + std::vector get_color_modes() const + { + K4A_INIT_STRUCT(k4a_color_mode_info_t, mode); + + std::vector modes; + uint32_t mode_count; + k4a_result_t result = k4a_device_get_color_mode_count(m_handle, &mode_count); + if (result == K4A_RESULT_SUCCEEDED) + { + modes.reserve(mode_count); + for (uint32_t i = 0; i < mode_count; i++) + { + if (k4a_device_get_color_mode(m_handle, i, &mode) == K4A_RESULT_SUCCEEDED) + { + modes.push_back(mode); + } + } + } + + return modes; + } + + /** Gets a device color mode by index. + * + * \sa k4a_device_get_color_mode + */ + k4a_color_mode_info_t get_color_mode(uint32_t color_mode_index) const + { + K4A_INIT_STRUCT(k4a_color_mode_info_t, mode); + + uint32_t mode_count; + k4a_result_t result = k4a_device_get_color_mode_count(m_handle, &mode_count); + if (result == K4A_RESULT_SUCCEEDED) + { + if (color_mode_index < mode_count) + { + if (k4a_device_get_color_mode(m_handle, color_mode_index, &mode) == K4A_RESULT_SUCCEEDED) + { + return mode; + } + } + } + + return mode; + } + + /** Gets the available device depth modes. + * + */ + std::vector get_depth_modes() const + { + K4A_INIT_STRUCT(k4a_depth_mode_info_t, mode); + + std::vector modes; + uint32_t mode_count; + k4a_result_t result = k4a_device_get_depth_mode_count(m_handle, &mode_count); + if (result == K4A_RESULT_SUCCEEDED) + { + modes.reserve(mode_count); + for (uint32_t i = 0; i < mode_count; i++) + { + if (k4a_device_get_depth_mode(m_handle, i, &mode) == K4A_RESULT_SUCCEEDED) + { + modes.push_back(mode); + } + } + } + + return modes; + } + + /** Gets the device depth mode by mode index. + * + * \sa k4a_device_get_depth_mode + */ + k4a_depth_mode_info_t get_depth_mode(uint32_t depth_mode_index) const + { + K4A_INIT_STRUCT(k4a_depth_mode_info_t, mode); + + uint32_t mode_count; + k4a_result_t result = k4a_device_get_depth_mode_count(m_handle, &mode_count); + if (result == K4A_RESULT_SUCCEEDED) + { + if (depth_mode_index < mode_count) + { + if (k4a_device_get_depth_mode(m_handle, depth_mode_index, &mode) == K4A_RESULT_SUCCEEDED) + { + return mode; + } + } + } + + return mode; + } + + /** Get available device fps modes. + * + */ + std::vector get_fps_modes() const + { + K4A_INIT_STRUCT(k4a_fps_mode_info_t, mode); + + std::vector modes; + uint32_t mode_count; + k4a_result_t result = k4a_device_get_fps_mode_count(m_handle, &mode_count); + if (result == K4A_RESULT_SUCCEEDED) + { + modes.reserve(mode_count); + for (uint32_t i = 0; i < mode_count; i++) + { + if (k4a_device_get_fps_mode(m_handle, i, &mode) == K4A_RESULT_SUCCEEDED) + { + modes.push_back(mode); + } + } + } + + return modes; + } + + /** Gets the device fps mode by mode index. + * + * \sa k4a_device_get_fps_mode + */ + k4a_fps_mode_info_t get_fps_mode(uint32_t fps_mode_index) const + { + K4A_INIT_STRUCT(k4a_fps_mode_info_t, mode); + + uint32_t mode_count; + k4a_result_t result = k4a_device_get_fps_mode_count(m_handle, &mode_count); + if (result == K4A_RESULT_SUCCEEDED) + { + if (fps_mode_index < mode_count) + { + if (k4a_device_get_fps_mode(m_handle, fps_mode_index, &mode) == K4A_RESULT_SUCCEEDED) + { + return mode; + } + } + } + + return mode; + } + private: k4a_device_t m_handle; }; diff --git a/include/k4a/k4atypes.h b/include/k4a/k4atypes.h index e7d17bd33..40f65564a 100644 --- a/include/k4a/k4atypes.h +++ b/include/k4a/k4atypes.h @@ -1,4 +1,4 @@ -/** \file k4atypes.h +/** \file k4atypes.h * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. * Kinect For Azure SDK Type definitions. @@ -25,7 +25,7 @@ extern "C" { /** * Declare an opaque handle type. * - * \param _handle_name_ The type name of the handle + * \param \_handle_name_ The type name of the handle * * \remarks * This is used to define the public handle types for the Azure Kinect APIs. @@ -218,6 +218,7 @@ typedef enum { K4A_RESULT_SUCCEEDED = 0, /**< The result was successful */ K4A_RESULT_FAILED, /**< The result was a failure */ + K4A_RESULT_UNSUPPORTED, /**< The operation was unsupported */ } k4a_result_t; /** Result code returned by Azure Kinect APIs. @@ -233,6 +234,7 @@ typedef enum K4A_BUFFER_RESULT_SUCCEEDED = 0, /**< The result was successful */ K4A_BUFFER_RESULT_FAILED, /**< The result was a failure */ K4A_BUFFER_RESULT_TOO_SMALL, /**< The input buffer was too small */ + K4A_BUFFER_RESULT_UNSUPPORTED, /**< The operation was unsupported */ } k4a_buffer_result_t; /** Result code returned by Azure Kinect APIs. @@ -248,6 +250,7 @@ typedef enum K4A_WAIT_RESULT_SUCCEEDED = 0, /**< The result was successful */ K4A_WAIT_RESULT_FAILED, /**< The result was a failure */ K4A_WAIT_RESULT_TIMEOUT, /**< The operation timed out */ + K4A_WAIT_RESULT_UNSUPPORTED, /**< The operation was unsupported */ } k4a_wait_result_t; /** Verbosity levels of debug messaging @@ -268,17 +271,14 @@ typedef enum K4A_LOG_LEVEL_OFF, /**< No logging is performed */ } k4a_log_level_t; -/** Depth sensor capture modes. +/** Device capabilities. * * \remarks - * See the hardware specification for additional details on the field of view, and supported frame rates - * for each mode. + * Used by \p k4a_device_info_t to store whether a device has a color camera, a depth camera, and IMU. * - * \remarks - * NFOV and WFOV denote Narrow and Wide Field Of View configurations. - * - * \remarks - * Binned modes reduce the captured camera resolution by combining adjacent sensor pixels into a bin. + * \note + * These are used in a bitmap, so the values should be unique powers of 2. These values should not be + * modified; if a new capability is available, a new enum field should be defined. * * \xmlonly * @@ -286,36 +286,13 @@ typedef enum * * \endxmlonly */ -// Be sure to update k4a_depth_mode_to_string in k4a.c if enum values are added. typedef enum { - K4A_DEPTH_MODE_OFF = 0, /**< Depth sensor will be turned off with this setting. */ - K4A_DEPTH_MODE_NFOV_2X2BINNED, /**< Depth captured at 320x288. Passive IR is also captured at 320x288. */ - K4A_DEPTH_MODE_NFOV_UNBINNED, /**< Depth captured at 640x576. Passive IR is also captured at 640x576. */ - K4A_DEPTH_MODE_WFOV_2X2BINNED, /**< Depth captured at 512x512. Passive IR is also captured at 512x512. */ - K4A_DEPTH_MODE_WFOV_UNBINNED, /**< Depth captured at 1024x1024. Passive IR is also captured at 1024x1024. */ - K4A_DEPTH_MODE_PASSIVE_IR, /**< Passive IR only, captured at 1024x1024. */ -} k4a_depth_mode_t; - -/** Color sensor resolutions. - * - * \xmlonly - * - * k4atypes.h (include k4a/k4a.h) - * - * \endxmlonly - */ -// Be sure to update k4a_color_resolution_to_string in k4a.c if enum values are added. -typedef enum -{ - K4A_COLOR_RESOLUTION_OFF = 0, /**< Color camera will be turned off with this setting */ - K4A_COLOR_RESOLUTION_720P, /**< 1280 * 720 16:9 */ - K4A_COLOR_RESOLUTION_1080P, /**< 1920 * 1080 16:9 */ - K4A_COLOR_RESOLUTION_1440P, /**< 2560 * 1440 16:9 */ - K4A_COLOR_RESOLUTION_1536P, /**< 2048 * 1536 4:3 */ - K4A_COLOR_RESOLUTION_2160P, /**< 3840 * 2160 16:9 */ - K4A_COLOR_RESOLUTION_3072P, /**< 4096 * 3072 4:3 */ -} k4a_color_resolution_t; + K4A_CAPABILITY_DEPTH = 1, /**< Depth sensor capability bitmap value. */ + K4A_CAPABILITY_COLOR = 2, /**< Color sensor capability bitmap value. */ + K4A_CAPABILITY_IMU = 4, /**< Inertial measurement unit capability bitmap value. */ + K4A_CAPABILITY_MICROPHONE = 8, /**< Microphone capability bitmap value. */ +} k4a_device_capabilities_t; /** Image format type. * @@ -462,26 +439,6 @@ typedef enum K4A_TRANSFORMATION_INTERPOLATION_TYPE_LINEAR, /**< Linear interpolation */ } k4a_transformation_interpolation_type_t; -/** Color and depth sensor frame rate. - * - * \remarks - * This enumeration is used to select the desired frame rate to operate the cameras. The actual - * frame rate may vary slightly due to dropped data, synchronization variation between devices, - * clock accuracy, or if the camera exposure priority mode causes reduced frame rate. - * \xmlonly - * - * k4atypes.h (include k4a/k4a.h) - * - * \endxmlonly - */ -// Be sure to update k4a_fps_to_string in k4a.c if enum values are added. -typedef enum -{ - K4A_FRAMES_PER_SECOND_5 = 0, /**< 5 FPS */ - K4A_FRAMES_PER_SECOND_15, /**< 15 FPS */ - K4A_FRAMES_PER_SECOND_30, /**< 30 FPS */ -} k4a_fps_t; - /** Color sensor control commands * * \remarks @@ -752,6 +709,28 @@ typedef enum */ #define K4A_FAILED(_result_) (!K4A_SUCCEEDED(_result_)) +/** + * + * \param T + * Type of struct + * + * \param S + * Instance of a struct of type T + * + * \remarks + * Initializes a struct of type T with a struct size and a struct version. + * + * \xmlonly + * + * k4atypes.h (include k4a/k4a.h) + * + * \endxmlonly + */ +#define K4A_INIT_STRUCT(T, S) \ + T S{}; \ + S.struct_size = sizeof(T); \ + S.struct_version = K4A_ABI_VERSION; + /** * * @} @@ -903,6 +882,114 @@ typedef uint8_t *(k4a_memory_allocate_cb_t)(int size, void **context); * @{ */ +/** Stores the vendor id, the device id and device capabilities. + * + * \sa k4a_device_capabilities_t + * + * \xmlonly + * + * k4atypes.h (include k4a/k4a.h) + * + * \endxmlonly + */ +typedef struct _k4a_device_info_t +{ + uint32_t struct_size; /**< The size of this device info struct */ + uint32_t struct_version; /**< The version of this device info struct */ + uint32_t vendor_id; /**< 0 to 65535 : reserved for registered USB VID numbers. */ + uint32_t device_id; /**< Vendor specific device ID. */ + + union + { + uint32_t value; /**< Unsigned int value of the binary combination of capability flags. */ + struct + { + uint32_t bHasDepth : 1; /**< Bit value of 1 specifies the device has depth sensor.*/ + uint32_t bHasColor : 1; /**< Bit value of 1 specifies the device has color sensor.*/ + uint32_t bHasIMU : 1; /**< Bit value of 1 specifies the device has IMU sensor.*/ + uint32_t bHasMic : 1; /**< Bit value of 1 specifies the device has microphone.*/ + uint32_t resv : 28; + } bitmap; /**< Bitmap of binary combination of capability flags. */ + + } capabilities; /**< Binary combination of capability flags. */ + +} k4a_device_info_t; + +/** Color mode info type representing color mode info. + * + * \remarks + * The mode_id field is used in k4a_device_configuration_t and passed to k4a_device_start_cameras(). + * This sets the device to a specific color mode of operation with properties specified in this struct. + * + * \xmlonly + * + * k4atypes.h (include k4a/k4a.h) + * + * \endxmlonly + */ +typedef struct _k4a_color_mode_info_t +{ + uint32_t struct_size; /**< Must be equal to sizeof(k4a_color_mode_info_t). */ + uint32_t struct_version; /**< Must be equal to 1. Future API versions may define new structure versions. */ + uint32_t mode_id; /**< Mode identifier to use to select this mode. 0 is reserved for disabling color */ + uint32_t width; /**< Image width. */ + uint32_t height; /**< Image height. */ + k4a_image_format_t native_format; /**< Image format. */ + float horizontal_fov; /**< Approximate horizontal field of view. */ + float vertical_fov; /**< Approximate vertical field of view. */ + uint32_t min_fps; /**< Minimum supported framerate. */ + uint32_t max_fps; /**< Maximum supported ramerate. */ +} k4a_color_mode_info_t; + +/** Depth mode info type representing depth mode info. + * + * \remarks + * The mode_id field is used in k4a_device_configuration_t and passed to k4a_device_start_cameras(). + * This sets the device to a specific depth mode of operation with depth properties specified in this struct. + * + * \xmlonly + * + * k4atypes.h (include k4a/k4a.h) + * + * \endxmlonly + */ +typedef struct _k4a_depth_mode_info_t +{ + uint32_t struct_size; /**< Must be equal to sizeof(k4a_depth_mode_info_t). */ + uint32_t struct_version; /**< Must be equal to 1. Future API versions may define new structure versions. */ + uint32_t mode_id; /**< Mode identifier to use to select this mode. 0 is reserved for disabling depth. */ + bool passive_ir_only; /**< True if only capturing passive IR. */ + uint32_t width; /**< Image width. */ + uint32_t height; /**< Image height. */ + k4a_image_format_t native_format; /**< Image format. */ + float horizontal_fov; /**< Approximate horizontal field of view. */ + float vertical_fov; /**< Approximate vertical field of view. */ + uint32_t min_fps; /**< Minimum supported framerate. */ + uint32_t max_fps; /**< Maximum supported framerate. */ + uint32_t min_range; /**< Min values expected for mode in millimeters */ + uint32_t max_range; /**< Max values expected for mode in millimeters */ +} k4a_depth_mode_info_t; + +/** Frames per second (fps) mode info type representing fps mode info. + * + * \remarks + * The mode_id field is used in k4a_device_configuration_t and passed to k4a_device_start_cameras(). + * This sets the device to a specific fps specified by the fps field in this struct. + * + * \xmlonly + * + * k4atypes.h (include k4a/k4a.h) + * + * \endxmlonly + */ +typedef struct _k4a_fps_mode_info_t +{ + uint32_t struct_size; /**< Must be equal to sizeof(k4a_fps_mode_info_t). */ + uint32_t struct_version; /**< Must be equal to 1. Future API versions may define new structure versions. */ + uint32_t mode_id; /**< Mode identifier to use to select this mode. */ + uint32_t fps; /**< The frame rate per second. */ +} k4a_fps_mode_info_t; + /** Configuration parameters for an Azure Kinect device. * * \remarks @@ -922,14 +1009,14 @@ typedef struct _k4a_device_configuration_t * Setting ::K4A_IMAGE_FORMAT_COLOR_BGRA32 for color_format will result in higher CPU utilization. */ k4a_image_format_t color_format; - /** Image resolution to capture with the color camera. */ - k4a_color_resolution_t color_resolution; + /** Capture mode for the color camera. */ + uint32_t color_mode_id; /** Capture mode for the depth camera. */ - k4a_depth_mode_t depth_mode; + uint32_t depth_mode_id; /** Desired frame rate for the color and depth camera. */ - k4a_fps_t camera_fps; + uint32_t fps_mode_id; /** Only produce k4a_capture_t objects if they contain synchronized color and depth images. * @@ -1110,8 +1197,8 @@ typedef struct _k4a_calibration_t */ k4a_calibration_extrinsics_t extrinsics[K4A_CALIBRATION_TYPE_NUM][K4A_CALIBRATION_TYPE_NUM]; - k4a_depth_mode_t depth_mode; /**< Depth camera mode for which calibration was obtained. */ - k4a_color_resolution_t color_resolution; /**< Color camera resolution for which calibration was obtained. */ + uint32_t depth_mode_id; /**< Depth camera mode for which calibration was obtained. */ + uint32_t color_mode_id; /**< Color camera mode for which calibration was obtained. */ } k4a_calibration_t; /** Version information. @@ -1217,6 +1304,19 @@ typedef struct _k4a_imu_sample_t * @{ */ +/** The ABI version of the SDK implementation. + * + * \remarks + * Vendors that modify the public API of this SDK should change the value. + * + * \xmlonly + * + * k4atypes.h (include k4a/k4a.h) + * + * \endxmlonly + */ +#define K4A_ABI_VERSION 1 + /** Default device index. * * Passed as an argument to \ref k4a_device_open() to open the default sensor @@ -1250,15 +1350,8 @@ typedef struct _k4a_imu_sample_t * * \endxmlonly */ -static const k4a_device_configuration_t K4A_DEVICE_CONFIG_INIT_DISABLE_ALL = { K4A_IMAGE_FORMAT_COLOR_MJPG, - K4A_COLOR_RESOLUTION_OFF, - K4A_DEPTH_MODE_OFF, - K4A_FRAMES_PER_SECOND_30, - false, - 0, - K4A_WIRED_SYNC_MODE_STANDALONE, - 0, - false }; +static const k4a_device_configuration_t K4A_DEVICE_CONFIG_INIT_DISABLE_ALL = + { K4A_IMAGE_FORMAT_COLOR_MJPG, 0, 0, 0, false, 0, K4A_WIRED_SYNC_MODE_STANDALONE, 0, false }; /** * @} @@ -1268,4 +1361,4 @@ static const k4a_device_configuration_t K4A_DEVICE_CONFIG_INIT_DISABLE_ALL = { K } #endif -#endif /* K4ATYPES_H */ +#endif /* K4ATYPES_H */ \ No newline at end of file diff --git a/include/k4ainternal/color.h b/include/k4ainternal/color.h index 90a9a99de..54f9b2cc7 100644 --- a/include/k4ainternal/color.h +++ b/include/k4ainternal/color.h @@ -9,7 +9,6 @@ #include #include -#include #include #include #include diff --git a/include/k4ainternal/common.h b/include/k4ainternal/common.h index 6da3c6296..47587a845 100644 --- a/include/k4ainternal/common.h +++ b/include/k4ainternal/common.h @@ -40,109 +40,30 @@ typedef struct _guid_t #define HZ_TO_PERIOD_US(Hz) (1000000 / Hz) #define HZ_TO_PERIOD_NS(Hz) (1000000000 / Hz) -inline static uint32_t k4a_convert_fps_to_uint(k4a_fps_t fps) -{ - uint32_t fps_int; - switch (fps) - { - case K4A_FRAMES_PER_SECOND_5: - fps_int = 5; - break; - case K4A_FRAMES_PER_SECOND_15: - fps_int = 15; - break; - case K4A_FRAMES_PER_SECOND_30: - fps_int = 30; - break; - default: - assert(0); - fps_int = 0; - break; +/* Copy struct to a result pointer, not exceeding the size specified in the result pointer +Assumes size comes before version */ +#define SAFE_COPY_STRUCT(result, temp) \ + { \ + size_t offset = ((char *)(&(temp)->struct_version) - (char *)(temp)) + sizeof((temp)->struct_version); \ + size_t size = sizeof(*temp); \ + if (size > (result)->struct_size) \ + size = (result)->struct_size; \ + if (size > offset) \ + { \ + memcpy((char *)result + offset, (char *)(temp) + offset, size - offset); \ + } \ } - return fps_int; -} -inline static bool k4a_convert_resolution_to_width_height(k4a_color_resolution_t resolution, - uint32_t *width_out, - uint32_t *height_out) -{ - uint32_t width = 0; - uint32_t height = 0; - switch (resolution) - { - case K4A_COLOR_RESOLUTION_720P: - width = 1280; - height = 720; - break; - case K4A_COLOR_RESOLUTION_1080P: - width = 1920; - height = 1080; - break; - case K4A_COLOR_RESOLUTION_1440P: - width = 2560; - height = 1440; - break; - case K4A_COLOR_RESOLUTION_1536P: - width = 2048; - height = 1536; - break; - case K4A_COLOR_RESOLUTION_2160P: - width = 3840; - height = 2160; - break; - case K4A_COLOR_RESOLUTION_3072P: - width = 4096; - height = 3072; - break; - default: - return false; - } +/* Macro for checking if a struct member is within the limits set by size */ +#define HAS_MEMBER(S, M) (((char *)(&((S)->M)) - (char *)(S)) + sizeof((S)->M) <= (S)->struct_size) - if (width_out != NULL) - *width_out = width; - if (height_out != NULL) - *height_out = height; - return true; -} +/* Safe setting a value in a struct */ +#define SAFE_SET_MEMBER(S, M, NEW_VALUE) \ + if (HAS_MEMBER(S, M)) \ + (S)->M = (NEW_VALUE) -inline static bool k4a_convert_depth_mode_to_width_height(k4a_depth_mode_t mode, - uint32_t *width_out, - uint32_t *height_out) -{ - uint32_t width = 0; - uint32_t height = 0; - switch (mode) - { - case K4A_DEPTH_MODE_NFOV_2X2BINNED: - width = 320; - height = 288; - break; - case K4A_DEPTH_MODE_NFOV_UNBINNED: - width = 640; - height = 576; - break; - case K4A_DEPTH_MODE_WFOV_2X2BINNED: - width = 512; - height = 512; - break; - case K4A_DEPTH_MODE_WFOV_UNBINNED: - width = 1024; - height = 1024; - break; - case K4A_DEPTH_MODE_PASSIVE_IR: - width = 1024; - height = 1024; - break; - default: - return false; - } - - if (width_out != NULL) - *width_out = width; - if (height_out != NULL) - *height_out = height; - return true; -} +/* Safe getting a value from a struct */ +#define SAFE_GET_MEMBER(S, M, DEFAULT_VALUE) (HAS_MEMBER(S, M) ? ((S)->M) : (DEFAULT_VALUE)) inline static bool k4a_is_version_greater_or_equal(k4a_version_t *fw_version_l, k4a_version_t *fw_version_r) { @@ -190,6 +111,7 @@ inline static bool k4a_is_version_greater_or_equal(k4a_version_t *fw_version_l, return (fw == FW_OK); } + #ifdef __cplusplus } #endif diff --git a/include/k4ainternal/depth_mcu.h b/include/k4ainternal/depth_mcu.h index abf66c918..7e2eb15cd 100644 --- a/include/k4ainternal/depth_mcu.h +++ b/include/k4ainternal/depth_mcu.h @@ -8,7 +8,6 @@ #define DEPTH_MCU_H #include -#include #include #include #include @@ -103,11 +102,11 @@ k4a_result_t depthmcu_depth_start_streaming(depthmcu_t depthmcu_handle, void depthmcu_depth_stop_streaming(depthmcu_t depthmcu_handle, bool quiet); -k4a_result_t depthmcu_depth_set_capture_mode(depthmcu_t depthmcu_handle, k4a_depth_mode_t depth_mode); -k4a_result_t depthmcu_depth_get_capture_mode(depthmcu_t depthmcu_handle, k4a_depth_mode_t *depth_mode); +k4a_result_t depthmcu_depth_set_capture_mode(depthmcu_t depthmcu_handle, uint32_t depth_mode_id); +k4a_result_t depthmcu_depth_get_capture_mode(depthmcu_t depthmcu_handle, uint32_t *depth_mode_id); -k4a_result_t depthmcu_depth_set_fps(depthmcu_t depthmcu_handle, k4a_fps_t depth_fps); -k4a_result_t depthmcu_depth_get_fps(depthmcu_t depthmcu_handle, k4a_fps_t *depth_fps); +k4a_result_t depthmcu_depth_set_fps(depthmcu_t depthmcu_handle, uint32_t fps_mode_id); +k4a_result_t depthmcu_depth_get_fps(depthmcu_t depthmcu_handle, uint32_t *fps_mode_id); k4a_result_t depthmcu_get_color_imu_calibration(depthmcu_t depthmcu_handle, k4a_capture_t cal, diff --git a/include/k4ainternal/math.h b/include/k4ainternal/math.h index 63d37fb4f..987f76f3c 100644 --- a/include/k4ainternal/math.h +++ b/include/k4ainternal/math.h @@ -54,6 +54,8 @@ void math_quadratic_transform_3(const float A[3 * 3], const float b[3], float out[3]); +int math_get_common_factor(int width, int height); + #ifdef __cplusplus } #endif diff --git a/include/k4ainternal/matroska_common.h b/include/k4ainternal/matroska_common.h index 0bc26f6f9..b236c67c0 100644 --- a/include/k4ainternal/matroska_common.h +++ b/include/k4ainternal/matroska_common.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/include/k4ainternal/modes.h b/include/k4ainternal/modes.h new file mode 100644 index 000000000..9710ec777 --- /dev/null +++ b/include/k4ainternal/modes.h @@ -0,0 +1,337 @@ +/** \file modes.h + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + * Kinect For Azure SDK. + */ + +#ifndef MODES_H +#define MODES_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Depth sensor capture modes. + * + * \remarks + * See the hardware specification for additional details on the field of view, and supported frame rates + * for each mode. + * + * \remarks + * NFOV and WFOV denote Narrow and Wide Field Of View configurations. + * + * \remarks + * Binned modes reduce the captured camera resolution by combining adjacent sensor pixels into a bin. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +// Be sure to update k4a_depth_mode_to_string in k4a.c if enum values are added. +typedef enum +{ + K4A_DEPTH_MODE_OFF = 0, /**< Depth sensor will be turned off with this setting. */ + K4A_DEPTH_MODE_NFOV_2X2BINNED, /**< Depth captured at 320x288. Passive IR is also captured at 320x288. */ + K4A_DEPTH_MODE_NFOV_UNBINNED, /**< Depth captured at 640x576. Passive IR is also captured at 640x576. */ + K4A_DEPTH_MODE_WFOV_2X2BINNED, /**< Depth captured at 512x512. Passive IR is also captured at 512x512. */ + K4A_DEPTH_MODE_WFOV_UNBINNED, /**< Depth captured at 1024x1024. Passive IR is also captured at 1024x1024. */ + K4A_DEPTH_MODE_PASSIVE_IR, /**< Passive IR only, captured at 1024x1024. */ + K4A_DEPTH_MODE_COUNT, /**< Must be last entry. */ +} k4a_depth_mode_t; + +/** Color sensor resolutions. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +// Be sure to update k4a_color_resolution_to_string in k4a.c if enum values are added. +typedef enum +{ + K4A_COLOR_RESOLUTION_OFF = 0, /**< Color camera will be turned off with this setting */ + K4A_COLOR_RESOLUTION_720P, /**< 1280 * 720 16:9 */ + K4A_COLOR_RESOLUTION_1080P, /**< 1920 * 1080 16:9 */ + K4A_COLOR_RESOLUTION_1440P, /**< 2560 * 1440 16:9 */ + K4A_COLOR_RESOLUTION_1536P, /**< 2048 * 1536 4:3 */ + K4A_COLOR_RESOLUTION_2160P, /**< 3840 * 2160 16:9 */ + K4A_COLOR_RESOLUTION_3072P, /**< 4096 * 3072 4:3 */ + K4A_COLOR_RESOLUTION_COUNT, /**< Must be last entry. */ +} k4a_color_resolution_t; + +/** Color and depth sensor frame rate. + * + * \remarks + * This enumeration is used to select the desired frame rate to operate the cameras. The actual + * frame rate may vary slightly due to dropped data, synchronization variation between devices, + * clock accuracy, or if the camera exposure priority mode causes reduced frame rate. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +// Be sure to update k4a_fps_to_string in k4a.c if enum values are added. +typedef enum +{ + K4A_FRAMES_PER_SECOND_0 = 0, /**< 0 FPS */ + K4A_FRAMES_PER_SECOND_5 = 5, /**< 5 FPS */ + K4A_FRAMES_PER_SECOND_15 = 15, /**< 15 FPS */ + K4A_FRAMES_PER_SECOND_30 = 30, /**< 30 FPS */ +} k4a_fps_t; + +/** Get count of device depth modes. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_get_device_depth_modes_count(); + +/** Get count of device color modes. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_get_device_color_modes_count(); + +/** Get count of device fps modes. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_get_device_fps_modes_count(); + +/** Get device depth mode for the given index. + * + * \param mode_index The index of the depth mode to get. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +k4a_depth_mode_info_t k4a_get_device_depth_mode(uint32_t mode_index); + +/** Get device color mode for the given index. + * + * \param mode_index The index of the depth mode to get. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +k4a_color_mode_info_t k4a_get_device_color_mode(uint32_t mode_index); + +/** Get device fps mode for the given index. + * + * \param mode_index The index of the depth mode to get. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +k4a_fps_mode_info_t k4a_get_device_fps_mode(uint32_t mode_index); + +/** Convert k4a_fps_t enum to the actual frame rate value. + * + * \remarks + * If the fps enum is not valid, then 0 fps is returned. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_convert_fps_to_uint(k4a_fps_t fps); + +/** Convert frame rate value to the corresponding k4a_fps_t enum. + * + * \remarks + * If the fps value does not correspond to a k4a_fps_t enum, then K4A_FRAME_PER_SECOND_0 is returned. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +k4a_fps_t k4a_convert_uint_to_fps(uint32_t fps_in); + +/** Return the image width and height for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +bool k4a_convert_resolution_to_width_height(k4a_color_resolution_t resolution, + uint32_t *width_out, + uint32_t *height_out); + +/** Return the image width for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_color_resolution_width(k4a_color_resolution_t resolution); + +/** Return the image height for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_color_resolution_height(k4a_color_resolution_t resolution); + +/** Return the camera field of view for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +bool k4a_convert_resolution_to_fov(k4a_color_resolution_t resolution, float *horizontal_fov, float *vertical_fov); + +/** Return the color camera horizontal fov for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +float k4a_color_resolution_horizontal_fov(k4a_color_resolution_t resolution); + +/** Return the color camera vertical fov for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +float k4a_color_resolution_vertical_fov(k4a_color_resolution_t resolution); + +/** Return the image width and height for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +bool k4a_convert_depth_mode_to_width_height(k4a_depth_mode_t mode_id, uint32_t *width_out, uint32_t *height_out); + +/** Return the image width for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_depth_mode_width(k4a_depth_mode_t mode_id); + +/** Return the image height for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_depth_mode_height(k4a_depth_mode_t mode_id); + +/** Return the depth camera field of view for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +bool k4a_convert_depth_mode_to_fov(k4a_depth_mode_t mode_id, float *horizontal_fov, float *vertical_fov); + +/** Return the depth camera horizontal fov for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +float k4a_depth_mode_horizontal_fov(k4a_depth_mode_t mode_id); + +/** Return the depth camera vertical fov for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +float k4a_depth_mode_vertical_fov(k4a_depth_mode_t mode_id); + +/** Return the min and max depth range for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +bool k4a_convert_depth_mode_to_min_max_range(k4a_depth_mode_t mode_id, uint32_t *min_range, uint32_t *max_range); + +/** Return the min depth range for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_depth_mode_min_range(k4a_depth_mode_t mode_id); + +/** Return the max depth range for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_depth_mode_max_range(k4a_depth_mode_t mode_id); + +#ifdef __cplusplus +} +#endif + +#endif /* MODES_H */ \ No newline at end of file diff --git a/include/k4ainternal/queue.h b/include/k4ainternal/queue.h index e378bda4b..43bd30128 100644 --- a/include/k4ainternal/queue.h +++ b/include/k4ainternal/queue.h @@ -9,7 +9,7 @@ #include #include -#include +#include #include diff --git a/include/k4ainternal/transformation.h b/include/k4ainternal/transformation.h index af467510c..d731b2084 100644 --- a/include/k4ainternal/transformation.h +++ b/include/k4ainternal/transformation.h @@ -59,8 +59,8 @@ k4a_result_t transformation_get_mode_specific_calibration(const k4a_calibration_ const k4a_calibration_camera_t *color_camera_calibration, const k4a_calibration_extrinsics_t *gyro_extrinsics, const k4a_calibration_extrinsics_t *accel_extrinsics, - const k4a_depth_mode_t depth_mode, - const k4a_color_resolution_t color_resolution, + const uint32_t depth_mode_id, + const uint32_t color_mode_id, k4a_calibration_t *calibration); k4a_result_t transformation_3d_to_3d(const k4a_calibration_t *calibration, @@ -188,12 +188,12 @@ transformation_depth_image_to_point_cloud(k4a_transformation_t transformation_ha // Mode specific calibration k4a_result_t transformation_get_mode_specific_depth_camera_calibration(const k4a_calibration_camera_t *raw_camera_calibration, - const k4a_depth_mode_t depth_mode, + const uint32_t depth_mode_id, k4a_calibration_camera_t *mode_specific_camera_calibration); k4a_result_t transformation_get_mode_specific_color_camera_calibration(const k4a_calibration_camera_t *raw_camera_calibration, - const k4a_color_resolution_t color_resolution, + const uint32_t color_mode_id, k4a_calibration_camera_t *mode_specific_camera_calibration); k4a_result_t diff --git a/include/k4ainternal/usb_device_ids.h b/include/k4ainternal/usb_device_ids.h new file mode 100644 index 000000000..69b3bdab7 --- /dev/null +++ b/include/k4ainternal/usb_device_ids.h @@ -0,0 +1,26 @@ +/** \file usb_device_ids.h + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + * Kinect For Azure SDK. + */ + +#ifndef USB_DEVICE_IDS_H +#define USB_DEVICE_IDS_H + +//************************ Includes ***************************** +#ifdef __cplusplus +extern "C" { +#endif + +//**************Symbolic Constant Macros (defines) ************* +#define K4A_MSFT_VID 0x045E /**< Microsoft vendor id. */ +#define K4A_RGB_PID 0x097D /**< Azure Kinect RGB sensor product id. */ +#define K4A_DEPTH_PID 0x097C /**< Azure Kinect Depth sensor product id. */ + +//************************ Typedefs ***************************** + +#ifdef __cplusplus +} +#endif + +#endif /* USB_DEVICE_IDS_H */ \ No newline at end of file diff --git a/include/k4ainternal/usbcommand.h b/include/k4ainternal/usbcommand.h index 2c75f9fff..108ba21e8 100644 --- a/include/k4ainternal/usbcommand.h +++ b/include/k4ainternal/usbcommand.h @@ -10,7 +10,6 @@ //************************ Includes ***************************** #include #include -#include #ifdef __cplusplus extern "C" { diff --git a/include/k4arecord/types.h b/include/k4arecord/types.h index f3533f212..8995d390e 100644 --- a/include/k4arecord/types.h +++ b/include/k4arecord/types.h @@ -130,6 +130,7 @@ typedef enum K4A_STREAM_RESULT_SUCCEEDED = 0, /**< The result was successful. */ K4A_STREAM_RESULT_FAILED, /**< The result was a failure. */ K4A_STREAM_RESULT_EOF, /**< The end of the data stream was reached. */ + K4A_STREAM_RESULT_UNSUPPORTED, /**< The result was unsupported. */ } k4a_stream_result_t; /** Playback seeking positions. @@ -170,14 +171,17 @@ typedef struct _k4a_record_configuration_t /** Image format used to record the color camera. */ k4a_image_format_t color_format; - /** Image resolution used to record the color camera. */ - k4a_color_resolution_t color_resolution; + /** Mode info used to record the color camera. */ + k4a_color_mode_info_t color_mode_info; - /** Mode used to record the depth camera. */ - k4a_depth_mode_t depth_mode; + /** Mode info used to record the depth camera. */ + k4a_depth_mode_info_t depth_mode_info; /** Frame rate used to record the color and depth camera. */ - k4a_fps_t camera_fps; + k4a_fps_mode_info_t fps_mode_info; + + /** Vendor Id, Device Id and device Capabilities. */ + k4a_device_info_t device_info; /** True if the recording contains Color camera frames. */ bool color_track_enabled; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0115577e6..9e1a87ba8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,6 +21,7 @@ add_subdirectory(image) add_subdirectory(imu) add_subdirectory(logging) add_subdirectory(math) +add_subdirectory(modes) add_subdirectory(queue) add_subdirectory(record) add_subdirectory(rwlock) diff --git a/src/calibration/calibration.c b/src/calibration/calibration.c index bf5f34a49..7c39d66ee 100644 --- a/src/calibration/calibration.c +++ b/src/calibration/calibration.c @@ -5,7 +5,6 @@ #include // Dependent libraries -#include #include #include //cJSON.h need this set correctly. diff --git a/src/capturesync/CMakeLists.txt b/src/capturesync/CMakeLists.txt index a4345932c..04aec96d0 100644 --- a/src/capturesync/CMakeLists.txt +++ b/src/capturesync/CMakeLists.txt @@ -12,7 +12,8 @@ target_include_directories(k4a_capturesync PUBLIC # Dependencies of this library target_link_libraries(k4a_capturesync PUBLIC azure::aziotsharedutil - k4ainternal::logging) + k4ainternal::logging + k4ainternal::modes) # Define alias for other targets to link against add_library(k4ainternal::capturesync ALIAS k4a_capturesync) \ No newline at end of file diff --git a/src/capturesync/capturesync.c b/src/capturesync/capturesync.c index 0c46b9139..456a7c0a6 100644 --- a/src/capturesync/capturesync.c +++ b/src/capturesync/capturesync.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include @@ -491,13 +491,13 @@ k4a_result_t capturesync_start(capturesync_t capturesync_handle, const k4a_devic sync->waiting_for_clean_depth_ts = true; sync->synchronized_images_only = config->synchronized_images_only; - sync->fps_period = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(config->camera_fps)); + sync->fps_period = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(config->fps_mode_id)); sync->fps_1_quarter_period = sync->fps_period / 4; sync->depth_delay_off_color_usec = config->depth_delay_off_color_usec; sync->sync_captures = true; sync->depth_captures_dropped = 0; - if (config->color_resolution == K4A_COLOR_RESOLUTION_OFF || config->depth_mode == K4A_DEPTH_MODE_OFF) + if (config->color_mode_id == K4A_COLOR_RESOLUTION_OFF || config->depth_mode_id == K4A_DEPTH_MODE_OFF) { // Only 1 sensor is running, disable synchronization sync->sync_captures = false; diff --git a/src/color/CMakeLists.txt b/src/color/CMakeLists.txt index cc0c91261..52f20b5a2 100644 --- a/src/color/CMakeLists.txt +++ b/src/color/CMakeLists.txt @@ -25,6 +25,7 @@ target_include_directories(k4a_color PUBLIC # Dependencies of this library target_link_libraries(k4a_color PUBLIC k4ainternal::logging + k4ainternal::modes ${K4A_COLOR_SYSTEM_DEPENDENCIES}) # Define alias for other targets to link against diff --git a/src/color/color.cpp b/src/color/color.cpp index f1c8e8e3c..ac0c28fc3 100644 --- a/src/color/color.cpp +++ b/src/color/color.cpp @@ -3,6 +3,7 @@ // This library #include +#include // Dependent libraries @@ -133,52 +134,20 @@ k4a_result_t color_start(color_t color_handle, const k4a_device_configuration_t color_context_t *color = color_t_get_context(color_handle); uint32_t width = 0; uint32_t height = 0; - float fps = 1.0f; + uint32_t fps = 1; - switch (config->color_resolution) + if (!k4a_convert_resolution_to_width_height(static_cast(config->color_mode_id), + &width, + &height)) { - case K4A_COLOR_RESOLUTION_720P: - width = 1280; - height = 720; - break; - case K4A_COLOR_RESOLUTION_2160P: - width = 3840; - height = 2160; - break; - case K4A_COLOR_RESOLUTION_1440P: - width = 2560; - height = 1440; - break; - case K4A_COLOR_RESOLUTION_1080P: - width = 1920; - height = 1080; - break; - case K4A_COLOR_RESOLUTION_3072P: - width = 4096; - height = 3072; - break; - case K4A_COLOR_RESOLUTION_1536P: - width = 2048; - height = 1536; - break; - default: - LOG_ERROR("color_resolution %d is invalid", config->color_resolution); + LOG_ERROR("color_resolution %d is invalid", config->color_mode_id); return K4A_RESULT_FAILED; } - switch (config->camera_fps) + fps = static_cast(config->fps_mode_id); + if (fps == 0) { - case K4A_FRAMES_PER_SECOND_30: - fps = 30.0f; - break; - case K4A_FRAMES_PER_SECOND_15: - fps = 15.0f; - break; - case K4A_FRAMES_PER_SECOND_5: - fps = 5.0f; - break; - default: - LOG_ERROR("camera_fps %d is invalid", config->camera_fps); + LOG_ERROR("camera_fps %d is invalid", config->fps_mode_id); return K4A_RESULT_FAILED; } @@ -188,7 +157,7 @@ k4a_result_t color_start(color_t color_handle, const k4a_device_configuration_t { result = TRACE_CALL(color->m_spCameraReader->Start(width, height, // Resolution - fps, // Framerate + static_cast(fps), // Framerate config->color_format, // Color format enum &color_capture_available, // Callback color)); // Callback context diff --git a/src/color/mfcamerareader.cpp b/src/color/mfcamerareader.cpp index 7183621c5..f37f82581 100644 --- a/src/color/mfcamerareader.cpp +++ b/src/color/mfcamerareader.cpp @@ -2,7 +2,6 @@ // Licensed under the MIT License. #include "mfcamerareader.h" -#include #include #include #include diff --git a/src/color/uvc_camerareader.cpp b/src/color/uvc_camerareader.cpp index f13a41add..03e8aa4ec 100644 --- a/src/color/uvc_camerareader.cpp +++ b/src/color/uvc_camerareader.cpp @@ -1,10 +1,7 @@ #include "uvc_camerareader.h" #include "ksmetadata.h" -#include #include - -#define COLOR_CAMERA_VID 0x045e -#define COLOR_CAMERA_PID 0x097d // K4A +#include #define UVC_AUTO_EXPOSURE_MODE_MANUAL 1 // manual exposure time, manual iris #define UVC_AUTO_EXPOSURE_MODE_AUTO 2 // auto exposure time, @@ -49,7 +46,7 @@ k4a_result_t UVCCameraReader::Init(const char *serialNumber) } // Find K4A Color Camera - res = uvc_find_device(m_pContext, &m_pDevice, COLOR_CAMERA_VID, COLOR_CAMERA_PID, serialNumber); + res = uvc_find_device(m_pContext, &m_pDevice, K4A_MSFT_VID, K4A_RGB_PID, serialNumber); if (res < 0) { LOG_ERROR("Can't find UVC device: %s", uvc_strerror(res)); diff --git a/src/color_mcu/color_mcu.c b/src/color_mcu/color_mcu.c index 6b5b09411..283a1eaa2 100644 --- a/src/color_mcu/color_mcu.c +++ b/src/color_mcu/color_mcu.c @@ -3,7 +3,6 @@ // This library * #include -#include // System dependencies #include diff --git a/src/csharp/Examples/WPF/MainWindow.xaml.cs b/src/csharp/Examples/WPF/MainWindow.xaml.cs index 547ddff3a..82e158d71 100644 --- a/src/csharp/Examples/WPF/MainWindow.xaml.cs +++ b/src/csharp/Examples/WPF/MainWindow.xaml.cs @@ -5,6 +5,7 @@ // //------------------------------------------------------------------------------ using System; +using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; using System.Windows; @@ -42,13 +43,32 @@ private async void Window_Loaded(object sender, RoutedEventArgs e) { using (Device device = Device.Open(0)) { + // We need to provide mode ids for color, depth and fps for the device configuration passed to the device start cameras method. + + // 1. Get the available modes for device using the get modes methods. + List colorModes = device.GetColorModes(); + List fpsModes = device.GetFPSModes(); + List depthModes = device.GetDepthModes(); + + // 2. For this example, let's find the first color mode with an image height of at least 1080. + ColorModeInfo colorModeInfo = colorModes.Find(c => c.Height >= 1080); + + // 3. For this example, let's find the first depth mode with an image height of at least 512 and a horizontal fov of at least 120. + DepthModeInfo depthModeInfo = depthModes.Find(d => d.Height >= 512 && d.HorizontalFOV >= 120); + + // 4. For this example, let's find the fps mode with the highest frames per second. + fpsModes.Sort((a, b) => b.FPS.CompareTo(a.FPS)); + FPSModeInfo fpsModeInfo = fpsModes.Find(f => f.ModeId != 0); + + // 5. If either a color or depth mode was found that met our example conditions and as long as there was at least one fps mode (there should always be), + // then the mode ids will be valid parameters for the device configuration passed into the device start camera function. device.StartCameras(new DeviceConfiguration { ColorFormat = ImageFormat.ColorBGRA32, - ColorResolution = ColorResolution.R720p, - DepthMode = DepthMode.WFOV_2x2Binned, + ColorModeId = colorModeInfo.ModeId, + DepthModeId = depthModeInfo.ModeId, SynchronizedImagesOnly = true, - CameraFPS = FPS.FPS30, + FPSModeId = fpsModeInfo.ModeId, }); int colorWidth = device.GetCalibration().ColorCameraCalibration.ResolutionWidth; diff --git a/src/csharp/Examples/WinForms/Form1.cs b/src/csharp/Examples/WinForms/Form1.cs index e107cf3ed..5368833ae 100644 --- a/src/csharp/Examples/WinForms/Form1.cs +++ b/src/csharp/Examples/WinForms/Form1.cs @@ -5,6 +5,7 @@ // //------------------------------------------------------------------------------ using System; +using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; @@ -43,12 +44,32 @@ private async void Form1_Load(object sender, EventArgs e) { using (Device device = Device.Open(0)) { + // We need to provide mode ids for color, depth and fps for the device configuration passed to the device start cameras method. + + // 1. Get the available modes for device using the get modes methods. + List colorModes = device.GetColorModes(); + List fpsModes = device.GetFPSModes(); + List depthModes = device.GetDepthModes(); + + // 2. For this example, let's find the first color mode that isn't the Off mode. + ColorModeInfo colorModeInfo = colorModes.Find(c => c.ModeId > 0); + + // 3. For this example, let's find the first depth mode that isn't the Off mode. + DepthModeInfo depthModeInfo = depthModes.Find(d => d.ModeId > 0); + + // 4. For this example, let's find the fps mode with the highest frames per second. + fpsModes.Sort((a, b) => b.FPS.CompareTo(a.FPS)); + FPSModeInfo fpsModeInfo = fpsModes.Find(f => f.ModeId != 0); + + // 5. If either a color or depth mode was found that met our example conditions and as long as there was at least one fps mode (there should always be), + // then the mode ids will be valid parameters for the device configuration passed into the device start camera function. device.StartCameras(new DeviceConfiguration { ColorFormat = ImageFormat.ColorBGRA32, - ColorResolution = ColorResolution.R720p, - DepthMode = DepthMode.NFOV_2x2Binned, + ColorModeId = colorModeInfo.ModeId, + DepthModeId = depthModeInfo.ModeId, SynchronizedImagesOnly = true, + FPSModeId = fpsModeInfo.ModeId, }); Stopwatch sw = new Stopwatch(); diff --git a/src/csharp/SDK/Calibration.cs b/src/csharp/SDK/Calibration.cs index 72bd3d0db..fa97d842c 100644 --- a/src/csharp/SDK/Calibration.cs +++ b/src/csharp/SDK/Calibration.cs @@ -45,14 +45,14 @@ public struct Calibration : IEquatable public Extrinsics[] DeviceExtrinsics; /// - /// Depth camera mode for which calibration was obtained. + /// Depth camera mode id for which calibration was obtained. /// - public DepthMode DepthMode; + public int DepthModeId; // TODO: will an int work for an uint when passing back to c/c++? /// - /// Color camera resolution for which calibration was obtained. + /// Color camera mode id for which calibration was obtained. /// - public ColorResolution ColorResolution; + public int ColorModeId; // TODO: will an int work for an uint when passing back to c/c++? #pragma warning restore CA1051 // Do not declare visible instance fields @@ -85,14 +85,14 @@ public struct Calibration : IEquatable /// Mode in which depth camera is operated. /// Resolution in which the color camera is operated. /// Calibration object. - public static Calibration GetFromRaw(byte[] raw, DepthMode depthMode, ColorResolution colorResolution) + public static Calibration GetFromRaw(byte[] raw, uint depthModeId, uint colorModeId) { Calibration calibration = default; AzureKinectException.ThrowIfNotSuccess(() => NativeMethods.k4a_calibration_get_from_raw( raw, (UIntPtr)raw.Length, - depthMode, - colorResolution, + depthModeId, + colorModeId, out calibration)); return calibration; @@ -245,8 +245,8 @@ public bool Equals(Calibration other) return this.DepthCameraCalibration.Equals(other.DepthCameraCalibration) && this.ColorCameraCalibration.Equals(other.ColorCameraCalibration) && EqualityComparer.Default.Equals(this.DeviceExtrinsics, other.DeviceExtrinsics) && - this.DepthMode == other.DepthMode && - this.ColorResolution == other.ColorResolution; + this.DepthModeId == other.DepthModeId && + this.ColorModeId == other.ColorModeId; } /// @@ -256,8 +256,8 @@ public override int GetHashCode() hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.DepthCameraCalibration); hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.ColorCameraCalibration); hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.DeviceExtrinsics); - hashCode = (hashCode * -1521134295) + this.DepthMode.GetHashCode(); - hashCode = (hashCode * -1521134295) + this.ColorResolution.GetHashCode(); + hashCode = (hashCode * -1521134295) + this.DepthModeId.GetHashCode(); + hashCode = (hashCode * -1521134295) + this.ColorModeId.GetHashCode(); return hashCode; } } diff --git a/src/csharp/SDK/ColorModeInfo.cs b/src/csharp/SDK/ColorModeInfo.cs new file mode 100644 index 000000000..d66bc2108 --- /dev/null +++ b/src/csharp/SDK/ColorModeInfo.cs @@ -0,0 +1,110 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +//------------------------------------------------------------------------------ +using System; +using System.Runtime.InteropServices; +using static Microsoft.Azure.Kinect.Sensor.NativeMethods; + +namespace Microsoft.Azure.Kinect.Sensor +{ + /// + /// Represents the configuration to run a color device in. + /// + /// + /// Gets or sets the Color Mode Info. + /// + public class ColorModeInfo + { + /// + /// Gets the Struct Size. Default set in the NativeMethods class and must be kept in sync with k4a_color_mode_info_t k4atypes.h. + /// + public int StructSize { get; private set; } = colorModeInfoStructSize; + + /// + /// Gets the Struct Version. + /// + public int StructVersion { get; private set; } = 1; + + /// + /// Gets the ModeId of the color camera. + /// + public int ModeId { get; private set; } = 0; + + /// + /// Gets the image Width. + /// + public int Width { get; private set; } = 0; + + /// + /// Gets the image Height. + /// + public int Height { get; private set; } = 0; + + /// + /// Gets the Native Image Format. + /// + public ImageFormat NativeFormat { get; private set; } = ImageFormat.ColorMJPG; + + /// + /// Gets the Horizontal FOV. + /// + public float HorizontalFOV { get; private set; } = 0; + + /// + /// Gets the Vertical FOV. + /// + public float VerticalFOV { get; private set; } = 0; + + /// + /// Gets the Min FPS. + /// + public int MinFPS { get; private set; } = 0; + + /// + /// Gets the Max FPS. + /// + public int MaxFPS { get; private set; } = 0; + + /// + /// Get the equivalent native configuration struct. + /// + /// k4a_color_mode_info_t. + internal k4a_color_mode_info_t GetNativeConfiguration() + { + return new k4a_color_mode_info_t + { + struct_size = (uint)this.StructSize, + struct_version = (uint)this.StructVersion, + mode_id = (uint)this.ModeId, + width = (uint)this.Width, + height = (uint)this.Height, + native_format = (k4a_image_format_t)this.NativeFormat, + horizontal_fov = this.HorizontalFOV, + vertical_fov = this.VerticalFOV, + min_fps = (uint)this.MinFPS, + max_fps = (uint)this.MaxFPS, + }; + } + + /// + /// Set properties using native configuration struct. + /// + /// colorModeInfo. + internal void SetUsingNativeConfiguration(k4a_color_mode_info_t colorModeInfo) + { + this.StructSize = (int)colorModeInfo.struct_size; + this.StructVersion = (int)colorModeInfo.struct_version; + this.ModeId = (int)colorModeInfo.mode_id; + this.Width = (int)colorModeInfo.width; + this.Height = (int)colorModeInfo.height; + this.NativeFormat = (ImageFormat)colorModeInfo.native_format; + this.HorizontalFOV = colorModeInfo.horizontal_fov; + this.VerticalFOV = colorModeInfo.vertical_fov; + this.MinFPS = (int)colorModeInfo.min_fps; + this.MaxFPS = (int)colorModeInfo.max_fps; + } + } +} diff --git a/src/csharp/SDK/ColorResolution.cs b/src/csharp/SDK/ColorResolution.cs deleted file mode 100644 index 719a6410e..000000000 --- a/src/csharp/SDK/ColorResolution.cs +++ /dev/null @@ -1,51 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.Azure.Kinect.Sensor -{ - /// - /// Color sensor resolutions. - /// - [Native.NativeReference("k4a_color_resolution_t")] - public enum ColorResolution - { - /// - /// Color camera will be turned off with this setting. - /// - Off = 0, - - /// - /// 1280 * 720 16:9 - /// - R720p, - - /// - /// 1920 * 1080 16:9 - /// - R1080p, - - /// - /// 2560 * 1440 16:9 - /// - R1440p, - - /// - /// 2048 * 1536 4:3 - /// - R1536p, - - /// - /// 3840 * 2160 16:9 - /// - R2160p, - - /// - /// 4096 * 3072 4:3 - /// - R3072p, - } -} diff --git a/src/csharp/SDK/DepthMode.cs b/src/csharp/SDK/DepthMode.cs deleted file mode 100644 index c00d9210f..000000000 --- a/src/csharp/SDK/DepthMode.cs +++ /dev/null @@ -1,53 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.Azure.Kinect.Sensor -{ - /// - /// Depth sensor capture modes. - /// - /// - /// See the hardware specification for additional details on the field of view, and supported frame rates for each mode. - /// NFOV and WFOV denote Narrow and Wide Field Of View configurations. - /// Binned modes reduce the captured camera resolution by combining adjacent sensor pixels into a bin. - /// - [Native.NativeReference("k4a_depth_mode_t")] - public enum DepthMode - { -#pragma warning disable CA1707 // Identifiers should not contain underscores - /// - /// Depth sensor will be turned off with this setting. - /// - Off = 0, - - /// - /// Depth and Passive IR are captured at 320x288. - /// - NFOV_2x2Binned, - - /// - /// Depth and Passive IR are captured at 640x576. - /// - NFOV_Unbinned, - - /// - /// Depth and Passive IR are captured at 512x512. - /// - WFOV_2x2Binned, - - /// - /// Depth and Passive IR are captured at 1024x1024. - /// - WFOV_Unbinned, - - /// - /// Passive IR only is captured at 1024x1024. - /// - PassiveIR, -#pragma warning restore CA1707 // Identifiers should not contain underscores - } -} diff --git a/src/csharp/SDK/DepthModeInfo.cs b/src/csharp/SDK/DepthModeInfo.cs new file mode 100644 index 000000000..5ef7b28f2 --- /dev/null +++ b/src/csharp/SDK/DepthModeInfo.cs @@ -0,0 +1,134 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +//------------------------------------------------------------------------------ +using System; +using System.Runtime.InteropServices; +using static Microsoft.Azure.Kinect.Sensor.NativeMethods; + +namespace Microsoft.Azure.Kinect.Sensor +{ + /// + /// Represents the configuration to run a depth device in. + /// + /// + /// Default initialization is the same as K4A_DEVICE_CONFIG_INIT_DISABLE_ALL. + /// + public class DepthModeInfo + { + /// + /// Gets the Struct Size. Default set in the NativeMethods class and must be kept in sync with k4a_depth_mode_info_t k4atypes.h. + /// + public int StructSize { get; private set; } = depthModeInfoInfoStructSize; + + /// + /// Gets the Struct Version. + /// + public int StructVersion { get; private set; } = 1; + + /// + /// Gets the ModeId of the depth camera. + /// + public int ModeId { get; private set; } = 0; + + /// + /// Gets a value indicating whether to use Passive IR Only. + /// + /// + /// If this is false, the Passive IR images are dropped. + /// + public bool PassiveIROnly { get; private set; } = false; + + /// + /// Gets the image width. + /// + public int Width { get; private set; } = 0; + + /// + /// Gets the image height. + /// + public int Height { get; private set; } = 0; + + /// + /// Gets the image format. Depth image type DEPTH16. Each pixel of DEPTH16 data is two bytes of little-endian unsigned depth data. + /// + public ImageFormat NativeFormat { get; private set; } = ImageFormat.Depth16; + + /// + /// Gets the Horizontal FOV. + /// + public float HorizontalFOV { get; private set; } = 0; + + /// + /// Gets the Vertical FOV. + /// + public float VerticalFOV { get; private set; } = 0; + + /// + /// Gets the Min FPS. + /// + public int MinFPS { get; private set; } = 0; + + /// + /// Gets the Max FPS. + /// + public int MaxFPS { get; private set; } = 0; + + /// + /// Gets the Min Range. + /// + public int MinRange { get; private set; } = 0; + + /// + /// Gets the Max Range. + /// + public int MaxRange { get; private set; } = 0; + + /// + /// Gets equivalent native configuration struct. + /// + /// k4a_depth_mode_info_t. + internal k4a_depth_mode_info_t GetNativeConfiguration() + { + return new k4a_depth_mode_info_t + { + struct_size = (uint)this.StructSize, + struct_version = (uint)this.StructVersion, + mode_id = (uint)this.ModeId, + passive_ir_only = Convert.ToByte(this.PassiveIROnly), + width = (uint)this.Width, + height = (uint)this.Height, + native_format = (NativeMethods.k4a_image_format_t)this.NativeFormat, + horizontal_fov = this.HorizontalFOV, + vertical_fov = this.VerticalFOV, + min_fps = (uint)this.MinFPS, + max_fps = (uint)this.MaxFPS, + min_range = (uint)this.MinRange, + max_range = (uint)this.MaxRange, + }; + } + + /// + /// Set properties using native configuration struct. + /// + /// depthModeInfo. + internal void SetUsingNativeConfiguration(k4a_depth_mode_info_t depthModeInfo) + { + this.StructSize = (int)depthModeInfo.struct_size; + this.StructVersion = (int)depthModeInfo.struct_version; + this.ModeId = (int)depthModeInfo.mode_id; + this.PassiveIROnly = Convert.ToBoolean(depthModeInfo.passive_ir_only); + this.Width = (int)depthModeInfo.width; + this.Height = (int)depthModeInfo.height; + this.NativeFormat = (ImageFormat)depthModeInfo.native_format; + this.HorizontalFOV = depthModeInfo.horizontal_fov; + this.VerticalFOV = depthModeInfo.vertical_fov; + this.MinFPS = (int)depthModeInfo.min_fps; + this.MaxFPS = (int)depthModeInfo.max_fps; + this.MinRange = (int)depthModeInfo.min_range; + this.MaxRange = (int)depthModeInfo.max_range; + } + } +} diff --git a/src/csharp/SDK/Device.cs b/src/csharp/SDK/Device.cs index fba4d2df8..9a8698f33 100644 --- a/src/csharp/SDK/Device.cs +++ b/src/csharp/SDK/Device.cs @@ -5,7 +5,9 @@ // //------------------------------------------------------------------------------ using System; +using System.Collections.Generic; using System.Text; +using static Microsoft.Azure.Kinect.Sensor.NativeMethods; namespace Microsoft.Azure.Kinect.Sensor { @@ -78,12 +80,12 @@ public string SerialNum /// /// Gets the depth mode the device is currently set to. /// - public DepthMode CurrentDepthMode { get; private set; } = DepthMode.Off; + public int CurrentDepthModeId { get; private set; } = 0; // 0 = Off /// /// Gets the color resolution the device is currently set to. /// - public ColorResolution CurrentColorResolution { get; private set; } = ColorResolution.Off; + public int CurrentColorModeId { get; private set; } = 0; // 0 = Off /// /// Gets a value indicating whether gets the Sync In jack is connected. @@ -192,10 +194,10 @@ public static Device Open(int index = 0) /// /// Gets the calibration of the device. /// - /// Depth mode for the calibration. - /// Color camera resolution for the calibration. + /// Depth mode id for the calibration. + /// Color modes id for the calibration. /// Calibration object. - public Calibration GetCalibration(DepthMode depthMode, ColorResolution colorResolution) + public Calibration GetCalibration(int depthModeId, int colorModeId) { lock (this) { @@ -205,7 +207,7 @@ public Calibration GetCalibration(DepthMode depthMode, ColorResolution colorReso } Calibration calibration = default; - AzureKinectException.ThrowIfNotSuccess(() => NativeMethods.k4a_device_get_calibration(this.handle, depthMode, colorResolution, out calibration)); + AzureKinectException.ThrowIfNotSuccess(() => NativeMethods.k4a_device_get_calibration(this.handle, (uint) depthModeId, (uint) colorModeId, out calibration)); return calibration; } } @@ -216,12 +218,12 @@ public Calibration GetCalibration(DepthMode depthMode, ColorResolution colorReso /// Calibration object. public Calibration GetCalibration() { - if (this.CurrentColorResolution == ColorResolution.Off && this.CurrentDepthMode == DepthMode.Off) + if (this.CurrentColorModeId == 0 && this.CurrentDepthModeId == 0) { throw new AzureKinectException("Cameras not started"); } - return this.GetCalibration(this.CurrentDepthMode, this.CurrentColorResolution); + return this.GetCalibration(this.CurrentDepthModeId, this.CurrentColorModeId); } /// @@ -439,8 +441,8 @@ public void StartCameras(DeviceConfiguration configuration) NativeMethods.k4a_device_configuration_t nativeConfig = configuration.GetNativeConfiguration(); AzureKinectStartCamerasException.ThrowIfNotSuccess(() => NativeMethods.k4a_device_start_cameras(this.handle, ref nativeConfig)); - this.CurrentDepthMode = configuration.DepthMode; - this.CurrentColorResolution = configuration.ColorResolution; + this.CurrentDepthModeId = configuration.DepthModeId; + this.CurrentColorModeId = configuration.ColorModeId; } } @@ -458,8 +460,8 @@ public void StopCameras() NativeMethods.k4a_device_stop_cameras(this.handle); - this.CurrentDepthMode = DepthMode.Off; - this.CurrentColorResolution = ColorResolution.Off; + this.CurrentDepthModeId = 0; + this.CurrentColorModeId = 0; } } @@ -495,6 +497,186 @@ public void StopImu() } } + /// + /// Get the Device Info. + /// + /// The Device Info. + public DeviceInfo GetInfo() + { + lock (this) + { + if (this.disposedValue) + { + throw new ObjectDisposedException(nameof(Device)); + } + + DeviceInfo deviceInfo = new DeviceInfo(); + k4a_device_info_t device_info = deviceInfo.GetNativeConfiguration(); + AzureKinectException.ThrowIfNotSuccess(() => k4a_device_get_info(this.handle, out device_info)); + deviceInfo.SetUsingNativeConfiguration(device_info); + return deviceInfo; + } + } + + /// + /// Lists the ColorMode Info. + /// + /// The ColorMode Info. + public List GetColorModes() + { + List colorModes = new List(); + uint colorModeInfoCount = 0; + + lock (this) + { + if (this.disposedValue) + { + throw new ObjectDisposedException(nameof(Device)); + } + + AzureKinectException.ThrowIfNotSuccess(() => k4a_device_get_color_mode_count(this.handle, out colorModeInfoCount)); + } + + for (int i = 0; i < colorModeInfoCount; i++) + { + ColorModeInfo colorModeInfo = this.GetColorMode(i); + if (colorModeInfo != null) + { + colorModes.Add(colorModeInfo); + } + } + + + return colorModes; + } + + /// + /// Get the ColorMode Info. + /// + /// colorModeid + /// The ColorMode Info. + public ColorModeInfo GetColorMode(int colorModeIndex) + { + lock (this) + { + if (this.disposedValue) + { + throw new ObjectDisposedException(nameof(Device)); + } + ColorModeInfo colorModeInfo = new ColorModeInfo(); + k4a_color_mode_info_t color_mode_info = colorModeInfo.GetNativeConfiguration(); + AzureKinectException.ThrowIfNotSuccess(() => k4a_device_get_color_mode(this.handle, (uint)colorModeIndex, out color_mode_info)); + colorModeInfo.SetUsingNativeConfiguration(color_mode_info); + return colorModeInfo; + } + } + + /// + /// Lists the DepthMode Info. + /// + /// The DepthModes. + public List GetDepthModes() + { + List depthModes = new List(); + uint depthModeInfoCount = 0; + + lock (this) + { + if (this.disposedValue) + { + throw new ObjectDisposedException(nameof(Device)); + } + + AzureKinectException.ThrowIfNotSuccess(() => k4a_device_get_depth_mode_count(this.handle, out depthModeInfoCount)); + } + + for (int i = 0; i < depthModeInfoCount; i++) + { + DepthModeInfo depthModeInfo = this.GetDepthMode(i); + if (depthModeInfo != null) + { + depthModes.Add(depthModeInfo); + } + } + + return depthModes; + } + + /// + /// Get the DepthMode Info. + /// + /// depthModeId + /// The DepthMode Info. + public DepthModeInfo GetDepthMode(int depthModeIndex) + { + lock (this) + { + if (this.disposedValue) + { + throw new ObjectDisposedException(nameof(Device)); + } + + DepthModeInfo depthModeInfo = new DepthModeInfo(); + k4a_depth_mode_info_t depth_mode_info = depthModeInfo.GetNativeConfiguration(); + AzureKinectException.ThrowIfNotSuccess(() => k4a_device_get_depth_mode(this.handle, (uint)depthModeIndex, out depth_mode_info)); + depthModeInfo.SetUsingNativeConfiguration(depth_mode_info); + return depthModeInfo; + } + } + + /// + /// Lists the FPSMode Info. + /// + /// The FPSModes. + public List GetFPSModes() + { + List fpsModes = new List(); + uint fpsModeInfoCount = 0; + + lock (this) + { + if (this.disposedValue) + { + throw new ObjectDisposedException(nameof(Device)); + } + + AzureKinectException.ThrowIfNotSuccess(() => k4a_device_get_fps_mode_count(this.handle, out fpsModeInfoCount)); + } + + for (int i = 0; i < fpsModeInfoCount; i++) + { + FPSModeInfo fpsModeInfo = this.GetFPSMode(i); + if (fpsModeInfo != null) + { + fpsModes.Add(fpsModeInfo); + } + } + + return fpsModes; + } + + /// + /// Get the FPShMode Info. + /// + /// fpsModeId + /// The FPSMode Info. + public FPSModeInfo GetFPSMode(int fpsModeIndex) + { + lock (this) + { + if (this.disposedValue) + { + throw new ObjectDisposedException(nameof(Device)); + } + + FPSModeInfo fpsModeInfo = new FPSModeInfo(); + k4a_fps_mode_info_t fps_mode_info = fpsModeInfo.GetNativeConfiguration(); + AzureKinectException.ThrowIfNotSuccess(() => k4a_device_get_fps_mode(this.handle, (uint)fpsModeIndex, out fps_mode_info)); + fpsModeInfo.SetUsingNativeConfiguration(fps_mode_info); + return fpsModeInfo; + } + } + /// public void Dispose() { diff --git a/src/csharp/SDK/DeviceConfiguration.cs b/src/csharp/SDK/DeviceConfiguration.cs index 8caca361f..bcdfa1eea 100644 --- a/src/csharp/SDK/DeviceConfiguration.cs +++ b/src/csharp/SDK/DeviceConfiguration.cs @@ -22,19 +22,19 @@ public class DeviceConfiguration public ImageFormat ColorFormat { get; set; } = ImageFormat.ColorMJPG; /// - /// Gets or sets the image resolution to capture with the color camera. + /// Gets or sets the color mode id to capture with the color camera. /// - public ColorResolution ColorResolution { get; set; } = ColorResolution.Off; + public int ColorModeId { get; set; } = 0; // 0 = Off /// - /// Gets or sets the capture mode for the depth camera. + /// Gets or sets the capture mode id for the depth camera. /// - public DepthMode DepthMode { get; set; } = DepthMode.Off; + public int DepthModeId { get; set; } = 0; // 0 = Off /// - /// Gets or sets the desired frame rate for the color and depth cameras. + /// Gets or sets the desired frame rate id for the color and depth cameras. /// - public FPS CameraFPS { get; set; } = FPS.FPS30; + public int FPSModeId { get; set; } = 0; /// /// Gets or sets a value indicating whether to only return synchronized depth and color images. @@ -80,9 +80,9 @@ internal NativeMethods.k4a_device_configuration_t GetNativeConfiguration() return new NativeMethods.k4a_device_configuration_t { color_format = this.ColorFormat, - color_resolution = this.ColorResolution, - depth_mode = this.DepthMode, - camera_fps = this.CameraFPS, + color_mode_id = (uint) this.ColorModeId, + depth_mode_id = (uint) this.DepthModeId, + fps_mode_id = (uint) this.FPSModeId, synchronized_images_only = this.SynchronizedImagesOnly, depth_delay_off_color_usec = depth_delay_off_color_usec, wired_sync_mode = this.WiredSyncMode, diff --git a/src/csharp/SDK/DeviceInfo.cs b/src/csharp/SDK/DeviceInfo.cs new file mode 100644 index 000000000..2e03af66b --- /dev/null +++ b/src/csharp/SDK/DeviceInfo.cs @@ -0,0 +1,75 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +//------------------------------------------------------------------------------ +using System; +using System.Runtime.InteropServices; +using static Microsoft.Azure.Kinect.Sensor.NativeMethods; + +namespace Microsoft.Azure.Kinect.Sensor +{ + /// + /// Represents the configuration to run an Azure Kinect device in. + /// + /// + /// Gets or sets the Device Info. + /// + public class DeviceInfo + { + /// + /// Gets Struct Size. Default set in the NativeMethods class and must be kept in sync with k4a_device_info_t k4atypes.h. + /// + public int StructSize { get; private set; } = deviceInfoStructSize; + + /// + /// Gets the Struct Version. + /// + public int StructVersion { get; private set; } = 1; + + /// + /// Gets the Vendor Id. + /// + public int VendorId { get; private set; } = 0; + + /// + /// Gets the Device Id. + /// + public int DeviceId { get; private set; } = 0; + + /// + /// Gets the Capabilities. + /// + public int Capabilities { get; private set; } = 0; + + /// + /// Get the equivalent native configuration structure. + /// + /// k4a_device_info_t. + internal k4a_device_info_t GetNativeConfiguration() + { + return new k4a_device_info_t + { + struct_size = (uint)this.StructSize, + struct_version = (uint)this.StructVersion, + vendor_id = (uint)this.VendorId, + device_id = (uint)this.DeviceId, + capabilities = (uint)this.Capabilities, + }; + } + + /// + /// Set properties using native configuration struct. + /// + /// deviceInfo. + internal void SetUsingNativeConfiguration(k4a_device_info_t deviceInfo) + { + this.StructSize = (int)deviceInfo.struct_size; + this.StructVersion = (int)deviceInfo.struct_version; + this.VendorId = (int)deviceInfo.vendor_id; + this.DeviceId = (int)deviceInfo.device_id; + this.Capabilities = (int)deviceInfo.capabilities; + } + } +} diff --git a/src/csharp/SDK/FPS.cs b/src/csharp/SDK/FPS.cs deleted file mode 100644 index 09a653cdd..000000000 --- a/src/csharp/SDK/FPS.cs +++ /dev/null @@ -1,43 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.Azure.Kinect.Sensor -{ - /// - /// Color and depth sensor frame rate. - /// - /// - /// This enumeration is used to select the desired frame rate to operate the cameras. - /// The actual frame rate may vary slightly due to dropped data, synchronization variation - /// between devices, clock accuracy, or if the camera exposure priority mode causes - /// reduced frame rate. - /// - [Native.NativeReference("k4a_fps_t")] -#pragma warning disable CA1717 // Only FlagsAttribute enums should have plural names - public enum FPS - { -#pragma warning disable CA1712 // Do not prefix enum values with type name - - /// - /// 5 Frames per second. - /// - FPS5 = 0, - - /// - /// 15 Frames per second. - /// - FPS15, - - /// - /// 30 Frames per second. - /// - FPS30, -#pragma warning restore CA1712 // Do not prefix enum values with type name - } - -#pragma warning restore CA1717 // Only FlagsAttribute enums should have plural names -} diff --git a/src/csharp/SDK/FPSModeInfo.cs b/src/csharp/SDK/FPSModeInfo.cs new file mode 100644 index 000000000..9dcd8e0ed --- /dev/null +++ b/src/csharp/SDK/FPSModeInfo.cs @@ -0,0 +1,68 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +//------------------------------------------------------------------------------ +using System; +using System.Runtime.InteropServices; +using static Microsoft.Azure.Kinect.Sensor.NativeMethods; + +namespace Microsoft.Azure.Kinect.Sensor +{ + /// + /// Represents the configuration to run a color and/or depth device in. + /// + /// + /// Gets or sets the FPS Mode Info. + /// + public class FPSModeInfo + { + /// + /// Gets the Struct Size. Default set in the NativeMethods class and must be kept in sync with k4a_fps_mode_info_t k4atypes.h. + /// + public int StructSize { get; private set; } = fpsModeInfoStructSize; + + /// + /// Gets the Struct Version. + /// + public int StructVersion { get; private set; } = 1; + + /// + /// Gets the ModeId. + /// + public int ModeId { get; private set; } = 0; + + /// + /// Gets the FPS. + /// + public int FPS { get; private set; } = 0; + + /// + /// Get the equivalent native configuration struct. + /// + /// k4a_fps_mode_info_t. + internal k4a_fps_mode_info_t GetNativeConfiguration() + { + return new k4a_fps_mode_info_t + { + struct_size = (uint)this.StructSize, + struct_version = (uint)this.StructVersion, + mode_id = (uint)this.ModeId, + fps = (uint)this.FPS, + }; + } + + /// + /// Set properties using native configuration struct. + /// + /// fpsModeInfo. + internal void SetUsingNativeConfiguration(k4a_fps_mode_info_t fpsModeInfo) + { + this.StructSize = (int)fpsModeInfo.struct_size; + this.StructVersion = (int)fpsModeInfo.struct_version; + this.ModeId = (int)fpsModeInfo.mode_id; + this.FPS = (int)fpsModeInfo.fps; + } + } +} diff --git a/src/csharp/SDK/Native/NativeMethods.cs b/src/csharp/SDK/Native/NativeMethods.cs index def287e7b..194c64a00 100644 --- a/src/csharp/SDK/Native/NativeMethods.cs +++ b/src/csharp/SDK/Native/NativeMethods.cs @@ -17,6 +17,11 @@ namespace Microsoft.Azure.Kinect.Sensor #pragma warning disable SA1602 // Enumeration items should be documented internal static class NativeMethods { + public const int deviceInfoStructSize = 20; + public const int colorModeInfoStructSize = 40; + public const int depthModeInfoInfoStructSize = 52; + public const int fpsModeInfoStructSize = 16; + private const CallingConvention k4aCallingConvention = CallingConvention.Cdecl; [UnmanagedFunctionPointer(k4aCallingConvention)] @@ -34,6 +39,7 @@ public enum k4a_buffer_result_t K4A_BUFFER_RESULT_SUCCEEDED = 0, K4A_BUFFER_RESULT_FAILED, K4A_BUFFER_RESULT_TOO_SMALL, + K4A_BUFFER_RESULT_UNSUPPORTED, } [NativeReference] @@ -42,6 +48,7 @@ public enum k4a_wait_result_t K4A_WAIT_RESULT_SUCCEEDED = 0, K4A_WAIT_RESULT_FAILED, K4A_WAIT_RESULT_TIMEOUT, + K4A_WAIT_RESULT_UNSUPPORTED, } [NativeReference] @@ -49,6 +56,7 @@ public enum k4a_result_t { K4A_RESULT_SUCCEEDED = 0, K4A_RESULT_FAILED, + K4A_RESULT_UNSUPPORTED, } [NativeReference] @@ -57,6 +65,30 @@ public enum k4a_stream_result_t K4A_STREAM_RESULT_SUCCEEDED = 0, K4A_STREAM_RESULT_FAILED, K4A_STREAM_RESULT_EOF, + K4A_STREAM_RESULT_UNSUPPORTED, + } + + [NativeReference] + public enum k4a_device_capabilities_t + { + K4A_CAPABILITY_DEPTH = 1, + K4A_CAPABILITY_COLOR = 2, + K4A_CAPABILITY_IMU = 4, + K4A_CAPABILITY_MICROPHONE = 8, + } + + [NativeReference] + public enum k4a_image_format_t + { + K4A_IMAGE_FORMAT_COLOR_MJPG = 0, + K4A_IMAGE_FORMAT_COLOR_NV12, + K4A_IMAGE_FORMAT_COLOR_YUY2, + K4A_IMAGE_FORMAT_COLOR_BGRA32, + K4A_IMAGE_FORMAT_DEPTH16, + K4A_IMAGE_FORMAT_IR16, + K4A_IMAGE_FORMAT_CUSTOM8, + K4A_IMAGE_FORMAT_CUSTOM16, + K4A_IMAGE_FORMAT_CUSTOM, } [DllImport("k4a", CallingConvention = k4aCallingConvention)] @@ -120,8 +152,8 @@ public static extern k4a_result_t k4a_calibration_color_2d_to_depth_2d( public static extern k4a_result_t k4a_calibration_get_from_raw( byte[] raw_calibration, UIntPtr raw_calibration_size, - DepthMode depth_mode, - ColorResolution color_resolution, + uint depth_mode_id, + uint color_mode_id, out Calibration calibration); [DllImport("k4a", CallingConvention = k4aCallingConvention)] @@ -252,8 +284,8 @@ public static extern k4a_result_t k4a_image_create_from_buffer( [NativeReference] public static extern k4a_result_t k4a_device_get_calibration( k4a_device_t device_handle, - DepthMode depth_mode, - ColorResolution color_resolution, + uint depth_mode_id, + uint color_mode_id, out Calibration calibration); [DllImport("k4a", CallingConvention = k4aCallingConvention)] @@ -390,6 +422,34 @@ public static extern k4a_result_t k4a_set_debug_message_handler( IntPtr message_cb_context, LogLevel min_level); + [DllImport("k4a", CallingConvention = k4aCallingConvention)] + [NativeReference] + public static extern k4a_result_t k4a_device_get_info(k4a_device_t device_handle, out k4a_device_info_t device_info); + + [DllImport("k4a", CallingConvention = k4aCallingConvention)] + [NativeReference] + public static extern k4a_result_t k4a_device_get_color_mode_count(k4a_device_t device_handle, out uint mode_count); + + [DllImport("k4a", CallingConvention = k4aCallingConvention)] + [NativeReference] + public static extern k4a_result_t k4a_device_get_color_mode(k4a_device_t device_handle, uint mode_index, out k4a_color_mode_info_t mode_info); + + [DllImport("k4a", CallingConvention = k4aCallingConvention)] + [NativeReference] + public static extern k4a_result_t k4a_device_get_depth_mode_count(k4a_device_t device_handle, out uint mode_count); + + [DllImport("k4a", CallingConvention = k4aCallingConvention)] + [NativeReference] + public static extern k4a_result_t k4a_device_get_depth_mode(k4a_device_t device_handle, uint mode_index, out k4a_depth_mode_info_t mode_info); + + [DllImport("k4a", CallingConvention = k4aCallingConvention)] + [NativeReference] + public static extern k4a_result_t k4a_device_get_fps_mode_count(k4a_device_t device_handle, out uint mode_count); + + [DllImport("k4a", CallingConvention = k4aCallingConvention)] + [NativeReference] + public static extern k4a_result_t k4a_device_get_fps_mode(k4a_device_t device_handle, uint mode_index, out k4a_fps_mode_info_t mode_info); + [NativeReference] [StructLayout(LayoutKind.Sequential)] public struct k4a_version_t @@ -434,9 +494,9 @@ public HardwareVersion ToHardwareVersion() public struct k4a_device_configuration_t { public ImageFormat color_format; - public ColorResolution color_resolution; - public DepthMode depth_mode; - public FPS camera_fps; + public uint color_mode_id; + public uint depth_mode_id; + public uint fps_mode_id; public bool synchronized_images_only; public int depth_delay_off_color_usec; public WiredSyncMode wired_sync_mode; @@ -444,6 +504,62 @@ public struct k4a_device_configuration_t public bool disable_streaming_indicator; } + [NativeReference] + [StructLayout(LayoutKind.Sequential)] + public struct k4a_device_info_t + { + public uint struct_size; + public uint struct_version; + public uint vendor_id; + public uint device_id; + public uint capabilities; + } + + [NativeReference] + [StructLayout(LayoutKind.Sequential)] + public struct k4a_color_mode_info_t + { + public uint struct_size; + public uint struct_version; + public uint mode_id; + public uint width; + public uint height; + public k4a_image_format_t native_format; + public float horizontal_fov; + public float vertical_fov; + public uint min_fps; + public uint max_fps; + } + + [NativeReference] + [StructLayout(LayoutKind.Sequential)] + public struct k4a_depth_mode_info_t + { + public uint struct_size; + public uint struct_version; + public uint mode_id; + public byte passive_ir_only; + public uint width; + public uint height; + public k4a_image_format_t native_format; + public float horizontal_fov; + public float vertical_fov; + public uint min_fps; + public uint max_fps; + public uint min_range; + public uint max_range; + } + + [NativeReference] + [StructLayout(LayoutKind.Sequential)] + public struct k4a_fps_mode_info_t + { + public uint struct_size; + public uint struct_version; + public uint mode_id; + public uint fps; + } + public class k4a_device_t : Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid { private k4a_device_t() diff --git a/src/csharp/Tests/FunctionalTests/Calibration.cs b/src/csharp/Tests/FunctionalTests/Calibration.cs index e01793b54..583fab448 100644 --- a/src/csharp/Tests/FunctionalTests/Calibration.cs +++ b/src/csharp/Tests/FunctionalTests/Calibration.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System.Collections.Generic; using System.Numerics; using Microsoft.Azure.Kinect.Sensor; using NUnit.Framework; @@ -8,24 +9,16 @@ namespace WrapperTests { public class CalibrationTests { - - - void ValidateCalibration(Calibration cal, - DepthMode depthMode, - ColorResolution colorResolution, - int depthWidth, int depthHeight, - int colorWidth, int colorHeight) + void ValidateCalibration(Calibration cal, int depthModeId, int colorModeId, int depthWidth, int depthHeight, int colorWidth, int colorHeight) { - Assert.AreEqual(depthMode, cal.DepthMode); - Assert.AreEqual(colorResolution, cal.ColorResolution); + Assert.AreEqual(depthModeId, cal.DepthModeId); + Assert.AreEqual(colorModeId, cal.ColorModeId); Assert.AreEqual(depthWidth, cal.DepthCameraCalibration.ResolutionWidth); Assert.AreEqual(depthHeight, cal.DepthCameraCalibration.ResolutionHeight); Assert.AreEqual(colorWidth, cal.ColorCameraCalibration.ResolutionWidth); Assert.AreEqual(colorHeight, cal.ColorCameraCalibration.ResolutionHeight); - Assert.IsTrue(cal.DepthCameraCalibration.Intrinsics.Type == CalibrationModelType.Rational6KT || - cal.DepthCameraCalibration.Intrinsics.Type == CalibrationModelType.BrownConrady); - Assert.IsTrue(cal.ColorCameraCalibration.Intrinsics.Type == CalibrationModelType.Rational6KT || - cal.ColorCameraCalibration.Intrinsics.Type == CalibrationModelType.BrownConrady); + Assert.IsTrue(cal.DepthCameraCalibration.Intrinsics.Type == CalibrationModelType.Rational6KT || cal.DepthCameraCalibration.Intrinsics.Type == CalibrationModelType.BrownConrady); + Assert.IsTrue(cal.ColorCameraCalibration.Intrinsics.Type == CalibrationModelType.Rational6KT || cal.ColorCameraCalibration.Intrinsics.Type == CalibrationModelType.BrownConrady); } [Test] @@ -35,19 +28,22 @@ public void GetFromRaw() { byte[] raw = device.GetRawCalibration(); - Calibration cal = Calibration.GetFromRaw(raw, DepthMode.WFOV_2x2Binned, ColorResolution.R1080p); + List colorModes = device.GetColorModes(); + List depthModes = device.GetDepthModes(); - // Sanity check a few of the outputs for well known fields + ColorModeInfo colorModeInfo = colorModes.Find(c => c.Height >= 1080); + DepthModeInfo depthModeInfo = depthModes.Find(d => d.Height >= 512 && d.HorizontalFOV >= 120); + + Calibration cal = Calibration.GetFromRaw(raw, (uint)depthModeInfo.ModeId, (uint)colorModeInfo.ModeId); - ValidateCalibration(cal, DepthMode.WFOV_2x2Binned, ColorResolution.R1080p, - 512, 512, - 1920, 1080); + // Sanity check a few of the outputs for well known fields + this.ValidateCalibration(cal, depthModeInfo.ModeId, colorModeInfo.ModeId, 512, 512, 1920, 1080); - cal = Calibration.GetFromRaw(raw, DepthMode.WFOV_Unbinned, ColorResolution.R720p); + colorModeInfo = colorModes.Find(c => c.Height >= 720); + depthModeInfo = depthModes.Find(d => d.Height >= 1024 && d.HorizontalFOV >= 120); + cal = Calibration.GetFromRaw(raw, (uint)depthModeInfo.ModeId, (uint)colorModeInfo.ModeId); - ValidateCalibration(cal, DepthMode.WFOV_Unbinned, ColorResolution.R720p, - 1024, 1024, - 1280, 720); + this.ValidateCalibration(cal, depthModeInfo.ModeId, colorModeInfo.ModeId, 1024, 1024, 1280, 720); } } @@ -58,7 +54,14 @@ public void Transform2Dto2D() { byte[] raw = device.GetRawCalibration(); - Calibration cal = Calibration.GetFromRaw(raw, DepthMode.WFOV_2x2Binned, ColorResolution.R1080p); + + List colorModes = device.GetColorModes(); + List depthModes = device.GetDepthModes(); + + ColorModeInfo colorModeInfo = colorModes.Find(c => c.Height >= 1080); + DepthModeInfo depthModeInfo = depthModes.Find(d => d.Height >= 512 && d.HorizontalFOV >= 120); + + Calibration cal = Calibration.GetFromRaw(raw, (uint)depthModeInfo.ModeId, (uint)colorModeInfo.ModeId); Vector2 source = new Vector2(0, 0); Vector2? result = cal.TransformTo2D(source, 1.0f, CalibrationDeviceType.Color, CalibrationDeviceType.Depth); diff --git a/src/csharp/Tests/StubGenerator.UnitTests/StubTests.cs b/src/csharp/Tests/StubGenerator.UnitTests/StubTests.cs index b6f8dab93..175716eb8 100644 --- a/src/csharp/Tests/StubGenerator.UnitTests/StubTests.cs +++ b/src/csharp/Tests/StubGenerator.UnitTests/StubTests.cs @@ -15,6 +15,7 @@ public enum k4a_result_t { K4A_RESULT_SUCCEEDED = 0, K4A_RESULT_FAILED, + K4A_RESULT_UNSUPPORTED, } public class k4a_device_t : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid diff --git a/src/csharp/Tests/UnitTests/DeviceFunctionTests.cs b/src/csharp/Tests/UnitTests/DeviceFunctionTests.cs index 0c7386708..63e317584 100644 --- a/src/csharp/Tests/UnitTests/DeviceFunctionTests.cs +++ b/src/csharp/Tests/UnitTests/DeviceFunctionTests.cs @@ -8,6 +8,7 @@ using Microsoft.Azure.Kinect.Sensor.Test.StubGenerator; using NUnit.Framework; using System; +using System.Collections.Generic; namespace Microsoft.Azure.Kinect.Sensor.UnitTests { @@ -77,6 +78,84 @@ void k4a_device_close(k4a_device_t device_handle) }"); } + // Helper function to implement device get color mode and color modes count + private void SetDeviceGetColorModeAndModesCountImplementation() + { + NativeK4a.SetImplementation(@" +k4a_result_t k4a_device_get_color_mode_count(k4a_device_t device_handle, uint32_t *mode_count) +{ + *mode_count = 7; + return K4A_RESULT_SUCCEEDED; +} + +k4a_result_t k4a_device_get_color_mode(k4a_device_t device_handle, uint32_t mode_index, k4a_color_mode_info_t *mode_info) +{ + static const k4a_color_mode_info_t device_color_modes[] = { + { 40, 1, 0, 0, 0, K4A_IMAGE_FORMAT_COLOR_MJPG, 0, 0, 0, 0 }, + { 40, 1, 1, 1280, 720, K4A_IMAGE_FORMAT_COLOR_MJPG, 90.0f, 59.0f, 5, 30 }, + { 40, 1, 2, 1920, 1080, K4A_IMAGE_FORMAT_COLOR_MJPG, 90.0f, 59.0f, 5, 30 }, + { 40, 1, 3, 2560, 1440, K4A_IMAGE_FORMAT_COLOR_MJPG, 90.0f, 59.0f, 5, 30 }, + { 40, 1, 4, 2048, 1536, K4A_IMAGE_FORMAT_COLOR_MJPG, 90.0f, 74.3f, 5, 30 }, + { 40, 1, 5, 3840, 2160, K4A_IMAGE_FORMAT_COLOR_MJPG, 90.0f, 59.0f, 5, 30 }, + { 40, 1, 6, 4096, 3072, K4A_IMAGE_FORMAT_COLOR_MJPG, 90.0f, 74.3f, 5, 30 } + }; + + *mode_info = device_color_modes[mode_index]; + return K4A_RESULT_SUCCEEDED; +} +"); + } + + // Helper function to implement device get depth mode and color modes count + private void SetDeviceGetDepthModeAndModesCountImplementation() + { + NativeK4a.SetImplementation(@" +k4a_result_t k4a_device_get_depth_mode_count(k4a_device_t device_handle, uint32_t *mode_count) +{ + *mode_count = 6; + return K4A_RESULT_SUCCEEDED; +} + +k4a_result_t k4a_device_get_depth_mode(k4a_device_t device_handle, uint32_t mode_index, k4a_depth_mode_info_t *mode_info) +{ + static const k4a_depth_mode_info_t device_depth_modes[] = { + { 52, 1, 0, false, 0, 0, K4A_IMAGE_FORMAT_DEPTH16, 0.0f, 0.0f, 0, 0, 0, 0 }, + { 52, 1, 1, false, 320, 288, K4A_IMAGE_FORMAT_DEPTH16, 75.0f, 65.0f, 5, 30, 500, 5800 }, + { 52, 1, 2, false, 640, 576, K4A_IMAGE_FORMAT_DEPTH16, 75.0f, 65.0f, 5, 30, 500, 4000 }, + { 52, 1, 3, false, 512, 512, K4A_IMAGE_FORMAT_DEPTH16, 120.0f, 120.0f, 5, 30, 250, 3000 }, + { 52, 1, 4, false, 1024, 1024, K4A_IMAGE_FORMAT_DEPTH16, 120.0f, 120.0f, 5, 30, 250, 2500 }, + { 52, 1, 5, true, 1024, 1024, K4A_IMAGE_FORMAT_DEPTH16, 120.0f, 120.0f, 5, 30, 0, 100 } + }; + + *mode_info = device_depth_modes[mode_index]; + return K4A_RESULT_SUCCEEDED; +} +"); + } + + // Helper function to implement device get fps mode and color modes count + private void SetDeviceGetFPSModeAndModesCountImplementation() + { + NativeK4a.SetImplementation(@" +k4a_result_t k4a_device_get_fps_mode_count(k4a_device_t device_handle, uint32_t *mode_count) +{ + *mode_count = 4; + return K4A_RESULT_SUCCEEDED; +} + +k4a_result_t k4a_device_get_fps_mode(k4a_device_t device_handle, uint32_t mode_index, k4a_fps_mode_info_t *mode_info) +{ + static const k4a_fps_mode_info_t device_fps_modes[] = { { 16, 1, 0, 0 }, + { 16, 1, 5, 5 }, + { 16, 1, 15, 15 }, + { 16, 1, 30, 30 } }; + + *mode_info = device_fps_modes[mode_index]; + return K4A_RESULT_SUCCEEDED; +} +"); + } + [Test] public void GetInstalledCount() { @@ -453,19 +532,21 @@ k4a_buffer_result_t k4a_device_get_raw_calibration(k4a_device_t device_handle, public void DeviceGetCalibration() { SetOpenCloseImplementation(); + SetDeviceGetColorModeAndModesCountImplementation(); + SetDeviceGetDepthModeAndModesCountImplementation(); NativeK4a.SetImplementation(@" -k4a_result_t k4a_device_get_calibration(k4a_device_t device_handle, k4a_depth_mode_t depth_mode, k4a_color_resolution_t color_resolution, k4a_calibration_t* calibration) +k4a_result_t k4a_device_get_calibration(k4a_device_t device_handle, uint32_t depth_mode_id, uint32_t color_mode_id, k4a_calibration_t* calibration) { STUB_ASSERT(device_handle == (k4a_device_t)0x1234ABCD); - STUB_ASSERT(depth_mode == K4A_DEPTH_MODE_NFOV_UNBINNED); - STUB_ASSERT(color_resolution == K4A_COLOR_RESOLUTION_1440P); + STUB_ASSERT(depth_mode_id > 0); + STUB_ASSERT(color_mode_id > 0); STUB_ASSERT(calibration != NULL); // Fill the structure with values we can verify (pick values to pass that are unique so that a swap of values will be detected) - calibration->depth_mode = depth_mode; - calibration->color_resolution = color_resolution; + calibration->depth_mode_id = depth_mode_id; + calibration->color_mode_id = color_mode_id; for (int i = 0; i < 9; i++) calibration->depth_camera_calibration.extrinsics.rotation[i] = (float)i * 1.2f; @@ -492,12 +573,18 @@ k4a_result_t k4a_device_get_calibration(k4a_device_t device_handle, k4a_depth_mo CallCount count = NativeK4a.CountCalls(); using (Device device = Device.Open(0)) { - Calibration calibration = device.GetCalibration(DepthMode.NFOV_Unbinned, ColorResolution.R1440p); + List colorModes = device.GetColorModes(); + List depthModes = device.GetDepthModes(); + + ColorModeInfo colorModeInfo = colorModes.Find(c => c.ModeId > 0); + DepthModeInfo depthModeInfo = depthModes.Find(d => d.ModeId > 0); + + Calibration calibration = device.GetCalibration(depthModeInfo.ModeId, colorModeInfo.ModeId); Assert.AreEqual(1, count.Calls("k4a_device_get_calibration")); - Assert.AreEqual(DepthMode.NFOV_Unbinned, calibration.DepthMode); - Assert.AreEqual(ColorResolution.R1440p, calibration.ColorResolution); + Assert.AreEqual(depthModeInfo.ModeId, calibration.DepthModeId); + Assert.AreEqual(colorModeInfo.ModeId, calibration.ColorModeId); for (int i = 0; i < 9; i++) { @@ -550,8 +637,8 @@ void k4a_device_stop_cameras(k4a_device_t device_handle) device.StartCameras(new DeviceConfiguration { - ColorResolution = ColorResolution.R1440p, - DepthMode = DepthMode.NFOV_Unbinned + ColorModeId = colorModeInfo.ModeId, + DepthModeId = depthModeInfo.ModeId }); // Calibration should return correctly now @@ -569,7 +656,7 @@ void k4a_device_stop_cameras(k4a_device_t device_handle) Assert.Throws(typeof(ObjectDisposedException), () => { - device.GetCalibration(DepthMode.NFOV_Unbinned, ColorResolution.R1440p); + device.GetCalibration(depthModeInfo.ModeId, colorModeInfo.ModeId); }); } @@ -581,14 +668,16 @@ void k4a_device_stop_cameras(k4a_device_t device_handle) public void DeviceGetCalibrationFailure() { SetOpenCloseImplementation(); + SetDeviceGetColorModeAndModesCountImplementation(); + SetDeviceGetDepthModeAndModesCountImplementation(); NativeK4a.SetImplementation(@" -k4a_result_t k4a_device_get_calibration(k4a_device_t device_handle, k4a_depth_mode_t depth_mode, k4a_color_resolution_t color_resolution, k4a_calibration_t* calibration) +k4a_result_t k4a_device_get_calibration(k4a_device_t device_handle, uint32_t depth_mode_id, uint32_t color_mode_id, k4a_calibration_t* calibration) { STUB_ASSERT(device_handle == (k4a_device_t)0x1234ABCD); - STUB_ASSERT(depth_mode == K4A_DEPTH_MODE_NFOV_UNBINNED); - STUB_ASSERT(color_resolution == K4A_COLOR_RESOLUTION_1440P); + STUB_ASSERT(depth_mode_id > 0); + STUB_ASSERT(color_mode_id > 0); STUB_ASSERT(calibration != NULL); return K4A_RESULT_FAILED; @@ -596,9 +685,15 @@ k4a_result_t k4a_device_get_calibration(k4a_device_t device_handle, k4a_depth_mo "); using (Device device = Device.Open(0)) { + List colorModes = device.GetColorModes(); + List depthModes = device.GetDepthModes(); + + ColorModeInfo colorModeInfo = colorModes.Find(c => c.ModeId > 0); + DepthModeInfo depthModeInfo = depthModes.Find(d => d.ModeId > 0); + Assert.Throws(typeof(AzureKinectException), () => { - Calibration calibration = device.GetCalibration(DepthMode.NFOV_Unbinned, ColorResolution.R1440p); + Calibration calibration = device.GetCalibration(depthModeInfo.ModeId, colorModeInfo.ModeId); }); } @@ -1295,6 +1390,9 @@ k4a_result_t k4a_device_get_version( public void DeviceStartCameras() { SetOpenCloseImplementation(); + SetDeviceGetColorModeAndModesCountImplementation(); + SetDeviceGetDepthModeAndModesCountImplementation(); + SetDeviceGetFPSModeAndModesCountImplementation(); NativeK4a.SetImplementation(@" k4a_result_t k4a_device_start_cameras( @@ -1306,9 +1404,9 @@ const k4a_device_configuration_t * config STUB_ASSERT(config != NULL); STUB_ASSERT(config->color_format == K4A_IMAGE_FORMAT_COLOR_MJPG); - STUB_ASSERT(config->color_resolution == K4A_COLOR_RESOLUTION_OFF); - STUB_ASSERT(config->depth_mode == K4A_DEPTH_MODE_OFF); - STUB_ASSERT(config->camera_fps == K4A_FRAMES_PER_SECOND_30); + STUB_ASSERT(config->color_mode_id == 0); + STUB_ASSERT(config->depth_mode_id == 0); + STUB_ASSERT(config->fps_mode_id == 0); STUB_ASSERT(config->synchronized_images_only == false); STUB_ASSERT(config->depth_delay_off_color_usec == 0); STUB_ASSERT(config->wired_sync_mode == K4A_WIRED_SYNC_MODE_STANDALONE); @@ -1342,9 +1440,9 @@ const k4a_device_configuration_t * config STUB_ASSERT(config != NULL); STUB_ASSERT(config->color_format == K4A_IMAGE_FORMAT_COLOR_BGRA32); - STUB_ASSERT(config->color_resolution == K4A_COLOR_RESOLUTION_1080P); - STUB_ASSERT(config->depth_mode == K4A_DEPTH_MODE_PASSIVE_IR); - STUB_ASSERT(config->camera_fps == K4A_FRAMES_PER_SECOND_15); + STUB_ASSERT(config->color_mode_id > 0); + STUB_ASSERT(config->depth_mode_id > 0); + STUB_ASSERT(config->fps_mode_id > 0); STUB_ASSERT(config->synchronized_images_only == true); STUB_ASSERT(config->depth_delay_off_color_usec == -1000000); STUB_ASSERT(config->wired_sync_mode == K4A_WIRED_SYNC_MODE_MASTER); @@ -1354,12 +1452,20 @@ const k4a_device_configuration_t * config return K4A_RESULT_SUCCEEDED; } "); + List colorModes = device.GetColorModes(); + List depthModes = device.GetDepthModes(); + List fpsModes = device.GetFPSModes(); + + ColorModeInfo colorModeInfo = colorModes.Find(c => c.ModeId > 0); + DepthModeInfo depthModeInfo = depthModes.Find(d => d.ModeId > 0); + FPSModeInfo fpsModeInfo = fpsModes.Find(f => f.ModeId > 0); + DeviceConfiguration config = new DeviceConfiguration { ColorFormat = ImageFormat.ColorBGRA32, - ColorResolution = ColorResolution.R1080p, - DepthMode = DepthMode.PassiveIR, - CameraFPS = FPS.FPS15, + ColorModeId = colorModeInfo.ModeId, + DepthModeId = depthModeInfo.ModeId, + FPSModeId = fpsModeInfo.ModeId, SynchronizedImagesOnly = true, DepthDelayOffColor = System.TimeSpan.FromSeconds(-1), WiredSyncMode = WiredSyncMode.Master, @@ -1385,6 +1491,9 @@ const k4a_device_configuration_t * config public void DeviceStartCamerasFailure() { SetOpenCloseImplementation(); + SetDeviceGetColorModeAndModesCountImplementation(); + SetDeviceGetDepthModeAndModesCountImplementation(); + SetDeviceGetFPSModeAndModesCountImplementation(); NativeK4a.SetImplementation(@" k4a_result_t k4a_device_start_cameras( @@ -1402,12 +1511,20 @@ const k4a_device_configuration_t * config CallCount count = NativeK4a.CountCalls(); using (Device device = Device.Open(0)) { + List colorModes = device.GetColorModes(); + List depthModes = device.GetDepthModes(); + List fpsModes = device.GetFPSModes(); + + ColorModeInfo colorModeInfo = colorModes.Find(c => c.ModeId > 0); + DepthModeInfo depthModeInfo = depthModes.Find(d => d.ModeId > 0); + FPSModeInfo fpsModeInfo = fpsModes.Find(f => f.ModeId > 0); + DeviceConfiguration config = new DeviceConfiguration { ColorFormat = ImageFormat.ColorBGRA32, - ColorResolution = ColorResolution.R1080p, - DepthMode = DepthMode.PassiveIR, - CameraFPS = FPS.FPS15, + ColorModeId = colorModeInfo.ModeId, + DepthModeId = depthModeInfo.ModeId, + FPSModeId = fpsModeInfo.ModeId, SynchronizedImagesOnly = true, DepthDelayOffColor = System.TimeSpan.FromSeconds(-1), WiredSyncMode = WiredSyncMode.Master, diff --git a/src/depth/depth.c b/src/depth/depth.c index 8f5e48398..b3a4ed38b 100644 --- a/src/depth/depth.c +++ b/src/depth/depth.c @@ -10,7 +10,6 @@ #include // Dependent libraries -#include #include // System dependencies @@ -374,7 +373,7 @@ k4a_result_t depth_start(depth_t depth_handle, const k4a_device_configuration_t if (K4A_SUCCEEDED(result)) { depth->running = true; // set to true once we know we need to call depth_stop to unwind - result = TRACE_CALL(depthmcu_depth_set_capture_mode(depth->depthmcu, config->depth_mode)); + result = TRACE_CALL(depthmcu_depth_set_capture_mode(depth->depthmcu, config->depth_mode_id)); } if (K4A_SUCCEEDED(result) && depth->calibration_init == false) @@ -400,7 +399,7 @@ k4a_result_t depth_start(depth_t depth_handle, const k4a_device_configuration_t if (K4A_SUCCEEDED(result)) { - result = TRACE_CALL(depthmcu_depth_set_fps(depth->depthmcu, config->camera_fps)); + result = TRACE_CALL(depthmcu_depth_set_fps(depth->depthmcu, config->fps_mode_id)); } if (K4A_SUCCEEDED(result)) diff --git a/src/depth_mcu/CMakeLists.txt b/src/depth_mcu/CMakeLists.txt index 8e6d42b54..c9b92b659 100644 --- a/src/depth_mcu/CMakeLists.txt +++ b/src/depth_mcu/CMakeLists.txt @@ -13,6 +13,7 @@ target_include_directories(k4a_depth_mcu PUBLIC target_link_libraries(k4a_depth_mcu PUBLIC k4ainternal::image k4ainternal::logging + k4ainternal::modes k4ainternal::usb_cmd) # Define alias for other targets to link against diff --git a/src/depth_mcu/depth_mcu.c b/src/depth_mcu/depth_mcu.c index c1582f80c..24d4b9495 100644 --- a/src/depth_mcu/depth_mcu.c +++ b/src/depth_mcu/depth_mcu.c @@ -6,6 +6,7 @@ // Dependent libraries #include +#include #include // System dependencies @@ -246,13 +247,13 @@ k4a_result_t depthmcu_get_version(depthmcu_t depthmcu_handle, depthmcu_firmware_ return result; } -k4a_result_t depthmcu_depth_set_capture_mode(depthmcu_t depthmcu_handle, k4a_depth_mode_t capture_mode) +k4a_result_t depthmcu_depth_set_capture_mode(depthmcu_t depthmcu_handle, uint32_t depth_mode_id) { RETURN_VALUE_IF_HANDLE_INVALID(K4A_RESULT_FAILED, depthmcu_t, depthmcu_handle); depthmcu_context_t *depthmcu = depthmcu_t_get_context(depthmcu_handle); uint32_t mode; - switch (capture_mode) + switch (depth_mode_id) { case K4A_DEPTH_MODE_NFOV_2X2BINNED: case K4A_DEPTH_MODE_NFOV_UNBINNED: @@ -276,7 +277,7 @@ k4a_result_t depthmcu_depth_set_capture_mode(depthmcu_t depthmcu_handle, k4a_dep depthmcu->mode_size = SENSOR_MODE_PSEUDO_COMMON_SIZE; break; default: - LOG_ERROR("Invalid mode %d", capture_mode); + LOG_ERROR("Invalid mode %d", depth_mode_id); return K4A_RESULT_FAILED; } @@ -285,26 +286,16 @@ k4a_result_t depthmcu_depth_set_capture_mode(depthmcu_t depthmcu_handle, k4a_dep usb_cmd_write(depthmcu->usb_cmd, DEV_CMD_DEPTH_MODE_SET, (uint8_t *)&mode, sizeof(mode), NULL, 0)); } -k4a_result_t depthmcu_depth_set_fps(depthmcu_t depthmcu_handle, k4a_fps_t capture_fps) +k4a_result_t depthmcu_depth_set_fps(depthmcu_t depthmcu_handle, uint32_t fps_mode_id) { RETURN_VALUE_IF_HANDLE_INVALID(K4A_RESULT_FAILED, depthmcu_t, depthmcu_handle); depthmcu_context_t *depthmcu = depthmcu_t_get_context(depthmcu_handle); - uint32_t fps; // Translate FPS to values understood by sensor module - switch (capture_fps) + uint32_t fps = k4a_convert_fps_to_uint((k4a_fps_t)fps_mode_id); + if (fps == 0) { - case K4A_FRAMES_PER_SECOND_30: - fps = 30; - break; - case K4A_FRAMES_PER_SECOND_15: - fps = 15; - break; - case K4A_FRAMES_PER_SECOND_5: - fps = 5; - break; - default: - LOG_ERROR("Invalid FPS %d", capture_fps); + LOG_ERROR("Invalid FPS %d", fps_mode_id); return K4A_RESULT_FAILED; } diff --git a/src/dewrapper/dewrapper.c b/src/dewrapper/dewrapper.c index 78ab5001c..4da0c3bc7 100644 --- a/src/dewrapper/dewrapper.c +++ b/src/dewrapper/dewrapper.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -36,8 +37,8 @@ typedef struct _dewrapper_context_t volatile bool thread_stop; k4a_result_t thread_start_result; - k4a_fps_t fps; - k4a_depth_mode_t depth_mode; + uint32_t fps_mode_id; + uint32_t depth_mode_id; TICK_COUNTER_HANDLE tick; dewrapper_streaming_capture_cb_t *capture_ready_cb; @@ -56,11 +57,11 @@ typedef struct _shared_image_context_t K4A_DECLARE_CONTEXT(dewrapper_t, dewrapper_context_t); -static k4a_depth_engine_mode_t get_de_mode_from_depth_mode(k4a_depth_mode_t mode) +static k4a_depth_engine_mode_t get_de_mode_from_depth_mode(uint32_t depth_mode_id) { k4a_depth_engine_mode_t de_mode; - switch (mode) + switch (depth_mode_id) { case K4A_DEPTH_MODE_NFOV_2X2BINNED: de_mode = K4A_DEPTH_ENGINE_MODE_LT_SW_BINNING; @@ -84,9 +85,9 @@ static k4a_depth_engine_mode_t get_de_mode_from_depth_mode(k4a_depth_mode_t mode return de_mode; } -static k4a_depth_engine_input_type_t get_input_format_from_depth_mode(k4a_depth_mode_t mode) +static k4a_depth_engine_input_type_t get_input_format_from_depth_mode(uint32_t depth_mode_id) { - k4a_depth_engine_mode_t de_mode = get_de_mode_from_depth_mode(mode); + k4a_depth_engine_mode_t de_mode = get_de_mode_from_depth_mode(depth_mode_id); k4a_depth_engine_input_type_t format; format = K4A_DEPTH_ENGINE_INPUT_TYPE_12BIT_COMPRESSED; @@ -122,20 +123,24 @@ static void free_shared_depth_image(void *buffer, void *context) } static k4a_result_t depth_engine_start_helper(dewrapper_context_t *dewrapper, - k4a_fps_t fps, - k4a_depth_mode_t depth_mode, + uint32_t fps_mode_id, + uint32_t depth_mode_id, int *depth_engine_max_compute_time_ms, size_t *depth_engine_output_buffer_size) { - RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, fps < K4A_FRAMES_PER_SECOND_5 || fps > K4A_FRAMES_PER_SECOND_30); - RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, depth_mode <= K4A_DEPTH_MODE_OFF || depth_mode > K4A_DEPTH_MODE_PASSIVE_IR); + RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, + fps_mode_id < (uint32_t)K4A_FRAMES_PER_SECOND_5 || + fps_mode_id > (uint32_t)K4A_FRAMES_PER_SECOND_30); + RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, + depth_mode_id <= (uint32_t)K4A_DEPTH_MODE_OFF || + depth_mode_id > (uint32_t)K4A_DEPTH_MODE_PASSIVE_IR); k4a_result_t result = K4A_RESULT_SUCCEEDED; assert(dewrapper->depth_engine == NULL); assert(dewrapper->calibration_memory != NULL); // Max comput time is the configured FPS - *depth_engine_max_compute_time_ms = HZ_TO_PERIOD_MS(k4a_convert_fps_to_uint(fps)); + *depth_engine_max_compute_time_ms = HZ_TO_PERIOD_MS(fps_mode_id); result = K4A_RESULT_FROM_BOOL(*depth_engine_max_compute_time_ms != 0); if (K4A_SUCCEEDED(result)) @@ -144,8 +149,8 @@ static k4a_result_t depth_engine_start_helper(dewrapper_context_t *dewrapper, deloader_depth_engine_create_and_initialize(&dewrapper->depth_engine, dewrapper->calibration_memory_size, dewrapper->calibration_memory, - get_de_mode_from_depth_mode(depth_mode), - get_input_format_from_depth_mode(depth_mode), + get_de_mode_from_depth_mode(depth_mode_id), + get_input_format_from_depth_mode(depth_mode_id), dewrapper->calibration, // k4a_calibration_camera_t* NULL, // Callback NULL); // Callback Context @@ -188,8 +193,8 @@ static int depth_engine_thread(void *param) bool received_valid_image = false; result = TRACE_CALL(depth_engine_start_helper(dewrapper, - dewrapper->fps, - dewrapper->depth_mode, + dewrapper->fps_mode_id, + dewrapper->depth_mode_id, &depth_engine_max_compute_time_ms, &depth_engine_output_buffer_size)); @@ -301,10 +306,10 @@ static int depth_engine_thread(void *param) result = TRACE_CALL(capture_create(&capture)); } - bool depth16_present = (dewrapper->depth_mode == K4A_DEPTH_MODE_NFOV_2X2BINNED || - dewrapper->depth_mode == K4A_DEPTH_MODE_NFOV_UNBINNED || - dewrapper->depth_mode == K4A_DEPTH_MODE_WFOV_2X2BINNED || - dewrapper->depth_mode == K4A_DEPTH_MODE_WFOV_UNBINNED); + bool depth16_present = (dewrapper->depth_mode_id == K4A_DEPTH_MODE_NFOV_2X2BINNED || + dewrapper->depth_mode_id == K4A_DEPTH_MODE_NFOV_UNBINNED || + dewrapper->depth_mode_id == K4A_DEPTH_MODE_WFOV_2X2BINNED || + dewrapper->depth_mode_id == K4A_DEPTH_MODE_WFOV_UNBINNED); if (K4A_SUCCEEDED(result) & depth16_present) { @@ -527,8 +532,8 @@ k4a_result_t dewrapper_start(dewrapper_t dewrapper_handle, queue_enable(dewrapper->queue); // NOTE: do not copy config ptr, it may be freed after this call - dewrapper->fps = config->camera_fps; - dewrapper->depth_mode = config->depth_mode; + dewrapper->fps_mode_id = config->fps_mode_id; + dewrapper->depth_mode_id = config->depth_mode_id; dewrapper->thread_stop = false; dewrapper->thread_started = false; @@ -586,8 +591,8 @@ void dewrapper_stop(dewrapper_t dewrapper_handle) THREADAPI_RESULT tresult = ThreadAPI_Join(thread, &thread_result); (void)K4A_RESULT_FROM_BOOL(tresult == THREADAPI_OK); // Trace the issue, but we don't return a failure - dewrapper->fps = (k4a_fps_t)-1; - dewrapper->depth_mode = K4A_DEPTH_MODE_OFF; + dewrapper->fps_mode_id = K4A_FRAMES_PER_SECOND_0; + dewrapper->depth_mode_id = K4A_DEPTH_MODE_OFF; } queue_disable(dewrapper->queue); diff --git a/src/imu/imu.c b/src/imu/imu.c index 4b4369951..1e77ede0f 100644 --- a/src/imu/imu.c +++ b/src/imu/imu.c @@ -6,7 +6,6 @@ #include // Dependent libraries -#include #include #include #include diff --git a/src/math/math.c b/src/math/math.c index 4160cb6fd..7096c23ec 100644 --- a/src/math/math.c +++ b/src/math/math.c @@ -107,4 +107,9 @@ void math_quadratic_transform_3(const float A[3 * 3], // y = B*x2 + temp math_affine_transform_3(B, x2, temp, out); +} + +int math_get_common_factor(int width, int height) +{ + return (height == 0) ? width : math_get_common_factor(height, width % height); } \ No newline at end of file diff --git a/src/modes/CMakeLists.txt b/src/modes/CMakeLists.txt new file mode 100644 index 000000000..de9ddce6d --- /dev/null +++ b/src/modes/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +add_library(k4a_modes STATIC + modes.c + ) + +# Consumers should #include +target_include_directories(k4a_modes PUBLIC + ${K4A_PRIV_INCLUDE_DIR}) + + +if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") + if ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "amd64.*|x86_64.*|AMD64.*|i686.*|i386.*|x86.*") + target_compile_options(k4a_modes PRIVATE "-msse4.1") + endif() +endif() + +# Define alias for other targets to link against +add_library(k4ainternal::modes ALIAS k4a_modes) diff --git a/src/modes/modes.c b/src/modes/modes.c new file mode 100644 index 000000000..e41500afd --- /dev/null +++ b/src/modes/modes.c @@ -0,0 +1,528 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// This library +#include +#include + +// Dependent libraries + +// System dependencies + +#ifdef __cplusplus +extern "C" { +#endif + +// Create a static array of color modes. Let the struct_size and variable fields be 0 for now. +// These values refer specifically to Azure Kinect device. +static const k4a_color_mode_info_t device_color_modes[] = { + { 0, K4A_ABI_VERSION, K4A_COLOR_RESOLUTION_OFF, 0, 0, K4A_IMAGE_FORMAT_COLOR_MJPG, 0, 0, 0, 0 }, + { 0, K4A_ABI_VERSION, K4A_COLOR_RESOLUTION_720P, 1280, 720, K4A_IMAGE_FORMAT_COLOR_MJPG, 90.0f, 59.0f, 5, 30 }, + { 0, K4A_ABI_VERSION, K4A_COLOR_RESOLUTION_1080P, 1920, 1080, K4A_IMAGE_FORMAT_COLOR_MJPG, 90.0f, 59.0f, 5, 30 }, + { 0, K4A_ABI_VERSION, K4A_COLOR_RESOLUTION_1440P, 2560, 1440, K4A_IMAGE_FORMAT_COLOR_MJPG, 90.0f, 59.0f, 5, 30 }, + { 0, K4A_ABI_VERSION, K4A_COLOR_RESOLUTION_1536P, 2048, 1536, K4A_IMAGE_FORMAT_COLOR_MJPG, 90.0f, 74.3f, 5, 30 }, + { 0, K4A_ABI_VERSION, K4A_COLOR_RESOLUTION_2160P, 3840, 2160, K4A_IMAGE_FORMAT_COLOR_MJPG, 90.0f, 59.0f, 5, 30 }, + { 0, K4A_ABI_VERSION, K4A_COLOR_RESOLUTION_3072P, 4096, 3072, K4A_IMAGE_FORMAT_COLOR_MJPG, 90.0f, 74.3f, 5, 30 } +}; + +// An alias so the lines below will not get too long. +#define DEPTH16 K4A_IMAGE_FORMAT_DEPTH16 + +// Create a static array of depth modes. Let the struct_size and variable fields be 0 for now. +// These values refer specifically to Azure Kinect device. +static const k4a_depth_mode_info_t device_depth_modes[] = { + { 0, K4A_ABI_VERSION, K4A_DEPTH_MODE_OFF, false, 0, 0, DEPTH16, 0.0f, 0.0f, 0, 0, 0, 0 }, + { 0, K4A_ABI_VERSION, K4A_DEPTH_MODE_NFOV_2X2BINNED, false, 320, 288, DEPTH16, 75.0f, 65.0f, 5, 30, 500, 5800 }, + { 0, K4A_ABI_VERSION, K4A_DEPTH_MODE_NFOV_UNBINNED, false, 640, 576, DEPTH16, 75.0f, 65.0f, 5, 30, 500, 4000 }, + { 0, K4A_ABI_VERSION, K4A_DEPTH_MODE_WFOV_2X2BINNED, false, 512, 512, DEPTH16, 120.0f, 120.0f, 5, 30, 250, 3000 }, + { 0, K4A_ABI_VERSION, K4A_DEPTH_MODE_WFOV_UNBINNED, false, 1024, 1024, DEPTH16, 120.0f, 120.0f, 5, 30, 250, 2500 }, + { 0, K4A_ABI_VERSION, K4A_DEPTH_MODE_PASSIVE_IR, true, 1024, 1024, DEPTH16, 120.0f, 120.0f, 5, 30, 0, 100 } +}; + +// Create a static array of fps modes. Let the struct_size and variable fields be 0 for now. +// These values refer specifically to Azure Kinect device. +static const k4a_fps_mode_info_t device_fps_modes[] = { { 0, K4A_ABI_VERSION, K4A_FRAMES_PER_SECOND_0, 0 }, + { 0, K4A_ABI_VERSION, K4A_FRAMES_PER_SECOND_5, 5 }, + { 0, K4A_ABI_VERSION, K4A_FRAMES_PER_SECOND_15, 15 }, + { 0, K4A_ABI_VERSION, K4A_FRAMES_PER_SECOND_30, 30 } }; + +/** Get count of device depth modes. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_get_device_depth_modes_count() +{ + return (uint32_t)(sizeof(device_depth_modes) / sizeof(device_depth_modes[0])); +} + +/** Get count of device color modes. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_get_device_color_modes_count() +{ + return (uint32_t)(sizeof(device_color_modes) / sizeof(device_color_modes[0])); +} + +/** Get count of device fps modes. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_get_device_fps_modes_count() +{ + return (uint32_t)(sizeof(device_fps_modes) / sizeof(device_fps_modes[0])); +} + +/** Get device depth mode for the given index. + * + * \param mode_index The index of the depth mode to get. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +k4a_depth_mode_info_t k4a_get_device_depth_mode(uint32_t mode_index) +{ + k4a_depth_mode_info_t depth_mode; + if (mode_index < k4a_get_device_depth_modes_count()) + depth_mode = device_depth_modes[mode_index]; + + depth_mode.struct_size = (uint32_t)sizeof(k4a_depth_mode_info_t); + return depth_mode; +} + +/** Get device color mode for the given index. + * + * \param mode_index The index of the depth mode to get. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +k4a_color_mode_info_t k4a_get_device_color_mode(uint32_t mode_index) +{ + k4a_color_mode_info_t color_mode; + if (mode_index < k4a_get_device_color_modes_count()) + color_mode = device_color_modes[mode_index]; + + color_mode.struct_size = (uint32_t)sizeof(k4a_color_mode_info_t); + return color_mode; +} + +/** Get device fps mode for the given index. + * + * \param mode_index The index of the depth mode to get. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +k4a_fps_mode_info_t k4a_get_device_fps_mode(uint32_t mode_index) +{ + k4a_fps_mode_info_t fps_mode; + if (mode_index < k4a_get_device_fps_modes_count()) + fps_mode = device_fps_modes[mode_index]; + + fps_mode.struct_size = (uint32_t)sizeof(k4a_fps_mode_info_t); + return fps_mode; +} + +/** Convert k4a_fps_t enum to the actual frame rate value. + * + * \remarks + * If the fps enum is not valid, then 0 fps is returned. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_convert_fps_to_uint(k4a_fps_t fps) +{ + uint32_t fpsValue = 0; + + // Search device_color_modes array for the given resolution. + for (size_t n = 0; n < sizeof(device_fps_modes) / sizeof(device_fps_modes[0]); ++n) + { + if ((k4a_fps_t)(device_fps_modes[n].mode_id) == fps) + { + fpsValue = (uint32_t)(device_fps_modes[n].fps); + break; + } + } + + return fpsValue; +} + +/** Convert frame rate value to the corresponding k4a_fps_t enum. + * + * \remarks + * If the fps value does not correspond to a k4a_fps_t enum, then K4A_FRAME_PER_SECOND_0 is returned. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +k4a_fps_t k4a_convert_uint_to_fps(uint32_t fps_in) +{ + k4a_fps_t fps_t = K4A_FRAMES_PER_SECOND_0; + + // Search device_color_modes array for the given resolution. + for (size_t n = 0; n < sizeof(device_fps_modes) / sizeof(device_fps_modes[0]); ++n) + { + if ((uint32_t)device_fps_modes[n].fps == fps_in) + { + fps_t = (k4a_fps_t)(device_fps_modes[n].mode_id); + break; + } + } + + return fps_t; +} + +/** Return the image width and height for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +bool k4a_convert_resolution_to_width_height(k4a_color_resolution_t resolution, + uint32_t *width_out, + uint32_t *height_out) +{ + bool resolutionFound = false; + + if (width_out == NULL || height_out == NULL) + { + return resolutionFound; + } + + // Search device_color_modes array for the given resolution. + for (size_t n = 0; n < sizeof(device_color_modes) / sizeof(device_color_modes[0]); ++n) + { + if (device_color_modes[n].mode_id == (uint32_t)resolution) + { + *width_out = device_color_modes[n].width; + *height_out = device_color_modes[n].height; + resolutionFound = true; + break; + } + } + + return resolutionFound; +} + +/** Return the image width for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_color_resolution_width(k4a_color_resolution_t resolution) +{ + uint32_t width = 0; + uint32_t height = 0; + k4a_convert_resolution_to_width_height(resolution, &width, &height); + return width; +} + +/** Return the image height for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_color_resolution_height(k4a_color_resolution_t resolution) +{ + uint32_t width = 0; + uint32_t height = 0; + k4a_convert_resolution_to_width_height(resolution, &width, &height); + return height; +} + +/** Return the camera field of view for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +bool k4a_convert_resolution_to_fov(k4a_color_resolution_t resolution, float *horizontal_fov, float *vertical_fov) +{ + bool resolutionFound = false; + + if (horizontal_fov == NULL || vertical_fov == NULL) + { + return resolutionFound; + } + + // Search device_color_modes array for the given resolution. + for (size_t n = 0; n < sizeof(device_color_modes) / sizeof(device_color_modes[0]); ++n) + { + if (device_color_modes[n].mode_id == (uint32_t)resolution) + { + *horizontal_fov = device_color_modes[n].horizontal_fov; + *vertical_fov = device_color_modes[n].vertical_fov; + resolutionFound = true; + break; + } + } + + return resolutionFound; +} + +/** Return the color camera horizontal fov for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +float k4a_color_resolution_horizontal_fov(k4a_color_resolution_t resolution) +{ + float horizontal_fov = 0; + float vertical_fov = 0; + k4a_convert_resolution_to_fov(resolution, &horizontal_fov, &vertical_fov); + return horizontal_fov; +} + +/** Return the color camera vertical fov for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +float k4a_color_resolution_vertical_fov(k4a_color_resolution_t resolution) +{ + float horizontal_fov = 0; + float vertical_fov = 0; + k4a_convert_resolution_to_fov(resolution, &horizontal_fov, &vertical_fov); + return vertical_fov; +} + +/** Return the image width and height for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +bool k4a_convert_depth_mode_to_width_height(k4a_depth_mode_t mode_id, uint32_t *width_out, uint32_t *height_out) +{ + bool modeFound = false; + + if (width_out == NULL || height_out == NULL) + { + return modeFound; + } + + // Search device_depth_modes array for the given resolution. + for (size_t n = 0; n < sizeof(device_depth_modes) / sizeof(device_depth_modes[0]); ++n) + { + if (device_depth_modes[n].mode_id == (uint32_t)mode_id) + { + *width_out = device_depth_modes[n].width; + *height_out = device_depth_modes[n].height; + modeFound = true; + break; + } + } + + return modeFound; +} + +/** Return the image width for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_depth_mode_width(k4a_depth_mode_t mode_id) +{ + uint32_t width = 0; + uint32_t height = 0; + k4a_convert_depth_mode_to_width_height(mode_id, &width, &height); + return width; +} + +/** Return the image height for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_depth_mode_height(k4a_depth_mode_t mode_id) +{ + uint32_t width = 0; + uint32_t height = 0; + k4a_convert_depth_mode_to_width_height(mode_id, &width, &height); + return height; +} + +/** Return the depth camera field of view for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +bool k4a_convert_depth_mode_to_fov(k4a_depth_mode_t mode_id, float *horizontal_fov, float *vertical_fov) +{ + bool modeFound = false; + + if (horizontal_fov == NULL || vertical_fov == NULL) + { + return modeFound; + } + + // Search device_depth_modes array for the given resolution. + for (size_t n = 0; n < sizeof(device_depth_modes) / sizeof(device_depth_modes[0]); ++n) + { + if (device_depth_modes[n].mode_id == (uint32_t)mode_id) + { + *horizontal_fov = device_depth_modes[n].horizontal_fov; + *vertical_fov = device_depth_modes[n].vertical_fov; + modeFound = true; + break; + } + } + + return modeFound; +} + +/** Return the depth camera horizontal fov for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +float k4a_depth_mode_horizontal_fov(k4a_depth_mode_t mode_id) +{ + float horizontal_fov = 0; + float vertical_fov = 0; + k4a_convert_depth_mode_to_fov(mode_id, &horizontal_fov, &vertical_fov); + return horizontal_fov; +} + +/** Return the depth camera vertical fov for the corresponding k4a_color_resolution_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +float k4a_depth_mode_vertical_fov(k4a_depth_mode_t mode_id) +{ + float horizontal_fov = 0; + float vertical_fov = 0; + k4a_convert_depth_mode_to_fov(mode_id, &horizontal_fov, &vertical_fov); + return vertical_fov; +} + +/** Return the min and max depth range for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +bool k4a_convert_depth_mode_to_min_max_range(k4a_depth_mode_t mode_id, uint32_t *min_range, uint32_t *max_range) +{ + bool modeFound = false; + + if (min_range == NULL || max_range == NULL) + { + return modeFound; + } + + // Search device_depth_modes array for the given resolution. + for (size_t n = 0; n < sizeof(device_depth_modes) / sizeof(device_depth_modes[0]); ++n) + { + if (device_depth_modes[n].mode_id == (uint32_t)mode_id) + { + *min_range = device_depth_modes[n].min_range; + *max_range = device_depth_modes[n].max_range; + modeFound = true; + break; + } + } + + return modeFound; +} + +/** Return the min depth range for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_depth_mode_min_range(k4a_depth_mode_t mode_id) +{ + uint32_t min_range = 0; + uint32_t max_range = 0; + k4a_convert_depth_mode_to_width_height(mode_id, &min_range, &max_range); + return min_range; +} + +/** Return the max depth range for the corresponding k4a_depth_mode_t enum. + * + * \xmlonly + * + * modes.h (include k4ainternal/modes.h) + * + * \endxmlonly + */ +uint32_t k4a_depth_mode_max_range(k4a_depth_mode_t mode_id) +{ + uint32_t min_range = 0; + uint32_t max_range = 0; + k4a_convert_depth_mode_to_width_height(mode_id, &min_range, &max_range); + return max_range; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/python/k4a/src/k4a/__init__.py b/src/python/k4a/src/k4a/__init__.py index d1ba561fa..b94dad1e4 100644 --- a/src/python/k4a/src/k4a/__init__.py +++ b/src/python/k4a/src/k4a/__init__.py @@ -1,5 +1,6 @@ from ._bindings.k4atypes import * from ._bindings.device import Device +from ._bindings.device import logging_message_cb, set_logging_callback from ._bindings.capture import Capture from ._bindings.image import Image from ._bindings.calibration import Calibration diff --git a/src/python/k4a/src/k4a/_bindings/calibration.py b/src/python/k4a/src/k4a/_bindings/calibration.py index e1b83c7e2..8f60d442a 100644 --- a/src/python/k4a/src/k4a/_bindings/calibration.py +++ b/src/python/k4a/src/k4a/_bindings/calibration.py @@ -10,7 +10,7 @@ import ctypes as _ctypes -from .k4atypes import _Calibration, EStatus, EDepthMode, EColorResolution, _Calibration +from .k4atypes import _Calibration, EStatus, _Calibration from .k4a import k4a_calibration_get_from_raw @@ -46,24 +46,24 @@ def __str__(self): @staticmethod def create_from_raw( raw_calibration:bytearray, - depth_mode:EDepthMode, - color_resolution:EColorResolution): + depth_mode_id:int, + color_mode_id:int): '''! Get the camera calibration for a device from a raw calibration blob. @param raw_calibration (bytearray): Raw calibration blob obtained from a device or recording. The raw calibration must be NULL terminated. - @param depth_mode (EDepthMode): Mode in which depth camera is operated. + @param depth_mode_id (int): Mode in which depth camera is operated. - @param color_resolution (EColorResolution): Resolution in which color + @param color_mode_id (int): Resolution in which color camera is operated. @returns Calibration: A Calibration instance. @remarks - The calibration represents the data needed to transform between the - camera views and is different for each operating @p depth_mode and - @p color_resolution the device is configured to operate in. + camera views and is different for each operating @p depth_mode_id and + @p color_mode_id the device is configured to operate in. @remarks - The function Device.get_raw_calibration() retrieves the raw @@ -80,10 +80,10 @@ def create_from_raw( # Get the _Calibration struct from the raw buffer. if (isinstance(raw_calibration, bytearray) and - isinstance(depth_mode, EDepthMode) and - isinstance(color_resolution, EColorResolution)): + isinstance(depth_mode_id, int) and + isinstance(color_mode_id, int)): - buffer_size_bytes = _ctypes.c_size_t(len(raw_calibration)) + buffer_size_bytes = _ctypes.c_ulonglong(len(raw_calibration)) cbuffer = (_ctypes.c_uint8 * buffer_size_bytes.value).from_buffer(raw_calibration) cbufferptr = _ctypes.cast(cbuffer, _ctypes.POINTER(_ctypes.c_char)) _calibration = _Calibration() @@ -91,8 +91,8 @@ def create_from_raw( status = k4a_calibration_get_from_raw( cbufferptr, buffer_size_bytes, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, _ctypes.byref(_calibration)) if status == EStatus.SUCCEEDED: @@ -116,11 +116,11 @@ def extrinsics(self): return self._calibration.extrinsics @property - def depth_mode(self): - return self._calibration.depth_mode + def depth_mode_id(self): + return self._calibration.depth_mode_id @property - def color_resolution(self): - return self._calibration.color_resolution + def color_mode_id(self): + return self._calibration.color_mode_id # ############### \ No newline at end of file diff --git a/src/python/k4a/src/k4a/_bindings/device.py b/src/python/k4a/src/k4a/_bindings/device.py index 503029e72..01cf93531 100644 --- a/src/python/k4a/src/k4a/_bindings/device.py +++ b/src/python/k4a/src/k4a/_bindings/device.py @@ -34,43 +34,111 @@ import ctypes as _ctypes from os import linesep as _newline +from math import log2 from .k4atypes import _DeviceHandle, HardwareVersion, EStatus, EBufferStatus, \ - _EmptyClass, EColorControlCommand, EColorControlMode, ImuSample, \ - EWaitStatus, DeviceConfiguration, _CaptureHandle, EDepthMode, EColorResolution, \ - _Calibration, ImuSample + EColorControlCommand, EColorControlMode, ImuSample, ELogLevel, \ + EWaitStatus, EDeviceCapabilities, DeviceConfiguration, _CaptureHandle, \ + _Calibration, ImuSample, DeviceInfo, DepthModeInfo, ColorModeInfo, \ + FPSModeInfo, DeviceInfo, ColorControlCapability, _logging_message_cb -from .k4a import k4a_device_get_installed_count, k4a_device_open, \ - k4a_device_get_serialnum, k4a_device_get_version, \ +from .k4a import k4a_set_debug_message_handler, k4a_device_get_installed_count, \ + k4a_device_open, k4a_device_get_serialnum, k4a_device_get_version, \ k4a_device_get_color_control_capabilities, k4a_device_close, \ k4a_device_get_imu_sample, k4a_device_get_color_control, \ k4a_device_start_cameras, k4a_device_stop_cameras, \ k4a_device_start_imu, k4a_device_stop_imu, \ k4a_device_set_color_control, k4a_device_get_raw_calibration, \ - k4a_device_get_sync_jack, k4a_device_get_capture, k4a_device_get_calibration + k4a_device_get_sync_jack, k4a_device_get_capture, k4a_device_get_calibration, \ + k4a_device_get_info, k4a_device_get_color_mode_count, k4a_device_get_color_mode, \ + k4a_device_get_depth_mode_count, k4a_device_get_depth_mode, \ + k4a_device_get_fps_mode_count, k4a_device_get_fps_mode from .capture import Capture from .calibration import Calibration -def _read_sync_jack_helper(device_handle:_DeviceHandle)->(bool, bool): - - retval = (False, False) +logging_message_cb = _logging_message_cb + +def set_logging_callback(callback_func:logging_message_cb, context_local, loglevel:ELogLevel)->EStatus: + '''Register a python callback function to handle the logging of messages that are + generated by the k4a library. + + The callback function must take the form of: - # Read the sync jack. - sync_in = _ctypes.c_bool(0) - sync_out = _ctypes.c_bool(0) + callback_func(context_local, loglevel:ELogLevel, filename:str, line:int, message:str) + + where callback_func is the name of the function to pass to set_logger_callback. + The callback must be annotated with '@k4a.logging_message_cb' to mark it as a + callback function. - status = k4a_device_get_sync_jack( - device_handle, - _ctypes.byref(sync_in), - _ctypes.byref(sync_out) - ) + The context_local is a Python object that is passed to the DLL, which is then passed back + to the callback function. If the user does not need a context, use None. In the callback + function, the context is passed in as the same Python object that is passed to the DLL. + + @note When using a context, the context object or instance must exist for the lifetime + of the loaded DLL. As such, a global context object is usually used for the entire lifetime + of the application. + + @code + 1. Callback function that ignores the context: + + # Define a callback function. The context argument will be ignored. + @k4a.logging_message_cb + def my_callback(context, loglevel:ELogLevel, filename:str, line:int, message:str): + formattedStr = str(k4a.ELogLevel(level)) + " in " + str(src_file, 'UTF-8') + \ + " at line " + str(src_line) + ": " + str(message, 'UTF-8') + print(formattedStr) + + # Pass the callback function to set_logger_callback. Pass None as the context. + status = set_logger_callback(my_callback, None, ELogLevel.INFO) + @endcode - if status == EStatus.SUCCEEDED: - retval = (sync_in.value, sync_out.value) + @code + 2. Callback function with context: + + # Define a context object. + class LogContext: + call_count = 0 + + def get_call_count(self): + retValue = self.call_count + self.call_count = self.call_count + 1 + return retValue + + # Instantiate a global context. + context = LogContext() + + # Define a callback function for logging. The context argument will be ignored. + @k4a.logging_message_cb + def logging_callback(context_local, loglevel:k4a.ELogLevel, src_filename:str, src_line:int, message:str): + + formattedStr = str() + + # Convert py_object to LogContext. + if context_local is not None: + formattedStr += str(context_local.get_call_count()) + " " + + formattedStr += str(k4a.ELogLevel(loglevel)) + " in " + str(src_filename, 'UTF-8') + " at line " + str(src_line) + ": " + str(message, 'UTF-8') + print(formattedStr) - return retval + # Pass the callback function to set_logger_callback. + status = set_logger_callback(my_callback, context, ELogLevel.INFO) + @endcode + + Args: + callback_func ([function]): A callback function with a specific signature. + context: The context associated with the callback function, if any. + loglevel (ELogLevel): The level of logging to use. + + Returns: + EStatus: Returns EStatus.SUCCEEDED if the callback function is successfully + registered, or EStatus.FAILED otherwise. + ''' + return k4a_set_debug_message_handler( + callback_func, + _ctypes.py_object(context_local), + loglevel) class Device: @@ -80,9 +148,7 @@ class Device: ------------------ | ---- | --- | ----------------------------------------- serial_number | str | R | The unique serial number of the device. hardware_version | HardwareVersion | R | The hardware versions in the device. - color_ctrl_cap | dict | R | The color control capabilities of the device. - sync_out_connected | bool | R | True if the sync out is connected. - sync_in_connected | bool | R | True if the sync in is connected. + device_info | DeviceInfo | R | The device product IDs and capabilities. @remarks - Use the static factory function open() to get a connected @@ -100,9 +166,7 @@ def __init__(self, device_index:int=0): self.__device_handle = None self._serial_number = None self._hardware_version = None - self._color_ctrl_cap = None - self._sync_out_connected = None - self._sync_in_connected = None + self._device_info = None # Allow syntax "with k4a.Depth.open() as device:" def __enter__(self): @@ -128,29 +192,21 @@ def __del__(self): del self.__device_handle del self._serial_number del self._hardware_version - del self._color_ctrl_cap - del self._sync_out_connected - del self._sync_in_connected + del self._device_info self.__device_handle = None self._serial_number = None self._hardware_version = None - self._color_ctrl_cap = None - self._sync_out_connected = None - self._sync_in_connected = None + self._device_info = None def __str__(self): return ''.join([ 'serial_number=%s, ', _newline, 'hardware_version=%s, ', _newline, - 'color_control_capabilities=%s, ', _newline, - 'sync_out_connected=%s, ', _newline, - 'sync_in_connected=%s']) % ( + 'device_info=%s ']) % ( self._serial_number, self._hardware_version.__str__(), - self._color_ctrl_cap.__str__(), - self._sync_out_connected, - self._sync_in_connected) + self._device_info.__str__()) @staticmethod def get_device_count()->int: @@ -184,7 +240,7 @@ def open(device_index:int=0): device.__device_handle = _DeviceHandle() device._serial_number = None device._hardware_version = HardwareVersion() - device._color_ctrl_cap = _EmptyClass() + device._device_info = DeviceInfo() # Open device and save device handle. status = k4a_device_open( @@ -196,7 +252,7 @@ def open(device_index:int=0): device = None else: # Get serial number. - serial_number_size = _ctypes.c_size_t(Device._MAX_SERIAL_NUM_LENGTH) + serial_number_size = _ctypes.c_ulonglong(Device._MAX_SERIAL_NUM_LENGTH) serial_number_buffer = _ctypes.create_string_buffer( Device._MAX_SERIAL_NUM_LENGTH) @@ -217,51 +273,14 @@ def open(device_index:int=0): if status != EStatus.SUCCEEDED: device._hardware_version = HardwareVersion() - - # Create a dictionary of color control capabilities. - color_control_commands = [ - EColorControlCommand.BACKLIGHT_COMPENSATION, - EColorControlCommand.BRIGHTNESS, - EColorControlCommand.CONTRAST, - EColorControlCommand.EXPOSURE_TIME_ABSOLUTE, - EColorControlCommand.GAIN, - EColorControlCommand.POWERLINE_FREQUENCY, - EColorControlCommand.SATURATION, - EColorControlCommand.SHARPNESS, - EColorControlCommand.WHITEBALANCE - ] - - supports_auto = _ctypes.c_bool(False) - min_value = _ctypes.c_int32(0) - max_value = _ctypes.c_int32(0) - step_value = _ctypes.c_int32(0) - default_value = _ctypes.c_int32(0) - color_control_mode = _ctypes.c_int32(EColorControlMode.AUTO.value) - - for command in color_control_commands: - - status = k4a_device_get_color_control_capabilities( - device.__device_handle, - command, - _ctypes.byref(supports_auto), - _ctypes.byref(min_value), - _ctypes.byref(max_value), - _ctypes.byref(step_value), - _ctypes.byref(default_value), - _ctypes.byref(color_control_mode)) - - if (status == EStatus.SUCCEEDED): - device._color_ctrl_cap.__dict__[command] = _EmptyClass() - device._color_ctrl_cap.__dict__[command].supports_auto = bool(supports_auto.value) - device._color_ctrl_cap.__dict__[command].min_value = int(min_value.value) - device._color_ctrl_cap.__dict__[command].max_value = int(max_value.value) - device._color_ctrl_cap.__dict__[command].step_value = int(step_value.value) - device._color_ctrl_cap.__dict__[command].default_value = int(default_value.value) - device._color_ctrl_cap.__dict__[command].default_mode = EColorControlMode(color_control_mode.value) - - # Read the sync jack. - (device._sync_in_connected, device._sync_out_connected) = \ - _read_sync_jack_helper(device.__device_handle) + + # Get device info. + status = k4a_device_get_info( + device.__device_handle, + _ctypes.byref(device._device_info)) + + if status != EStatus.SUCCEEDED: + device._device_info = DeviceInfo() return device @@ -275,11 +294,118 @@ def close(self): - Before deleting a Device object, ensure that all Captures have been deleted to ensure that all memory is freed. ''' - self.stop_cameras() self.stop_imu() k4a_device_close(self.__device_handle) + def _get_device_info(self)->DeviceInfo: + '''! Get device information and capabilities. + + @returns A DeviceInfo instance, or None if failed. + ''' + device_info = DeviceInfo() + status = k4a_device_get_info( + self.__device_handle, + _ctypes.byref(device_info)) + + if status != EStatus.SUCCEEDED: + device_info = None + + return device_info + + def get_color_modes(self)->list: + '''! Get a list of all available ColorModeInfo. + + \note The color mode with mode_id equal to 0 is reserved for "Color Off". + + @returns A list of all available ColorModeInfo, or None if failed. + ''' + color_mode_infos = list() + + num_color_modes = _ctypes.c_int(0) + status = k4a_device_get_color_mode_count( + self.__device_handle, + _ctypes.byref(num_color_modes)) + + if status == EStatus.SUCCEEDED: + for mode_index in range(num_color_modes.value): + color_mode_info = ColorModeInfo() + status = k4a_device_get_color_mode( + self.__device_handle, + mode_index, + _ctypes.byref(color_mode_info)) + + if status == EStatus.SUCCEEDED: + color_mode_infos.append(color_mode_info) + + # If there are no color modes, return None. + if (len(color_mode_infos) == 0): + color_mode_infos = None + + return color_mode_infos + + def get_depth_modes(self)->list: + '''! Get a list of all available DepthModeInfo. + + \note The depth mode with mode_id equal to 0 is reserved for "Depth Off". + + @returns A list of all available DepthModeInfo, or None if failed. + ''' + depth_mode_infos = list() + + num_depth_modes = _ctypes.c_int(0) + status = k4a_device_get_depth_mode_count( + self.__device_handle, + _ctypes.byref(num_depth_modes)) + + if status == EStatus.SUCCEEDED: + for mode_index in range(num_depth_modes.value): + depth_mode_info = DepthModeInfo() + status = k4a_device_get_depth_mode( + self.__device_handle, + mode_index, + _ctypes.byref(depth_mode_info)) + + if status == EStatus.SUCCEEDED: + depth_mode_infos.append(depth_mode_info) + + # If there are no color modes, return None. + if (len(depth_mode_infos) == 0): + depth_mode_infos = None + + return depth_mode_infos + + def get_fps_modes(self)->list: + '''! Get a list of all available FPSModeInfo. + + \note The fps mode with mode_id equal to 0 is reserved for "0 frames per second". + + @returns A list of all available FPSModeInfo, or None if failed. + ''' + fps_mode_infos = list() + + num_fps_modes = _ctypes.c_int(0) + status = k4a_device_get_fps_mode_count( + self.__device_handle, + _ctypes.byref(num_fps_modes)) + + if status == EStatus.SUCCEEDED: + for mode_index in range(num_fps_modes.value): + fps_mode_info = FPSModeInfo() + status = k4a_device_get_fps_mode( + self.__device_handle, + mode_index, + _ctypes.byref(fps_mode_info)) + + if status == EStatus.SUCCEEDED: + fps_mode_infos.append(fps_mode_info) + + # If there are no color modes, return None. + if (len(fps_mode_infos) == 0): + fps_mode_infos = None + + return fps_mode_infos + def get_capture(self, timeout_ms:int)->Capture: '''! Reads a sensor capture. @@ -440,8 +566,9 @@ def stop_cameras(self): def start_imu(self)->EStatus: '''! Starts the IMU sample stream. - @returns EStatus: EStatus.SUCCEEDED is returned on success, and - EStatus.FAILED is returned otherwise. + @returns EStatus: EStatus.SUCCEEDED is returned on success, + EStatus.FAILED on failure, and EStatus.UNSUPPORTED if the device + does not support this operation. @remarks - Call this API to start streaming IMU data. It is not valid @@ -471,6 +598,83 @@ def stop_imu(self): ''' k4a_device_stop_imu(self.__device_handle) + def get_color_control_capabilities(self)->tuple: + '''! Get the device color control capability. + + @returns (list, dict): A list of ColorControlCapability. It also + returns the same information in a dictionary. If the device + does not support a color camera, then (None, None) may be returned. + + @remarks Each control command may be set to manual or automatic. See the + definition of @ref EColorControlCommand on how to interpret the value + for each command. + + @remarks Some control commands are only supported in manual mode. When a + command is in automatic mode, the value for that command is not valid. + ''' + # Get device capabilities and check if it supports COLOR. + if (self.device_info.capabilities.bitmap.bHasColor) == 0: + return (None, None) + + ret_list = list() + ret_dict = dict() + + # Get color control capabilities. + color_control_commands = [ + EColorControlCommand.BACKLIGHT_COMPENSATION, + EColorControlCommand.BRIGHTNESS, + EColorControlCommand.CONTRAST, + EColorControlCommand.EXPOSURE_TIME_ABSOLUTE, + EColorControlCommand.GAIN, + EColorControlCommand.POWERLINE_FREQUENCY, + EColorControlCommand.SATURATION, + EColorControlCommand.SHARPNESS, + EColorControlCommand.WHITEBALANCE + ] + + for command in color_control_commands: + + c_command = _ctypes.c_int(command) + supports_auto = _ctypes.c_bool(False) + min_value = _ctypes.c_int32(0) + max_value = _ctypes.c_int32(0) + step_value = _ctypes.c_int32(0) + default_value = _ctypes.c_int32(0) + color_control_mode = _ctypes.c_int(0) + + status = k4a_device_get_color_control_capabilities( + self.__device_handle, + c_command, + _ctypes.byref(supports_auto), + _ctypes.byref(min_value), + _ctypes.byref(max_value), + _ctypes.byref(step_value), + _ctypes.byref(default_value), + _ctypes.byref(color_control_mode)) + + if (status == EStatus.SUCCEEDED): + + capability = ColorControlCapability( + command=EColorControlCommand(c_command.value), + supports_auto=bool(supports_auto.value), + min_value=int(min_value.value), + max_value=int(max_value.value), + step_value=int(step_value.value), + default_value=int(default_value.value), + default_mode=EColorControlMode(color_control_mode.value)) + + ret_list.append(capability) + ret_dict[EColorControlCommand(command.value)] = capability + + if (len(ret_list) == 0): + ret_list = None + + if (len(ret_dict) == 0): + ret_dict = None + + return ret_list, ret_dict + + def get_color_control(self, color_ctrl_command:EColorControlCommand)->(int, EColorControlMode): '''! Get the Azure Kinect color sensor control. @@ -514,7 +718,7 @@ def get_color_control(self, status = k4a_device_get_color_control( self.__device_handle, - color_ctrl_command, + command, _ctypes.byref(mode), _ctypes.byref(color_ctrl_value)) @@ -542,7 +746,8 @@ def set_color_control( control. The value is only valid if @p color_ctrl_mode is set to EColorControlMode.MANUAL, and is otherwise ignored. - @returns EStatus.SUCCEEDED if successful, EStatus.FAILED otherwise. + @returns EStatus.SUCCEEDED if successful, EStatus.FAILED if unsuccessful, + or EStatus.UNSUPPORTED if the device does not support this operation. @remarks - Each control command may be set to manual or automatic. See @@ -562,6 +767,33 @@ def set_color_control( return status + def get_sync_jack(self)->(bool, bool): + '''! Get the statuc of sync jacks (if available). + + @returns (bool, bool): If the sync in port is connected, the first + value is True. Otherwise it is False. If the sync out port is + connected, the second value is True. Otherwise it is False. + ''' + + sync_in_ret = False + sync_out_ret = False + + # Read the sync jack. + sync_in = _ctypes.c_bool(0) + sync_out = _ctypes.c_bool(0) + + status = k4a_device_get_sync_jack( + self.__device_handle, + _ctypes.byref(sync_in), + _ctypes.byref(sync_out) + ) + + if status == EStatus.SUCCEEDED: + sync_in_ret = sync_in.value + sync_out_ret = sync_out.value + + return sync_in_ret, sync_out_ret + def get_raw_calibration(self)->bytearray: '''! Get the raw calibration blob for the entire Azure Kinect device. @@ -579,7 +811,7 @@ def get_raw_calibration(self)->bytearray: # Get the size in bytes of the buffer that is required to # hold the raw calibration data. - buffer_size_bytes = _ctypes.c_size_t(0) + buffer_size_bytes = _ctypes.c_ulonglong(0) buffer_ptr = _ctypes.c_uint8(0) status = k4a_device_get_raw_calibration( @@ -590,8 +822,6 @@ def get_raw_calibration(self)->bytearray: if status != EBufferStatus.BUFFER_TOO_SMALL: return buffer - print(buffer_size_bytes.value) - # Create buffer of the correct size and get the raw calibration data. buffer = bytearray(buffer_size_bytes.value) cbuffer = (_ctypes.c_uint8 * buffer_size_bytes.value).from_buffer(buffer) @@ -608,15 +838,15 @@ def get_raw_calibration(self)->bytearray: return buffer def get_calibration(self, - depth_mode:EDepthMode, - color_resolution:EColorResolution)->Calibration: + depth_mode_id:int, + color_mode_id:int)->Calibration: '''! Get the camera calibration for the entire Azure Kinect device for a specific depth mode and color resolution. - @param depth_mode (EDepthMode): The mode in which the depth camera is + @param depth_mode_id (int): The mode in which the depth camera is operated. - @param color_resolution (EColorResolution): The resolution in which the + @param color_mode_id (int): The resolution in which the color camera is operated. @returns Calibration: A Calibration instance containing the calibration @@ -627,7 +857,7 @@ def get_calibration(self, @remarks - The calibration represents the data needed to transform between the camera views and may be different for each operating - @p depth_mode and @p color_resolution the device is configured to + @p depth_mode_id and @p color_mode_id the device is configured to operate in. @remarks @@ -636,18 +866,12 @@ def get_calibration(self, ''' calibration = None - if not isinstance(depth_mode, EDepthMode): - depth_mode = EDepthMode(depth_mode) - - if not isinstance(color_resolution, EColorResolution): - color_resolution = EColorResolution(color_resolution) - # Get ctypes calibration struct. _calibration = _Calibration() status = k4a_device_get_calibration( self.__device_handle, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, _ctypes.byref(_calibration)) if status == EStatus.SUCCEEDED: @@ -672,34 +896,13 @@ def hardware_version(self): @hardware_version.deleter def hardware_version(self): del self._hardware_version - - @property - def color_ctrl_cap(self): - return self._color_ctrl_cap - - @color_ctrl_cap.deleter - def color_ctrl_cap(self): - del self._color_ctrl_cap - + @property - def sync_in_connected(self): - # Read the sync jack. - (self._sync_in_connected, self._sync_out_connected) = \ - _read_sync_jack_helper(self.__device_handle) - return self._sync_in_connected + def device_info(self): + return self._device_info - @sync_in_connected.deleter - def sync_in_connected(self): - del self._sync_in_connected - - @property - def sync_out_connected(self): - # Read the sync jack. - (self._sync_in_connected, self._sync_out_connected) = \ - _read_sync_jack_helper(self.__device_handle) - return self._sync_out_connected + @device_info.deleter + def device_info(self): + del self._device_info - @sync_out_connected.deleter - def sync_out_connected(self): - del self._sync_out_connected # ############### diff --git a/src/python/k4a/src/k4a/_bindings/k4a.py b/src/python/k4a/src/k4a/_bindings/k4a.py index 3746aa353..cfb5e9cba 100644 --- a/src/python/k4a/src/k4a/_bindings/k4a.py +++ b/src/python/k4a/src/k4a/_bindings/k4a.py @@ -21,7 +21,7 @@ from .k4atypes import * from .k4atypes import _DeviceHandle, _CaptureHandle, _ImageHandle, \ _TransformationHandle, _Calibration, _Float2, _Float3, \ - _memory_allocate_cb, _memory_destroy_cb + _memory_allocate_cb, _memory_destroy_cb, _logging_message_cb __all__ = [] @@ -33,8 +33,10 @@ _lib_dir = _os_path.join(_os_path.dirname(_os_path.dirname(__file__)), '_libs') if _IS_WINDOWS: + _k4a_lib = _ctypes.CDLL(_os_path.join(_lib_dir, 'k4a.dll')) else: + _k4a_lib = _ctypes.CDLL(_os_path.join(_lib_dir, 'libk4a.so')) except Exception as ee: @@ -44,18 +46,12 @@ # Map _ctypes symbols to functions in the k4a.dll. -#K4A_EXPORT uint32_t k4a_device_get_installed_count(void); -k4a_device_get_installed_count = _k4a_lib.k4a_device_get_installed_count -k4a_device_get_installed_count.restype = _ctypes.c_uint32 -k4a_device_get_installed_count.argtypes = None - - #K4A_EXPORT k4a_status_t k4a_set_debug_message_handler(logging_message_cb *message_cb, # void *message_cb_context, # k4a_log_level_t min_level); k4a_set_debug_message_handler = _k4a_lib.k4a_set_debug_message_handler k4a_set_debug_message_handler.restype = EStatus -k4a_set_debug_message_handler.argtypes = (_ctypes.POINTER(logging_message_cb), _ctypes.c_void_p, _ctypes.c_int) +k4a_set_debug_message_handler.argtypes = (_logging_message_cb, _ctypes.py_object, _ctypes.c_int) #K4A_EXPORT k4a_result_t k4a_set_allocator(k4a_memory_allocate_cb_t allocate, k4a_memory_destroy_cb_t free); @@ -64,6 +60,12 @@ k4a_set_allocator.argtypes = (_memory_allocate_cb, _memory_destroy_cb,) +#K4A_EXPORT uint32_t k4a_device_get_installed_count(void); +k4a_device_get_installed_count = _k4a_lib.k4a_device_get_installed_count +k4a_device_get_installed_count.restype = _ctypes.c_uint32 +k4a_device_get_installed_count.argtypes = None + + #K4A_EXPORT k4a_status_t k4a_device_open(uint32_t index, k4a_device_t *device_handle); k4a_device_open = _k4a_lib.k4a_device_open k4a_device_open.restype = EStatus @@ -76,6 +78,54 @@ k4a_device_close.argtypes = (_DeviceHandle,) +#K4A_EXPORT k4a_result_t k4a_device_get_info(k4a_device_t device_handle, k4a_device_info_t *device_info); +k4a_device_get_info = _k4a_lib.k4a_device_get_info +k4a_device_get_info.restype = EStatus +k4a_device_get_info.argtypes = (_DeviceHandle, _ctypes.POINTER(DeviceInfo)) + + +#K4A_EXPORT k4a_result_t k4a_device_get_color_mode_count(k4a_device_t device_handle, int *mode_count); +k4a_device_get_color_mode_count = _k4a_lib.k4a_device_get_color_mode_count +k4a_device_get_color_mode_count.restype = EStatus +k4a_device_get_color_mode_count.argtypes = (_DeviceHandle, _ctypes.POINTER(_ctypes.c_int)) + + +#K4A_EXPORT k4a_result_t k4a_device_get_color_mode(k4a_device_t device_handle, +# uint32_t mode_id, +# k4a_color_mode_info_t *mode_info); +k4a_device_get_color_mode = _k4a_lib.k4a_device_get_color_mode +k4a_device_get_color_mode.restype = EStatus +k4a_device_get_color_mode.argtypes = (_DeviceHandle, _ctypes.c_uint32, _ctypes.POINTER(ColorModeInfo)) + + +#K4A_EXPORT k4a_result_t k4a_device_get_depth_mode_count(k4a_device_t device_handle, int *mode_count); +k4a_device_get_depth_mode_count = _k4a_lib.k4a_device_get_depth_mode_count +k4a_device_get_depth_mode_count.restype = EStatus +k4a_device_get_depth_mode_count.argtypes = (_DeviceHandle, _ctypes.POINTER(_ctypes.c_int)) + + +#K4A_EXPORT k4a_result_t k4a_device_get_depth_mode(k4a_device_t device_handle, +# uint32_t mode_id, +# k4a_depth_mode_info_t *mode_info); +k4a_device_get_depth_mode = _k4a_lib.k4a_device_get_depth_mode +k4a_device_get_depth_mode.restype = EStatus +k4a_device_get_depth_mode.argtypes = (_DeviceHandle, _ctypes.c_uint32, _ctypes.POINTER(DepthModeInfo)) + + +#K4A_EXPORT k4a_result_t k4a_device_get_fps_mode_count(k4a_device_t device_handle, int *mode_count); +k4a_device_get_fps_mode_count = _k4a_lib.k4a_device_get_fps_mode_count +k4a_device_get_fps_mode_count.restype = EStatus +k4a_device_get_fps_mode_count.argtypes = (_DeviceHandle, _ctypes.POINTER(_ctypes.c_int)) + + +#K4A_EXPORT k4a_result_t k4a_device_get_fps_mode(k4a_device_t device_handle, +# uint32_t mode_id, +# k4a_fps_mode_info_t *mode_info); +k4a_device_get_fps_mode = _k4a_lib.k4a_device_get_fps_mode +k4a_device_get_fps_mode.restype = EStatus +k4a_device_get_fps_mode.argtypes = (_DeviceHandle, _ctypes.c_uint32, _ctypes.POINTER(FPSModeInfo)) + + #K4A_EXPORT k4a_wait_status_t k4a_device_get_capture(k4a_device_t device_handle, # k4a_capture_t *capture_handle, # int32_t timeout_in_ms); @@ -182,7 +232,7 @@ k4a_image_create_from_buffer.restype = EStatus k4a_image_create_from_buffer.argtypes=( _ctypes.c_int, _ctypes.c_int, _ctypes.c_int, _ctypes.c_int, _ctypes.POINTER(_ctypes.c_uint8), - _ctypes.c_size_t, _memory_allocate_cb, _ctypes.c_void_p, _ctypes.POINTER(_ImageHandle)) + _ctypes.c_ulonglong, _memory_allocate_cb, _ctypes.c_void_p, _ctypes.POINTER(_ImageHandle)) @@ -194,7 +244,7 @@ #K4A_EXPORT size_t k4a_image_get_size(k4a_image_t image_handle); k4a_image_get_size = _k4a_lib.k4a_image_get_size -k4a_image_get_size.restype = _ctypes.c_size_t +k4a_image_get_size.restype = _ctypes.c_ulonglong k4a_image_get_size.argtypes=(_ImageHandle,) @@ -296,7 +346,7 @@ #K4A_EXPORT k4a_status_t k4a_device_start_cameras(k4a_device_t device_handle, const k4a_device_configuration_t *config); k4a_device_start_cameras = _k4a_lib.k4a_device_start_cameras -k4a_device_start_cameras.restype = EWaitStatus +k4a_device_start_cameras.restype = EStatus k4a_device_start_cameras.argtypes = (_DeviceHandle, _ctypes.POINTER(DeviceConfiguration)) @@ -324,7 +374,7 @@ k4a_device_get_serialnum = _k4a_lib.k4a_device_get_serialnum k4a_device_get_serialnum.restype = EBufferStatus k4a_device_get_serialnum.argtypes = (_DeviceHandle, - _ctypes.POINTER(_ctypes.c_char), _ctypes.POINTER(_ctypes.c_size_t)) + _ctypes.POINTER(_ctypes.c_char), _ctypes.POINTER(_ctypes.c_ulonglong)) #K4A_EXPORT k4a_status_t k4a_device_get_version(k4a_device_t device_handle, HardwareVersion *version); @@ -373,16 +423,16 @@ # size_t *data_size); k4a_device_get_raw_calibration = _k4a_lib.k4a_device_get_raw_calibration k4a_device_get_raw_calibration.restype = EBufferStatus -k4a_device_get_raw_calibration.argtypes = (_DeviceHandle, _ctypes.POINTER(_ctypes.c_uint8), _ctypes.POINTER(_ctypes.c_size_t)) +k4a_device_get_raw_calibration.argtypes = (_DeviceHandle, _ctypes.POINTER(_ctypes.c_uint8), _ctypes.POINTER(_ctypes.c_ulonglong)) #K4A_EXPORT k4a_status_t k4a_device_get_calibration(k4a_device_t device_handle, -# const k4a_depth_mode_t depth_mode, -# const k4a_color_resolution_t color_resolution, +# const uint32_t depth_mode_id, +# const uint3_t color_mode_id, # k4a_calibration_t *calibration); k4a_device_get_calibration = _k4a_lib.k4a_device_get_calibration k4a_device_get_calibration.restype = EStatus -k4a_device_get_calibration.argtypes = (_DeviceHandle, _ctypes.c_int, _ctypes.c_int, _ctypes.POINTER(_Calibration)) +k4a_device_get_calibration.argtypes = (_DeviceHandle, _ctypes.c_uint32, _ctypes.c_uint32, _ctypes.POINTER(_Calibration)) #K4A_EXPORT k4a_status_t k4a_device_get_sync_jack(k4a_device_t device_handle, @@ -395,13 +445,13 @@ #K4A_EXPORT k4a_status_t k4a_calibration_get_from_raw(char *raw_calibration, # size_t raw_calibration_size, -# const k4a_depth_mode_t depth_mode, -# const k4a_color_resolution_t color_resolution, +# const uint32_t depth_mode_id, +# const uint32_t color_mode_id, # k4a_calibration_t *calibration); k4a_calibration_get_from_raw = _k4a_lib.k4a_calibration_get_from_raw k4a_calibration_get_from_raw.restype = EStatus k4a_calibration_get_from_raw.argtypes = (_ctypes.POINTER(_ctypes.c_char), - _ctypes.c_size_t, _ctypes.c_int, _ctypes.c_int, _ctypes.POINTER(_Calibration)) + _ctypes.c_ulonglong, _ctypes.c_uint32, _ctypes.c_uint32, _ctypes.POINTER(_Calibration)) #K4A_EXPORT k4a_status_t k4a_calibration_3d_to_3d(const k4a_calibration_t *calibration, diff --git a/src/python/k4a/src/k4a/_bindings/k4atypes.py b/src/python/k4a/src/k4a/_bindings/k4atypes.py index a75abde54..02e38a050 100644 --- a/src/python/k4a/src/k4a/_bindings/k4atypes.py +++ b/src/python/k4a/src/k4a/_bindings/k4atypes.py @@ -18,25 +18,43 @@ import platform as _platform -# Determine the calling convention to use. -_IS_WINDOWS = 'Windows' == _platform.system() -if _IS_WINDOWS: - _FUNCTYPE = _ctypes.CFUNCTYPE -else: - _FUNCTYPE = _ctypes.CFUNCTYPE +'''! The ABI version of the SDK implementation. + +@remarks This must be equivalent to the value in k4atypes.h. + +@note Users should not modify this value. +''' +K4A_ABI_VERSION = 1 + + +'''! The index to use to connect to a default device. + +@note Users should not modify this value. +''' +K4A_DEVICE_DEFAULT = 0 + + +'''! The value to use in functions that accept a timeout argument to signify to +the function to wait forever. + +@note Users should not modify this value. +''' +K4A_WAIT_INFINITE = -1 @_unique class EStatus(_IntEnum): '''! Result code returned by Azure Kinect APIs. - Name | Description - ----------------- | ------------------------------------------------------- - EStatus.SUCCEEDED | Successful status. - EStatus.FAILED | Failed status. + Name | Description + ------------------- | ----------------------------------------------------- + EStatus.SUCCEEDED | Successful status. + EStatus.FAILED | Failed status. + EStatus.UNSUPPORTED | Unsupported operation. ''' SUCCEEDED = 0 FAILED = _auto() + UNSUPPORTED = _auto() @_unique @@ -48,10 +66,12 @@ class EBufferStatus(_IntEnum): EBufferStatus.SUCCEEDED | Successful buffer request status. EBufferStatus.FAILED | Failed buffer request status. EBufferStatus.BUFFER_TOO_SMALL | Buffer is too small. + EBufferStatus.UNSUPPORTED | Unsupported operation. ''' SUCCEEDED = 0 FAILED = _auto() BUFFER_TOO_SMALL = _auto() + UNSUPPORTED = _auto() @_unique @@ -63,10 +83,12 @@ class EWaitStatus(_IntEnum): EWaitStatus.SUCCEEDED | Successful result status. EWaitStatus.FAILED | Failed result status. EWaitStatus.TIMEOUT | The request timed out. + EWaitStatus.UNSUPPORTED | Unsupported operation. ''' SUCCEEDED = 0 FAILED = _auto() TIMEOUT = _auto() + UNSUPPORTED = _auto() @_unique @@ -91,55 +113,22 @@ class ELogLevel(_IntEnum): @_unique -class EDepthMode(_IntEnum): - '''! Depth sensor capture modes. - - See the hardware specification for additional details on the field of view - and supported frame rates for each mode. +class EDeviceCapabilities(_IntEnum): + '''! Defines capabilities of a device. - NFOV and WFOV denote Narrow and Wide Field of View configurations. - - Binned modes reduce the captured camera resolution by combining adjacent - sensor pixels into a bin. - - Name | Description - ------------------------------- | ----------------------------------------- - EDepthMode.OFF | Depth sensor will be turned off. - EDepthMode.NFOV_2X2BINNED | Depth and Active IR captured at 320x288. - EDepthMode.NFOV_UNBINNED | Depth and Active IR captured at 640x576. - EDepthMode.WFOV_2X2BINNED | Depth and Active IR captured at 512x512. - EDepthMode.WFOV_UNBINNED | Depth and Active IR captured at 1024x1024. - EDepthMode.PASSIVE_IR | Passive IR only, captured at 1024x1024. - ''' - OFF = 0 - NFOV_2X2BINNED = _auto() - NFOV_UNBINNED = _auto() - WFOV_2X2BINNED = _auto() - WFOV_UNBINNED = _auto() - PASSIVE_IR = _auto() - - -@_unique -class EColorResolution(_IntEnum): - '''! Color sensor resolutions, width * height and aspect ratio. + @note This is used in bitmaps so the values should take on powers of 2. Name | Description ------------------------------- | ----------------------------------------- - EColorResolution.OFF | Color camera will be turned off. - EColorResolution.RES_720P | 1280 * 720 16:9. - EColorResolution.RES_1080P | 1920 * 1080 16:9. - EColorResolution.RES_1440P | 2560 * 1440 16:9. - EColorResolution.RES_1536P | 2048 * 1536 4:3. - EColorResolution.RES_2160P | 3840 * 2160 16:9. - EColorResolution.RES_3072P | 4096 * 3072 4:3. + EDeviceCapabilities.DEPTH | The device has a depth sensor. + EDeviceCapabilities.COLOR | The device has a color camera. + EDeviceCapabilities.IMU | The device has an IMU. + EDeviceCapabilities.MICROPHONE | The device has a microphone. ''' - OFF = 0 - RES_720P = _auto() - RES_1080P = _auto() - RES_1440P = _auto() - RES_1536P = _auto() - RES_2160P = _auto() - RES_3072P = _auto() + DEPTH = 1 + COLOR = 2 + IMU = 4 + MICROPHONE = 8 @_unique @@ -273,26 +262,6 @@ class ETransformInterpolationType(_IntEnum): LINEAR = _auto() -@_unique -class EFramesPerSecond(_IntEnum): - '''! Color and depth sensor frame rate. - - This enumeration is used to select the desired frame rate to operate the - cameras. The actual frame rate may vary slightly due to dropped data, - synchronization variation between devices, clock accuracy, or if the camera - exposure priority mode causes reduced frame rate. - - Name | Description - ------------------------------- | ----------------------------------------- - EFramesPerSecond.FPS_5 | 5 frames per second. - EFramesPerSecond.FPS_15 | 15 frames per second. - EFramesPerSecond.FPS_30 | 30 frames per second. - ''' - FPS_5 = 0 - FPS_15 = _auto() - FPS_30 = _auto() - - @_unique class EColorControlCommand(_IntEnum): '''! Color sensor control commands @@ -547,24 +516,24 @@ def K4A_FAILED(result): # const char *file, # const int line, # const char *message); -logging_message_cb = _FUNCTYPE(None, - _ctypes.c_void_p, _ctypes.c_int, _ctypes.POINTER(_ctypes.c_char), - _ctypes.c_int, _ctypes.POINTER(_ctypes.c_char)) +_logging_message_cb = _ctypes.CFUNCTYPE(None, + _ctypes.py_object, _ctypes.c_int, _ctypes.c_char_p, + _ctypes.c_int, _ctypes.c_char_p) #typedef void(k4a_memory_destroy_cb_t)(void *buffer, void *context); -_memory_destroy_cb = _FUNCTYPE( +_memory_destroy_cb = _ctypes.CFUNCTYPE( None, _ctypes.c_void_p, _ctypes.c_void_p) #typedef uint8_t *(k4a_memory_allocate_cb_t)(int size, void **context); -_memory_allocate_cb = _FUNCTYPE( +_memory_allocate_cb = _ctypes.CFUNCTYPE( _ctypes.c_uint8, _ctypes.c_int, _ctypes.POINTER(_ctypes.c_void_p)) # K4A_DECLARE_HANDLE(handle_k4a_device_t); class __handle_k4a_device_t(_ctypes.Structure): - _fields_= [ + _fields_ = [ ("_rsvd", _ctypes.c_size_t), ] _DeviceHandle = _ctypes.POINTER(__handle_k4a_device_t) @@ -572,7 +541,7 @@ class __handle_k4a_device_t(_ctypes.Structure): # K4A_DECLARE_HANDLE(handle_k4a_capture_t); class __handle_k4a_capture_t(_ctypes.Structure): - _fields_= [ + _fields_ = [ ("_rsvd", _ctypes.c_size_t), ] _CaptureHandle = _ctypes.POINTER(__handle_k4a_capture_t) @@ -580,7 +549,7 @@ class __handle_k4a_capture_t(_ctypes.Structure): # K4A_DECLARE_HANDLE(handle_k4a_image_t); class __handle_k4a_image_t(_ctypes.Structure): - _fields_= [ + _fields_ = [ ("_rsvd", _ctypes.c_size_t), ] _ImageHandle = _ctypes.POINTER(__handle_k4a_image_t) @@ -588,12 +557,281 @@ class __handle_k4a_image_t(_ctypes.Structure): # K4A_DECLARE_HANDLE(k4a_transformation_t); class __handle_k4a_transformation_t(_ctypes.Structure): - _fields_= [ + _fields_ = [ ("_rsvd", _ctypes.c_size_t), ] _TransformationHandle = _ctypes.POINTER(__handle_k4a_transformation_t) +class _CapabilitiesBitmap(_ctypes.Structure): + _fields_ = [ + ("bHasDepth", _ctypes.c_uint32, 1), + ("bHasColor", _ctypes.c_uint32, 1), + ("bHasIMU", _ctypes.c_uint32, 1), + ("bHasMic", _ctypes.c_uint32, 1), + ("resv", _ctypes.c_uint32, 28), + ] + +class _Capabilities(_ctypes.Union): + _fields_ = [ + ("value", _ctypes.c_uint32), + ("bitmap", _CapabilitiesBitmap), + ] + +'''! Device information. + + Name | Type | Description + -------------- | ----- | ---------------------------------------------- + struct_size | int | The size in bytes of this struct. + struct_version | int | The version of this struct. + vendor_id | int | The unique vendor ID of the device. + device_id | int | The ID of the device (i.e. product ID, PID). + capabilities | int | A bitmap of device capabilities. + ''' +class DeviceInfo(_ctypes.Structure): + _fields_ = [ + ("struct_size", _ctypes.c_uint32), + ("struct_version", _ctypes.c_uint32), + ("vendor_id", _ctypes.c_uint32), + ("device_id", _ctypes.c_uint32), + ("capabilities", _Capabilities), + ] + + def __init__(self, + struct_size:int=20, # Size of this struct in bytes. + struct_version:int=K4A_ABI_VERSION, + vendor_id:int=0, + device_id:int=0, + capabilities:int=0): + + self.struct_size = struct_size + self.struct_version = struct_version + self.vendor_id = vendor_id + self.device_id = device_id + self.capabilities.value = capabilities + + def __str__(self): + return ''.join([ + 'struct_size=%d, ', + 'struct_version=%d, ', + 'vendor_id=0x%04x, ', + 'device_id=0x%04x, ', + 'capabilities=%s']) % ( + self.struct_size, + self.struct_version, + self.vendor_id, + self.device_id, + format(self.capabilities.value, '#b')) + + +'''! Color mode information. + + Name | Type | Description + -------------- | ----- | ---------------------------------------------- + struct_size | int | The size in bytes of this struct. + struct_version | int | The version of this struct. + mode_id | int | The mode identifier to use to select a color mode. 0 is reserved for off. + width | int | The image width in pixels. + height | int | The image height in pixels. + native_format | EImageFormat | The default image format. + horizontal_fov | float | The approximate horizontal field of view in degrees. + vertical_fov | float | The approximate vertical field of view in degrees. + min_fps | int | The minimum supported frame rate. + max_fps | int | The maximum supported frame rate. + ''' +class ColorModeInfo(_ctypes.Structure): + _fields_ = [ + ("struct_size", _ctypes.c_uint32), + ("struct_version", _ctypes.c_uint32), + ("mode_id", _ctypes.c_uint32), + ("width", _ctypes.c_uint32), + ("height", _ctypes.c_uint32), + ("native_format", _ctypes.c_uint32), + ("horizontal_fov", _ctypes.c_float), + ("vertical_fov", _ctypes.c_float), + ("min_fps", _ctypes.c_uint32), + ("max_fps", _ctypes.c_uint32), + ] + + def __init__(self, + struct_size:int=40, # Size of this struct in bytes. + struct_version:int=K4A_ABI_VERSION, + mode_id:int=0, + width:int=0, + height:int=0, + native_format:EImageFormat=EImageFormat.COLOR_MJPG, + horizontal_fov:float=0, + vertical_fov:float=0, + min_fps:int=0, + max_fps:int=0): + + self.struct_size = struct_size + self.struct_version = struct_version + self.mode_id = mode_id + self.width = width + self.height = height + self.native_format = native_format + self.horizontal_fov = horizontal_fov + self.vertical_fov = vertical_fov + self.min_fps = min_fps + self.max_fps = max_fps + + def __str__(self): + return ''.join([ + 'struct_size=%d, ', + 'struct_version=%d, ', + 'mode_id=%d, ', + 'width=%d, ', + 'height=%d, ', + 'native_format=%s, ', + 'horizontal_fov=%f, ', + 'vertical_fov=%f, ', + 'min_fps=%d, ', + 'max_fps=%d']) % ( + self.struct_size, + self.struct_version, + self.mode_id, + self.width, + self.height, + self.native_format, + self.horizontal_fov, + self.vertical_fov, + self.min_fps, + self.max_fps) + + +'''! Depth mode information. + + Name | Type | Description + --------------- | ----- | ---------------------------------------------- + struct_size | int | The size in bytes of this struct. + struct_version | int | The version of this struct. + mode_id | int | The mode identifier to use to select a depth mode. 0 is reserved for off. + passive_ir_only | bool | True if only capturing passive IR. + width | int | The image width in pixels. + height | int | The image height in pixels. + native_format | EImageFormat | The default image format. + horizontal_fov | float | The approximate horizontal field of view in degrees. + vertical_fov | float | The approximate vertical field of view in degrees. + min_fps | int | The minimum supported frame rate. + max_fps | int | The maximum supported frame rate. + min_range | int | The minimum expected depth value in millimeters. + max_range | int | The maximum expected depth value in millimeters. + ''' +class DepthModeInfo(_ctypes.Structure): + _fields_ = [ + ("struct_size", _ctypes.c_uint32), + ("struct_version", _ctypes.c_uint32), + ("mode_id", _ctypes.c_uint32), + ("passive_ir_only", _ctypes.c_bool), + ("width", _ctypes.c_uint32), + ("height", _ctypes.c_uint32), + ("native_format", _ctypes.c_uint32), + ("horizontal_fov", _ctypes.c_float), + ("vertical_fov", _ctypes.c_float), + ("min_fps", _ctypes.c_uint32), + ("max_fps", _ctypes.c_uint32), + ("min_range", _ctypes.c_uint32), + ("max_range", _ctypes.c_uint32), + ] + + def __init__(self, + struct_size:int=52, # Size of this struct in bytes (in C). + struct_version:int=K4A_ABI_VERSION, + mode_id:int=0, + passive_ir_only:bool=False, + width:int=0, + height:int=0, + native_format:EImageFormat=EImageFormat.COLOR_MJPG, + horizontal_fov:float=0, + vertical_fov:float=0, + min_fps:int=0, + max_fps:int=0, + min_range:int=0, + max_range:int=0): + + self.struct_size = struct_size + self.struct_version = struct_version + self.mode_id = mode_id + self.passive_ir_only = passive_ir_only + self.width = width + self.height = height + self.native_format = native_format + self.horizontal_fov = horizontal_fov + self.vertical_fov = vertical_fov + self.min_fps = min_fps + self.max_fps = max_fps + + def __str__(self): + return ''.join([ + 'struct_size=%d, ', + 'struct_version=%d, ', + 'mode_id=%d, ', + 'passive_ir_only=%s, ', + 'width=%d, ', + 'height=%d, ', + 'native_format=%s, ', + 'horizontal_fov=%f, ', + 'vertical_fov=%f, ', + 'min_fps=%d, ', + 'max_fps=%d, ', + 'min_range=%d, ', + 'max_range=%d']) % ( + self.struct_size, + self.struct_version, + self.mode_id, + self.passive_ir_only, + self.width, + self.height, + self.native_format, + self.horizontal_fov, + self.vertical_fov, + self.min_fps, + self.max_fps, + self.min_range, + self.max_range) + + +'''! FPS mode information for specifying frame rates. + + Name | Type | Description + --------------- | ----- | ---------------------------------------------- + struct_size | int | The size in bytes of this struct. + struct_version | int | The version of this struct. + mode_id | int | The mode identifier to use to select an FPS mode. + fps | int | The frame rate per second. + ''' +class FPSModeInfo(_ctypes.Structure): + _fields_ = [ + ("struct_size", _ctypes.c_uint32), + ("struct_version", _ctypes.c_uint32), + ("mode_id", _ctypes.c_uint32), + ("fps", _ctypes.c_uint32), + ] + + def __init__(self, + struct_size:int=16, # Size of this struct in bytes. + struct_version:int=K4A_ABI_VERSION, + mode_id:int=0, + fps:int=0): + + self.struct_size = struct_size + self.struct_version = struct_version + self.mode_id = mode_id + self.fps = fps + + def __str__(self): + return ''.join([ + 'struct_size=%d, ', + 'struct_version=%d, ', + 'mode_id=%d, ', + 'fps=%d']) % ( + self.struct_size, + self.struct_version, + self.mode_id, + self.fps) + + class DeviceConfiguration(_ctypes.Structure): '''! Configuration parameters for an Azure Kinect device. @@ -617,22 +855,22 @@ class DeviceConfiguration(_ctypes.Structure): - color_resolution - EColorResolution + color_mode_id + int Image resolution to capture with the color camera. - depth_mode - EDepthMode + depth_mode_id + int Capture mode for the depth camera. - camera_fps - EFramesPerSecond + fps_mode_id + int Desired frame rate for the color and depth camera. @@ -700,11 +938,11 @@ class DeviceConfiguration(_ctypes.Structure): ''' - _fields_= [ + _fields_ = [ ("color_format", _ctypes.c_int), - ("color_resolution", _ctypes.c_int), - ("depth_mode", _ctypes.c_int), - ("camera_fps", _ctypes.c_int), + ("color_mode_id", _ctypes.c_uint32), + ("depth_mode_id", _ctypes.c_uint32), + ("fps_mode_id", _ctypes.c_uint32), ("synchronized_images_only", _ctypes.c_bool), ("depth_delay_off_color_usec", _ctypes.c_int32), ("wired_sync_mode", _ctypes.c_int), @@ -714,9 +952,9 @@ class DeviceConfiguration(_ctypes.Structure): def __init__(self, color_format:EImageFormat=EImageFormat.CUSTOM, - color_resolution:EColorResolution=EColorResolution.RES_720P, - depth_mode:EDepthMode=EDepthMode.OFF, - camera_fps:EFramesPerSecond=EFramesPerSecond.FPS_5, + color_mode_id:int=0, # 720P + depth_mode_id:int=0, # OFF + fps_mode_id:int=0, # FPS_0 synchronized_images_only:bool=True, depth_delay_off_color_usec:int=0, wired_sync_mode:EWiredSyncMode=EWiredSyncMode.STANDALONE, @@ -724,9 +962,9 @@ def __init__(self, disable_streaming_indicator:bool=False): self.color_format = color_format - self.color_resolution = color_resolution - self.depth_mode = depth_mode - self.camera_fps = camera_fps + self.color_mode_id = color_mode_id + self.depth_mode_id = depth_mode_id + self.fps_mode_id = fps_mode_id self.synchronized_images_only = synchronized_images_only self.depth_delay_off_color_usec = depth_delay_off_color_usec self.wired_sync_mode = wired_sync_mode @@ -735,19 +973,19 @@ def __init__(self, def __str__(self): return ''.join([ - 'color_format=%d, ', - 'color_resolution=%d, ', - 'depth_mode=%d, ', - 'camera_fps=%d, ', + 'color_format=%s, ', + 'color_mode_id=%d, ', + 'depth_mode_id=%d, ', + 'fps_mode_id=%d, ', 'synchronized_images_only=%s, ', 'depth_delay_off_color_usec=%d, ', - 'wired_sync_mode=%d, ', + 'wired_sync_mode=%s, ', 'subordinate_delay_off_master_usec=%d, ', 'disable_streaming_indicator=%s']) % ( self.color_format, - self.color_resolution, - self.depth_mode, - self.camera_fps, + self.color_mode_id, + self.depth_mode_id, + self.fps_mode_id, self.synchronized_images_only, self.depth_delay_off_color_usec, self.wired_sync_mode, @@ -767,7 +1005,7 @@ class CalibrationExtrinsics(_ctypes.Structure): rotation | float * 9 | 3x3 Rotation matrix stored in row major order. translation | float * 3 | Translation vector, x,y,z (in millimeters). ''' - _fields_= [ + _fields_ = [ ("rotation", (_ctypes.c_float * 3) * 3), ("translation", _ctypes.c_float * 3), ] @@ -846,7 +1084,7 @@ def __str__(self): class _CalibrationIntrinsicParameters(_ctypes.Union): - _fields_= [ + _fields_ = [ ("param", CalibrationIntrinsicParam), ("v", _ctypes.c_float * 15), ] @@ -872,7 +1110,7 @@ class CalibrationIntrinsics(_ctypes.Structure): parameter_count | int | Number of valid entries in parameters. parameters | struct | Calibration parameters. ''' - _fields_= [ + _fields_ = [ ("type", _ctypes.c_int), ("parameter_count", _ctypes.c_uint), ("parameters", _CalibrationIntrinsicParameters), @@ -900,7 +1138,7 @@ class CalibrationCamera(_ctypes.Structure): resolution_height | int | Resolution height of the calibration sensor. metric_radius | float | Max FOV of the camera. ''' - _fields_= [ + _fields_ = [ ("extrinsics", CalibrationExtrinsics), ("intrinsics", CalibrationIntrinsics), ("resolution_width", _ctypes.c_int), @@ -923,12 +1161,12 @@ def __str__(self): class _Calibration(_ctypes.Structure): - _fields_= [ + _fields_ = [ ("depth_camera_calibration", CalibrationCamera), ("color_camera_calibration", CalibrationCamera), ("extrinsics", (CalibrationExtrinsics * ECalibrationType.NUM_TYPES) * ECalibrationType.NUM_TYPES), - ("depth_mode", _ctypes.c_int), - ("color_resolution", _ctypes.c_int), + ("depth_mode_id", _ctypes.c_int), + ("color_mode_id", _ctypes.c_int), ] def __str__(self): @@ -944,10 +1182,10 @@ def __str__(self): s = ''.join([s, 'extrinsics[%d][%d]=%s, ']) % (r, c, self.extrinsics[r][c].__str__()) s = ''.join([s, - 'depth_mode=%d, ', - 'color_resolution=%d']) % ( - self.depth_mode, - self.color_resolution + 'depth_mode_id=%d, ', + 'color_mode_id=%d']) % ( + self.depth_mode_id, + self.color_mode_id ) return s @@ -962,7 +1200,7 @@ class Version(_ctypes.Structure): minor | int | Minor version; represents additional features, no regression from lower versions with same major version. iteration | int | Reserved. ''' - _fields_= [ + _fields_ = [ ("major", _ctypes.c_uint32), ("minor", _ctypes.c_uint32), ("iteration", _ctypes.c_uint32), @@ -987,7 +1225,7 @@ class HardwareVersion(_ctypes.Structure): firmware_build | int | Build type reported by the firmware. firmware_signature | int | Signature type of the firmware. ''' - _fields_= [ + _fields_ = [ ("rgb", Version), ("depth", Version), ("audio", Version), @@ -1013,7 +1251,7 @@ def __str__(self): class _XY(_ctypes.Structure): - _fields_= [ + _fields_ = [ ("x", _ctypes.c_float), ("y", _ctypes.c_float), ] @@ -1027,7 +1265,7 @@ def __str__(self): class _Float2(_ctypes.Union): - _fields_= [ + _fields_ = [ ("xy", _XY), ("v", _ctypes.c_float * 2), ] @@ -1040,7 +1278,7 @@ def __str__(self): class _XYZ(_ctypes.Structure): - _fields_= [ + _fields_ = [ ("x", _ctypes.c_float), ("y", _ctypes.c_float), ("z", _ctypes.c_float), @@ -1056,7 +1294,7 @@ def __str__(self): class _Float3(_ctypes.Union): - _fields_= [ + _fields_ = [ ("xyz", _XYZ), ("v", _ctypes.c_float * 3) ] @@ -1079,7 +1317,7 @@ class ImuSample(_ctypes.Structure): gyro_sample | float * 3 | Gyro sample in radians per second. gyro_timestamp_usec | int | Timestamp of the gyroscope in microseconds. ''' - _fields_= [ + _fields_ = [ ("temperature", _ctypes.c_float), ("acc_sample", _Float3), ("acc_timestamp_usec", _ctypes.c_uint64), @@ -1101,118 +1339,49 @@ def __str__(self): self.gyro_timestamp_usec) -# An empty class for appending fields dynamically. -class _EmptyClass: - +class ColorControlCapability(): + '''! Color control capabilities. + + Name | Type | Description + ------------- | -------------------- | --------------------------------------------- + command | EColorControlCommand | The type of color control command. + supports_auto | bool | True if the capability supports auto-level. + min_value | int | The minimum value of the capability. + max_value | int | The maximum value of the capability. + step_value | int | The step value of the capability. + default_value | int | The default value of the capability. + default_mode | EColorControlMode | The default mode of the command, AUTO or MANUAL. + ''' + def __init__(self, + command:EColorControlCommand, + supports_auto:bool=True, + min_value:int=0, + max_value:int=0, + step_value:int=0, + default_value:int=0, + default_mode:EColorControlMode=EColorControlMode.AUTO): + + self.command = command + self.supports_auto = supports_auto + self.min_value = min_value + self.max_value = max_value + self.step_value = step_value + self.default_value = default_value + self.default_mode = default_mode + def __str__(self): - keys = list(self.__dict__.keys()) - tempstr = '' - - if len(keys) > 0: - for n in range(len(keys)-1): - tempstr = tempstr + str(keys[n]) + "=" + str(self.__dict__[keys[n]]) + ", " - tempstr = tempstr + str(keys[len(keys)-1]) + "=" + str(self.__dict__[keys[len(keys)-1]]) - - return tempstr - - -# ############# Define global instances of device configurations. ############# - -DEVICE_CONFIG_DISABLE_ALL = DeviceConfiguration( - color_format = EImageFormat.COLOR_MJPG, - color_resolution = EColorResolution.OFF, - depth_mode = EDepthMode.OFF, - camera_fps = EFramesPerSecond.FPS_30, - synchronized_images_only = False, - depth_delay_off_color_usec = 0, - wired_sync_mode = EWiredSyncMode.STANDALONE, - subordinate_delay_off_master_usec = 0, - disable_streaming_indicator = False) - -DEVICE_CONFIG_BGRA32_2160P_WFOV_UNBINNED_FPS15 = DeviceConfiguration( - color_format = EImageFormat.COLOR_BGRA32, - color_resolution = EColorResolution.RES_2160P, - depth_mode = EDepthMode.WFOV_UNBINNED, - camera_fps = EFramesPerSecond.FPS_15, - synchronized_images_only = True, - depth_delay_off_color_usec = 0, - wired_sync_mode = EWiredSyncMode.STANDALONE, - subordinate_delay_off_master_usec = 0, - disable_streaming_indicator = False) - -DEVICE_CONFIG_BGRA32_2160P_WFOV_2X2BINNED_FPS15 = DeviceConfiguration( - color_format = EImageFormat.COLOR_BGRA32, - color_resolution = EColorResolution.RES_2160P, - depth_mode = EDepthMode.WFOV_2X2BINNED, - camera_fps = EFramesPerSecond.FPS_15, - synchronized_images_only = True, - depth_delay_off_color_usec = 0, - wired_sync_mode = EWiredSyncMode.STANDALONE, - subordinate_delay_off_master_usec = 0, - disable_streaming_indicator = False) - -DEVICE_CONFIG_BGRA32_2160P_NFOV_UNBINNED_FPS15 = DeviceConfiguration( - color_format = EImageFormat.COLOR_BGRA32, - color_resolution = EColorResolution.RES_2160P, - depth_mode = EDepthMode.NFOV_UNBINNED, - camera_fps = EFramesPerSecond.FPS_15, - synchronized_images_only = True, - depth_delay_off_color_usec = 0, - wired_sync_mode = EWiredSyncMode.STANDALONE, - subordinate_delay_off_master_usec = 0, - disable_streaming_indicator = False) - -DEVICE_CONFIG_BGRA32_2160P_NFOV_2X2BINNED_FPS15 = DeviceConfiguration( - color_format = EImageFormat.COLOR_BGRA32, - color_resolution = EColorResolution.RES_2160P, - depth_mode = EDepthMode.NFOV_2X2BINNED, - camera_fps = EFramesPerSecond.FPS_15, - synchronized_images_only = True, - depth_delay_off_color_usec = 0, - wired_sync_mode = EWiredSyncMode.STANDALONE, - subordinate_delay_off_master_usec = 0, - disable_streaming_indicator = False) - -DEVICE_CONFIG_BGRA32_1080P_WFOV_UNBINNED_FPS15 = DeviceConfiguration( - color_format = EImageFormat.COLOR_BGRA32, - color_resolution = EColorResolution.RES_1080P, - depth_mode = EDepthMode.WFOV_UNBINNED, - camera_fps = EFramesPerSecond.FPS_15, - synchronized_images_only = True, - depth_delay_off_color_usec = 0, - wired_sync_mode = EWiredSyncMode.STANDALONE, - subordinate_delay_off_master_usec = 0, - disable_streaming_indicator = False) - -DEVICE_CONFIG_BGRA32_1080P_WFOV_2X2BINNED_FPS15 = DeviceConfiguration( - color_format = EImageFormat.COLOR_BGRA32, - color_resolution = EColorResolution.RES_1080P, - depth_mode = EDepthMode.WFOV_2X2BINNED, - camera_fps = EFramesPerSecond.FPS_15, - synchronized_images_only = True, - depth_delay_off_color_usec = 0, - wired_sync_mode = EWiredSyncMode.STANDALONE, - subordinate_delay_off_master_usec = 0, - disable_streaming_indicator = False) - -DEVICE_CONFIG_BGRA32_1080P_NFOV_UNBINNED_FPS15 = DeviceConfiguration( - color_format = EImageFormat.COLOR_BGRA32, - color_resolution = EColorResolution.RES_1080P, - depth_mode = EDepthMode.NFOV_UNBINNED, - camera_fps = EFramesPerSecond.FPS_15, - synchronized_images_only = True, - depth_delay_off_color_usec = 0, - wired_sync_mode = EWiredSyncMode.STANDALONE, - subordinate_delay_off_master_usec = 0, - disable_streaming_indicator = False) - -DEVICE_CONFIG_BGRA32_1080P_NFOV_2X2BINNED_FPS15 = DeviceConfiguration( - color_format = EImageFormat.COLOR_BGRA32, - color_resolution = EColorResolution.RES_1080P, - depth_mode = EDepthMode.NFOV_2X2BINNED, - camera_fps = EFramesPerSecond.FPS_15, - synchronized_images_only = True, - depth_delay_off_color_usec = 0, - wired_sync_mode = EWiredSyncMode.STANDALONE, - subordinate_delay_off_master_usec = 0, - disable_streaming_indicator = False) + return ''.join([ + 'command=%s, ', + 'supports_auto=%s, ', + 'min_value=%d, ', + 'max_value=%d, ', + 'step_value=%d, ', + 'default_value=%d, ', + 'default_mode=%s']) % ( + self.command, + self.supports_auto, + self.min_value, + self.max_value, + self.step_value, + self.default_value, + self.default_mode) diff --git a/src/python/k4a/tests/mock_k4a_dll_azurekinect.py b/src/python/k4a/tests/mock_k4a_dll_azurekinect.py new file mode 100644 index 000000000..d76e09016 --- /dev/null +++ b/src/python/k4a/tests/mock_k4a_dll_azurekinect.py @@ -0,0 +1,511 @@ +''' +mock_device_azurekinect.py + +Mock an Azure Kinect device. + +Copyright (C) Microsoft Corporation. All rights reserved. +''' + +import ctypes + +import k4a + +# Mock function for opening a device. +opened_device_handles = [] +max_num_devices = 4 + +def mock_k4a_device_get_installed_count()->int: + global max_num_devices + return max_num_devices + +def mock_k4a_device_open(device_index, device_handle)->k4a.EStatus: + global opened_device_handles + global max_num_devices + status = k4a.EStatus.FAILED + + if not isinstance(device_handle._obj, k4a._bindings.k4atypes._DeviceHandle): + return status + + if (len(opened_device_handles) <= max_num_devices and + device_handle._obj not in opened_device_handles): + opened_device_handles.append(device_handle._obj) + status = k4a.EStatus.SUCCEEDED + + return status + +def mock_k4a_device_close(device_handle): + global opened_device_handles + + if isinstance(device_handle, k4a._bindings.k4atypes._DeviceHandle): + if device_handle in opened_device_handles: + opened_device_handles.remove(device_handle) + + return + +# Mock function for getting device serial number +def mock_k4a_get_serialnum(device_handle, buffer, buffer_size)->k4a.EStatus: + + status = k4a.EStatus.FAILED + + if not isinstance(buffer, ctypes.c_char * 32): + return status + + if not isinstance(buffer_size._obj, ctypes.c_ulonglong): + return status + + if buffer_size._obj.value != 32: + return status + + serial_number = "0123-4567890" + buffer.value = bytes(serial_number, "utf-8") + buffer_size._obj.value = len(serial_number) + + status = k4a.EStatus.SUCCEEDED + return status + +# Mock function for getting device hardware version. +def mock_k4a_get_version(device_handle, hardware_version)->k4a.EStatus: + + status = k4a.EStatus.FAILED + + if not isinstance(hardware_version._obj, k4a.HardwareVersion): + return status + + hardware_version._obj.rgb.major = 0 + hardware_version._obj.rgb.minor = 1 + hardware_version._obj.rgb.iteration = 0 + + hardware_version._obj.depth.major = 0 + hardware_version._obj.depth.minor = 1 + hardware_version._obj.depth.iteration = 0 + + hardware_version._obj.audio.major = 0 + hardware_version._obj.audio.minor = 1 + hardware_version._obj.audio.iteration = 0 + + hardware_version._obj.depth_sensor.major = 0 + hardware_version._obj.depth_sensor.minor = 1 + hardware_version._obj.depth_sensor.iteration = 0 + + hardware_version._obj.firmware_build = 1 + hardware_version._obj.firmware_signature = 1 + + status = k4a.EStatus.SUCCEEDED + return status + +# Mock function for getting device info. +def mock_k4a_get_device_info(device_handle, device_info)->k4a.EStatus: + + status = k4a.EStatus.FAILED + temp_device_info = k4a.DeviceInfo() + + if not isinstance(device_info._obj, k4a.DeviceInfo): + return status + + if device_info._obj.struct_size != temp_device_info.struct_size: + return status + + if device_info._obj.struct_version != temp_device_info.struct_version: + return status + + device_info._obj.struct_size = temp_device_info.struct_size + device_info._obj.struct_version = temp_device_info.struct_version + device_info._obj.vendor_id = 0x045E + device_info._obj.device_id = 0x097C + device_info._obj.capabilities.value = ( + k4a.EDeviceCapabilities.DEPTH | + k4a.EDeviceCapabilities.COLOR | + k4a.EDeviceCapabilities.IMU | + k4a.EDeviceCapabilities.MICROPHONE + ) + + status = k4a.EStatus.SUCCEEDED + return status + +# Mock function for starting cameras. +def mock_k4a_start_cameras(device_handle, device_config)->k4a.EStatus: + + status = k4a.EStatus.SUCCEEDED + + if not isinstance(device_config._obj, k4a.DeviceConfiguration): + status = k4a.EStatus.FAILED + + if device_config._obj.color_format != k4a.EImageFormat.COLOR_BGRA32: + status = k4a.EStatus.FAILED + + if device_config._obj.color_mode_id != 1: + status = k4a.EStatus.FAILED + + if device_config._obj.depth_mode_id != 1: + status = k4a.EStatus.FAILED + + if device_config._obj.fps_mode_id != 15: + status = k4a.EStatus.FAILED + + return status + +# Mock function for getting device serial number +def mock_k4a_get_serialnum(device_handle, buffer, buffer_size)->k4a.EStatus: + + status = k4a.EStatus.FAILED + + if not isinstance(buffer, ctypes.c_char * 32): + return status + + if not isinstance(buffer_size._obj, ctypes.c_ulonglong): + return status + + if buffer_size._obj.value != 32: + return status + + serial_number = "0123-4567890" + buffer.value = bytes(serial_number, "utf-8") + buffer_size._obj.value = len(serial_number) + + status = k4a.EStatus.SUCCEEDED + return status + +# Mock function for getting mode count +def mock_k4a_get_mode_count(device_handle, mode_count)->k4a.EStatus: + + status = k4a.EStatus.FAILED + + if not isinstance(mode_count._obj, ctypes.c_long): + return status + + mode_count._obj.value = 2 + + status = k4a.EStatus.SUCCEEDED + return status + +# Mock function for getting color mode. +def mock_k4a_get_color_mode(device_handle, mode_index, color_mode)->k4a.EStatus: + + status = k4a.EStatus.FAILED + + if not isinstance(mode_index, int): + return status + + if mode_index < 0 or mode_index >= 2: + return status + + if not isinstance(color_mode._obj, k4a.ColorModeInfo): + return status + + if color_mode._obj.struct_size != 40: + return status + + if color_mode._obj.struct_version != k4a.K4A_ABI_VERSION: + return status + + color_mode._obj._struct_size = 40 + color_mode._obj.struct_version = k4a.K4A_ABI_VERSION + color_mode._obj.mode_id = 0 + color_mode._obj.width = 0 + color_mode._obj.height = 0 + color_mode._obj.native_format = k4a.EImageFormat.COLOR_MJPG + color_mode._obj.horizontal_fov = 0 + color_mode._obj.vertical_fov = 0 + color_mode._obj.min_fps = 0 + color_mode._obj.max_fps = 0 + + if mode_index == 1: + color_mode._obj.mode_id = 1 + color_mode._obj.width = 512 + color_mode._obj.height = 256 + color_mode._obj.native_format = k4a.EImageFormat.COLOR_MJPG + color_mode._obj.horizontal_fov = 120 + color_mode._obj.vertical_fov = 120 + color_mode._obj.min_fps = 5 + color_mode._obj.max_fps = 30 + + status = k4a.EStatus.SUCCEEDED + return status + +# Mock function for getting depth mode. +def mock_k4a_get_depth_mode(device_handle, mode_index, depth_mode)->k4a.EStatus: + + status = k4a.EStatus.FAILED + + if not isinstance(mode_index, int): + return status + + if mode_index < 0 or mode_index >= 2: + return status + + if not isinstance(depth_mode._obj, k4a.DepthModeInfo): + return status + + if depth_mode._obj.struct_size != 52: + return status + + if depth_mode._obj.struct_version != k4a.K4A_ABI_VERSION: + return status + + depth_mode._obj._struct_size = 52 + depth_mode._obj.struct_version = k4a.K4A_ABI_VERSION + depth_mode._obj.mode_id = 0 + depth_mode._obj.width = 0 + depth_mode._obj.height = 0 + depth_mode._obj.passive_ir_only = False + depth_mode._obj.native_format = k4a.EImageFormat.DEPTH16 + depth_mode._obj.horizontal_fov = 0 + depth_mode._obj.vertical_fov = 0 + depth_mode._obj.min_fps = 0 + depth_mode._obj.max_fps = 0 + depth_mode._obj.min_range = 0 + depth_mode._obj.max_range = 0 + + if mode_index == 1: + depth_mode._obj.mode_id = 1 + depth_mode._obj.width = 512 + depth_mode._obj.height = 256 + depth_mode._obj.passive_ir_only = False + depth_mode._obj.native_format = k4a.EImageFormat.DEPTH16 + depth_mode._obj.horizontal_fov = 120 + depth_mode._obj.vertical_fov = 120 + depth_mode._obj.min_fps = 5 + depth_mode._obj.max_fps = 30 + depth_mode._obj.min_range = 100 + depth_mode._obj.max_range = 1500 + + status = k4a.EStatus.SUCCEEDED + return status + +# Mock function for getting fps mode. +def mock_k4a_get_fps_mode(device_handle, mode_index, fps_mode)->k4a.EStatus: + + status = k4a.EStatus.FAILED + + if not isinstance(mode_index, int): + return status + + if mode_index < 0 or mode_index >= 2: + return status + + if not isinstance(fps_mode._obj, k4a.FPSModeInfo): + return status + + if fps_mode._obj.struct_size != 16: + return status + + if fps_mode._obj.struct_version != k4a.K4A_ABI_VERSION: + return status + + fps_mode._obj._struct_size = 16 + fps_mode._obj.struct_version = k4a.K4A_ABI_VERSION + fps_mode._obj.mode_id = 0 + fps_mode._obj.fps = 0 + + if mode_index == 1: + fps_mode._obj.mode_id = 15 + fps_mode._obj.fps = 15 + + status = k4a.EStatus.SUCCEEDED + return status + +# Mock function for getting capture. +def mock_k4a_device_get_capture(device_handle, capture_handle, timeout_in_ms): + + status = k4a.EWaitStatus.FAILED + + if not isinstance(device_handle, k4a._bindings.k4atypes._DeviceHandle): + return status + + if not isinstance(capture_handle._obj, k4a._bindings.k4atypes._CaptureHandle): + return status + + if not isinstance(timeout_in_ms, ctypes.c_long): + return status + + if device_handle not in opened_device_handles: + return status + + status = k4a.EWaitStatus.SUCCEEDED + return status + +# Mock function for getting imu sample. +def mock_k4a_device_get_imu_sample(device_handle, imu_sample, timeout_in_ms): + + status = k4a.EWaitStatus.FAILED + + if not isinstance(device_handle, k4a._bindings.k4atypes._DeviceHandle): + return status + + if not isinstance(imu_sample._obj, k4a._bindings.k4atypes.ImuSample): + return status + + if not isinstance(timeout_in_ms, ctypes.c_long): + return status + + if device_handle not in opened_device_handles: + return status + + imu_sample._obj.temperature = 1.2 + imu_sample._obj.acc_sample.xyz.x = 1 + imu_sample._obj.acc_sample.xyz.y = 2 + imu_sample._obj.acc_sample.xyz.z = 3 + imu_sample._obj.acc_timestamp_usec = 1 + imu_sample._obj.gyro_sample.xyz.x = 4 + imu_sample._obj.gyro_sample.xyz.y = 5 + imu_sample._obj.gyro_sample.xyz.z = 6 + imu_sample._obj.gyro_timestamp_usec = 2 + + status = k4a.EWaitStatus.SUCCEEDED + return status + +# Mock function for getting color control capabilities. +def mock_k4a_device_get_color_control_capabilities(device_handle, command, supports_auto, + min_value, max_value, step_value, default_value, default_mode): + + status = k4a.EStatus.FAILED + + if not isinstance(device_handle, k4a._bindings.k4atypes._DeviceHandle): + return status + + if not isinstance(command, ctypes.c_long): + return status + + if not isinstance(supports_auto._obj, ctypes.c_bool): + return status + + if not isinstance(min_value._obj, ctypes.c_long): + return status + + if not isinstance(max_value._obj, ctypes.c_long): + return status + + if not isinstance(step_value._obj, ctypes.c_long): + return status + + if not isinstance(default_value._obj, ctypes.c_long): + return status + + if not isinstance(default_mode._obj, ctypes.c_long): + return status + + if command.value >= len(k4a.EColorControlCommand): + return status + + # Write values just so they do not remain zeros. + supports_auto._obj.value = True + min_value._obj.value = 100 + max_value._obj.value = 9999 + step_value._obj.value = 1 + default_value._obj.value = 700 + default_mode._obj.value = k4a.EColorControlMode.MANUAL + + status = k4a.EStatus.SUCCEEDED + return status + +# Mock function for getting color control. +def mock_k4a_device_get_color_control(device_handle, command, mode, value): + + status = k4a.EStatus.FAILED + + if not isinstance(device_handle, k4a._bindings.k4atypes._DeviceHandle): + return status + + if not isinstance(command, ctypes.c_long): + return status + + if not isinstance(mode._obj, ctypes.c_long): + return status + + if not isinstance(value._obj, ctypes.c_long): + return status + + if command.value >= len(k4a.EColorControlCommand): + return status + + mode._obj.value = k4a.EColorControlMode.MANUAL + value._obj.value = 1000 + + status = k4a.EStatus.SUCCEEDED + return status + +# Mock function for setting color control. +def mock_k4a_device_set_color_control(device_handle, command, mode, value): + + status = k4a.EStatus.FAILED + + if not isinstance(device_handle, k4a._bindings.k4atypes._DeviceHandle): + return status + + if not isinstance(command, ctypes.c_long): + return status + + if not isinstance(mode, ctypes.c_long): + return status + + if not isinstance(value, ctypes.c_long): + return status + + if command.value >= len(k4a.EColorControlCommand): + return status + + # Just return success. + status = k4a.EStatus.SUCCEEDED + return status + +# Mock function for setting color control. +def mock_k4a_device_get_sync_jack(device_handle, sync_in, sync_out): + + status = k4a.EStatus.FAILED + + if not isinstance(device_handle, k4a._bindings.k4atypes._DeviceHandle): + return status + + if not isinstance(sync_in._obj, ctypes.c_bool): + return status + + if not isinstance(sync_out._obj, ctypes.c_bool): + return status + + sync_in._obj.value = False + sync_out._obj.value = True + + # Just return success. + status = k4a.EStatus.SUCCEEDED + return status + +# Mock function for getting raw calibration. +def mock_k4a_device_get_raw_calibration(device_handle, buffer, buffer_size_bytes): + + status = k4a.EStatus.FAILED + + if not isinstance(device_handle, k4a._bindings.k4atypes._DeviceHandle): + return status + + if not isinstance(buffer_size_bytes._obj, ctypes.c_ulonglong): + return status + + if buffer_size_bytes._obj.value < 1024*1024: + buffer_size_bytes._obj.value = 1024*1024 + status = k4a.EBufferStatus.BUFFER_TOO_SMALL + else: + # Just return success. + status = k4a.EBufferStatus.SUCCEEDED + + return status + +# Mock function for getting raw calibration. +def mock_k4a_device_get_calibration(device_handle, depth_mode_id, color_mode_id, calibration): + + status = k4a.EStatus.FAILED + + if not isinstance(device_handle, k4a._bindings.k4atypes._DeviceHandle): + return status + + if not isinstance(depth_mode_id, int): + return status + + if not isinstance(color_mode_id, int): + return status + + if not isinstance(calibration._obj, k4a._bindings.k4atypes._Calibration): + return status + + # Just return success. + status = k4a.EBufferStatus.SUCCEEDED + return status \ No newline at end of file diff --git a/src/python/k4a/tests/test_config.py b/src/python/k4a/tests/test_config.py index 92062703e..deba420d4 100644 --- a/src/python/k4a/tests/test_config.py +++ b/src/python/k4a/tests/test_config.py @@ -15,37 +15,28 @@ # Save capture to reuse in tests since it takes a while to get a capture from the device. glb_capture = None glb_color_format = None -glb_color_resolution = None -glb_depth_mode = None +glb_color_mode_id = None +glb_depth_mode_id = None glb_lock = Lock() - - -# Use for logging callback. But it doesn't work right now... -def glb_print_message(context:ctypes.c_void_p, - level:k4a.ELogLevel, - src_file:ctypes.POINTER(ctypes.c_char), - src_line:ctypes.c_int, - message:ctypes.POINTER(ctypes.c_char)): - print(str(level) + " in " + str(src_file) + " at line " + str(src_line) + ": " + str(message)) # Used to get a capture from device, or a previously-captured capture. def get_capture(device_handle:k4a._bindings.k4atypes._DeviceHandle, color_format:k4a.EImageFormat, - color_resolution:k4a.EColorResolution, - depth_mode:k4a.EDepthMode)->k4a._bindings.k4atypes._CaptureHandle: + color_mode_id:int, + depth_mode_id:int)->k4a._bindings.k4atypes._CaptureHandle: global glb_capture global glb_color_format - global glb_color_resolution - global glb_depth_mode + global glb_color_mode_id + global glb_depth_mode_id capture = glb_capture if (capture is None or glb_color_format != color_format or - glb_color_resolution != color_resolution or - glb_depth_mode != depth_mode): + glb_color_mode_id != color_mode_id or + glb_depth_mode_id != depth_mode_id): # Release any previous captures. if (capture is not None): @@ -55,9 +46,9 @@ def get_capture(device_handle:k4a._bindings.k4atypes._DeviceHandle, # Start the cameras. device_config = k4a.DeviceConfiguration() device_config.color_format = color_format - device_config.color_resolution = color_resolution - device_config.depth_mode = depth_mode - device_config.camera_fps = k4a.EFramesPerSecond.FPS_15 + device_config.color_mode_id = color_mode_id + device_config.depth_mode_id = depth_mode_id + device_config.fps_mode_id = 15 # FPS_15 device_config.synchronized_images_only = True device_config.depth_delay_off_color_usec = 0 device_config.wired_sync_mode = k4a.EWiredSyncMode.STANDALONE @@ -81,7 +72,7 @@ def get_capture(device_handle:k4a._bindings.k4atypes._DeviceHandle, glb_capture = capture glb_color_format = color_format - glb_color_resolution = color_resolution - glb_depth_mode = depth_mode + glb_color_mode_id = color_mode_id + glb_depth_mode_id = depth_mode_id - return capture \ No newline at end of file + return capture diff --git a/src/python/k4a/tests/test_functional_api_azurekinect.py b/src/python/k4a/tests/test_functional_api_azurekinect.py index bad9a7e1a..c8010aa47 100644 --- a/src/python/k4a/tests/test_functional_api_azurekinect.py +++ b/src/python/k4a/tests/test_functional_api_azurekinect.py @@ -8,7 +8,7 @@ import unittest import copy -from time import sleep +import ctypes import numpy as np @@ -16,6 +16,32 @@ import test_config +class LogContext: + call_count = 0 + + def get_call_count(self): + retValue = self.call_count + self.call_count = self.call_count + 1 + return retValue + +# Global context. +context = LogContext() + + +# Define a callback function for logging. +@k4a.logging_message_cb +def logging_callback(context_local, loglevel:k4a.ELogLevel, src_filename:str, src_line:int, message:str): + + formattedStr = str() + + # Convert py_object to LogContext. + if context_local is not None: + formattedStr += str(context_local.get_call_count()) + " " + + formattedStr += str(k4a.ELogLevel(loglevel)) + " in " + str(src_filename, 'UTF-8') + " at line " + str(src_line) + ": " + str(message, 'UTF-8') + print(formattedStr) + + def k4a_device_set_and_get_color_control( device:k4a.Device, color_control_command:k4a.EColorControlCommand): @@ -23,11 +49,12 @@ def k4a_device_set_and_get_color_control( saved_value = 0 # Get the step size. - supports_auto = device.color_ctrl_cap.__dict__[color_control_command].supports_auto - min_value = device.color_ctrl_cap.__dict__[color_control_command].min_value - max_value = device.color_ctrl_cap.__dict__[color_control_command].max_value - step_value = device.color_ctrl_cap.__dict__[color_control_command].step_value - default_value = device.color_ctrl_cap.__dict__[color_control_command].default_value + cap_list, cap_dict = device.get_color_control_capabilities() + supports_auto = cap_dict[color_control_command].supports_auto + min_value = cap_dict[color_control_command].min_value + max_value = cap_dict[color_control_command].max_value + step_value = cap_dict[color_control_command].step_value + default_value = cap_dict[color_control_command].default_value mode = k4a.EColorControlMode.MANUAL # Read the original value. @@ -60,7 +87,7 @@ def k4a_device_set_and_get_color_control( return (status1, status2, saved_value, saved_value_readback, new_value, new_value_readback) -class Test_Functional_API_Device_AzureKinect(unittest.TestCase): +class Test_Functional_Fast_API_Device_AzureKinect(unittest.TestCase): '''Test Device class for Azure Kinect device. ''' @@ -80,6 +107,30 @@ def tearDownClass(cls): cls.device.close() del cls.device + def test_functional_logging_nocontext(self): + # Pass the callback function to set_logger_callback. + status = k4a.set_logging_callback(logging_callback, None, k4a.ELogLevel.INFO) + self.assertEqual(status, k4a.EStatus.SUCCEEDED) + + # Force a log message to call the python callback function. Starting IMU without starting cameras + # should log an error message. + # But cannot really automate this test except to debug this test and set a breakpoint in the callback function. + bytearray = self.device.get_raw_calibration() + self.assertIsNotNone(bytearray) + + def test_functional_logging_withcontext(self): + global context + + # Pass the callback function to set_logger_callback. + status = k4a.set_logging_callback(logging_callback, context, k4a.ELogLevel.INFO) + self.assertEqual(status, k4a.EStatus.SUCCEEDED) + + # Force a log message to call the python callback function. Starting IMU without starting cameras + # should log an error message. + # But cannot really automate this test except to debug this test and set a breakpoint in the callback function. + bytearray = self.device.get_raw_calibration() + self.assertIsNotNone(bytearray) + def test_functional_fast_api_open_twice_expected_fail(self): device2 = k4a.Device.open() self.assertIsNone(device2) @@ -99,22 +150,91 @@ def test_functional_fast_api_get_serial_number(self): serial_number = self.device.serial_number self.assertIsInstance(serial_number, str) self.assertGreater(len(serial_number), 0) + + def test_functional_fast_api_get_device_info_property(self): + device_info = self.device.device_info + self.assertIsNotNone(device_info) + self.assertIsInstance(device_info, k4a.DeviceInfo) + self.assertNotEqual(device_info.struct_size, 0) + self.assertNotEqual(device_info.struct_version, 0) + self.assertNotEqual(device_info.vendor_id, 0) + self.assertNotEqual(device_info.capabilities.value, 0) + + def test_functional_fast_api_get_device_info(self): + device_info = self.device.device_info + self.assertIsNotNone(device_info) + self.assertIsInstance(device_info, k4a.DeviceInfo) + self.assertNotEqual(device_info.struct_size, 0) + self.assertNotEqual(device_info.struct_version, 0) + self.assertNotEqual(device_info.vendor_id, 0) + self.assertNotEqual(device_info.capabilities.value, 0) + + def test_functional_fast_api_get_depth_modes(self): + depth_modes = self.device.get_depth_modes() + self.assertIsNotNone(depth_modes) + self.assertIsInstance(depth_modes, list) + self.assertNotEqual(len(depth_modes), 0) - # Helper method for test_set_serial_number(). - @staticmethod - def set_serial_number(device:k4a.Device, serial_number:str): - device.serial_number = serial_number - - def test_functional_fast_api_set_serial_number(self): - self.assertRaises(AttributeError, - Test_Functional_API_Device_AzureKinect.set_serial_number, - self.device, "not settable") + for depth_mode in depth_modes: + self.assertIsInstance(depth_mode, k4a.DepthModeInfo) + self.assertNotEqual(depth_mode.struct_size, 0) + self.assertNotEqual(depth_mode.struct_version, 0) + + if depth_mode.mode_id != 0: + self.assertGreater(depth_mode.width, 0) + self.assertGreater(depth_mode.height, 0) + self.assertGreaterEqual(depth_mode.horizontal_fov, 0.0) + self.assertLessEqual(depth_mode.horizontal_fov, 360.0) + self.assertGreaterEqual(depth_mode.vertical_fov, 0.0) + self.assertLessEqual(depth_mode.vertical_fov, 360.0) + self.assertGreaterEqual(depth_mode.min_range, 0.0) + + def test_functional_fast_api_get_color_modes(self): + color_modes = self.device.get_color_modes() + self.assertIsNotNone(color_modes) + self.assertIsInstance(color_modes, list) + self.assertNotEqual(len(color_modes), 0) + + for color_mode in color_modes: + self.assertIsInstance(color_mode, k4a.ColorModeInfo) + self.assertNotEqual(color_mode.struct_size, 0) + self.assertNotEqual(color_mode.struct_version, 0) + + if color_mode.mode_id != 0: + self.assertGreater(color_mode.width, 0) + self.assertGreater(color_mode.height, 0) + self.assertGreaterEqual(color_mode.horizontal_fov, 0.0) + self.assertLessEqual(color_mode.horizontal_fov, 360.0) + self.assertGreaterEqual(color_mode.vertical_fov, 0.0) + self.assertLessEqual(color_mode.vertical_fov, 360.0) + + def test_functional_fast_api_get_fps_modes(self): + fps_modes = self.device.get_fps_modes() + self.assertIsNotNone(fps_modes) + self.assertIsInstance(fps_modes, list) + self.assertNotEqual(len(fps_modes), 0) + + for fps_mode in fps_modes: + self.assertIsInstance(fps_mode, k4a.FPSModeInfo) + self.assertNotEqual(fps_mode.struct_size, 0) + self.assertNotEqual(fps_mode.struct_version, 0) + self.assertGreaterEqual(fps_mode.fps, 0) def test_functional_fast_api_get_capture(self): # Start the cameras. - status = self.device.start_cameras( - k4a.DEVICE_CONFIG_BGRA32_2160P_WFOV_UNBINNED_FPS15) + device_config = k4a.DeviceConfiguration( + color_format=k4a.EImageFormat.COLOR_BGRA32, + color_mode_id=5, # 2160P + depth_mode_id=4, # WFOV_UNBINNED + fps_mode_id=15, # FPS_15 + synchronized_images_only=True, + depth_delay_off_color_usec=0, + wired_sync_mode=k4a.EWiredSyncMode.STANDALONE, + subordinate_delay_off_master_usec=0, + disable_streaming_indicator=False) + + status = self.device.start_cameras(device_config) self.assertEqual(status, k4a.EStatus.SUCCEEDED) # Get a capture, waiting indefinitely. @@ -127,8 +247,18 @@ def test_functional_fast_api_get_capture(self): def test_functional_fast_api_get_imu_sample(self): # Start the cameras. - status = self.device.start_cameras( - k4a.DEVICE_CONFIG_BGRA32_2160P_WFOV_UNBINNED_FPS15) + device_config = k4a.DeviceConfiguration( + color_format=k4a.EImageFormat.COLOR_BGRA32, + color_mode_id=5, # 2160P + depth_mode_id=4, # WFOV_UNBINNED + fps_mode_id=15, # FPS_15 + synchronized_images_only=True, + depth_delay_off_color_usec=0, + wired_sync_mode=k4a.EWiredSyncMode.STANDALONE, + subordinate_delay_off_master_usec=0, + disable_streaming_indicator=False) + + status = self.device.start_cameras(device_config) self.assertEqual(status, k4a.EStatus.SUCCEEDED) # Start the imu. @@ -154,25 +284,52 @@ def test_functional_fast_api_get_hardware_version(self): self.assertNotEqual(str(hardware_version), 0) def test_functional_fast_api_get_color_ctrl_cap(self): - color_ctrl_cap = self.device.color_ctrl_cap - self.assertNotEqual(str(color_ctrl_cap), 0) + color_ctrl_caps, color_ctrl_caps_dict = self.device.get_color_control_capabilities() + self.assertIsInstance(color_ctrl_caps, list) + self.assertIsInstance(color_ctrl_caps_dict, dict) + + for cap in color_ctrl_caps: + self.assertIsInstance(cap, k4a.ColorControlCapability) + self.assertNotEqual(str(cap), 0) - def test_functional_fast_api_get_sync_out_connected(self): - sync_out_connected = self.device.sync_out_connected - self.assertIsInstance(sync_out_connected, bool) + for entry in color_ctrl_caps_dict: + self.assertIsInstance(color_ctrl_caps_dict[entry], k4a.ColorControlCapability) - def test_functional_fast_api_get_sync_in_connected(self): - sync_in_connected = self.device.sync_in_connected - self.assertIsInstance(sync_in_connected, bool) + def test_functional_fast_api_get_sync_jack_connected(self): + (sync_in, sync_out) = self.device.get_sync_jack() + self.assertIsInstance(sync_in, bool) + self.assertIsInstance(sync_out, bool) def test_functional_fast_api_start_stop_cameras(self): - status = self.device.start_cameras(k4a.DEVICE_CONFIG_BGRA32_2160P_WFOV_UNBINNED_FPS15) + device_config = k4a.DeviceConfiguration( + color_format=k4a.EImageFormat.COLOR_BGRA32, + color_mode_id=5, # 2160P + depth_mode_id=4, # WFOV_UNBINNED + fps_mode_id=15, # FPS_15 + synchronized_images_only=True, + depth_delay_off_color_usec=0, + wired_sync_mode=k4a.EWiredSyncMode.STANDALONE, + subordinate_delay_off_master_usec=0, + disable_streaming_indicator=False) + + status = self.device.start_cameras(device_config) self.assertEqual(status, k4a.EStatus.SUCCEEDED) self.device.stop_cameras() def test_functional_fast_api_start_stop_imu(self): - status = self.device.start_cameras(k4a.DEVICE_CONFIG_BGRA32_2160P_WFOV_UNBINNED_FPS15) + device_config = k4a.DeviceConfiguration( + color_format=k4a.EImageFormat.COLOR_BGRA32, + color_mode_id=5, # 2160P + depth_mode_id=4, # WFOV_UNBINNED + fps_mode_id=15, # FPS_15 + synchronized_images_only=True, + depth_delay_off_color_usec=0, + wired_sync_mode=k4a.EWiredSyncMode.STANDALONE, + subordinate_delay_off_master_usec=0, + disable_streaming_indicator=False) + + status = self.device.start_cameras(device_config) self.assertEqual(status, k4a.EStatus.SUCCEEDED) status = self.device.start_imu() @@ -233,38 +390,23 @@ def test_functional_fast_api_get_raw_calibration(self): def test_functional_fast_api_get_calibration(self): - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - k4a.EDepthMode.PASSIVE_IR, - ] - - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] - - for depth_mode in depth_modes: - for color_resolution in color_resolutions: + depth_mode_ids = range(1, 6) + color_mode_ids = range(1, 7) + for depth_mode_id in depth_mode_ids: + for color_mode_id in color_mode_ids: with self.subTest( - depth_mode = depth_mode, - color_resolution = color_resolution): + depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id): calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) self.assertIsNotNone(calibration) self.assertIsInstance(calibration, k4a.Calibration) -class Test_Functional_API_Capture_AzureKinect(unittest.TestCase): +class Test_Functional_Fast_API_Capture_AzureKinect(unittest.TestCase): '''Test Capture class for Azure Kinect device. ''' @@ -285,8 +427,18 @@ def tearDownClass(cls): del cls.device def setUp(self): - status = self.device.start_cameras( - k4a.DEVICE_CONFIG_BGRA32_2160P_WFOV_UNBINNED_FPS15) + device_config = k4a.DeviceConfiguration( + color_format=k4a.EImageFormat.COLOR_BGRA32, + color_mode_id=5, # 2160P + depth_mode_id=4, # WFOV_UNBINNED + fps_mode_id=15, # FPS_15 + synchronized_images_only=True, + depth_delay_off_color_usec=0, + wired_sync_mode=k4a.EWiredSyncMode.STANDALONE, + subordinate_delay_off_master_usec=0, + disable_streaming_indicator=False) + + status = self.device.start_cameras(device_config) self.assertEqual(status, k4a.EStatus.SUCCEEDED) self.capture = self.device.get_capture(-1) @@ -484,7 +636,7 @@ def test_functional_fast_api_set_ir(self): self.assertIs(ir3, ir2) -class Test_Functional_API_Image_AzureKinect(unittest.TestCase): +class Test_Functional_Fast_API_Image_AzureKinect(unittest.TestCase): '''Test Image class for Azure Kinect device. ''' @@ -505,8 +657,18 @@ def tearDownClass(cls): del cls.device def setUp(self): - status = self.device.start_cameras( - k4a.DEVICE_CONFIG_BGRA32_2160P_WFOV_UNBINNED_FPS15) + device_config = k4a.DeviceConfiguration( + color_format=k4a.EImageFormat.COLOR_BGRA32, + color_mode_id=5, # 2160P + depth_mode_id=4, # WFOV_UNBINNED + fps_mode_id=15, # FPS_15 + synchronized_images_only=True, + depth_delay_off_color_usec=0, + wired_sync_mode=k4a.EWiredSyncMode.STANDALONE, + subordinate_delay_off_master_usec=0, + disable_streaming_indicator=False) + + status = self.device.start_cameras(device_config) self.assertEqual(status, k4a.EStatus.SUCCEEDED) self.capture = self.device.get_capture(-1) @@ -710,7 +872,7 @@ def test_functional_fast_api_set_iso_speed(self): self.assertEqual(iso_speed, 100) -class Test_Functional_API_Calibration_AzureKinect(unittest.TestCase): +class Test_Functional_Fast_API_Calibration_AzureKinect(unittest.TestCase): '''Test Calibration class for Azure Kinect device. ''' @@ -732,32 +894,17 @@ def tearDownClass(cls): def test_functional_fast_api_get_calibration_from_device(self): - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - k4a.EDepthMode.PASSIVE_IR, - ] - - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] - - for depth_mode in depth_modes: - for color_resolution in color_resolutions: + depth_mode_ids = range(1, 6) + color_mode_ids = range(1, 7) + for depth_mode_id in depth_mode_ids: + for color_mode_id in color_mode_ids: with self.subTest( - depth_mode = depth_mode, - color_resolution = color_resolution): + depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id): calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) self.assertIsNotNone(calibration) self.assertIsInstance(calibration, k4a.Calibration) @@ -765,64 +912,28 @@ def test_functional_fast_api_get_calibration_from_raw(self): raw_calibration = self.device.get_raw_calibration() self.assertIsNotNone(raw_calibration) - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - k4a.EDepthMode.PASSIVE_IR, - ] - - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] + depth_mode_ids = range(1, 6) + color_mode_ids = range(1, 7) - for depth_mode in depth_modes: - for color_resolution in color_resolutions: + for depth_mode_id in depth_mode_ids: + for color_mode_id in color_mode_ids: with self.subTest( - depth_mode = depth_mode, - color_resolution = color_resolution): + depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id): calibration = k4a.Calibration.create_from_raw( raw_calibration, - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) self.assertIsNotNone(calibration) self.assertIsInstance(calibration, k4a.Calibration) -class Test_Functional_API_Transformation_AzureKinect(unittest.TestCase): +class Test_Functional_Fast_API_Transformation_AzureKinect(unittest.TestCase): '''Test Transformation class for Azure Kinect device. ''' - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - k4a.EDepthMode.PASSIVE_IR, - ] - - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] - - calibration_types = [ - k4a.ECalibrationType.COLOR, - k4a.ECalibrationType.DEPTH - ] - @classmethod def setUpClass(cls): cls.device = k4a.Device.open() @@ -831,8 +942,8 @@ def setUpClass(cls): cls.lock = test_config.glb_lock cls.calibration = cls.device.get_calibration( - k4a.EDepthMode.WFOV_UNBINNED, - k4a.EColorResolution.RES_2160P) + 4, # WFOV_UNBINNED + 5) # 2160P @classmethod def tearDownClass(cls): @@ -846,15 +957,15 @@ def tearDownClass(cls): def test_functional_fast_api_point_3d_to_point_3d(self): - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P source_camera = k4a.ECalibrationType.COLOR target_camera = k4a.ECalibrationType.DEPTH # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -871,15 +982,15 @@ def test_functional_fast_api_point_3d_to_point_3d(self): def test_functional_fast_api_pixel_2d_to_point_3d(self): - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P source_camera = k4a.ECalibrationType.COLOR target_camera = k4a.ECalibrationType.DEPTH # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -897,15 +1008,15 @@ def test_functional_fast_api_pixel_2d_to_point_3d(self): def test_functional_fast_api_point_3d_to_pixel_2d(self): - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P source_camera = k4a.ECalibrationType.COLOR target_camera = k4a.ECalibrationType.DEPTH # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -921,15 +1032,15 @@ def test_functional_fast_api_point_3d_to_pixel_2d(self): def test_functional_fast_api_pixel_2d_to_pixel_2d(self): - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P source_camera = k4a.ECalibrationType.COLOR target_camera = k4a.ECalibrationType.DEPTH # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -946,17 +1057,17 @@ def test_functional_fast_api_pixel_2d_to_pixel_2d(self): def test_functional_fast_api_color_2d_to_depth_2d(self): - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P source_camera = k4a.ECalibrationType.COLOR target_camera = k4a.ECalibrationType.DEPTH # Get a depth image. device_config = k4a.DeviceConfiguration( color_format = k4a.EImageFormat.COLOR_BGRA32, - color_resolution = color_resolution, - depth_mode = depth_mode, - camera_fps = k4a.EFramesPerSecond.FPS_15, + color_mode_id = color_mode_id, + depth_mode_id = depth_mode_id, + fps_mode_id = 15, # FPS_15 synchronized_images_only = True, depth_delay_off_color_usec = 0, wired_sync_mode = k4a.EWiredSyncMode.STANDALONE, @@ -969,8 +1080,8 @@ def test_functional_fast_api_color_2d_to_depth_2d(self): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -985,15 +1096,15 @@ def test_functional_fast_api_color_2d_to_depth_2d(self): def test_functional_fast_api_depth_image_to_color_camera(self): - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P # Get a depth image. device_config = k4a.DeviceConfiguration( color_format = k4a.EImageFormat.COLOR_BGRA32, - color_resolution = color_resolution, - depth_mode = depth_mode, - camera_fps = k4a.EFramesPerSecond.FPS_15, + color_mode_id = color_mode_id, + depth_mode_id = depth_mode_id, + fps_mode_id = 15, # FPS_15 synchronized_images_only = True, depth_delay_off_color_usec = 0, wired_sync_mode = k4a.EWiredSyncMode.STANDALONE, @@ -1008,8 +1119,8 @@ def test_functional_fast_api_depth_image_to_color_camera(self): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -1021,15 +1132,15 @@ def test_functional_fast_api_depth_image_to_color_camera(self): def test_functional_fast_api_depth_image_to_color_camera_custom(self): - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P # Get a depth image. device_config = k4a.DeviceConfiguration( color_format = k4a.EImageFormat.COLOR_BGRA32, - color_resolution = color_resolution, - depth_mode = depth_mode, - camera_fps = k4a.EFramesPerSecond.FPS_15, + color_mode_id = color_mode_id, + depth_mode_id = depth_mode_id, + fps_mode_id = 15, # FPS_15 synchronized_images_only = True, depth_delay_off_color_usec = 0, wired_sync_mode = k4a.EWiredSyncMode.STANDALONE, @@ -1051,8 +1162,8 @@ def test_functional_fast_api_depth_image_to_color_camera_custom(self): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -1070,15 +1181,15 @@ def test_functional_fast_api_depth_image_to_color_camera_custom(self): def test_functional_fast_api_color_image_to_depth_camera(self): - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P # Get a depth and color image. device_config = k4a.DeviceConfiguration( color_format = k4a.EImageFormat.COLOR_BGRA32, - color_resolution = color_resolution, - depth_mode = depth_mode, - camera_fps = k4a.EFramesPerSecond.FPS_15, + color_mode_id = color_mode_id, + depth_mode_id = depth_mode_id, + fps_mode_id = 15, # FPS_15 synchronized_images_only = True, depth_delay_off_color_usec = 0, wired_sync_mode = k4a.EWiredSyncMode.STANDALONE, @@ -1093,8 +1204,8 @@ def test_functional_fast_api_color_image_to_depth_camera(self): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -1108,15 +1219,15 @@ def test_functional_fast_api_color_image_to_depth_camera(self): def test_functional_fast_api_depth_image_to_point_cloud(self): - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P # Get a depth image. device_config = k4a.DeviceConfiguration( color_format = k4a.EImageFormat.COLOR_BGRA32, - color_resolution = color_resolution, - depth_mode = depth_mode, - camera_fps = k4a.EFramesPerSecond.FPS_15, + color_mode_id = color_mode_id, + depth_mode_id = depth_mode_id, + fps_mode_id = 15, # FPS_15 synchronized_images_only = True, depth_delay_off_color_usec = 0, wired_sync_mode = k4a.EWiredSyncMode.STANDALONE, @@ -1131,8 +1242,8 @@ def test_functional_fast_api_depth_image_to_point_cloud(self): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -1149,21 +1260,53 @@ def test_functional_fast_api_depth_image_to_point_cloud(self): # It is not recommended to run them frequently. # +class Test_Functional_API_Transformation_AzureKinect(unittest.TestCase): + '''Test Transformation class for Azure Kinect device. + ''' + + depth_mode_ids = range(1, 6) + color_mode_ids = range(1, 7) + calibration_types = [ + k4a.ECalibrationType.COLOR, + k4a.ECalibrationType.DEPTH + ] + + @classmethod + def setUpClass(cls): + cls.device = k4a.Device.open() + assert(cls.device is not None) + + cls.lock = test_config.glb_lock + + cls.calibration = cls.device.get_calibration( + 4, # WFOV_UNBINNED + 5) # 2160P + + @classmethod + def tearDownClass(cls): + + # Stop the cameras and imus before closing device. + cls.device.stop_cameras() + cls.device.stop_imu() + cls.device.close() + del cls.device + del cls.calibration + def test_functional_api_point_3d_to_point_3d(self): - for depth_mode in Test_Transformation_AzureKinect.depth_modes: - for color_resolution in Test_Transformation_AzureKinect.color_resolutions: - for source_camera in Test_Transformation_AzureKinect.calibration_types: - for target_camera in Test_Transformation_AzureKinect.calibration_types: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution, + for depth_mode_id in Test_Functional_API_Transformation_AzureKinect.depth_mode_ids: + for color_mode_id in Test_Functional_API_Transformation_AzureKinect.color_mode_ids: + for source_camera in Test_Functional_API_Transformation_AzureKinect.calibration_types: + for target_camera in Test_Functional_API_Transformation_AzureKinect.calibration_types: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id, source_camera = source_camera, target_camera = target_camera): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -1180,19 +1323,19 @@ def test_functional_api_point_3d_to_point_3d(self): def test_functional_api_pixel_2d_to_point_3d(self): - for depth_mode in Test_Transformation_AzureKinect.depth_modes: - for color_resolution in Test_Transformation_AzureKinect.color_resolutions: - for source_camera in Test_Transformation_AzureKinect.calibration_types: - for target_camera in Test_Transformation_AzureKinect.calibration_types: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution, + for depth_mode_id in Test_Functional_API_Transformation_AzureKinect.depth_mode_ids: + for color_mode_id in Test_Functional_API_Transformation_AzureKinect.color_mode_ids: + for source_camera in Test_Functional_API_Transformation_AzureKinect.calibration_types: + for target_camera in Test_Functional_API_Transformation_AzureKinect.calibration_types: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id, source_camera = source_camera, target_camera = target_camera): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -1210,19 +1353,19 @@ def test_functional_api_pixel_2d_to_point_3d(self): def test_functional_api_point_3d_to_pixel_2d(self): - for depth_mode in Test_Transformation_AzureKinect.depth_modes: - for color_resolution in Test_Transformation_AzureKinect.color_resolutions: - for source_camera in Test_Transformation_AzureKinect.calibration_types: - for target_camera in Test_Transformation_AzureKinect.calibration_types: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution, + for depth_mode_id in Test_Functional_API_Transformation_AzureKinect.depth_mode_ids: + for color_mode_id in Test_Functional_API_Transformation_AzureKinect.color_mode_ids: + for source_camera in Test_Functional_API_Transformation_AzureKinect.calibration_types: + for target_camera in Test_Functional_API_Transformation_AzureKinect.calibration_types: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id, source_camera = source_camera, target_camera = target_camera): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -1238,19 +1381,19 @@ def test_functional_api_point_3d_to_pixel_2d(self): def test_functional_api_pixel_2d_to_pixel_2d(self): - for depth_mode in Test_Transformation_AzureKinect.depth_modes: - for color_resolution in Test_Transformation_AzureKinect.color_resolutions: - for source_camera in Test_Transformation_AzureKinect.calibration_types: - for target_camera in Test_Transformation_AzureKinect.calibration_types: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution, + for depth_mode_id in Test_Functional_API_Transformation_AzureKinect.depth_mode_ids: + for color_mode_id in Test_Functional_API_Transformation_AzureKinect.color_mode_ids: + for source_camera in Test_Functional_API_Transformation_AzureKinect.calibration_types: + for target_camera in Test_Functional_API_Transformation_AzureKinect.calibration_types: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id, source_camera = source_camera, target_camera = target_camera): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -1267,21 +1410,21 @@ def test_functional_api_pixel_2d_to_pixel_2d(self): def test_functional_api_color_2d_to_depth_2d(self): - for depth_mode in Test_Transformation_AzureKinect.depth_modes[:4]: - for color_resolution in Test_Transformation_AzureKinect.color_resolutions: - for source_camera in Test_Transformation_AzureKinect.calibration_types: - for target_camera in Test_Transformation_AzureKinect.calibration_types: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution, + for depth_mode_id in Test_Functional_API_Transformation_AzureKinect.depth_mode_ids[:4]: + for color_mode_id in Test_Functional_API_Transformation_AzureKinect.color_mode_ids: + for source_camera in Test_Functional_API_Transformation_AzureKinect.calibration_types: + for target_camera in Test_Functional_API_Transformation_AzureKinect.calibration_types: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id, source_camera = source_camera, target_camera = target_camera): # Get a depth image. device_config = k4a.DeviceConfiguration( color_format = k4a.EImageFormat.COLOR_BGRA32, - color_resolution = color_resolution, - depth_mode = depth_mode, - camera_fps = k4a.EFramesPerSecond.FPS_15, + color_mode_id = color_mode_id, + depth_mode_id = depth_mode_id, + fps_mode_id = 15, synchronized_images_only = True, depth_delay_off_color_usec = 0, wired_sync_mode = k4a.EWiredSyncMode.STANDALONE, @@ -1294,8 +1437,8 @@ def test_functional_api_color_2d_to_depth_2d(self): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -1310,17 +1453,17 @@ def test_functional_api_color_2d_to_depth_2d(self): def test_functional_api_depth_image_to_color_camera(self): - for depth_mode in Test_Transformation_AzureKinect.depth_modes[:4]: - for color_resolution in Test_Transformation_AzureKinect.color_resolutions: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution): + for depth_mode_id in Test_Functional_API_Transformation_AzureKinect.depth_mode_ids[:4]: + for color_mode_id in Test_Functional_API_Transformation_AzureKinect.color_mode_ids: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id): # Get a depth image. device_config = k4a.DeviceConfiguration( color_format = k4a.EImageFormat.COLOR_BGRA32, - color_resolution = color_resolution, - depth_mode = depth_mode, - camera_fps = k4a.EFramesPerSecond.FPS_15, + color_mode_id = color_mode_id, + depth_mode_id = depth_mode_id, + fps_mode_id = 15, synchronized_images_only = True, depth_delay_off_color_usec = 0, wired_sync_mode = k4a.EWiredSyncMode.STANDALONE, @@ -1335,8 +1478,8 @@ def test_functional_api_depth_image_to_color_camera(self): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -1348,17 +1491,17 @@ def test_functional_api_depth_image_to_color_camera(self): def test_functional_api_depth_image_to_color_camera_custom(self): - for depth_mode in Test_Transformation_AzureKinect.depth_modes[:4]: - for color_resolution in Test_Transformation_AzureKinect.color_resolutions: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution): + for depth_mode_id in Test_Functional_API_Transformation_AzureKinect.depth_mode_ids[:4]: + for color_mode_id in Test_Functional_API_Transformation_AzureKinect.color_mode_ids: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id): # Get a depth image. device_config = k4a.DeviceConfiguration( color_format = k4a.EImageFormat.COLOR_BGRA32, - color_resolution = color_resolution, - depth_mode = depth_mode, - camera_fps = k4a.EFramesPerSecond.FPS_15, + color_mode_id = color_mode_id, + depth_mode_id = depth_mode_id, + fps_mode_id = 15, synchronized_images_only = True, depth_delay_off_color_usec = 0, wired_sync_mode = k4a.EWiredSyncMode.STANDALONE, @@ -1380,8 +1523,8 @@ def test_functional_api_depth_image_to_color_camera_custom(self): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -1399,17 +1542,17 @@ def test_functional_api_depth_image_to_color_camera_custom(self): def test_functional_api_color_image_to_depth_camera(self): - for depth_mode in Test_Transformation_AzureKinect.depth_modes[:4]: - for color_resolution in Test_Transformation_AzureKinect.color_resolutions: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution): + for depth_mode_id in Test_Functional_API_Transformation_AzureKinect.depth_mode_ids[:4]: + for color_mode_id in Test_Functional_API_Transformation_AzureKinect.color_mode_ids: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id): # Get a depth and color image. device_config = k4a.DeviceConfiguration( color_format = k4a.EImageFormat.COLOR_BGRA32, - color_resolution = color_resolution, - depth_mode = depth_mode, - camera_fps = k4a.EFramesPerSecond.FPS_15, + color_mode_id = color_mode_id, + depth_mode_id = depth_mode_id, + fps_mode_id = 15, synchronized_images_only = True, depth_delay_off_color_usec = 0, wired_sync_mode = k4a.EWiredSyncMode.STANDALONE, @@ -1424,8 +1567,8 @@ def test_functional_api_color_image_to_depth_camera(self): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) @@ -1439,17 +1582,17 @@ def test_functional_api_color_image_to_depth_camera(self): def test_functional_api_depth_image_to_point_cloud(self): - for depth_mode in Test_Transformation_AzureKinect.depth_modes[:4]: - for color_resolution in Test_Transformation_AzureKinect.color_resolutions: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution): + for depth_mode_id in Test_Functional_API_Transformation_AzureKinect.depth_mode_ids[:4]: + for color_mode_id in Test_Functional_API_Transformation_AzureKinect.color_mode_ids: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id): # Get a depth image. device_config = k4a.DeviceConfiguration( color_format = k4a.EImageFormat.COLOR_BGRA32, - color_resolution = color_resolution, - depth_mode = depth_mode, - camera_fps = k4a.EFramesPerSecond.FPS_15, + color_mode_id = color_mode_id, + depth_mode_id = depth_mode_id, + fps_mode_id = 15, synchronized_images_only = True, depth_delay_off_color_usec = 0, wired_sync_mode = k4a.EWiredSyncMode.STANDALONE, @@ -1464,8 +1607,8 @@ def test_functional_api_depth_image_to_point_cloud(self): # Get calibration. calibration = self.device.get_calibration( - depth_mode, - color_resolution) + depth_mode_id, + color_mode_id) # Create transformation. transformation = k4a.Transformation(calibration) diff --git a/src/python/k4a/tests/test_functional_ctypes_azurekinect.py b/src/python/k4a/tests/test_functional_ctypes_azurekinect.py index 79ce249ed..999e00d7e 100644 --- a/src/python/k4a/tests/test_functional_ctypes_azurekinect.py +++ b/src/python/k4a/tests/test_functional_ctypes_azurekinect.py @@ -8,17 +8,43 @@ import unittest import ctypes -from time import sleep import k4a import test_config +class LogContext: + call_count = 0 + + def get_call_count(self): + retValue = self.call_count + self.call_count = self.call_count + 1 + return retValue + +# Global context. +context = LogContext() + +@k4a._bindings.k4a._logging_message_cb +def logging_print_message(context_local, + level:ctypes.c_int, + src_file:ctypes.c_char_p, + src_line:ctypes.c_int, + message:ctypes.c_char_p): + formattedStr = str() + + # Convert c_void_p to LogContext. + if context_local is not None: + formattedStr += str(context_local.get_call_count()) + " " + + formattedStr += str(k4a.ELogLevel(level)) + " in " + str(src_file, 'UTF-8') + " at line " + str(src_line) + ": " + str(message, 'UTF-8') + print(formattedStr) + + def get_1080p_bgr32_nfov_2x2binned(device_handle): return test_config.get_capture(device_handle, k4a.EImageFormat.COLOR_BGRA32, - k4a.EColorResolution.RES_1080P, - k4a.EDepthMode.NFOV_2X2BINNED) + 2, # 1080P + 1) # NFOV_2X2BINNED def k4a_device_get_color_control_capability( @@ -120,7 +146,7 @@ def k4a_device_set_and_get_color_control( saved_value, saved_value_readback, new_value, new_value_readback) -class Test_Functional_Ctypes_AzureKinect(unittest.TestCase): +class Test_Functional_Fast_Ctypes_AzureKinect(unittest.TestCase): '''Test k4a functions requiring a device handle for Azure Kinect device. ''' @@ -156,25 +182,150 @@ def test_functional_fast_ctypes_device_get_installed_count(self): device_count = k4a._bindings.k4a.k4a_device_get_installed_count() self.assertGreater(device_count, 0) - @unittest.skip def test_functional_fast_ctypes_set_debug_message_handler_NULL_callback(self): - status = k4a._bindings.k4a_set_debug_message_handler( - ctypes.cast(ctypes.c_void_p(), ctypes.POINTER(k4a.logging_message_cb)), + status = k4a._bindings.k4a.k4a_set_debug_message_handler( + ctypes.cast(ctypes.c_void_p(), k4a._bindings.k4a._logging_message_cb), ctypes.c_void_p(), k4a.ELogLevel.TRACE) self.assertTrue(k4a.K4A_SUCCEEDED(status)) - @unittest.skip - def test_functional_fast_ctypes_set_debug_message_handler_callback(self): - logger_cb = k4a.logging_message_cb(glb_print_message) - context = ctypes.c_void_p() - status = k4a._bindings.k4a_set_debug_message_handler( - ctypes.byref(logger_cb), - context, + # Force a log message to call the python callback function. + # But cannot really automate this test except to debug this test and set a breakpoint in the callback function. + status = k4a._bindings.k4a.k4a_device_start_imu(self.device_handle) + self.assertTrue(k4a.K4A_FAILED(status)) + + def test_functional_fast_ctypes_set_debug_message_handler_nocontext(self): + status = k4a._bindings.k4a.k4a_set_debug_message_handler( + logging_print_message, + None, + k4a.ELogLevel.TRACE + ) + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + + # Force a log message to call the python callback function. + # But cannot really automate this test except to debug this test and set a breakpoint in the callback function. + strsize = ctypes.c_ulonglong(32) + serial_number = (ctypes.c_char * strsize.value)() + status = k4a._bindings.k4a.k4a_device_get_serialnum(self.device_handle, serial_number, ctypes.byref(strsize)) + self.assertEqual(k4a.EStatus.SUCCEEDED, status) + + def test_functional_fast_ctypes_set_debug_message_handler_withcontext(self): + global context + status = k4a._bindings.k4a.k4a_set_debug_message_handler( + logging_print_message, + ctypes.py_object(context), k4a.ELogLevel.TRACE ) self.assertTrue(k4a.K4A_SUCCEEDED(status)) + # Force a log message to call the python callback function. + # But cannot really automate this test except to debug this test and set a breakpoint in the callback function. + strsize = ctypes.c_ulonglong(32) + serial_number = (ctypes.c_char * strsize.value)() + status = k4a._bindings.k4a.k4a_device_get_serialnum(self.device_handle, serial_number, ctypes.byref(strsize)) + self.assertEqual(k4a.EStatus.SUCCEEDED, status) + + def test_functional_fast_ctypes_device_get_info(self): + device_info = k4a.DeviceInfo() + status = k4a._bindings.k4a.k4a_device_get_info( + self.device_handle, ctypes.byref(device_info)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertEqual(device_info.vendor_id, 0x045E) + self.assertEqual(device_info.device_id, 0x097C) + self.assertEqual(device_info.capabilities.value, + k4a.EDeviceCapabilities.MICROPHONE | k4a.EDeviceCapabilities.IMU | + k4a.EDeviceCapabilities.COLOR | k4a.EDeviceCapabilities.DEPTH) + + def test_functional_fast_ctypes_device_get_color_mode_count(self): + color_mode_count = ctypes.c_int(0) + status = k4a._bindings.k4a.k4a_device_get_color_mode_count( + self.device_handle, ctypes.byref(color_mode_count)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertGreater(color_mode_count.value, 0) + + def test_functional_fast_ctypes_device_get_color_mode(self): + color_mode_count = ctypes.c_int(0) + status = k4a._bindings.k4a.k4a_device_get_color_mode_count( + self.device_handle, ctypes.byref(color_mode_count)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertGreater(color_mode_count.value, 0) + + for mode in range(color_mode_count.value): + color_mode_info = k4a.ColorModeInfo() + status = k4a._bindings.k4a.k4a_device_get_color_mode( + self.device_handle, ctypes.c_uint32(mode), ctypes.byref(color_mode_info)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertEqual(color_mode_info.struct_size, 40) + + if color_mode_info.mode_id > 0: + self.assertGreaterEqual(color_mode_info.horizontal_fov, 0.0) + self.assertLessEqual(color_mode_info.horizontal_fov, 360.0) + self.assertGreaterEqual(color_mode_info.vertical_fov, 0.0) + self.assertLessEqual(color_mode_info.vertical_fov, 360.0) + + def test_functional_fast_ctypes_device_get_depth_mode_count(self): + depth_mode_count = ctypes.c_int(0) + status = k4a._bindings.k4a.k4a_device_get_depth_mode_count( + self.device_handle, ctypes.byref(depth_mode_count)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertGreater(depth_mode_count.value, 0) + + def test_functional_fast_ctypes_device_get_depth_mode(self): + depth_mode_count = ctypes.c_int(0) + status = k4a._bindings.k4a.k4a_device_get_depth_mode_count( + self.device_handle, ctypes.byref(depth_mode_count)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertGreater(depth_mode_count.value, 0) + + for mode in range(depth_mode_count.value): + depth_mode_info = k4a.DepthModeInfo() + status = k4a._bindings.k4a.k4a_device_get_depth_mode( + self.device_handle, ctypes.c_uint32(mode), ctypes.byref(depth_mode_info)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertEqual(depth_mode_info.struct_size, 52) + + if depth_mode_info.mode_id > 0: + self.assertGreaterEqual(depth_mode_info.horizontal_fov, 0.0) + self.assertLessEqual(depth_mode_info.horizontal_fov, 360.0) + self.assertGreaterEqual(depth_mode_info.vertical_fov, 0.0) + self.assertLessEqual(depth_mode_info.vertical_fov, 360.0) + + def test_functional_fast_ctypes_device_get_fps_mode_count(self): + fps_mode_count = ctypes.c_int(0) + status = k4a._bindings.k4a.k4a_device_get_fps_mode_count( + self.device_handle, ctypes.byref(fps_mode_count)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertGreater(fps_mode_count.value, 0) + + def test_functional_fast_ctypes_device_get_fps_mode(self): + fps_mode_count = ctypes.c_int(0) + status = k4a._bindings.k4a.k4a_device_get_fps_mode_count( + self.device_handle, ctypes.byref(fps_mode_count)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertGreater(fps_mode_count.value, 0) + + for mode in range(fps_mode_count.value): + fps_mode_info = k4a.FPSModeInfo() + status = k4a._bindings.k4a.k4a_device_get_fps_mode( + self.device_handle, ctypes.c_uint32(mode), ctypes.byref(fps_mode_info)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertEqual(fps_mode_info.struct_size, 16) + + if (fps_mode_info.mode_id == 0): + self.assertEqual(fps_mode_info.fps, 0) + else: + self.assertGreater(fps_mode_info.fps, 0) + def test_functional_fast_ctypes_device_get_capture(self): with self.lock: capture = get_1080p_bgr32_nfov_2x2binned(self.device_handle) @@ -183,7 +334,17 @@ def test_functional_fast_ctypes_device_get_capture(self): def test_functional_fast_ctypes_device_get_imu_sample(self): with self.lock: - device_config = k4a.DEVICE_CONFIG_BGRA32_1080P_NFOV_2X2BINNED_FPS15 + device_config = k4a.DeviceConfiguration( + color_format=k4a.EImageFormat.COLOR_BGRA32, + color_mode_id=2, # 1080P + depth_mode_id=1, # NFOV_2X2BINNED + fps_mode_id=15, # FPS_15 + synchronized_images_only=True, + depth_delay_off_color_usec=0, + wired_sync_mode=k4a.EWiredSyncMode.STANDALONE, + subordinate_delay_off_master_usec=0, + disable_streaming_indicator=False) + status = k4a._bindings.k4a.k4a_device_start_cameras(self.device_handle, ctypes.byref(device_config)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -728,9 +889,9 @@ def test_functional_fast_ctypes_device_start_cameras_stop_cameras(self): # Start the cameras. device_config = k4a.DeviceConfiguration() device_config.color_format = k4a.EImageFormat.COLOR_BGRA32 - device_config.color_resolution = k4a.EColorResolution.RES_1080P - device_config.depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - device_config.camera_fps = k4a.EFramesPerSecond.FPS_15 + device_config.color_mode_id = 2 # 1080P + device_config.depth_mode_id = 1 # NFOV_2X2BINNED + device_config.fps_mode_id = 15 # FPS_15 device_config.synchronized_images_only = True device_config.depth_delay_off_color_usec = 0 device_config.wired_sync_mode = k4a.EWiredSyncMode.STANDALONE @@ -743,7 +904,7 @@ def test_functional_fast_ctypes_device_start_cameras_stop_cameras(self): def test_functional_fast_ctypes_device_start_cameras_stop_cameras_DEFAULT_DISABLE(self): with self.lock: - device_config = k4a.DEVICE_CONFIG_DISABLE_ALL + device_config = k4a.DeviceConfiguration() status = k4a._bindings.k4a.k4a_device_start_cameras(self.device_handle, ctypes.byref(device_config)) self.assertTrue(k4a.K4A_FAILED(status)) # Seems to fail when DISABLE_ALL config is used. k4a._bindings.k4a.k4a_device_stop_cameras(self.device_handle) @@ -751,7 +912,17 @@ def test_functional_fast_ctypes_device_start_cameras_stop_cameras_DEFAULT_DISABL def test_functional_fast_ctypes_device_start_imu_stop_imu(self): with self.lock: - device_config = k4a.DEVICE_CONFIG_BGRA32_1080P_NFOV_2X2BINNED_FPS15 + device_config = k4a.DeviceConfiguration( + color_format=k4a.EImageFormat.COLOR_BGRA32, + color_mode_id=2, # 1080P + depth_mode_id=1, # NFOV_2X2BINNED + fps_mode_id=15, # FPS_15 + synchronized_images_only=True, + depth_delay_off_color_usec=0, + wired_sync_mode=k4a.EWiredSyncMode.STANDALONE, + subordinate_delay_off_master_usec=0, + disable_streaming_indicator=False) + status = k4a._bindings.k4a.k4a_device_start_cameras(self.device_handle, ctypes.byref(device_config)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -762,7 +933,7 @@ def test_functional_fast_ctypes_device_start_imu_stop_imu(self): k4a._bindings.k4a.k4a_device_stop_cameras(self.device_handle) def test_functional_fast_ctypes_device_get_serialnum(self): - strsize = ctypes.c_size_t(32) + strsize = ctypes.c_ulonglong(32) serial_number = (ctypes.c_char * strsize.value)() status = k4a._bindings.k4a.k4a_device_get_serialnum(self.device_handle, serial_number, ctypes.byref(strsize)) self.assertEqual(k4a.EStatus.SUCCEEDED, status) @@ -858,7 +1029,7 @@ def test_functional_fast_ctypes_device_get_raw_calibration(self): with self.lock: # Get buffer size requirement. - buffer_size = ctypes.c_size_t(0) + buffer_size = ctypes.c_ulonglong(0) buffer = ctypes.c_uint8(0) status = k4a._bindings.k4a.k4a_device_get_raw_calibration( self.device_handle, ctypes.byref(buffer), ctypes.byref(buffer_size)) @@ -872,32 +1043,17 @@ def test_functional_fast_ctypes_device_get_raw_calibration(self): def test_functional_fast_ctypes_device_get_calibration(self): with self.lock: - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - k4a.EDepthMode.PASSIVE_IR, - ] - - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] - + depth_modes_ids = range(1, 6) + color_mode_ids = range(1, 7) calibration = k4a._bindings.k4a._Calibration() - for depth_mode in depth_modes: - for color_resolution in color_resolutions: - with self.subTest(depth_mode = depth_mode, color_resolution = color_resolution): + for depth_mode_id in depth_modes_ids: + for color_mode_id in color_mode_ids: + with self.subTest(depth_mode_id = depth_mode_id, color_mode_id = color_mode_id): status = k4a._bindings.k4a.k4a_device_get_calibration( self.device_handle, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, ctypes.byref(calibration)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -915,7 +1071,7 @@ def test_functional_fast_ctypes_calibration_get_from_raw(self): with self.lock: # Get buffer size requirement. - buffer_size = ctypes.c_size_t(0) + buffer_size = ctypes.c_ulonglong(0) buffer = ctypes.c_uint8(0) status = k4a._bindings.k4a.k4a_device_get_raw_calibration( self.device_handle, ctypes.byref(buffer), ctypes.byref(buffer_size)) @@ -928,34 +1084,19 @@ def test_functional_fast_ctypes_calibration_get_from_raw(self): self.assertEqual(status, k4a.EBufferStatus.SUCCEEDED) # Now get the calibration from the buffer. - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - k4a.EDepthMode.PASSIVE_IR, - ] - - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] - + depth_modes_ids = range(1, 6) + color_mode_ids = range(1, 7) buffer = ctypes.cast(buffer, ctypes.POINTER(ctypes.c_char)) calibration = k4a._bindings.k4a._Calibration() - for depth_mode in depth_modes: - for color_resolution in color_resolutions: - with self.subTest(depth_mode = depth_mode, color_resolution = color_resolution): + for depth_mode_id in depth_modes_ids: + for color_mode_id in color_mode_ids: + with self.subTest(depth_mode_id = depth_mode_id, color_mode_id = color_mode_id): status = k4a._bindings.k4a.k4a_calibration_get_from_raw( buffer, buffer_size, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, ctypes.byref(calibration)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -963,8 +1104,8 @@ def test_functional_fast_ctypes_calibration_get_from_raw(self): def test_functional_fast_ctypes_calibration_3d_to_3d(self): with self.lock: - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P source_camera = k4a.ECalibrationType.COLOR target_camera = k4a.ECalibrationType.DEPTH @@ -974,8 +1115,8 @@ def test_functional_fast_ctypes_calibration_3d_to_3d(self): status = k4a._bindings.k4a.k4a_device_get_calibration( self.device_handle, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, ctypes.byref(calibration)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -998,8 +1139,8 @@ def test_functional_fast_ctypes_calibration_3d_to_3d(self): def test_functional_fast_ctypes_calibration_2d_to_3d(self): with self.lock: - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P source_camera = k4a.ECalibrationType.COLOR target_camera = k4a.ECalibrationType.DEPTH @@ -1011,8 +1152,8 @@ def test_functional_fast_ctypes_calibration_2d_to_3d(self): status = k4a._bindings.k4a.k4a_device_get_calibration( self.device_handle, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, ctypes.byref(calibration)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -1033,8 +1174,8 @@ def test_functional_fast_ctypes_calibration_2d_to_3d(self): def test_functional_fast_ctypes_calibration_3d_to_2d(self): with self.lock: - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P source_camera = k4a.ECalibrationType.COLOR target_camera = k4a.ECalibrationType.DEPTH @@ -1045,8 +1186,8 @@ def test_functional_fast_ctypes_calibration_3d_to_2d(self): status = k4a._bindings.k4a.k4a_device_get_calibration( self.device_handle, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, ctypes.byref(calibration)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -1065,8 +1206,8 @@ def test_functional_fast_ctypes_calibration_3d_to_2d(self): def test_functional_fast_ctypes_calibration_2d_to_2d(self): with self.lock: - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P source_camera = k4a.ECalibrationType.COLOR target_camera = k4a.ECalibrationType.DEPTH @@ -1078,8 +1219,8 @@ def test_functional_fast_ctypes_calibration_2d_to_2d(self): status = k4a._bindings.k4a.k4a_device_get_calibration( self.device_handle, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, ctypes.byref(calibration)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -1104,8 +1245,8 @@ def test_functional_fast_ctypes_calibration_2d_to_2d(self): def test_functional_fast_ctypes_calibration_color_2d_to_depth_2d(self): with self.lock: - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P calibration = k4a._bindings.k4a._Calibration() target_point = k4a._bindings.k4a._Float2() @@ -1113,16 +1254,16 @@ def test_functional_fast_ctypes_calibration_color_2d_to_depth_2d(self): status = k4a._bindings.k4a.k4a_device_get_calibration( self.device_handle, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, ctypes.byref(calibration)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) # Get a depth image. capture = test_config.get_capture(self.device_handle, k4a.EImageFormat.COLOR_BGRA32, - color_resolution, - depth_mode) + color_mode_id, + depth_mode_id) depth_image = k4a._bindings.k4a.k4a_capture_get_depth_image(capture) self.assertIsNotNone(depth_image) @@ -1146,471 +1287,139 @@ def test_functional_fast_ctypes_calibration_color_2d_to_depth_2d(self): self.assertTrue(k4a.K4A_SUCCEEDED(status)) self.assertEqual(valid_int_flag.value, 1) - - def test_functional_ctypes_calibration_3d_to_3d(self): + + def test_functional_fast_ctypes_transformation_create_destroy(self): with self.lock: - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - k4a.EDepthMode.PASSIVE_IR, - ] - - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] - - calibration_types = [ - k4a.ECalibrationType.COLOR, - k4a.ECalibrationType.DEPTH - ] - + depth_mode_id = 1 + color_mode_id = 1 calibration = k4a._bindings.k4a._Calibration() - source_point = k4a._bindings.k4a._Float3(300, 300, 500) - target_point = k4a._bindings.k4a._Float3() - for depth_mode in depth_modes: - for color_resolution in color_resolutions: - for source_camera in calibration_types: - for target_camera in calibration_types: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution, - source_camera = source_camera, - target_camera = target_camera): - - status = k4a._bindings.k4a.k4a_device_get_calibration( - self.device_handle, - depth_mode, - color_resolution, - ctypes.byref(calibration)) - - self.assertTrue(k4a.K4A_SUCCEEDED(status)) - - # Transform source point from source_camera to target_camera. - status = k4a._bindings.k4a.k4a_calibration_3d_to_3d( - ctypes.byref(calibration), - ctypes.byref(source_point), - source_camera, - target_camera, - ctypes.byref(target_point)) + status = k4a._bindings.k4a.k4a_device_get_calibration( + self.device_handle, + depth_mode_id, + color_mode_id, + ctypes.byref(calibration)) - self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertTrue(k4a.K4A_SUCCEEDED(status)) - if source_camera == target_camera: - self.assertAlmostEqual(source_point.xyz.x, target_point.xyz.x) - self.assertAlmostEqual(source_point.xyz.y, target_point.xyz.y) - self.assertAlmostEqual(source_point.xyz.z, target_point.xyz.z) + transformation = k4a._bindings.k4a.k4a_transformation_create(ctypes.byref(calibration)) + self.assertIsNotNone(transformation) # Might not be a valid assert. + k4a._bindings.k4a.k4a_transformation_destroy(transformation) - def test_functional_ctypes_calibration_2d_to_3d(self): + def test_functional_fast_ctypes_transformation_depth_image_to_color_camera(self): with self.lock: - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - k4a.EDepthMode.PASSIVE_IR, - ] - - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] - - calibration_types = [ - k4a.ECalibrationType.COLOR, - k4a.ECalibrationType.DEPTH - ] + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P calibration = k4a._bindings.k4a._Calibration() - source_point = k4a._bindings.k4a._Float2(300, 300) - depth_mm = 500.0 - target_point = k4a._bindings.k4a._Float3() - valid_int_flag = ctypes.c_int(0) - for depth_mode in depth_modes: - for color_resolution in color_resolutions: - for source_camera in calibration_types: - for target_camera in calibration_types: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution, - source_camera = source_camera, - target_camera = target_camera): + status = k4a._bindings.k4a.k4a_device_get_calibration( + self.device_handle, + depth_mode_id, + color_mode_id, + ctypes.byref(calibration)) + self.assertTrue(k4a.K4A_SUCCEEDED(status)) - status = k4a._bindings.k4a.k4a_device_get_calibration( - self.device_handle, - depth_mode, - color_resolution, - ctypes.byref(calibration)) + transformation = k4a._bindings.k4a.k4a_transformation_create(ctypes.byref(calibration)) + self.assertIsNotNone(transformation) # Might not be a valid assert. - self.assertTrue(k4a.K4A_SUCCEEDED(status)) + # Get a depth image. + capture = test_config.get_capture(self.device_handle, + k4a.EImageFormat.COLOR_BGRA32, + color_mode_id, + depth_mode_id) - # Transform source point from source_camera to target_camera. - status = k4a._bindings.k4a.k4a_calibration_2d_to_3d( - ctypes.byref(calibration), - ctypes.byref(source_point), - ctypes.c_float(depth_mm), - ctypes.c_int(source_camera), - ctypes.c_int(target_camera), - ctypes.byref(target_point), - ctypes.byref(valid_int_flag)) + depth_image = k4a._bindings.k4a.k4a_capture_get_depth_image(capture) + image_format = k4a._bindings.k4a.k4a_image_get_format(depth_image) - self.assertTrue(k4a.K4A_SUCCEEDED(status)) - self.assertEqual(valid_int_flag.value, 1) + # Get color image width and height. + color_image = k4a._bindings.k4a.k4a_capture_get_color_image(capture) + width_pixels = k4a._bindings.k4a.k4a_image_get_width_pixels(color_image) + height_pixels = k4a._bindings.k4a.k4a_image_get_height_pixels(color_image) + stride_bytes = width_pixels * 2 - def test_functional_ctypes_calibration_3d_to_2d(self): - with self.lock: + # Create an output depth image. + transformed_image = k4a._bindings.k4a._ImageHandle() + status = k4a._bindings.k4a.k4a_image_create( + image_format, + width_pixels, + height_pixels, + stride_bytes, + ctypes.byref(transformed_image) + ) + self.assertTrue(k4a.K4A_SUCCEEDED(status)) - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - k4a.EDepthMode.PASSIVE_IR, - ] + # Apply the transformation. + status = k4a._bindings.k4a.k4a_transformation_depth_image_to_color_camera( + transformation, + depth_image, + transformed_image + ) + self.assertTrue(k4a.K4A_SUCCEEDED(status)) - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] + k4a._bindings.k4a.k4a_transformation_destroy(transformation) + k4a._bindings.k4a.k4a_image_release(transformed_image) + k4a._bindings.k4a.k4a_image_release(depth_image) - calibration_types = [ - k4a.ECalibrationType.COLOR, - k4a.ECalibrationType.DEPTH - ] + def test_functional_fast_ctypes_transformation_depth_image_to_color_camera_custom(self): + with self.lock: + + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P calibration = k4a._bindings.k4a._Calibration() - source_point = k4a._bindings.k4a._Float3(300, 300, 500) - target_point = k4a._bindings.k4a._Float2() - valid_int_flag = ctypes.c_int(0) - for depth_mode in depth_modes: - for color_resolution in color_resolutions: - for source_camera in calibration_types: - for target_camera in calibration_types: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution, - source_camera = source_camera, - target_camera = target_camera): + status = k4a._bindings.k4a.k4a_device_get_calibration( + self.device_handle, + depth_mode_id, + color_mode_id, + ctypes.byref(calibration)) + self.assertTrue(k4a.K4A_SUCCEEDED(status)) - status = k4a._bindings.k4a.k4a_device_get_calibration( - self.device_handle, - depth_mode, - color_resolution, - ctypes.byref(calibration)) - self.assertTrue(k4a.K4A_SUCCEEDED(status)) + transformation = k4a._bindings.k4a.k4a_transformation_create(ctypes.byref(calibration)) + self.assertIsNotNone(transformation) # Might not be a valid assert. - # Transform source point from source_camera to target_camera. - status = k4a._bindings.k4a.k4a_calibration_3d_to_2d( - ctypes.byref(calibration), - ctypes.byref(source_point), - source_camera, - target_camera, - ctypes.byref(target_point), - ctypes.byref(valid_int_flag)) + # Get a capture. + capture = test_config.get_capture(self.device_handle, + k4a.EImageFormat.COLOR_BGRA32, + color_mode_id, + depth_mode_id) - self.assertTrue(k4a.K4A_SUCCEEDED(status)) - self.assertEqual(valid_int_flag.value, 1) + # Get color image width and height. + color_image = k4a._bindings.k4a.k4a_capture_get_color_image(capture) + output_width_pixels = k4a._bindings.k4a.k4a_image_get_width_pixels(color_image) + output_height_pixels = k4a._bindings.k4a.k4a_image_get_height_pixels(color_image) + output_stride_bytes = output_width_pixels * 2 - def test_functional_ctypes_calibration_2d_to_2d(self): - with self.lock: + # Get a depth image. + depth_image = k4a._bindings.k4a.k4a_capture_get_depth_image(capture) + image_format = k4a._bindings.k4a.k4a_image_get_format(depth_image) + input_width_pixels = k4a._bindings.k4a.k4a_image_get_width_pixels(depth_image) + input_height_pixels = k4a._bindings.k4a.k4a_image_get_height_pixels(depth_image) - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - k4a.EDepthMode.PASSIVE_IR, - ] + # Create an output depth image. + transformed_depth_image = k4a._bindings.k4a._ImageHandle() + status = k4a._bindings.k4a.k4a_image_create( + image_format, + output_width_pixels, + output_height_pixels, + output_stride_bytes, + ctypes.byref(transformed_depth_image) + ) + self.assertTrue(k4a.K4A_SUCCEEDED(status)) - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] - - calibration_types = [ - k4a.ECalibrationType.COLOR, - k4a.ECalibrationType.DEPTH - ] - - calibration = k4a._bindings.k4a._Calibration() - source_point = k4a._bindings.k4a._Float2(300, 300) - depth_mm = 500 - target_point = k4a._bindings.k4a._Float2() - valid_int_flag = ctypes.c_int(0) - - for depth_mode in depth_modes: - for color_resolution in color_resolutions: - for source_camera in calibration_types: - for target_camera in calibration_types: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution, - source_camera = source_camera, - target_camera = target_camera): - - status = k4a._bindings.k4a.k4a_device_get_calibration( - self.device_handle, - depth_mode, - color_resolution, - ctypes.byref(calibration)) - - self.assertTrue(k4a.K4A_SUCCEEDED(status)) - - # Transform source point from source_camera to target_camera. - status = k4a._bindings.k4a.k4a_calibration_2d_to_2d( - ctypes.byref(calibration), - ctypes.byref(source_point), - depth_mm, - source_camera, - target_camera, - ctypes.byref(target_point), - ctypes.byref(valid_int_flag)) - - self.assertTrue(k4a.K4A_SUCCEEDED(status)) - self.assertEqual(valid_int_flag.value, 1) - - if source_camera == target_camera: - self.assertAlmostEqual(source_point.xy.x, target_point.xy.x) - self.assertAlmostEqual(source_point.xy.y, target_point.xy.y) - - # This test is data dependent. It may fail based on scene content. - # It is favorable to point the camera at a flat wall about 30 cm away. - # Perhaps it's better to generate synthetic data. - def test_functional_ctypes_calibration_color_2d_to_depth_2d(self): - with self.lock: - - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - ] - - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] - - calibration = k4a._bindings.k4a._Calibration() - target_point = k4a._bindings.k4a._Float2() - valid_int_flag = ctypes.c_int(0) - - for depth_mode in depth_modes: - for color_resolution in color_resolutions: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution): - - status = k4a._bindings.k4a.k4a_device_get_calibration( - self.device_handle, - depth_mode, - color_resolution, - ctypes.byref(calibration)) - self.assertTrue(k4a.K4A_SUCCEEDED(status)) - - # Get a depth image. - capture = test_config.get_capture(self.device_handle, - k4a.EImageFormat.COLOR_BGRA32, - color_resolution, - depth_mode) - - depth_image = k4a._bindings.k4a.k4a_capture_get_depth_image(capture) - self.assertIsNotNone(depth_image) - - # Get color image width and height to specify the source point. - color_image = k4a._bindings.k4a.k4a_capture_get_color_image(capture) - width_pixels = k4a._bindings.k4a.k4a_image_get_width_pixels(color_image) - height_pixels = k4a._bindings.k4a.k4a_image_get_height_pixels(color_image) - source_point = k4a._bindings.k4a._Float2(width_pixels/4, height_pixels/4) - - # Transform source point from source_camera to target_camera. - status = k4a._bindings.k4a.k4a_calibration_color_2d_to_depth_2d( - ctypes.byref(calibration), - ctypes.byref(source_point), - depth_image, - ctypes.byref(target_point), - ctypes.byref(valid_int_flag)) - - k4a._bindings.k4a.k4a_image_release(depth_image) - k4a._bindings.k4a.k4a_image_release(color_image) - - self.assertTrue(k4a.K4A_SUCCEEDED(status)) - self.assertEqual(valid_int_flag.value, 1) - - def test_functional_fast_ctypes_transformation_create_destroy(self): - with self.lock: - - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - k4a.EDepthMode.PASSIVE_IR, - ] - - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] - - calibration = k4a._bindings.k4a._Calibration() - - for depth_mode in depth_modes: - for color_resolution in color_resolutions: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution): - - status = k4a._bindings.k4a.k4a_device_get_calibration( - self.device_handle, - depth_mode, - color_resolution, - ctypes.byref(calibration)) - - self.assertTrue(k4a.K4A_SUCCEEDED(status)) - - transformation = k4a._bindings.k4a.k4a_transformation_create(ctypes.byref(calibration)) - self.assertIsNotNone(transformation) # Might not be a valid assert. - k4a._bindings.k4a.k4a_transformation_destroy(transformation) - - def test_functional_fast_ctypes_transformation_depth_image_to_color_camera(self): - with self.lock: - - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P - - calibration = k4a._bindings.k4a._Calibration() - - status = k4a._bindings.k4a.k4a_device_get_calibration( - self.device_handle, - depth_mode, - color_resolution, - ctypes.byref(calibration)) - self.assertTrue(k4a.K4A_SUCCEEDED(status)) - - transformation = k4a._bindings.k4a.k4a_transformation_create(ctypes.byref(calibration)) - self.assertIsNotNone(transformation) # Might not be a valid assert. - - # Get a depth image. - capture = test_config.get_capture(self.device_handle, - k4a.EImageFormat.COLOR_BGRA32, - color_resolution, - depth_mode) - - depth_image = k4a._bindings.k4a.k4a_capture_get_depth_image(capture) - image_format = k4a._bindings.k4a.k4a_image_get_format(depth_image) - - # Get color image width and height. - color_image = k4a._bindings.k4a.k4a_capture_get_color_image(capture) - width_pixels = k4a._bindings.k4a.k4a_image_get_width_pixels(color_image) - height_pixels = k4a._bindings.k4a.k4a_image_get_height_pixels(color_image) - stride_bytes = width_pixels * 2 - - # Create an output depth image. - transformed_image = k4a._bindings.k4a._ImageHandle() - status = k4a._bindings.k4a.k4a_image_create( - image_format, - width_pixels, - height_pixels, - stride_bytes, - ctypes.byref(transformed_image) - ) - self.assertTrue(k4a.K4A_SUCCEEDED(status)) - - # Apply the transformation. - status = k4a._bindings.k4a.k4a_transformation_depth_image_to_color_camera( - transformation, - depth_image, - transformed_image - ) - self.assertTrue(k4a.K4A_SUCCEEDED(status)) - - k4a._bindings.k4a.k4a_transformation_destroy(transformation) - k4a._bindings.k4a.k4a_image_release(transformed_image) - k4a._bindings.k4a.k4a_image_release(depth_image) - - def test_functional_fast_ctypes_transformation_depth_image_to_color_camera_custom(self): - with self.lock: - - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P - - calibration = k4a._bindings.k4a._Calibration() - - status = k4a._bindings.k4a.k4a_device_get_calibration( - self.device_handle, - depth_mode, - color_resolution, - ctypes.byref(calibration)) - self.assertTrue(k4a.K4A_SUCCEEDED(status)) - - transformation = k4a._bindings.k4a.k4a_transformation_create(ctypes.byref(calibration)) - self.assertIsNotNone(transformation) # Might not be a valid assert. - - # Get a capture. - capture = test_config.get_capture(self.device_handle, - k4a.EImageFormat.COLOR_BGRA32, - color_resolution, - depth_mode) - - # Get color image width and height. - color_image = k4a._bindings.k4a.k4a_capture_get_color_image(capture) - output_width_pixels = k4a._bindings.k4a.k4a_image_get_width_pixels(color_image) - output_height_pixels = k4a._bindings.k4a.k4a_image_get_height_pixels(color_image) - output_stride_bytes = output_width_pixels * 2 - - # Get a depth image. - depth_image = k4a._bindings.k4a.k4a_capture_get_depth_image(capture) - image_format = k4a._bindings.k4a.k4a_image_get_format(depth_image) - input_width_pixels = k4a._bindings.k4a.k4a_image_get_width_pixels(depth_image) - input_height_pixels = k4a._bindings.k4a.k4a_image_get_height_pixels(depth_image) - - # Create an output depth image. - transformed_depth_image = k4a._bindings.k4a._ImageHandle() - status = k4a._bindings.k4a.k4a_image_create( - image_format, - output_width_pixels, - output_height_pixels, - output_stride_bytes, - ctypes.byref(transformed_depth_image) - ) - self.assertTrue(k4a.K4A_SUCCEEDED(status)) - - # Create a custom image. - image_format = k4a.EImageFormat.CUSTOM16 - custom_image = k4a._bindings.k4a._ImageHandle() - status = k4a._bindings.k4a.k4a_image_create( - image_format.value, - input_width_pixels, - input_height_pixels, - input_width_pixels * 2, - ctypes.byref(custom_image)) - self.assertEqual(k4a.EStatus.SUCCEEDED, status) + # Create a custom image. + image_format = k4a.EImageFormat.CUSTOM16 + custom_image = k4a._bindings.k4a._ImageHandle() + status = k4a._bindings.k4a.k4a_image_create( + image_format.value, + input_width_pixels, + input_height_pixels, + input_width_pixels * 2, + ctypes.byref(custom_image)) + self.assertEqual(k4a.EStatus.SUCCEEDED, status) # Create a transformed custom image. image_format = k4a.EImageFormat.CUSTOM16 @@ -1644,15 +1453,15 @@ def test_functional_fast_ctypes_transformation_depth_image_to_color_camera_custo def test_functional_fast_ctypes_transformation_color_image_to_depth_camera(self): with self.lock: - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - color_resolution = k4a.EColorResolution.RES_720P + depth_mode_id = 1 # NFOV_2X2BINNED + color_mode_id = 1 # 720P calibration = k4a._bindings.k4a._Calibration() status = k4a._bindings.k4a.k4a_device_get_calibration( self.device_handle, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, ctypes.byref(calibration)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -1662,8 +1471,8 @@ def test_functional_fast_ctypes_transformation_color_image_to_depth_camera(self) # Get a capture and depth and color images. capture = test_config.get_capture(self.device_handle, k4a.EImageFormat.COLOR_BGRA32, - color_resolution, - depth_mode) + color_mode_id, + depth_mode_id) depth_image = k4a._bindings.k4a.k4a_capture_get_depth_image(capture) color_image = k4a._bindings.k4a.k4a_capture_get_color_image(capture) @@ -1701,15 +1510,14 @@ def test_functional_fast_ctypes_transformation_color_image_to_depth_camera(self) def test_functional_fast_ctypes_transformation_depth_image_to_point_cloud(self): with self.lock: - depth_mode = k4a.EDepthMode.NFOV_2X2BINNED - + depth_mode_id = 1 # NFOV_2X2BINNED calibration = k4a._bindings.k4a._Calibration() # Get a capture and depth image. capture = test_config.get_capture(self.device_handle, k4a.EImageFormat.COLOR_BGRA32, - k4a.EColorResolution.RES_1080P, - depth_mode) + 2, # 1080P + depth_mode_id) depth_image = k4a._bindings.k4a.k4a_capture_get_depth_image(capture) @@ -1732,8 +1540,8 @@ def test_functional_fast_ctypes_transformation_depth_image_to_point_cloud(self): # Get a transformation. status = k4a._bindings.k4a.k4a_device_get_calibration( self.device_handle, - depth_mode, - k4a.EColorResolution.RES_1080P, + depth_mode_id, + 2, # 1080P ctypes.byref(calibration)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -1754,36 +1562,47 @@ def test_functional_fast_ctypes_transformation_depth_image_to_point_cloud(self): k4a._bindings.k4a.k4a_image_release(xyz_image) k4a._bindings.k4a.k4a_image_release(depth_image) - def test_functional_ctypes_transformation_depth_image_to_color_camera(self): - with self.lock: +class Test_Functional_Ctypes_AzureKinect(unittest.TestCase): + '''Test k4a functions requiring a device handle for Azure Kinect device. + ''' - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - ] + @classmethod + def setUpClass(cls): + cls.device_handle = k4a._bindings.k4a._DeviceHandle() + status = k4a._bindings.k4a.k4a_device_open(ctypes.c_uint32(0), ctypes.byref(cls.device_handle)) + assert(k4a.K4A_SUCCEEDED(status)) - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] + cls.lock = test_config.glb_lock + + @classmethod + def tearDownClass(cls): + + if test_config.glb_capture is not None: + k4a._bindings.k4a.k4a_capture_release(test_config.glb_capture) + test_config.glb_capture = None + + # Stop the cameras and imus before closing device. + k4a._bindings.k4a.k4a_device_stop_cameras(cls.device_handle) + k4a._bindings.k4a.k4a_device_stop_imu(cls.device_handle) + k4a._bindings.k4a.k4a_device_close(cls.device_handle) + + + def test_functional_ctypes_transformation_depth_image_to_color_camera(self): + with self.lock: + depth_modes_ids = range(1, 5) + color_mode_ids = range(1, 7) calibration = k4a._bindings.k4a._Calibration() - for depth_mode in depth_modes: - for color_resolution in color_resolutions: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution): + for depth_mode_id in depth_modes_ids: + for color_mode_id in color_mode_ids: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id): status = k4a._bindings.k4a.k4a_device_get_calibration( self.device_handle, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, ctypes.byref(calibration)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -1793,8 +1612,8 @@ def test_functional_ctypes_transformation_depth_image_to_color_camera(self): # Get a depth image. capture = test_config.get_capture(self.device_handle, k4a.EImageFormat.COLOR_BGRA32, - color_resolution, - depth_mode) + color_mode_id, + depth_mode_id) depth_image = k4a._bindings.k4a.k4a_capture_get_depth_image(capture) image_format = k4a._bindings.k4a.k4a_image_get_format(depth_image) @@ -1831,33 +1650,19 @@ def test_functional_ctypes_transformation_depth_image_to_color_camera(self): def test_functional_ctypes_transformation_depth_image_to_color_camera_custom(self): with self.lock: - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - ] - - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] - + depth_modes_ids = range(1, 5) + color_mode_ids = range(1, 7) calibration = k4a._bindings.k4a._Calibration() - for depth_mode in depth_modes: - for color_resolution in color_resolutions: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution): + for depth_mode_id in depth_modes_ids: + for color_mode_id in color_mode_ids: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id): status = k4a._bindings.k4a.k4a_device_get_calibration( self.device_handle, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, ctypes.byref(calibration)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -1867,8 +1672,8 @@ def test_functional_ctypes_transformation_depth_image_to_color_camera_custom(sel # Get a capture. capture = test_config.get_capture(self.device_handle, k4a.EImageFormat.COLOR_BGRA32, - color_resolution, - depth_mode) + color_mode_id, + depth_mode_id) # Get color image width and height. color_image = k4a._bindings.k4a.k4a_capture_get_color_image(capture) @@ -1936,33 +1741,19 @@ def test_functional_ctypes_transformation_depth_image_to_color_camera_custom(sel def test_functional_ctypes_transformation_color_image_to_depth_camera(self): with self.lock: - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - ] - - color_resolutions = [ - k4a.EColorResolution.RES_3072P, - k4a.EColorResolution.RES_2160P, - k4a.EColorResolution.RES_1536P, - k4a.EColorResolution.RES_1440P, - k4a.EColorResolution.RES_1080P, - k4a.EColorResolution.RES_720P, - ] - + depth_modes_ids = range(1, 5) + color_mode_ids = range(1, 7) calibration = k4a._bindings.k4a._Calibration() - for depth_mode in depth_modes: - for color_resolution in color_resolutions: - with self.subTest(depth_mode = depth_mode, - color_resolution = color_resolution): + for depth_mode_id in depth_modes_ids: + for color_mode_id in color_mode_ids: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id): status = k4a._bindings.k4a.k4a_device_get_calibration( self.device_handle, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, ctypes.byref(calibration)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -1972,8 +1763,8 @@ def test_functional_ctypes_transformation_color_image_to_depth_camera(self): # Get a capture and depth and color images. capture = test_config.get_capture(self.device_handle, k4a.EImageFormat.COLOR_BGRA32, - color_resolution, - depth_mode) + color_mode_id, + depth_mode_id) depth_image = k4a._bindings.k4a.k4a_capture_get_depth_image(capture) color_image = k4a._bindings.k4a.k4a_capture_get_color_image(capture) @@ -2011,23 +1802,17 @@ def test_functional_ctypes_transformation_color_image_to_depth_camera(self): def test_functional_ctypes_transformation_depth_image_to_point_cloud(self): with self.lock: - depth_modes = [ - k4a.EDepthMode.NFOV_2X2BINNED, - k4a.EDepthMode.NFOV_UNBINNED, - k4a.EDepthMode.WFOV_2X2BINNED, - k4a.EDepthMode.WFOV_UNBINNED, - ] - - for depth_mode in depth_modes: - with self.subTest(depth_mode = depth_mode): + depth_modes_ids = range(1, 5) + for depth_mode_id in depth_modes_ids: + with self.subTest(depth_mode_id = depth_mode_id): calibration = k4a._bindings.k4a._Calibration() # Get a capture and depth image. capture = test_config.get_capture(self.device_handle, k4a.EImageFormat.COLOR_BGRA32, - k4a.EColorResolution.RES_1080P, - depth_mode) + 2, # 1080P + depth_mode_id) depth_image = k4a._bindings.k4a.k4a_capture_get_depth_image(capture) @@ -2050,8 +1835,8 @@ def test_functional_ctypes_transformation_depth_image_to_point_cloud(self): # Get a transformation. status = k4a._bindings.k4a.k4a_device_get_calibration( self.device_handle, - depth_mode, - k4a.EColorResolution.RES_1080P, + depth_mode_id, + 2, # 1080P ctypes.byref(calibration)) self.assertTrue(k4a.K4A_SUCCEEDED(status)) @@ -2072,5 +1857,268 @@ def test_functional_ctypes_transformation_depth_image_to_point_cloud(self): k4a._bindings.k4a.k4a_image_release(xyz_image) k4a._bindings.k4a.k4a_image_release(depth_image) + + def test_functional_ctypes_transformation_create_destroy(self): + with self.lock: + + depth_mode_ids = range(1, 6) + color_mode_ids = range(1, 7) + calibration = k4a._bindings.k4a._Calibration() + + for depth_mode_id in depth_mode_ids: + for color_mode_id in color_mode_ids: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id): + + status = k4a._bindings.k4a.k4a_device_get_calibration( + self.device_handle, + depth_mode_id, + color_mode_id, + ctypes.byref(calibration)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + + transformation = k4a._bindings.k4a.k4a_transformation_create(ctypes.byref(calibration)) + self.assertIsNotNone(transformation) # Might not be a valid assert. + k4a._bindings.k4a.k4a_transformation_destroy(transformation) + + def test_functional_ctypes_calibration_3d_to_3d(self): + with self.lock: + + depth_modes_ids = range(1, 6) + color_mode_ids = range(1, 7) + calibration_types = [ + k4a.ECalibrationType.COLOR, + k4a.ECalibrationType.DEPTH + ] + + calibration = k4a._bindings.k4a._Calibration() + source_point = k4a._bindings.k4a._Float3(300, 300, 500) + target_point = k4a._bindings.k4a._Float3() + + for depth_mode_id in depth_modes_ids: + for color_mode_id in color_mode_ids: + for source_camera in calibration_types: + for target_camera in calibration_types: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id, + source_camera = source_camera, + target_camera = target_camera): + + status = k4a._bindings.k4a.k4a_device_get_calibration( + self.device_handle, + depth_mode_id, + color_mode_id, + ctypes.byref(calibration)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + + # Transform source point from source_camera to target_camera. + status = k4a._bindings.k4a.k4a_calibration_3d_to_3d( + ctypes.byref(calibration), + ctypes.byref(source_point), + source_camera, + target_camera, + ctypes.byref(target_point)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + + if source_camera == target_camera: + self.assertAlmostEqual(source_point.xyz.x, target_point.xyz.x) + self.assertAlmostEqual(source_point.xyz.y, target_point.xyz.y) + self.assertAlmostEqual(source_point.xyz.z, target_point.xyz.z) + + def test_functional_ctypes_calibration_2d_to_3d(self): + with self.lock: + + depth_modes_ids = range(1, 6) + color_mode_ids = range(1, 7) + calibration_types = [ + k4a.ECalibrationType.COLOR, + k4a.ECalibrationType.DEPTH + ] + + calibration = k4a._bindings.k4a._Calibration() + source_point = k4a._bindings.k4a._Float2(300, 300) + depth_mm = 500.0 + target_point = k4a._bindings.k4a._Float3() + valid_int_flag = ctypes.c_int(0) + + for depth_mode_id in depth_modes_ids: + for color_mode_id in color_mode_ids: + for source_camera in calibration_types: + for target_camera in calibration_types: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id, + source_camera = source_camera, + target_camera = target_camera): + + status = k4a._bindings.k4a.k4a_device_get_calibration( + self.device_handle, + depth_mode_id, + color_mode_id, + ctypes.byref(calibration)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + + # Transform source point from source_camera to target_camera. + status = k4a._bindings.k4a.k4a_calibration_2d_to_3d( + ctypes.byref(calibration), + ctypes.byref(source_point), + ctypes.c_float(depth_mm), + ctypes.c_int(source_camera), + ctypes.c_int(target_camera), + ctypes.byref(target_point), + ctypes.byref(valid_int_flag)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertEqual(valid_int_flag.value, 1) + + def test_functional_ctypes_calibration_3d_to_2d(self): + with self.lock: + + depth_modes_ids = range(1, 6) + color_mode_ids = range(1, 7) + calibration_types = [ + k4a.ECalibrationType.COLOR, + k4a.ECalibrationType.DEPTH + ] + + calibration = k4a._bindings.k4a._Calibration() + source_point = k4a._bindings.k4a._Float3(300, 300, 500) + target_point = k4a._bindings.k4a._Float2() + valid_int_flag = ctypes.c_int(0) + + for depth_mode_id in depth_modes_ids: + for color_mode_id in color_mode_ids: + for source_camera in calibration_types: + for target_camera in calibration_types: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id, + source_camera = source_camera, + target_camera = target_camera): + + status = k4a._bindings.k4a.k4a_device_get_calibration( + self.device_handle, + depth_mode_id, + color_mode_id, + ctypes.byref(calibration)) + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + + # Transform source point from source_camera to target_camera. + status = k4a._bindings.k4a.k4a_calibration_3d_to_2d( + ctypes.byref(calibration), + ctypes.byref(source_point), + source_camera, + target_camera, + ctypes.byref(target_point), + ctypes.byref(valid_int_flag)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertEqual(valid_int_flag.value, 1) + + def test_functional_ctypes_calibration_2d_to_2d(self): + with self.lock: + + depth_modes_ids = range(1, 6) + color_mode_ids = range(1, 7) + calibration_types = [ + k4a.ECalibrationType.COLOR, + k4a.ECalibrationType.DEPTH + ] + + calibration = k4a._bindings.k4a._Calibration() + source_point = k4a._bindings.k4a._Float2(300, 300) + depth_mm = 500 + target_point = k4a._bindings.k4a._Float2() + valid_int_flag = ctypes.c_int(0) + + for depth_mode_id in depth_modes_ids: + for color_mode_id in color_mode_ids: + for source_camera in calibration_types: + for target_camera in calibration_types: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id, + source_camera = source_camera, + target_camera = target_camera): + + status = k4a._bindings.k4a.k4a_device_get_calibration( + self.device_handle, + depth_mode_id, + color_mode_id, + ctypes.byref(calibration)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + + # Transform source point from source_camera to target_camera. + status = k4a._bindings.k4a.k4a_calibration_2d_to_2d( + ctypes.byref(calibration), + ctypes.byref(source_point), + depth_mm, + source_camera, + target_camera, + ctypes.byref(target_point), + ctypes.byref(valid_int_flag)) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertEqual(valid_int_flag.value, 1) + + if source_camera == target_camera: + self.assertAlmostEqual(source_point.xy.x, target_point.xy.x) + self.assertAlmostEqual(source_point.xy.y, target_point.xy.y) + + # This test is data dependent. It may fail based on scene content. + # It is favorable to point the camera at a flat wall about 30 cm away. + # Perhaps it's better to generate synthetic data. + def test_functional_ctypes_calibration_color_2d_to_depth_2d(self): + with self.lock: + + depth_modes_ids = range(1, 5) + color_mode_ids = range(1, 7) + calibration = k4a._bindings.k4a._Calibration() + target_point = k4a._bindings.k4a._Float2() + valid_int_flag = ctypes.c_int(0) + + for depth_mode_id in depth_modes_ids: + for color_mode_id in color_mode_ids: + with self.subTest(depth_mode_id = depth_mode_id, + color_mode_id = color_mode_id): + + status = k4a._bindings.k4a.k4a_device_get_calibration( + self.device_handle, + depth_mode_id, + color_mode_id, + ctypes.byref(calibration)) + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + + # Get a depth image. + capture = test_config.get_capture(self.device_handle, + k4a.EImageFormat.COLOR_BGRA32, + color_mode_id, + depth_mode_id) + + depth_image = k4a._bindings.k4a.k4a_capture_get_depth_image(capture) + self.assertIsNotNone(depth_image) + + # Get color image width and height to specify the source point. + color_image = k4a._bindings.k4a.k4a_capture_get_color_image(capture) + width_pixels = k4a._bindings.k4a.k4a_image_get_width_pixels(color_image) + height_pixels = k4a._bindings.k4a.k4a_image_get_height_pixels(color_image) + source_point = k4a._bindings.k4a._Float2(width_pixels/4, height_pixels/4) + + # Transform source point from source_camera to target_camera. + status = k4a._bindings.k4a.k4a_calibration_color_2d_to_depth_2d( + ctypes.byref(calibration), + ctypes.byref(source_point), + depth_image, + ctypes.byref(target_point), + ctypes.byref(valid_int_flag)) + + k4a._bindings.k4a.k4a_image_release(depth_image) + k4a._bindings.k4a.k4a_image_release(color_image) + + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + self.assertEqual(valid_int_flag.value, 1) + if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/src/python/k4a/tests/test_unit_api_azurekinect.py b/src/python/k4a/tests/test_unit_api_azurekinect.py new file mode 100644 index 000000000..5e5aa17f3 --- /dev/null +++ b/src/python/k4a/tests/test_unit_api_azurekinect.py @@ -0,0 +1,632 @@ +''' +test_k4a_azurekinect.py + +Tests for the k4a functions for Azure Kinect device. + +Copyright (C) Microsoft Corporation. All rights reserved. +''' + +import unittest +from unittest import mock +import ctypes + +import k4a + +from mock_k4a_dll_azurekinect import * + + +class Test_Unit_Device_AzureKinect(unittest.TestCase): + '''Test k4a ctypes functions without requiring a device. + ''' + + @classmethod + @mock.patch('k4a._bindings.device.k4a_device_get_info', side_effect=mock_k4a_get_device_info) + @mock.patch('k4a._bindings.device.k4a_device_get_version', side_effect=mock_k4a_get_version) + @mock.patch('k4a._bindings.device.k4a_device_get_serialnum', side_effect=mock_k4a_get_serialnum) + @mock.patch('k4a._bindings.device.k4a_device_open', side_effect=mock_k4a_device_open) + def setUpClass(cls, mock_func_open, mock_func_serialnum, mock_func_version, mock_func_info): + + cls.device = k4a.Device.open() + + mock_func_open.assert_called_once() + mock_func_serialnum.assert_called_once() + mock_func_version.assert_called_once() + mock_func_info.assert_called_once() + + cls.assertIsNotNone(cls, cls.device) + cls.assertTrue(cls, cls.device.serial_number == "b'0123-4567890'") + cls.assertTrue(cls, str(cls.device.hardware_version.rgb)=="0.1.0") + cls.assertTrue(cls, str(cls.device.hardware_version.depth)=="0.1.0") + cls.assertTrue(cls, str(cls.device.hardware_version.audio)=="0.1.0") + cls.assertTrue(cls, str(cls.device.hardware_version.depth_sensor)=="0.1.0") + cls.assertTrue(cls, cls.device.hardware_version.firmware_build==1) + cls.assertTrue(cls, cls.device.hardware_version.firmware_signature==1) + + @classmethod + @mock.patch('k4a._bindings.device.k4a_device_close', side_effect=mock_k4a_device_close) + @mock.patch('k4a._bindings.device.k4a_device_stop_imu') + @mock.patch('k4a._bindings.device.k4a_device_stop_cameras') + def tearDownClass(cls, mock_func_stop_cameras, mock_func_stop_imu, mock_func_close): + + cls.device.close() + + mock_func_stop_cameras.assert_called_once() + mock_func_stop_imu.assert_called_once() + mock_func_close.assert_called_once() + + @mock.patch('k4a._bindings.device.k4a_device_get_info', side_effect=mock_k4a_get_device_info) + @mock.patch('k4a._bindings.device.k4a_device_get_version', side_effect=mock_k4a_get_version) + @mock.patch('k4a._bindings.device.k4a_device_get_serialnum', side_effect=mock_k4a_get_serialnum) + @mock.patch('k4a._bindings.device.k4a_device_open', side_effect=mock_k4a_device_open) + @mock.patch('k4a._bindings.device.k4a_device_close', side_effect=mock_k4a_device_close) + @mock.patch('k4a._bindings.device.k4a_device_stop_imu') + @mock.patch('k4a._bindings.device.k4a_device_stop_cameras') + def test_unit_device_open_and_close_same_device_many_times(self, + mock_stop_cameras, mock_stop_imu, mock_close, mock_open, + mock_get_serial, mock_get_version, mock_get_info): + + devices_list = list() + num_iter = 10 + + self.assertEqual(mock_stop_cameras.call_count, 0) + self.assertEqual(mock_stop_imu.call_count, 0) + self.assertEqual(mock_open.call_count, 0) + self.assertEqual(mock_close.call_count, 0) + self.assertEqual(mock_get_serial.call_count, 0) + self.assertEqual(mock_get_version.call_count, 0) + self.assertEqual(mock_get_info.call_count, 0) + + # Open device index 1 and close it. The device at index 0 is already opened. + for n in range(1, num_iter + 1): + device = k4a.Device.open(1) + devices_list.append(device) + device.close() + + self.assertIsNotNone(device) + self.assertEqual(mock_stop_cameras.call_count, n) + self.assertEqual(mock_stop_imu.call_count, n) + self.assertEqual(mock_open.call_count, n) + self.assertEqual(mock_close.call_count, n) + self.assertEqual(mock_get_serial.call_count, n) + self.assertEqual(mock_get_version.call_count, n) + self.assertEqual(mock_get_info.call_count, n) + + self.assertEqual(mock_stop_cameras.call_count, num_iter) + self.assertEqual(mock_stop_imu.call_count, num_iter) + self.assertEqual(mock_open.call_count, num_iter) + self.assertEqual(mock_close.call_count, num_iter) + self.assertEqual(mock_get_serial.call_count, num_iter) + self.assertEqual(mock_get_version.call_count, num_iter) + self.assertEqual(mock_get_info.call_count, num_iter) + + @mock.patch('k4a._bindings.device.k4a_device_open', return_value=k4a.EStatus.FAILED) + def test_unit_device_open_fail(self, mock_func): + + device = k4a.Device.open() + self.assertIsNone(device) + self.assertEqual(mock_func.call_count, 1) + + @mock.patch('k4a._bindings.device.k4a_device_get_info', side_effect=mock_k4a_get_device_info) + @mock.patch('k4a._bindings.device.k4a_device_get_version', side_effect=mock_k4a_get_version) + @mock.patch('k4a._bindings.device.k4a_device_get_serialnum', return_value=k4a.EStatus.FAILED) + @mock.patch('k4a._bindings.device.k4a_device_open', side_effect=mock_k4a_device_open) + def test_unit_device_open_get_serial_num_fail(self, mock_open, mock_serialnum, mock_version, mock_info): + + device = k4a.Device.open() + self.assertIsNotNone(device) + + # Check that serial number is empty. + self.assertEqual(device.serial_number, '') + + self.assertIsInstance(device.device_info, k4a.DeviceInfo) + self.assertEqual(device.device_info.struct_size, 20) + self.assertEqual(device.device_info.struct_version, k4a.K4A_ABI_VERSION) + self.assertEqual(device.device_info.vendor_id, 0x045E) + self.assertEqual(device.device_info.device_id, 0x097C) + self.assertEqual(device.device_info.capabilities.value, 0x000F) + + self.assertIsInstance(device.hardware_version, k4a.HardwareVersion) + self.assertTrue(str(device.hardware_version.rgb)=="0.1.0") + self.assertTrue(str(device.hardware_version.depth)=="0.1.0") + self.assertTrue(str(device.hardware_version.audio)=="0.1.0") + self.assertTrue(str(device.hardware_version.depth_sensor)=="0.1.0") + self.assertTrue(device.hardware_version.firmware_build==1) + self.assertTrue(device.hardware_version.firmware_signature==1) + + self.assertEqual(mock_open.call_count, 1) + self.assertEqual(mock_serialnum.call_count, 1) + self.assertEqual(mock_version.call_count, 1) + self.assertEqual(mock_info.call_count, 1) + + @mock.patch('k4a._bindings.device.k4a_device_get_info', side_effect=mock_k4a_get_device_info) + @mock.patch('k4a._bindings.device.k4a_device_get_version', return_value=k4a.EStatus.FAILED) + @mock.patch('k4a._bindings.device.k4a_device_get_serialnum', side_effect=mock_k4a_get_serialnum) + @mock.patch('k4a._bindings.device.k4a_device_open', side_effect=mock_k4a_device_open) + def test_unit_device_open_get_version_fail(self, mock_open, mock_serialnum, mock_version, mock_info): + + device = k4a.Device.open() + self.assertIsNotNone(device) + + # Check that serial number is empty. + self.assertEqual(device.serial_number, "b'0123-4567890'") + + self.assertIsInstance(device.device_info, k4a.DeviceInfo) + self.assertEqual(device.device_info.struct_size, 20) + self.assertEqual(device.device_info.struct_version, k4a.K4A_ABI_VERSION) + self.assertEqual(device.device_info.vendor_id, 0x045E) + self.assertEqual(device.device_info.device_id, 0x097C) + self.assertEqual(device.device_info.capabilities.value, 0x000F) + + self.assertIsInstance(device.hardware_version, k4a.HardwareVersion) + self.assertTrue(str(device.hardware_version.rgb)=="0.0.0") + self.assertTrue(str(device.hardware_version.depth)=="0.0.0") + self.assertTrue(str(device.hardware_version.audio)=="0.0.0") + self.assertTrue(str(device.hardware_version.depth_sensor)=="0.0.0") + self.assertTrue(device.hardware_version.firmware_build==0) + self.assertTrue(device.hardware_version.firmware_signature==0) + + self.assertEqual(mock_open.call_count, 1) + self.assertEqual(mock_serialnum.call_count, 1) + self.assertEqual(mock_version.call_count, 1) + self.assertEqual(mock_info.call_count, 1) + + @mock.patch('k4a._bindings.device.k4a_device_get_info', return_value=k4a.EStatus.FAILED) + @mock.patch('k4a._bindings.device.k4a_device_get_version', side_effect=mock_k4a_get_version) + @mock.patch('k4a._bindings.device.k4a_device_get_serialnum', side_effect=mock_k4a_get_serialnum) + @mock.patch('k4a._bindings.device.k4a_device_open', side_effect=mock_k4a_device_open) + def test_unit_device_open_get_info_fail(self, mock_open, mock_serialnum, mock_version, mock_info): + + device = k4a.Device.open() + self.assertIsNotNone(device) + + # Check that serial number is empty. + self.assertEqual(device.serial_number, "b'0123-4567890'") + + self.assertIsInstance(device.device_info, k4a.DeviceInfo) + self.assertEqual(device.device_info.struct_size, 20) + self.assertEqual(device.device_info.struct_version, k4a.K4A_ABI_VERSION) + self.assertEqual(device.device_info.vendor_id, 0) + self.assertEqual(device.device_info.device_id, 0) + self.assertEqual(device.device_info.capabilities.value, 0) + + self.assertIsInstance(device.hardware_version, k4a.HardwareVersion) + self.assertTrue(str(device.hardware_version.rgb)=="0.1.0") + self.assertTrue(str(device.hardware_version.depth)=="0.1.0") + self.assertTrue(str(device.hardware_version.audio)=="0.1.0") + self.assertTrue(str(device.hardware_version.depth_sensor)=="0.1.0") + self.assertTrue(device.hardware_version.firmware_build==1) + self.assertTrue(device.hardware_version.firmware_signature==1) + + self.assertEqual(mock_open.call_count, 1) + self.assertEqual(mock_serialnum.call_count, 1) + self.assertEqual(mock_version.call_count, 1) + self.assertEqual(mock_info.call_count, 1) + + @mock.patch('k4a._bindings.device.k4a_device_get_installed_count', side_effect=mock_k4a_device_get_installed_count) + def test_unit_device_get_installed_count(self, mock_func): + + device_count = k4a.Device.get_device_count() + + self.assertEqual(device_count, 4) # Allow for up to 4 connected non-existent devices. + mock_func.assert_called_once() + + @mock.patch('k4a._bindings.device.k4a_device_stop_cameras') + @mock.patch('k4a._bindings.device.k4a_device_start_cameras', side_effect=mock_k4a_start_cameras) + def test_unit_device_start_stop_cameras(self, mock_func_start_cameras, mock_func_stop_cameras): + + # Start cameras. + config = k4a.DeviceConfiguration( + color_format=k4a.EImageFormat.COLOR_BGRA32, + color_mode_id=1, # 720p + depth_mode_id=1, # NFOV_2X2BINNED + fps_mode_id=15 # 15 frames per second + ) + + status = self.device.start_cameras(config) + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + mock_func_start_cameras.assert_called_once() + mock_func_stop_cameras.assert_not_called() + + # Stop cameras. + self.device.stop_cameras() + mock_func_stop_cameras.assert_called_once() + mock_func_start_cameras.assert_called_once() + + @mock.patch('k4a._bindings.device.k4a_device_stop_cameras') + @mock.patch('k4a._bindings.device.k4a_device_start_cameras', return_value=k4a.EStatus.FAILED) + def test_unit_device_start_stop_cameras_fail(self, mock_func_start_cameras, mock_func_stop_cameras): + + # Start cameras. + config = k4a.DeviceConfiguration( + color_format=k4a.EImageFormat.COLOR_BGRA32, + color_mode_id=1, # 720p + depth_mode_id=1, # NFOV_2X2BINNED + fps_mode_id=15 # 15 frames per second + ) + + status = self.device.start_cameras(config) + self.assertTrue(k4a.K4A_FAILED(status)) + mock_func_start_cameras.assert_called_once() + mock_func_stop_cameras.assert_not_called() + + # Stop cameras. + self.device.stop_cameras() + mock_func_stop_cameras.assert_called_once() + mock_func_start_cameras.assert_called_once() + + @mock.patch('k4a._bindings.device.k4a_device_stop_imu') + @mock.patch('k4a._bindings.device.k4a_device_start_imu', return_value=k4a.EStatus.SUCCEEDED) + def test_unit_device_start_stop_imu(self, mock_func_start_imu, mock_func_stop_imu): + + status = self.device.start_imu() + self.assertTrue(k4a.K4A_SUCCEEDED(status)) + mock_func_start_imu.assert_called_once() + mock_func_stop_imu.assert_not_called() + + # Stop cameras. + self.device.stop_imu() + mock_func_stop_imu.assert_called_once() + mock_func_start_imu.assert_called_once() + + @mock.patch('k4a._bindings.device.k4a_device_get_serialnum', side_effect=mock_k4a_get_serialnum) + def test_unit_device_serial_number(self, mock_func_serialnum): + + serial_number = self.device.serial_number + + self.assertIsInstance(serial_number, str) + self.assertEqual(serial_number, "b'0123-4567890'") + mock_func_serialnum.assert_not_called() # Not called because it is a device property. + + @mock.patch('k4a._bindings.device.k4a_device_get_version', side_effect=mock_k4a_get_version) + def test_unit_device_hardware_version(self, mock_func_version): + + hardware_version = self.device.hardware_version + + self.assertIsInstance(hardware_version, k4a.HardwareVersion) + self.assertTrue(str(hardware_version.rgb)=="0.1.0") + self.assertTrue(str(hardware_version.depth)=="0.1.0") + self.assertTrue(str(hardware_version.audio)=="0.1.0") + self.assertTrue(str(hardware_version.depth_sensor)=="0.1.0") + self.assertTrue(hardware_version.firmware_build==1) + self.assertTrue(hardware_version.firmware_signature==1) + mock_func_version.assert_not_called() + + @mock.patch('k4a._bindings.device.k4a_device_get_info', side_effect=mock_k4a_get_device_info) + def test_unit_device_device_info(self, mock_func_info): + + device_info = self.device.device_info + + capabilities = (k4a.EDeviceCapabilities.DEPTH | k4a.EDeviceCapabilities.COLOR | + k4a.EDeviceCapabilities.IMU | k4a.EDeviceCapabilities.MICROPHONE) + + self.assertIsInstance(device_info, k4a.DeviceInfo) + self.assertEqual(device_info.struct_size, 20) + self.assertEqual(device_info.struct_version, k4a.K4A_ABI_VERSION) + self.assertEqual(device_info.vendor_id, 0x045E) + self.assertEqual(device_info.device_id, 0x097C) + self.assertEqual(device_info.capabilities.value, capabilities) + mock_func_info.assert_not_called() + + @mock.patch('k4a._bindings.device.k4a_device_get_color_mode_count', side_effect=mock_k4a_get_mode_count) + @mock.patch('k4a._bindings.device.k4a_device_get_color_mode', side_effect=mock_k4a_get_color_mode) + def test_unit_device_get_color_modes(self, mock_func_mode, mock_func_count): + + color_modes = self.device.get_color_modes() + + self.assertIsInstance(color_modes, list) + self.assertEqual(len(color_modes), 2) + + self.assertIsInstance(color_modes[0], k4a.ColorModeInfo) + self.assertEqual(color_modes[0].struct_size, 40) + self.assertEqual(color_modes[0].struct_version, k4a.K4A_ABI_VERSION) + self.assertEqual(color_modes[0].mode_id, 0) + self.assertEqual(color_modes[0].width, 0) + self.assertEqual(color_modes[0].height, 0) + self.assertEqual(color_modes[0].native_format, k4a.EImageFormat.COLOR_MJPG) + self.assertEqual(color_modes[0].horizontal_fov, 0) + self.assertEqual(color_modes[0].vertical_fov, 0) + self.assertEqual(color_modes[0].min_fps, 0) + self.assertEqual(color_modes[0].max_fps, 0) + + self.assertIsInstance(color_modes[1], k4a.ColorModeInfo) + self.assertEqual(color_modes[1].struct_size, 40) + self.assertEqual(color_modes[1].struct_version, k4a.K4A_ABI_VERSION) + self.assertEqual(color_modes[1].mode_id, 1) + self.assertEqual(color_modes[1].width, 512) + self.assertEqual(color_modes[1].height, 256) + self.assertEqual(color_modes[1].native_format, k4a.EImageFormat.COLOR_MJPG) + self.assertEqual(color_modes[1].horizontal_fov, 120) + self.assertEqual(color_modes[1].vertical_fov, 120) + self.assertEqual(color_modes[1].min_fps, 5) + self.assertEqual(color_modes[1].max_fps, 30) + + mock_func_count.assert_called_once() + self.assertEqual(mock_func_mode.call_count, 2) # Check that k4a_get_color_mode is called twice, once for each mode. + + @mock.patch('k4a._bindings.device.k4a_device_get_color_mode_count', return_value=k4a.EStatus.FAILED) + @mock.patch('k4a._bindings.device.k4a_device_get_color_mode', side_effect=mock_k4a_get_color_mode) + def test_unit_device_get_color_modes_count_fail(self, mock_func_mode, mock_func_count): + + color_modes = self.device.get_color_modes() + self.assertIsNone(color_modes) + + mock_func_count.assert_called_once() + mock_func_mode.assert_not_called() # If mode count fails, then get mode does not get called. + + @mock.patch('k4a._bindings.device.k4a_device_get_color_mode_count', side_effect=mock_k4a_get_mode_count) + @mock.patch('k4a._bindings.device.k4a_device_get_color_mode', return_value=k4a.EStatus.FAILED) + def test_unit_device_get_color_modes_fail(self, mock_func_mode, mock_func_count): + + color_modes = self.device.get_color_modes() + self.assertIsNone(color_modes) + + mock_func_count.assert_called_once() + self.assertEqual(mock_func_mode.call_count, 2) + + @mock.patch('k4a._bindings.device.k4a_device_get_depth_mode_count', side_effect=mock_k4a_get_mode_count) + @mock.patch('k4a._bindings.device.k4a_device_get_depth_mode', side_effect=mock_k4a_get_depth_mode) + def test_unit_device_get_depth_modes(self, mock_func_mode, mock_func_count): + + depth_modes = self.device.get_depth_modes() + + self.assertIsInstance(depth_modes, list) + self.assertEqual(len(depth_modes), 2) + + self.assertIsInstance(depth_modes[0], k4a.DepthModeInfo) + self.assertEqual(depth_modes[0].struct_size, 52) + self.assertEqual(depth_modes[0].struct_version, k4a.K4A_ABI_VERSION) + self.assertEqual(depth_modes[0].mode_id, 0) + self.assertEqual(depth_modes[0].width, 0) + self.assertEqual(depth_modes[0].height, 0) + self.assertEqual(depth_modes[0].native_format, k4a.EImageFormat.DEPTH16) + self.assertEqual(depth_modes[0].horizontal_fov, 0) + self.assertEqual(depth_modes[0].vertical_fov, 0) + self.assertEqual(depth_modes[0].min_fps, 0) + self.assertEqual(depth_modes[0].max_fps, 0) + + self.assertIsInstance(depth_modes[1], k4a.DepthModeInfo) + self.assertEqual(depth_modes[1].struct_size, 52) + self.assertEqual(depth_modes[1].struct_version, k4a.K4A_ABI_VERSION) + self.assertEqual(depth_modes[1].mode_id, 1) + self.assertEqual(depth_modes[1].width, 512) + self.assertEqual(depth_modes[1].height, 256) + self.assertEqual(depth_modes[1].native_format, k4a.EImageFormat.DEPTH16) + self.assertEqual(depth_modes[1].horizontal_fov, 120) + self.assertEqual(depth_modes[1].vertical_fov, 120) + self.assertEqual(depth_modes[1].min_fps, 5) + self.assertEqual(depth_modes[1].max_fps, 30) + + mock_func_count.assert_called_once() + self.assertEqual(mock_func_mode.call_count, 2) # Check that k4a_get_depth_mode is called twice, once for each mode. + + @mock.patch('k4a._bindings.device.k4a_device_get_depth_mode_count', return_value=k4a.EStatus.FAILED) + @mock.patch('k4a._bindings.device.k4a_device_get_depth_mode', side_effect=mock_k4a_get_depth_mode) + def test_unit_device_get_depth_modes_count_fail(self, mock_func_mode, mock_func_count): + + depth_modes = self.device.get_depth_modes() + self.assertIsNone(depth_modes) + + mock_func_count.assert_called_once() + mock_func_mode.assert_not_called() # If mode count fails, then get mode does not get called. + + @mock.patch('k4a._bindings.device.k4a_device_get_depth_mode_count', side_effect=mock_k4a_get_mode_count) + @mock.patch('k4a._bindings.device.k4a_device_get_depth_mode', return_value=k4a.EStatus.FAILED) + def test_unit_device_get_depth_modes_fail(self, mock_func_mode, mock_func_count): + + depth_modes = self.device.get_depth_modes() + self.assertIsNone(depth_modes) + + mock_func_count.assert_called_once() + self.assertEqual(mock_func_mode.call_count, 2) + + @mock.patch('k4a._bindings.device.k4a_device_get_fps_mode_count', side_effect=mock_k4a_get_mode_count) + @mock.patch('k4a._bindings.device.k4a_device_get_fps_mode', side_effect=mock_k4a_get_fps_mode) + def test_unit_device_get_fps_modes(self, mock_func_mode, mock_func_count): + + fps_modes = self.device.get_fps_modes() + + self.assertIsInstance(fps_modes, list) + self.assertEqual(len(fps_modes), 2) + + self.assertIsInstance(fps_modes[0], k4a.FPSModeInfo) + self.assertEqual(fps_modes[0].struct_size, 16) + self.assertEqual(fps_modes[0].struct_version, k4a.K4A_ABI_VERSION) + self.assertEqual(fps_modes[0].mode_id, 0) + self.assertEqual(fps_modes[0].fps, 0) + + self.assertIsInstance(fps_modes[1], k4a.FPSModeInfo) + self.assertEqual(fps_modes[1].struct_size, 16) + self.assertEqual(fps_modes[1].struct_version, k4a.K4A_ABI_VERSION) + self.assertEqual(fps_modes[1].mode_id, 15) + self.assertEqual(fps_modes[1].fps, 15) + + mock_func_count.assert_called_once() + self.assertEqual(mock_func_mode.call_count, 2) # Check that k4a_get_depth_mode is called twice, once for each mode. + + @mock.patch('k4a._bindings.device.k4a_device_get_fps_mode_count', return_value=k4a.EStatus.FAILED) + @mock.patch('k4a._bindings.device.k4a_device_get_fps_mode', side_effect=mock_k4a_get_fps_mode) + def test_unit_device_get_fps_modes_count_fail(self, mock_func_mode, mock_func_count): + + fps_modes = self.device.get_fps_modes() + self.assertIsNone(fps_modes) + + mock_func_count.assert_called_once() + mock_func_mode.assert_not_called() # If mode count fails, then get mode does not get called. + + @mock.patch('k4a._bindings.device.k4a_device_get_fps_mode_count', side_effect=mock_k4a_get_mode_count) + @mock.patch('k4a._bindings.device.k4a_device_get_fps_mode', return_value=k4a.EStatus.FAILED) + def test_unit_device_get_fps_modes_fail(self, mock_func_mode, mock_func_count): + + fps_modes = self.device.get_fps_modes() + self.assertIsNone(fps_modes) + + mock_func_count.assert_called_once() + self.assertEqual(mock_func_mode.call_count, 2) + + @mock.patch('k4a._bindings.device.k4a_device_get_capture', side_effect=mock_k4a_device_get_capture) + def test_unit_device_get_capture(self, mock_func_capture): + + capture = self.device.get_capture(0) + self.assertIsInstance(capture, k4a.Capture) + mock_func_capture.assert_called_once() + + @mock.patch('k4a._bindings.device.k4a_device_get_capture', return_value=k4a.EStatus.FAILED) + def test_unit_device_get_capture_fail(self, mock_func_capture): + + capture = self.device.get_capture(0) + self.assertIsNone(capture) + mock_func_capture.assert_called_once() + + @mock.patch('k4a._bindings.device.k4a_device_get_imu_sample', side_effect=mock_k4a_device_get_imu_sample) + def test_unit_device_get_imu(self, mock_func_imu): + + imu_sample = self.device.get_imu_sample(0) + self.assertIsInstance(imu_sample, k4a.ImuSample) + self.assertAlmostEqual(imu_sample.temperature, 1.2, 6) + self.assertEqual(imu_sample.acc_sample.xyz.x, 1) + self.assertEqual(imu_sample.acc_sample.xyz.y, 2) + self.assertEqual(imu_sample.acc_sample.xyz.z, 3) + self.assertEqual(imu_sample.acc_timestamp_usec, 1) + self.assertEqual(imu_sample.gyro_sample.xyz.x, 4) + self.assertEqual(imu_sample.gyro_sample.xyz.y, 5) + self.assertEqual(imu_sample.gyro_sample.xyz.z, 6) + + mock_func_imu.assert_called_once() + + @mock.patch('k4a._bindings.device.k4a_device_get_imu_sample', return_value=k4a.EStatus.FAILED) + def test_unit_device_get_imu_fail(self, mock_func_imu): + + imu_sample = self.device.get_imu_sample(0) + self.assertIsNone(imu_sample) + mock_func_imu.assert_called_once() + + @mock.patch('k4a._bindings.device.k4a_device_get_color_control_capabilities', side_effect=mock_k4a_device_get_color_control_capabilities) + def test_unit_device_get_color_control_capabilities(self, mock_func): + + cap_list, cap_dict = self.device.get_color_control_capabilities() + self.assertIsInstance(cap_list, list) + self.assertIsInstance(cap_dict, dict) + + self.assertEqual(mock_func.call_count, 9) # Check that get_color_control_capabilities is called 9 times, once for each capability. + + for cap in cap_list: + self.assertIsInstance(cap, k4a.ColorControlCapability) + self.assertIsInstance(cap.command, k4a.EColorControlCommand) + self.assertEqual(cap.supports_auto, True) + self.assertEqual(cap.min_value, 100) + self.assertEqual(cap.max_value, 9999) + self.assertEqual(cap.step_value, 1) + self.assertEqual(cap.default_value, 700) + self.assertEqual(cap.default_mode, k4a.EColorControlMode.MANUAL) + + for command, cap in cap_dict.items(): + self.assertIsInstance(command, k4a.EColorControlCommand) + self.assertIsInstance(cap, k4a.ColorControlCapability) + self.assertIsInstance(cap.command, k4a.EColorControlCommand) + self.assertEqual(cap.supports_auto, True) + self.assertEqual(cap.min_value, 100) + self.assertEqual(cap.max_value, 9999) + self.assertEqual(cap.step_value, 1) + self.assertEqual(cap.default_value, 700) + self.assertEqual(cap.default_mode, k4a.EColorControlMode.MANUAL) + + @mock.patch('k4a._bindings.device.k4a_device_get_color_control_capabilities', return_value=k4a.EStatus.FAILED) + def test_unit_device_get_color_control_capabilities_fail(self, mock_func): + + cap_list, cap_dict = self.device.get_color_control_capabilities() + self.assertIsNone(cap_list) + self.assertIsNone(cap_dict) + self.assertEqual(mock_func.call_count, 9) # Check that get_color_control_capabilities is called 9 times, once for each capability. + + @mock.patch('k4a._bindings.device.k4a_device_get_color_control', side_effect=mock_k4a_device_get_color_control) + def test_unit_device_get_color_control(self, mock_func): + + for command in k4a.EColorControlCommand: + + value, mode = self.device.get_color_control(command) + + self.assertIsNotNone(value) + self.assertIsNotNone(mode) + self.assertIsInstance(mode, k4a.EColorControlMode) + self.assertEqual(value, 1000) + self.assertEqual(mode, k4a.EColorControlMode.MANUAL) + + self.assertEqual(mock_func.call_count, len(k4a.EColorControlCommand)) + + @mock.patch('k4a._bindings.device.k4a_device_get_color_control', return_value=k4a.EStatus.FAILED) + def test_unit_device_get_color_control_fail(self, mock_func): + + for command in k4a.EColorControlCommand: + + value, mode = self.device.get_color_control(command) + + self.assertIsNone(value) + self.assertIsNone(mode) + + self.assertEqual(mock_func.call_count, len(k4a.EColorControlCommand)) + + @mock.patch('k4a._bindings.device.k4a_device_set_color_control', side_effect=mock_k4a_device_set_color_control) + def test_unit_device_set_color_control(self, mock_func): + + for command in k4a.EColorControlCommand: + status = self.device.set_color_control(command, k4a.EColorControlMode.MANUAL, 1000) + self.assertEqual(status, k4a.EStatus.SUCCEEDED) + + @mock.patch('k4a._bindings.device.k4a_device_set_color_control', return_value=k4a.EStatus.FAILED) + def test_unit_device_set_color_control_fail(self, mock_func): + + for command in k4a.EColorControlCommand: + status = self.device.set_color_control(command, k4a.EColorControlMode.MANUAL, 1000) + self.assertEqual(status, k4a.EStatus.FAILED) + + @mock.patch('k4a._bindings.device.k4a_device_get_sync_jack', side_effect=mock_k4a_device_get_sync_jack) + def test_unit_device_get_sync_jack(self, mock_func): + + sync_in, sync_out = self.device.get_sync_jack() + + mock_func.assert_called_once() + self.assertIsNotNone(sync_in) + self.assertIsNotNone(sync_out) + self.assertEqual(sync_in, False) + self.assertEqual(sync_out, True) + + @mock.patch('k4a._bindings.device.k4a_device_get_sync_jack', return_value=k4a.EStatus.FAILED) + def test_unit_device_get_sync_jack_fail(self, mock_func): + + sync_in, sync_out = self.device.get_sync_jack() + + mock_func.assert_called_once() + self.assertIsNotNone(sync_in) + self.assertIsNotNone(sync_out) + self.assertEqual(sync_in, False) + self.assertEqual(sync_out, False) + + @mock.patch('k4a._bindings.device.k4a_device_get_raw_calibration', side_effect=mock_k4a_device_get_raw_calibration) + def test_unit_device_get_raw_calibration(self, mock_func): + + buffer = self.device.get_raw_calibration() + self.assertEqual(mock_func.call_count, 2) + self.assertIsNotNone(buffer) + + @mock.patch('k4a._bindings.device.k4a_device_get_raw_calibration', return_value=k4a.EBufferStatus.FAILED) + def test_unit_device_get_raw_calibration_fail(self, mock_func): + + buffer = self.device.get_raw_calibration() + self.assertEqual(mock_func.call_count, 1) + self.assertIsNone(buffer) + + @mock.patch('k4a._bindings.device.k4a_device_get_calibration', side_effect=mock_k4a_device_get_calibration) + def test_unit_device_get_calibration(self, mock_func): + + calibration = self.device.get_calibration(1, 1) + self.assertEqual(mock_func.call_count, 1) + self.assertIsNotNone(calibration) + self.assertIsInstance(calibration, k4a.Calibration) + + @mock.patch('k4a._bindings.device.k4a_device_get_calibration', return_value=k4a.EStatus.FAILED) + def test_unit_device_get_calibration_fail(self, mock_func): + + calibration = self.device.get_calibration(1, 1) + self.assertEqual(mock_func.call_count, 1) + self.assertIsNone(calibration) + diff --git a/src/python/k4a/tests/test_unit_k4atypes.py b/src/python/k4a/tests/test_unit_k4atypes.py index f6c8aef23..073a90616 100644 --- a/src/python/k4a/tests/test_unit_k4atypes.py +++ b/src/python/k4a/tests/test_unit_k4atypes.py @@ -14,10 +14,10 @@ def get_enum_values(n, start_value = 0): value = start_value - while(value < n): + while(value < n + start_value): yield value value = value + 1 - + class TestEnums(unittest.TestCase): '''Test enum instantiation and values to ensure they are not broken. @@ -35,18 +35,24 @@ def test_unit_EStatus(self): enum_values = get_enum_values(len(k4a.EStatus)) self.assertEqual(k4a.EStatus.SUCCEEDED, next(enum_values)) self.assertEqual(k4a.EStatus.FAILED, next(enum_values)) + self.assertEqual(k4a.EStatus.UNSUPPORTED, next(enum_values)) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. def test_unit_EBufferStatus(self): enum_values = get_enum_values(len(k4a.EBufferStatus)) self.assertEqual(k4a.EBufferStatus.SUCCEEDED, next(enum_values)) self.assertEqual(k4a.EBufferStatus.FAILED, next(enum_values)) self.assertEqual(k4a.EBufferStatus.BUFFER_TOO_SMALL, next(enum_values)) + self.assertEqual(k4a.EBufferStatus.UNSUPPORTED, next(enum_values)) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. def test_unit_EWaitStatus(self): enum_values = get_enum_values(len(k4a.EWaitStatus)) self.assertEqual(k4a.EWaitStatus.SUCCEEDED, next(enum_values)) self.assertEqual(k4a.EWaitStatus.FAILED, next(enum_values)) self.assertEqual(k4a.EWaitStatus.TIMEOUT, next(enum_values)) + self.assertEqual(k4a.EWaitStatus.UNSUPPORTED, next(enum_values)) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. def test_unit_ELogLevel(self): enum_values = get_enum_values(len(k4a.ELogLevel)) @@ -56,25 +62,15 @@ def test_unit_ELogLevel(self): self.assertEqual(k4a.ELogLevel.INFO, next(enum_values)) self.assertEqual(k4a.ELogLevel.TRACE, next(enum_values)) self.assertEqual(k4a.ELogLevel.OFF, next(enum_values)) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. - def test_unit_EDepthMode(self): - enum_values = get_enum_values(len(k4a.EDepthMode)) - self.assertEqual(k4a.EDepthMode.OFF, next(enum_values)) - self.assertEqual(k4a.EDepthMode.NFOV_2X2BINNED, next(enum_values)) - self.assertEqual(k4a.EDepthMode.NFOV_UNBINNED, next(enum_values)) - self.assertEqual(k4a.EDepthMode.WFOV_2X2BINNED, next(enum_values)) - self.assertEqual(k4a.EDepthMode.WFOV_UNBINNED, next(enum_values)) - self.assertEqual(k4a.EDepthMode.PASSIVE_IR, next(enum_values)) - - def test_unit_EColorResolution(self): - enum_values = get_enum_values(len(k4a.EColorResolution)) - self.assertEqual(k4a.EColorResolution.OFF, next(enum_values)) - self.assertEqual(k4a.EColorResolution.RES_720P, next(enum_values)) - self.assertEqual(k4a.EColorResolution.RES_1080P, next(enum_values)) - self.assertEqual(k4a.EColorResolution.RES_1440P, next(enum_values)) - self.assertEqual(k4a.EColorResolution.RES_1536P, next(enum_values)) - self.assertEqual(k4a.EColorResolution.RES_2160P, next(enum_values)) - self.assertEqual(k4a.EColorResolution.RES_3072P, next(enum_values)) + def test_unit_EDeviceCapabilities(self): + enum_values = get_enum_values(len(k4a.EDeviceCapabilities), 1) + self.assertEqual(k4a.EDeviceCapabilities.DEPTH, 1), next(enum_values) + self.assertEqual(k4a.EDeviceCapabilities.COLOR, 2), next(enum_values) + self.assertEqual(k4a.EDeviceCapabilities.IMU, 4), next(enum_values) + self.assertEqual(k4a.EDeviceCapabilities.MICROPHONE, 8), next(enum_values) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. def test_unit_EImageFormat(self): enum_values = get_enum_values(len(k4a.EImageFormat)) @@ -87,17 +83,13 @@ def test_unit_EImageFormat(self): self.assertEqual(k4a.EImageFormat.CUSTOM8, next(enum_values)) self.assertEqual(k4a.EImageFormat.CUSTOM16, next(enum_values)) self.assertEqual(k4a.EImageFormat.CUSTOM, next(enum_values)) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. def test_unit_ETransformInterpolationType(self): enum_values = get_enum_values(len(k4a.ETransformInterpolationType)) self.assertEqual(k4a.ETransformInterpolationType.NEAREST, next(enum_values)) self.assertEqual(k4a.ETransformInterpolationType.LINEAR, next(enum_values)) - - def test_unit_EFramesPerSecond(self): - enum_values = get_enum_values(len(k4a.EFramesPerSecond)) - self.assertEqual(k4a.EFramesPerSecond.FPS_5, next(enum_values)) - self.assertEqual(k4a.EFramesPerSecond.FPS_15, next(enum_values)) - self.assertEqual(k4a.EFramesPerSecond.FPS_30, next(enum_values)) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. def test_unit_EColorControlCommand(self): enum_values = get_enum_values(len(k4a.EColorControlCommand)) @@ -111,17 +103,20 @@ def test_unit_EColorControlCommand(self): self.assertEqual(k4a.EColorControlCommand.BACKLIGHT_COMPENSATION, next(enum_values)) self.assertEqual(k4a.EColorControlCommand.GAIN, next(enum_values)) self.assertEqual(k4a.EColorControlCommand.POWERLINE_FREQUENCY, next(enum_values)) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. def test_unit_EColorControlMode(self): enum_values = get_enum_values(len(k4a.EColorControlMode)) self.assertEqual(k4a.EColorControlMode.AUTO, next(enum_values)) self.assertEqual(k4a.EColorControlMode.MANUAL, next(enum_values)) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. def test_unit_EWiredSyncMode(self): enum_values = get_enum_values(len(k4a.EWiredSyncMode)) self.assertEqual(k4a.EWiredSyncMode.STANDALONE, next(enum_values)) self.assertEqual(k4a.EWiredSyncMode.MASTER, next(enum_values)) self.assertEqual(k4a.EWiredSyncMode.SUBORDINATE, next(enum_values)) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. def test_unit_ECalibrationType(self): enum_values = get_enum_values(len(k4a.ECalibrationType), start_value = -1) @@ -131,6 +126,7 @@ def test_unit_ECalibrationType(self): self.assertEqual(k4a.ECalibrationType.GYRO, next(enum_values)) self.assertEqual(k4a.ECalibrationType.ACCEL, next(enum_values)) self.assertEqual(k4a.ECalibrationType.NUM_TYPES, next(enum_values)) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. def test_unit_ECalibrationModelType(self): enum_values = get_enum_values(len(k4a.ECalibrationModelType)) @@ -139,17 +135,20 @@ def test_unit_ECalibrationModelType(self): self.assertEqual(k4a.ECalibrationModelType.LENS_DISTORTION_MODEL_POLYNOMIAL_3K, next(enum_values)) self.assertEqual(k4a.ECalibrationModelType.LENS_DISTORTION_MODEL_RATIONAL_6KT, next(enum_values)) self.assertEqual(k4a.ECalibrationModelType.LENS_DISTORTION_MODEL_BROWN_CONRADY, next(enum_values)) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. def test_unit_EFirmwareBuild(self): enum_values = get_enum_values(len(k4a.EFirmwareBuild)) self.assertEqual(k4a.EFirmwareBuild.RELEASE, next(enum_values)) self.assertEqual(k4a.EFirmwareBuild.DEBUG, next(enum_values)) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. def test_unit_EFirmwareSignature(self): enum_values = get_enum_values(len(k4a.EFirmwareSignature)) self.assertEqual(k4a.EFirmwareSignature.MSFT, next(enum_values)) self.assertEqual(k4a.EFirmwareSignature.TEST, next(enum_values)) self.assertEqual(k4a.EFirmwareSignature.UNSIGNED, next(enum_values)) + self.assertRaises(StopIteration, next, enum_values) # Must be last assert. def test_unit_K4A_SUCCEEDED_True(self): self.assertTrue(k4a.K4A_SUCCEEDED(k4a.EStatus.SUCCEEDED)) @@ -186,71 +185,150 @@ def test_unit__TransformationHandle(self): transformation_handle = k4a._bindings.k4a._TransformationHandle() self.assertIsInstance(transformation_handle, k4a._bindings.k4a._TransformationHandle) + def test_unit_DeviceInfo(self): + device_info = k4a.DeviceInfo() + self.assertIsNotNone(device_info) + self.assertEqual(len(device_info._fields_), 5) + + s = device_info.__str__() + self.assertIsInstance(s, str) + + def test_unit_ColorModeInfo(self): + color_mode_info = k4a.ColorModeInfo() + self.assertIsNotNone(color_mode_info) + self.assertEqual(len(color_mode_info._fields_), 10) + + s = color_mode_info.__str__() + self.assertIsInstance(s, str) + + def test_unit_DepthModeInfo(self): + depth_mode_info = k4a.DepthModeInfo() + self.assertIsNotNone(depth_mode_info) + self.assertEqual(len(depth_mode_info._fields_), 13) + + s = depth_mode_info.__str__() + self.assertIsInstance(s, str) + + def test_unit_FPSModeInfo(self): + fps_mode_info = k4a.FPSModeInfo() + self.assertIsNotNone(fps_mode_info) + self.assertEqual(len(fps_mode_info._fields_), 4) + + s = fps_mode_info.__str__() + self.assertIsInstance(s, str) + def test_unit_DeviceConfiguration(self): device_config = k4a.DeviceConfiguration() self.assertIsNotNone(device_config) self.assertEqual(len(device_config._fields_), 9) + s = device_config.__str__() + self.assertIsInstance(s, str) + def test_unit_CalibrationExtrinsics(self): calibration_extrinsics = k4a.CalibrationExtrinsics() self.assertIsNotNone(calibration_extrinsics) self.assertEqual(len(calibration_extrinsics._fields_), 2) + s = calibration_extrinsics.__str__() + self.assertIsInstance(s, str) + def test_unit_CalibrationIntrinsicParam(self): calib_intrinsic = k4a.CalibrationIntrinsicParam() self.assertIsNotNone(calib_intrinsic) self.assertEqual(len(calib_intrinsic._fields_), 15) + s = calib_intrinsic.__str__() + self.assertIsInstance(s, str) + def test_unit_CalibrationIntrinsics(self): calib_intrinsic = k4a.CalibrationIntrinsics() self.assertIsNotNone(calib_intrinsic) self.assertEqual(len(calib_intrinsic._fields_), 3) + s = calib_intrinsic.__str__() + self.assertIsInstance(s, str) + def test_unit_CalibrationCamera(self): camera_calibration = k4a.CalibrationCamera() self.assertIsNotNone(camera_calibration) self.assertEqual(len(camera_calibration._fields_), 5) + s = camera_calibration.__str__() + self.assertIsInstance(s, str) + def test_unit__Calibration(self): calibration = k4a._bindings.k4a._Calibration() self.assertIsNotNone(calibration) self.assertEqual(len(calibration._fields_), 5) + s = calibration.__str__() + self.assertIsInstance(s, str) + def test_unit_Version(self): version = k4a.Version() self.assertIsNotNone(version) self.assertEqual(len(version._fields_), 3) + s = version.__str__() + self.assertIsInstance(s, str) + def test_unit_HardwareVersion(self): version = k4a.HardwareVersion() self.assertIsNotNone(version) self.assertEqual(len(version._fields_), 6) + s = version.__str__() + self.assertIsInstance(s, str) + def test_unit__XY(self): xy = k4a._bindings.k4atypes._XY() self.assertIsNotNone(xy) self.assertEqual(len(xy._fields_), 2) + s = xy.__str__() + self.assertIsInstance(s, str) + def test_unit__Float2(self): xy = k4a._bindings.k4a._Float2() self.assertIsNotNone(xy) self.assertEqual(len(xy._fields_), 2) + s = xy.__str__() + self.assertIsInstance(s, str) + def test_unit__XYZ(self): xyz = k4a._bindings.k4atypes._XYZ() self.assertIsNotNone(xyz) self.assertEqual(len(xyz._fields_), 3) + s = xyz.__str__() + self.assertIsInstance(s, str) + def test_unit__Float3(self): xyz = k4a._bindings.k4a._Float3() self.assertIsNotNone(xyz) self.assertEqual(len(xyz._fields_), 2) + s = xyz.__str__() + self.assertIsInstance(s, str) + def test_unit_ImuSample(self): imu = k4a.ImuSample() self.assertIsNotNone(imu) self.assertEqual(len(imu._fields_), 5) + s = imu.__str__() + self.assertIsInstance(s, str) + + def test_unit_ColorControlCapability(self): + capability = k4a.ColorControlCapability(k4a.EColorControlCommand.BRIGHTNESS) + self.assertIsNotNone(capability) + self.assertEqual(len(capability.__dict__), 7) + + s = capability.__str__() + self.assertIsInstance(s, str) + if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/src/record/internal/CMakeLists.txt b/src/record/internal/CMakeLists.txt index 97c6cf3a2..7d23fca27 100644 --- a/src/record/internal/CMakeLists.txt +++ b/src/record/internal/CMakeLists.txt @@ -21,13 +21,16 @@ target_include_directories(k4a_playback PUBLIC target_link_libraries(k4a_record PUBLIC k4a::k4a + cJSON::cJSON k4ainternal::logging + k4ainternal::modes ebml::ebml matroska::matroska ) target_link_libraries(k4a_playback PUBLIC k4a::k4a + cJSON::cJSON k4ainternal::logging ebml::ebml matroska::matroska diff --git a/src/record/internal/matroska_read.cpp b/src/record/internal/matroska_read.cpp index bd360118f..c0e6db93d 100644 --- a/src/record/internal/matroska_read.cpp +++ b/src/record/internal/matroska_read.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #include @@ -8,13 +8,18 @@ #include #include +#include #include -#include +#include #include +#include #include #include +#include +#include //cJSON.h need this set correctly. + using namespace LIBMATROSKA_NAMESPACE; namespace k4arecord @@ -421,6 +426,11 @@ k4a_result_t parse_recording_config(k4a_playback_context_t *context) LOG_WARNING("Device calibration is missing from recording.", 0); } + // Make some reasonable assumptions: Color is OFF, Depth is OFF, and FPS is 30. + uint32_t color_mode_id = K4A_COLOR_RESOLUTION_OFF; + uint32_t depth_mode_id = K4A_DEPTH_MODE_OFF; + uint32_t fps_mode_id = K4A_FRAMES_PER_SECOND_30; + uint64_t frame_period_ns = 0; if (context->color_track) { @@ -433,7 +443,7 @@ k4a_result_t parse_recording_config(k4a_playback_context_t *context) frame_period_ns = context->color_track->frame_period_ns; RETURN_IF_ERROR(read_bitmap_info_header(context->color_track)); - context->record_config.color_resolution = K4A_COLOR_RESOLUTION_OFF; + for (size_t i = 0; i < arraysize(color_resolutions); i++) { uint32_t width, height; @@ -441,13 +451,13 @@ k4a_result_t parse_recording_config(k4a_playback_context_t *context) { if (context->color_track->width == width && context->color_track->height == height) { - context->record_config.color_resolution = color_resolutions[i]; + color_mode_id = color_resolutions[i]; break; } } } - if (context->record_config.color_resolution == K4A_COLOR_RESOLUTION_OFF) + if (color_mode_id == K4A_COLOR_RESOLUTION_OFF) { LOG_WARNING("The color resolution is not officially supported: %dx%d. You cannot get the calibration " "information for this color resolution", @@ -461,7 +471,6 @@ k4a_result_t parse_recording_config(k4a_playback_context_t *context) } else { - context->record_config.color_resolution = K4A_COLOR_RESOLUTION_OFF; // Set to a default color format if color track is disabled. context->record_config.color_format = K4A_IMAGE_FORMAT_CUSTOM; context->color_format_conversion = K4A_IMAGE_FORMAT_CUSTOM; @@ -477,7 +486,6 @@ k4a_result_t parse_recording_config(k4a_playback_context_t *context) std::string depth_mode_str; uint32_t depth_width = 0; uint32_t depth_height = 0; - context->record_config.depth_mode = K4A_DEPTH_MODE_OFF; if (depth_mode_tag != NULL) { @@ -488,13 +496,13 @@ k4a_result_t parse_recording_config(k4a_playback_context_t *context) { if (k4a_convert_depth_mode_to_width_height(depth_modes[i].first, &depth_width, &depth_height)) { - context->record_config.depth_mode = depth_modes[i].first; + depth_mode_id = depth_modes[i].first; break; } } } - if (context->record_config.depth_mode == K4A_DEPTH_MODE_OFF) + if (depth_mode_id == K4A_DEPTH_MODE_OFF) { // Try to find the mode matching strings in the legacy modes for (size_t i = 0; i < arraysize(legacy_depth_modes); i++) @@ -505,13 +513,13 @@ k4a_result_t parse_recording_config(k4a_playback_context_t *context) &depth_width, &depth_height)) { - context->record_config.depth_mode = legacy_depth_modes[i].first; + depth_mode_id = legacy_depth_modes[i].first; break; } } } } - if (context->record_config.depth_mode == K4A_DEPTH_MODE_OFF) + if (depth_mode_id == K4A_DEPTH_MODE_OFF) { LOG_ERROR("Unsupported depth mode: %s", depth_mode_str.c_str()); return K4A_RESULT_FAILED; @@ -606,29 +614,459 @@ k4a_result_t parse_recording_config(k4a_playback_context_t *context) context->sync_period_ns = frame_period_ns; if (frame_period_ns > 0) { - switch (1_s / frame_period_ns) + k4a_fps_t fps_t = k4a_convert_uint_to_fps(static_cast(1_s / frame_period_ns)); + if (fps_t == K4A_FRAMES_PER_SECOND_0) { - case 5: - context->record_config.camera_fps = K4A_FRAMES_PER_SECOND_5; - break; - case 15: - context->record_config.camera_fps = K4A_FRAMES_PER_SECOND_15; - break; - case 30: - context->record_config.camera_fps = K4A_FRAMES_PER_SECOND_30; - break; - default: LOG_ERROR("Unsupported recording frame period: %llu ns (%llu fps)", frame_period_ns, (1_s / frame_period_ns)); return K4A_RESULT_FAILED; } + + fps_mode_id = static_cast(fps_t); } else { // Default to 30 fps if no video tracks are enabled. - context->record_config.camera_fps = K4A_FRAMES_PER_SECOND_30; + fps_mode_id = K4A_FRAMES_PER_SECOND_30; + } + + KaxTag *device_info_tag = get_tag(context, "K4A_DEVICE_INFO"); + KaxTag *color_mode_info_tag = get_tag(context, "K4A_COLOR_MODE_INFO"); + KaxTag *depth_mode_info_tag = get_tag(context, "K4A_DEPTH_MODE_INFO"); + KaxTag *fps_mode_info_tag = get_tag(context, "K4A_FPS_MODE_INFO"); + + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_fps_mode_info_t fps_mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + + k4a_result_t device_info_result = K4A_RESULT_SUCCEEDED; + k4a_result_t color_mode_info_result = K4A_RESULT_SUCCEEDED; + k4a_result_t depth_mode_info_result = K4A_RESULT_SUCCEEDED; + k4a_result_t fps_mode_info_result = K4A_RESULT_SUCCEEDED; + + bool hasColorDevice = false; + bool hasDepthDevice = false; + + // device info + if (device_info_tag != NULL) + { + std::string device_info_string = get_tag_string(device_info_tag); + if (!device_info_string.empty()) + { + cJSON *device_info_json = cJSON_Parse(device_info_string.c_str()); + if (device_info_json != NULL) + { + const cJSON *device_info_json_capabilities = cJSON_GetObjectItem(device_info_json, "capabilities"); + if (device_info_json_capabilities != nullptr && cJSON_IsNumber(device_info_json_capabilities)) + { + device_info.capabilities.value = (uint32_t)device_info_json_capabilities->valueint; + hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + } + else + { + device_info_result = K4A_RESULT_FAILED; + } + + const cJSON *device_info_json_device_id = cJSON_GetObjectItem(device_info_json, "device_id"); + if (device_info_json_device_id != nullptr && cJSON_IsNumber(device_info_json_device_id)) + { + device_info.device_id = (uint32_t)device_info_json_device_id->valueint; + } + else + { + device_info_result = K4A_RESULT_FAILED; + } + + const cJSON *device_info_json_vendor_id = cJSON_GetObjectItem(device_info_json, "vendor_id"); + if (device_info_json_vendor_id != nullptr && cJSON_IsNumber(device_info_json_vendor_id)) + { + device_info.vendor_id = (uint32_t)device_info_json_vendor_id->valueint; + } + else + { + device_info_result = K4A_RESULT_FAILED; + } + } + else + { + device_info_result = K4A_RESULT_FAILED; + } + cJSON_Delete(device_info_json); + } + else + { + device_info_result = K4A_RESULT_FAILED; + } + } + + if (!K4A_SUCCEEDED(device_info_result) || device_info_tag == NULL) + { + device_info.device_id = K4A_DEPTH_PID; + device_info.vendor_id = K4A_MSFT_VID; + device_info.capabilities.value = K4A_CAPABILITY_IMU | K4A_CAPABILITY_COLOR | K4A_CAPABILITY_DEPTH | + K4A_CAPABILITY_MICROPHONE; + } + + context->record_config.device_info = device_info; + + // color + if (hasColorDevice && color_mode_info_tag != NULL) + { + std::string color_mode_info_string = get_tag_string(color_mode_info_tag); + + if (!color_mode_info_string.empty()) + { + cJSON *color_mode_info_json = cJSON_Parse(color_mode_info_string.c_str()); + + if (color_mode_info_json != NULL) + { + const cJSON *color_mode_info_json_mode_id = cJSON_GetObjectItem(color_mode_info_json, "mode_id"); + if (color_mode_info_json_mode_id != nullptr && cJSON_IsNumber(color_mode_info_json_mode_id)) + { + color_mode_info.mode_id = (uint32_t)color_mode_info_json_mode_id->valueint; + } + else + { + color_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *color_mode_info_json_width = cJSON_GetObjectItem(color_mode_info_json, "width"); + if (color_mode_info_json_width != nullptr && cJSON_IsNumber(color_mode_info_json_width)) + { + color_mode_info.width = (uint32_t)color_mode_info_json_width->valueint; + } + else + { + color_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *color_mode_info_json_height = cJSON_GetObjectItem(color_mode_info_json, "height"); + if (color_mode_info_json_height != nullptr && cJSON_IsNumber(color_mode_info_json_height)) + { + color_mode_info.height = (uint32_t)color_mode_info_json_height->valueint; + } + else + { + color_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *color_mode_info_json_native_format = cJSON_GetObjectItem(color_mode_info_json, + "native_format"); + if (color_mode_info_json_native_format != nullptr && cJSON_IsNumber(color_mode_info_json_native_format)) + { + color_mode_info.native_format = (k4a_image_format_t)( + int)color_mode_info_json_native_format->valueint; + } + else + { + color_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *color_mode_info_json_horizontal_fov = cJSON_GetObjectItem(color_mode_info_json, + "horizontal_fov"); + if (color_mode_info_json_horizontal_fov != nullptr && + cJSON_IsNumber(color_mode_info_json_horizontal_fov)) + { + color_mode_info.horizontal_fov = (float)color_mode_info_json_horizontal_fov->valuedouble; + } + else + { + color_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *color_mode_info_json_vertical_fov = cJSON_GetObjectItem(color_mode_info_json, + "vertical_fov"); + if (color_mode_info_json_vertical_fov != nullptr && cJSON_IsNumber(color_mode_info_json_vertical_fov)) + { + color_mode_info.vertical_fov = (float)color_mode_info_json_vertical_fov->valuedouble; + } + else + { + color_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *color_mode_info_json_min_fps = cJSON_GetObjectItem(color_mode_info_json, "min_fps"); + if (color_mode_info_json_min_fps != nullptr && cJSON_IsNumber(color_mode_info_json_min_fps)) + { + color_mode_info.min_fps = (uint32_t)color_mode_info_json_min_fps->valueint; + } + else + { + color_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *color_mode_info_json_max_fps = cJSON_GetObjectItem(color_mode_info_json, "max_fps"); + if (color_mode_info_json_max_fps != nullptr && cJSON_IsNumber(color_mode_info_json_max_fps)) + { + color_mode_info.max_fps = (uint32_t)color_mode_info_json_max_fps->valueint; + } + else + { + color_mode_info_result = K4A_RESULT_FAILED; + } + } + else + { + color_mode_info_result = K4A_RESULT_FAILED; + } + + cJSON_Delete(color_mode_info_json); + } + else + { + color_mode_info_result = K4A_RESULT_FAILED; + } } + else + { + color_mode_info_result = K4A_RESULT_FAILED; + } + + if (!K4A_SUCCEEDED(color_mode_info_result)) + { + int mode_count = (int)k4a_get_device_color_modes_count(); + k4a_color_mode_info_t color_mode; + for (int i = 0; i < mode_count; i++) + { + color_mode = k4a_get_device_color_mode(i); + if (color_mode.mode_id == color_mode_id) + { + SAFE_COPY_STRUCT(&color_mode_info, &color_mode); + break; + } + } + } + + context->record_config.color_mode_info = color_mode_info; + + // depth + if (hasDepthDevice && depth_mode_info_tag != NULL) + { + std::string depth_mode_info_string = get_tag_string(depth_mode_info_tag); + + if (!depth_mode_info_string.empty()) + { + cJSON *depth_mode_info_json = cJSON_Parse(depth_mode_info_string.c_str()); + if (depth_mode_info_json != NULL) + { + const cJSON *depth_mode_info_json_mode_id = cJSON_GetObjectItem(depth_mode_info_json, "mode_id"); + if (depth_mode_info_json_mode_id != nullptr && cJSON_IsNumber(depth_mode_info_json_mode_id)) + { + depth_mode_info.mode_id = (uint32_t)depth_mode_info_json_mode_id->valueint; + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *depth_mode_info_json_passive_ir_only = cJSON_GetObjectItem(depth_mode_info_json, + "passive_ir_only"); + if (depth_mode_info_json_passive_ir_only != nullptr && + cJSON_IsBool(depth_mode_info_json_passive_ir_only)) + { + depth_mode_info.passive_ir_only = cJSON_IsTrue(depth_mode_info_json_passive_ir_only) ? true : false; + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *depth_mode_info_json_width = cJSON_GetObjectItem(depth_mode_info_json, "width"); + if (depth_mode_info_json_width != nullptr && cJSON_IsNumber(depth_mode_info_json_width)) + { + depth_mode_info.width = (uint32_t)depth_mode_info_json_width->valueint; + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *depth_mode_info_json_height = cJSON_GetObjectItem(depth_mode_info_json, "height"); + if (depth_mode_info_json_height != nullptr && cJSON_IsNumber(depth_mode_info_json_height)) + { + depth_mode_info.height = (uint32_t)depth_mode_info_json_height->valueint; + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *depth_mode_info_json_native_format = cJSON_GetObjectItem(depth_mode_info_json, + "native_format"); + if (depth_mode_info_json_native_format != nullptr && cJSON_IsNumber(depth_mode_info_json_native_format)) + { + depth_mode_info.native_format = (k4a_image_format_t)( + int)depth_mode_info_json_native_format->valueint; + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *depth_mode_info_json_horizontal_fov = cJSON_GetObjectItem(depth_mode_info_json, + "horizontal_fov"); + if (depth_mode_info_json_horizontal_fov != nullptr && + cJSON_IsNumber(depth_mode_info_json_horizontal_fov)) + { + depth_mode_info.horizontal_fov = (float)depth_mode_info_json_horizontal_fov->valuedouble; + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *depth_mode_info_json_vertical_fov = cJSON_GetObjectItem(depth_mode_info_json, + "vertical_fov"); + if (depth_mode_info_json_vertical_fov != nullptr && cJSON_IsNumber(depth_mode_info_json_vertical_fov)) + { + depth_mode_info.vertical_fov = (float)depth_mode_info_json_vertical_fov->valuedouble; + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *depth_mode_info_json_min_fps = cJSON_GetObjectItem(depth_mode_info_json, "min_fps"); + if (depth_mode_info_json_min_fps != nullptr && cJSON_IsNumber(depth_mode_info_json_min_fps)) + { + depth_mode_info.min_fps = (uint32_t)depth_mode_info_json_min_fps->valueint; + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *depth_mode_info_json_max_fps = cJSON_GetObjectItem(depth_mode_info_json, "max_fps"); + if (depth_mode_info_json_max_fps != nullptr && cJSON_IsNumber(depth_mode_info_json_max_fps)) + { + depth_mode_info.max_fps = (uint32_t)depth_mode_info_json_max_fps->valueint; + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *depth_mode_info_json_min_range = cJSON_GetObjectItem(depth_mode_info_json, "min_range"); + if (depth_mode_info_json_min_range != nullptr && cJSON_IsNumber(depth_mode_info_json_min_range)) + { + depth_mode_info.min_range = (uint32_t)depth_mode_info_json_min_range->valueint; + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *depth_mode_info_json_max_range = cJSON_GetObjectItem(depth_mode_info_json, "max_range"); + if (depth_mode_info_json_max_range != nullptr && cJSON_IsNumber(depth_mode_info_json_max_range)) + { + depth_mode_info.max_range = (uint32_t)depth_mode_info_json_max_range->valueint; + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + + cJSON_Delete(depth_mode_info_json); + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + } + else + { + depth_mode_info_result = K4A_RESULT_FAILED; + } + + if (!K4A_SUCCEEDED(depth_mode_info_result)) + { + int mode_count = (int)k4a_get_device_depth_modes_count(); + k4a_depth_mode_info_t depth_mode; + for (int i = 0; i < mode_count; i++) + { + depth_mode = k4a_get_device_depth_mode(i); + if (depth_mode.mode_id == depth_mode_id) + { + SAFE_COPY_STRUCT(&depth_mode_info, &depth_mode); + break; + } + } + } + + context->record_config.depth_mode_info = depth_mode_info; + + // fps + if (fps_mode_info_tag != NULL && (hasColorDevice || hasDepthDevice)) + { + std::string fps_mode_info_string = get_tag_string(fps_mode_info_tag); + + if (!fps_mode_info_string.empty()) + { + cJSON *fps_mode_info_json = cJSON_Parse(fps_mode_info_string.c_str()); + if (fps_mode_info_json != NULL) + { + const cJSON *fps_mode_info_json_mode_id = cJSON_GetObjectItem(fps_mode_info_json, "mode_id"); + if (fps_mode_info_json_mode_id != nullptr && cJSON_IsNumber(fps_mode_info_json_mode_id)) + { + fps_mode_info.mode_id = (uint32_t)fps_mode_info_json_mode_id->valueint; + } + else + { + fps_mode_info_result = K4A_RESULT_FAILED; + } + + const cJSON *fps_mode_info_json_fps = cJSON_GetObjectItem(fps_mode_info_json, "fps"); + if (fps_mode_info_json_fps != nullptr && cJSON_IsNumber(fps_mode_info_json_fps)) + { + fps_mode_info.fps = (uint32_t)fps_mode_info_json_fps->valueint; + } + else + { + fps_mode_info_result = K4A_RESULT_FAILED; + } + } + else + { + fps_mode_info_result = K4A_RESULT_FAILED; + } + + cJSON_Delete(fps_mode_info_json); + } + else + { + fps_mode_info_result = K4A_RESULT_FAILED; + } + } + else + { + fps_mode_info_result = K4A_RESULT_FAILED; + } + + if (!K4A_SUCCEEDED(fps_mode_info_result)) + { + // device_fps_modes is statically defined in . + int mode_count = (int)k4a_get_device_fps_modes_count(); + k4a_fps_mode_info_t fps_mode; + for (int i = 0; i < mode_count; i++) + { + fps_mode = k4a_get_device_fps_mode(i); + if (fps_mode.mode_id == fps_mode_id) + { + SAFE_COPY_STRUCT(&fps_mode_info, &fps_mode); + break; + } + } + } + + context->record_config.fps_mode_info = fps_mode_info; // Read depth_delay_off_color_usec and set offsets for each builtin track accordingly. KaxTag *depth_delay_tag = get_tag(context, "K4A_DEPTH_DELAY_NS"); diff --git a/src/record/sdk/playback.cpp b/src/record/sdk/playback.cpp index 0e93ac534..aaf1724f9 100644 --- a/src/record/sdk/playback.cpp +++ b/src/record/sdk/playback.cpp @@ -8,7 +8,6 @@ #include #include #include -#include using namespace k4arecord; using namespace LIBMATROSKA_NAMESPACE; @@ -153,8 +152,8 @@ k4a_result_t k4a_playback_get_calibration(k4a_playback_t playback_handle, k4a_ca buffer[buffer.size() - 1] = '\0'; k4a_result_t result = k4a_calibration_get_from_raw(buffer.data(), buffer.size(), - context->record_config.depth_mode, - context->record_config.color_resolution, + context->record_config.depth_mode_info.mode_id, + context->record_config.color_mode_info.mode_id, context->device_calibration.get()); if (K4A_FAILED(result)) { diff --git a/src/record/sdk/record.cpp b/src/record/sdk/record.cpp index 4cd5b2985..c30323715 100644 --- a/src/record/sdk/record.cpp +++ b/src/record/sdk/record.cpp @@ -9,7 +9,10 @@ #include #include #include -#include +#include + +#include +#include //cJSON.h need this set correctly. using namespace k4arecord; using namespace LIBMATROSKA_NAMESPACE; @@ -45,9 +48,8 @@ k4a_result_t k4a_record_create(const char *path, if (K4A_SUCCEEDED(result)) { context->device_config = device_config; - context->timecode_scale = MATROSKA_TIMESCALE_NS; - context->camera_fps = k4a_convert_fps_to_uint(device_config.camera_fps); + context->camera_fps = static_cast(device_config.fps_mode_id); if (context->camera_fps == 0) { // Set camera FPS to 30 if no cameras are enabled so IMU can still be written. @@ -57,11 +59,13 @@ k4a_result_t k4a_record_create(const char *path, uint32_t color_width = 0; uint32_t color_height = 0; - if (K4A_SUCCEEDED(result) && device_config.color_resolution != K4A_COLOR_RESOLUTION_OFF) + if (K4A_SUCCEEDED(result) && device_config.color_mode_id != K4A_COLOR_RESOLUTION_OFF) { - if (!k4a_convert_resolution_to_width_height(device_config.color_resolution, &color_width, &color_height)) + if (!k4a_convert_resolution_to_width_height((k4a_color_resolution_t)device_config.color_mode_id, + &color_width, + &color_height)) { - LOG_ERROR("Unsupported color_resolution specified in recording: %d", device_config.color_resolution); + LOG_ERROR("Unsupported color_resolution specified in recording: %d", device_config.color_mode_id); result = K4A_RESULT_FAILED; } } @@ -69,7 +73,7 @@ k4a_result_t k4a_record_create(const char *path, std::ostringstream color_mode_str; if (K4A_SUCCEEDED(result)) { - if (device_config.color_resolution != K4A_COLOR_RESOLUTION_OFF) + if (device_config.color_mode_id != K4A_COLOR_RESOLUTION_OFF) { switch (device_config.color_format) { @@ -101,15 +105,15 @@ k4a_result_t k4a_record_create(const char *path, uint32_t depth_height = 0; if (K4A_SUCCEEDED(result)) { - if (device_config.depth_mode != K4A_DEPTH_MODE_OFF) + if (device_config.depth_mode_id != K4A_DEPTH_MODE_OFF) { for (size_t i = 0; i < arraysize(depth_modes); i++) { - if (device_config.depth_mode == depth_modes[i].first) + if ((k4a_depth_mode_t)device_config.depth_mode_id == depth_modes[i].first) { if (!k4a_convert_depth_mode_to_width_height(depth_modes[i].first, &depth_width, &depth_height)) { - LOG_ERROR("Unsupported depth_mode specified in recording: %d", device_config.depth_mode); + LOG_ERROR("Unsupported depth_mode specified in recording: %d", device_config.depth_mode_id); result = K4A_RESULT_FAILED; } depth_mode_str = depth_modes[i].second.c_str(); @@ -118,7 +122,7 @@ k4a_result_t k4a_record_create(const char *path, } if (depth_width == 0 || depth_height == 0) { - LOG_ERROR("Unsupported depth_mode specified in recording: %d", device_config.depth_mode); + LOG_ERROR("Unsupported depth_mode specified in recording: %d", device_config.depth_mode_id); result = K4A_RESULT_FAILED; } } @@ -144,7 +148,7 @@ k4a_result_t k4a_record_create(const char *path, tags.EnableChecksum(); } - if (K4A_SUCCEEDED(result) && device_config.color_resolution != K4A_COLOR_RESOLUTION_OFF) + if (K4A_SUCCEEDED(result) && device_config.color_mode_id != K4A_COLOR_RESOLUTION_OFF) { BITMAPINFOHEADER codec_info = {}; result = TRACE_CALL( @@ -175,11 +179,11 @@ k4a_result_t k4a_record_create(const char *path, if (K4A_SUCCEEDED(result)) { - if (device_config.depth_mode == K4A_DEPTH_MODE_PASSIVE_IR) + if (device_config.depth_mode_id == K4A_DEPTH_MODE_PASSIVE_IR) { add_tag(context, "K4A_DEPTH_MODE", depth_mode_str); } - else if (device_config.depth_mode != K4A_DEPTH_MODE_OFF) + else if (device_config.depth_mode_id != K4A_DEPTH_MODE_OFF) { // Depth track BITMAPINFOHEADER codec_info = {}; @@ -210,7 +214,7 @@ k4a_result_t k4a_record_create(const char *path, } } - if (K4A_SUCCEEDED(result) && device_config.depth_mode != K4A_DEPTH_MODE_OFF) + if (K4A_SUCCEEDED(result) && device_config.depth_mode_id != K4A_DEPTH_MODE_OFF) { // IR Track BITMAPINFOHEADER codec_info = {}; @@ -232,7 +236,7 @@ k4a_result_t k4a_record_create(const char *path, add_tag(context, "K4A_IR_TRACK", track_uid_str.str().c_str(), TAG_TARGET_TYPE_TRACK, track_uid); add_tag(context, "K4A_IR_MODE", - device_config.depth_mode == K4A_DEPTH_MODE_PASSIVE_IR ? "PASSIVE" : "ACTIVE", + device_config.depth_mode_id == K4A_DEPTH_MODE_PASSIVE_IR ? "PASSIVE" : "ACTIVE", TAG_TARGET_TYPE_TRACK, track_uid); } @@ -243,8 +247,8 @@ k4a_result_t k4a_record_create(const char *path, } } - if (K4A_SUCCEEDED(result) && device_config.color_resolution != K4A_COLOR_RESOLUTION_OFF && - device_config.depth_mode != K4A_DEPTH_MODE_OFF) + if (K4A_SUCCEEDED(result) && device_config.color_mode_id != K4A_COLOR_RESOLUTION_OFF && + device_config.depth_mode_id != K4A_DEPTH_MODE_OFF) { std::ostringstream delay_str; delay_str << device_config.depth_delay_off_color_usec * 1000; @@ -275,24 +279,27 @@ k4a_result_t k4a_record_create(const char *path, { // Add the firmware version and device serial number to the recording k4a_hardware_version_t version_info; - result = TRACE_CALL(k4a_device_get_version(device, &version_info)); - - std::ostringstream color_firmware_str; - color_firmware_str << version_info.rgb.major << "." << version_info.rgb.minor << "." - << version_info.rgb.iteration; - std::ostringstream depth_firmware_str; - depth_firmware_str << version_info.depth.major << "." << version_info.depth.minor << "." - << version_info.depth.iteration; - add_tag(context, "K4A_COLOR_FIRMWARE_VERSION", color_firmware_str.str().c_str()); - add_tag(context, "K4A_DEPTH_FIRMWARE_VERSION", depth_firmware_str.str().c_str()); + k4a_result_t version_result = TRACE_CALL(k4a_device_get_version(device, &version_info)); - char serial_number_buffer[256]; - size_t serial_number_buffer_size = sizeof(serial_number_buffer); - // If reading the device serial number fails, just log the error and continue. The recording is still valid. - if (TRACE_BUFFER_CALL(k4a_device_get_serialnum(device, serial_number_buffer, &serial_number_buffer_size)) == - K4A_BUFFER_RESULT_SUCCEEDED) + if (K4A_SUCCEEDED(version_result)) { - add_tag(context, "K4A_DEVICE_SERIAL_NUMBER", serial_number_buffer); + std::ostringstream color_firmware_str; + color_firmware_str << version_info.rgb.major << "." << version_info.rgb.minor << "." + << version_info.rgb.iteration; + std::ostringstream depth_firmware_str; + depth_firmware_str << version_info.depth.major << "." << version_info.depth.minor << "." + << version_info.depth.iteration; + add_tag(context, "K4A_COLOR_FIRMWARE_VERSION", color_firmware_str.str().c_str()); + add_tag(context, "K4A_DEPTH_FIRMWARE_VERSION", depth_firmware_str.str().c_str()); + + char serial_number_buffer[256]; + size_t serial_number_buffer_size = sizeof(serial_number_buffer); + // If reading the device serial number fails, just log the error and continue. The recording is still valid. + if (TRACE_BUFFER_CALL(k4a_device_get_serialnum(device, serial_number_buffer, &serial_number_buffer_size)) == + K4A_BUFFER_RESULT_SUCCEEDED) + { + add_tag(context, "K4A_DEVICE_SERIAL_NUMBER", serial_number_buffer); + } } } @@ -325,14 +332,188 @@ k4a_result_t k4a_record_create(const char *path, TAG_TARGET_TYPE_ATTACHMENT, get_attachment_uid(attached)); } - else + } + } + + bool hasColorDevice = false; + bool hasDepthDevice = false; + + // Write device info. + if (K4A_SUCCEEDED(result) && device != NULL) + { + const char *device_info_str = ""; + + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + k4a_result_t device_info_result = k4a_device_get_info(device, &device_info); + + if (K4A_SUCCEEDED(device_info_result)) + { + hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + + cJSON *device_info_json = cJSON_CreateObject(); + + if (cJSON_AddNumberToObject(device_info_json, "capabilities", device_info.capabilities.value) == NULL) { - result = K4A_RESULT_FAILED; + device_info_result = K4A_RESULT_FAILED; } + + if (cJSON_AddNumberToObject(device_info_json, "device_id", device_info.device_id) == NULL) + { + device_info_result = K4A_RESULT_FAILED; + } + + if (cJSON_AddNumberToObject(device_info_json, "vendor_id", device_info.vendor_id) == NULL) + { + device_info_result = K4A_RESULT_FAILED; + } + + device_info_str = cJSON_Print(device_info_json); + if (K4A_SUCCEEDED(device_info_result) && device_info_str != NULL) + { + add_tag(context, "K4A_DEVICE_INFO", device_info_str); + } + + cJSON_Delete(device_info_json); } - else + } + + if (K4A_SUCCEEDED(result) && device != NULL && hasColorDevice) + { + const char *color_mode_info_str = ""; + + // Get the color mode info that corresponds to the color_mode_id. + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + uint32_t color_mode_count = 0; + + k4a_result_t color_mode_result = k4a_device_get_color_mode_count(device, &color_mode_count); + if (K4A_SUCCEEDED(color_mode_result)) { - result = K4A_RESULT_FAILED; + color_mode_result = K4A_RESULT_FAILED; + for (uint32_t color_mode_index = 0; color_mode_index < color_mode_count; ++color_mode_index) + { + k4a_result_t color_mode_search_result = k4a_device_get_color_mode(device, + color_mode_index, + &color_mode_info); + if (K4A_SUCCEEDED(color_mode_search_result) && device_config.color_mode_id == color_mode_info.mode_id) + { + color_mode_result = K4A_RESULT_SUCCEEDED; + break; + } + } + } + + if (K4A_SUCCEEDED(color_mode_result)) + { + cJSON *color_mode_info_json = cJSON_CreateObject(); + + cJSON_AddNumberToObject(color_mode_info_json, "mode_id", color_mode_info.mode_id); + cJSON_AddNumberToObject(color_mode_info_json, "width", color_mode_info.width); + cJSON_AddNumberToObject(color_mode_info_json, "height", color_mode_info.height); + cJSON_AddNumberToObject(color_mode_info_json, "native_format", color_mode_info.native_format); + cJSON_AddNumberToObject(color_mode_info_json, "horizontal_fov", color_mode_info.horizontal_fov); + cJSON_AddNumberToObject(color_mode_info_json, "vertical_fov", color_mode_info.vertical_fov); + cJSON_AddNumberToObject(color_mode_info_json, "min_fps", color_mode_info.min_fps); + cJSON_AddNumberToObject(color_mode_info_json, "max_fps", color_mode_info.max_fps); + + color_mode_info_str = cJSON_Print(color_mode_info_json); + if (color_mode_info_str != NULL) + { + add_tag(context, "K4A_COLOR_MODE_INFO", color_mode_info_str); + } + + cJSON_Delete(color_mode_info_json); + } + } + + if (K4A_SUCCEEDED(result) && device != NULL && hasDepthDevice) + { + const char *depth_mode_info_str = ""; + + // Get the depth mode info that corresponds to the depth_mode_id. + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + uint32_t depth_mode_count = 0; + + k4a_result_t depth_mode_result = k4a_device_get_depth_mode_count(device, &depth_mode_count); + if (K4A_SUCCEEDED(depth_mode_result)) + { + depth_mode_result = K4A_RESULT_FAILED; + for (uint32_t depth_mode_index = 0; depth_mode_index < depth_mode_count; ++depth_mode_index) + { + k4a_result_t depth_mode_search_result = k4a_device_get_depth_mode(device, + depth_mode_index, + &depth_mode_info); + if (K4A_SUCCEEDED(depth_mode_search_result) && device_config.depth_mode_id == depth_mode_info.mode_id) + { + depth_mode_result = K4A_RESULT_SUCCEEDED; + break; + } + } + } + + if (K4A_SUCCEEDED(depth_mode_result)) + { + cJSON *depth_mode_info_json = cJSON_CreateObject(); + + cJSON_AddNumberToObject(depth_mode_info_json, "mode_id", depth_mode_info.mode_id); + cJSON_AddNumberToObject(depth_mode_info_json, "width", depth_mode_info.width); + cJSON_AddNumberToObject(depth_mode_info_json, "height", depth_mode_info.height); + cJSON_AddNumberToObject(depth_mode_info_json, "native_format", depth_mode_info.native_format); + cJSON_AddNumberToObject(depth_mode_info_json, "horizontal_fov", depth_mode_info.horizontal_fov); + cJSON_AddNumberToObject(depth_mode_info_json, "vertical_fov", depth_mode_info.vertical_fov); + cJSON_AddNumberToObject(depth_mode_info_json, "min_fps", depth_mode_info.min_fps); + cJSON_AddNumberToObject(depth_mode_info_json, "max_fps", depth_mode_info.max_fps); + cJSON_AddNumberToObject(depth_mode_info_json, "min_range", depth_mode_info.min_range); + cJSON_AddNumberToObject(depth_mode_info_json, "max_range", depth_mode_info.max_range); + cJSON_AddBoolToObject(depth_mode_info_json, "passive_ir_only", depth_mode_info.passive_ir_only); + + depth_mode_info_str = cJSON_Print(depth_mode_info_json); + if (depth_mode_info_str != NULL) + { + add_tag(context, "K4A_DEPTH_MODE_INFO", depth_mode_info_str); + } + + cJSON_Delete(depth_mode_info_json); + } + } + + if (K4A_SUCCEEDED(result) && device != NULL && (hasColorDevice || hasDepthDevice)) + { + const char *fps_mode_info_str = ""; + + // Get the fps mode info that corresponds to the fps_mode_id. + k4a_fps_mode_info_t fps_mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + uint32_t fps_mode_count = 0; + + k4a_result_t fps_mode_result = k4a_device_get_fps_mode_count(device, &fps_mode_count); + if (K4A_SUCCEEDED(fps_mode_result)) + { + fps_mode_result = K4A_RESULT_FAILED; + for (uint32_t fps_mode_index = 0; fps_mode_index < fps_mode_count; ++fps_mode_index) + { + k4a_result_t fps_mode_search_result = k4a_device_get_fps_mode(device, fps_mode_index, &fps_mode_info); + if (K4A_SUCCEEDED(fps_mode_search_result) && device_config.fps_mode_id == fps_mode_info.mode_id) + { + fps_mode_result = K4A_RESULT_SUCCEEDED; + break; + } + } + } + + if (K4A_SUCCEEDED(fps_mode_result)) + { + cJSON *fps_mode_info_json = cJSON_CreateObject(); + + cJSON_AddNumberToObject(fps_mode_info_json, "mode_id", fps_mode_info.mode_id); + cJSON_AddNumberToObject(fps_mode_info_json, "fps", fps_mode_info.fps); + + fps_mode_info_str = cJSON_Print(fps_mode_info_json); + if (fps_mode_info_str != NULL) + { + add_tag(context, "K4A_FPS_MODE_INFO", fps_mode_info_str); + } + + cJSON_Delete(fps_mode_info_json); } } @@ -918,4 +1099,4 @@ void k4a_record_close(const k4a_record_t recording_handle) } } k4a_record_t_destroy(recording_handle); -} +} \ No newline at end of file diff --git a/src/rwlock/rwlock_linux.c b/src/rwlock/rwlock_linux.c index 7dba95b3c..3dca6ed01 100644 --- a/src/rwlock/rwlock_linux.c +++ b/src/rwlock/rwlock_linux.c @@ -4,8 +4,6 @@ // This library #include -#include - // System dependencies #include #include diff --git a/src/sdk/CMakeLists.txt b/src/sdk/CMakeLists.txt index 3616f400e..a3136bc57 100644 --- a/src/sdk/CMakeLists.txt +++ b/src/sdk/CMakeLists.txt @@ -51,6 +51,7 @@ target_link_libraries(k4a PRIVATE k4ainternal::image k4ainternal::imu k4ainternal::logging + k4ainternal::modes k4ainternal::queue k4ainternal::transformation) diff --git a/src/sdk/k4a.c b/src/sdk/k4a.c index c97641d6d..1bd3a90ab 100644 --- a/src/sdk/k4a.c +++ b/src/sdk/k4a.c @@ -1,11 +1,10 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. // This library #include // Dependent libraries -#include #include #include #include @@ -16,7 +15,9 @@ #include #include #include +#include #include +#include // System dependencies #include @@ -520,9 +521,9 @@ void k4a_image_release(k4a_image_t image_handle) image_dec_ref(image_handle); } -static const char *k4a_depth_mode_to_string(k4a_depth_mode_t depth_mode) +static const char *k4a_depth_mode_to_string(uint32_t depth_mode_id) { - switch (depth_mode) + switch (depth_mode_id) { K4A_DEPTH_MODE_TO_STRING_CASE(K4A_DEPTH_MODE_OFF); K4A_DEPTH_MODE_TO_STRING_CASE(K4A_DEPTH_MODE_NFOV_2X2BINNED); @@ -534,9 +535,9 @@ static const char *k4a_depth_mode_to_string(k4a_depth_mode_t depth_mode) return "Unexpected k4a_depth_mode_t value."; } -static const char *k4a_color_resolution_to_string(k4a_color_resolution_t resolution) +static const char *k4a_color_resolution_to_string(uint32_t color_mode_id) { - switch (resolution) + switch (color_mode_id) { K4A_COLOR_RESOLUTION_TO_STRING_CASE(K4A_COLOR_RESOLUTION_OFF); K4A_COLOR_RESOLUTION_TO_STRING_CASE(K4A_COLOR_RESOLUTION_720P); @@ -566,9 +567,9 @@ static const char *k4a_image_format_to_string(k4a_image_format_t image_format) return "Unexpected k4a_image_format_t value."; } -static const char *k4a_fps_to_string(k4a_fps_t fps) +static const char *k4a_fps_to_string(uint32_t fps_mode_id) { - switch (fps) + switch (fps_mode_id) { K4A_FPS_TO_STRING_CASE(K4A_FRAMES_PER_SECOND_5); K4A_FPS_TO_STRING_CASE(K4A_FRAMES_PER_SECOND_15); @@ -594,8 +595,7 @@ static k4a_result_t validate_configuration(k4a_context_t *device, const k4a_devi if (K4A_SUCCEEDED(result)) { - if (config->color_resolution < K4A_COLOR_RESOLUTION_OFF || - config->color_resolution > K4A_COLOR_RESOLUTION_3072P) + if (config->color_mode_id > K4A_COLOR_RESOLUTION_3072P) { result = K4A_RESULT_FAILED; LOG_ERROR("The configured color_resolution is not a valid k4a_color_resolution_t value.", 0); @@ -604,7 +604,7 @@ static k4a_result_t validate_configuration(k4a_context_t *device, const k4a_devi if (K4A_SUCCEEDED(result)) { - if (config->depth_mode < K4A_DEPTH_MODE_OFF || config->depth_mode > K4A_DEPTH_MODE_PASSIVE_IR) + if (config->depth_mode_id > K4A_DEPTH_MODE_PASSIVE_IR) { result = K4A_RESULT_FAILED; LOG_ERROR("The configured depth_mode is not a valid k4a_depth_mode_t value.", 0); @@ -613,8 +613,8 @@ static k4a_result_t validate_configuration(k4a_context_t *device, const k4a_devi if (K4A_SUCCEEDED(result)) { - if (config->camera_fps != K4A_FRAMES_PER_SECOND_5 && config->camera_fps != K4A_FRAMES_PER_SECOND_15 && - config->camera_fps != K4A_FRAMES_PER_SECOND_30) + if (config->fps_mode_id != K4A_FRAMES_PER_SECOND_5 && config->fps_mode_id != K4A_FRAMES_PER_SECOND_15 && + config->fps_mode_id != K4A_FRAMES_PER_SECOND_30) { result = K4A_RESULT_FAILED; LOG_ERROR("The configured camera_fps is not a valid k4a_fps_t value.", 0); @@ -663,7 +663,7 @@ static k4a_result_t validate_configuration(k4a_context_t *device, const k4a_devi 0); } - if (config->color_resolution == K4A_COLOR_RESOLUTION_OFF) + if (config->color_mode_id == K4A_COLOR_RESOLUTION_OFF) { result = K4A_RESULT_FAILED; LOG_ERROR( @@ -681,7 +681,7 @@ static k4a_result_t validate_configuration(k4a_context_t *device, const k4a_devi if (config->wired_sync_mode == K4A_WIRED_SYNC_MODE_SUBORDINATE && config->subordinate_delay_off_master_usec != 0) { - uint32_t fps_in_usec = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(config->camera_fps)); + uint32_t fps_in_usec = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(config->fps_mode_id)); if (config->subordinate_delay_off_master_usec > fps_in_usec) { result = K4A_RESULT_FAILED; @@ -704,19 +704,19 @@ static k4a_result_t validate_configuration(k4a_context_t *device, const k4a_devi if (K4A_SUCCEEDED(result)) { - if (config->depth_mode != K4A_DEPTH_MODE_OFF) + if (config->depth_mode_id != K4A_DEPTH_MODE_OFF) { depth_enabled = true; } - if (config->color_resolution != K4A_COLOR_RESOLUTION_OFF) + if (config->color_mode_id != K4A_COLOR_RESOLUTION_OFF) { color_enabled = true; } if (depth_enabled && color_enabled) { - int64_t fps = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(config->camera_fps)); + int64_t fps = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(config->fps_mode_id)); if (config->depth_delay_off_color_usec < -fps || config->depth_delay_off_color_usec > fps) { result = K4A_RESULT_FAILED; @@ -770,8 +770,8 @@ static k4a_result_t validate_configuration(k4a_context_t *device, const k4a_devi bool depth_fps_and_mode_supported = false; for (unsigned int x = 0; x < COUNTOF(supported_depth_configs); x++) { - if (supported_depth_configs[x].mode == config->depth_mode && - supported_depth_configs[x].max_fps >= config->camera_fps) + if (supported_depth_configs[x].mode == (k4a_depth_mode_t)config->depth_mode_id && + supported_depth_configs[x].max_fps >= (k4a_fps_t)config->fps_mode_id) { depth_fps_and_mode_supported = true; break; @@ -782,8 +782,8 @@ static k4a_result_t validate_configuration(k4a_context_t *device, const k4a_devi { result = K4A_RESULT_FAILED; LOG_ERROR("The configured depth_mode %s does not support the configured camera_fps %s.", - k4a_depth_mode_to_string(config->depth_mode), - k4a_fps_to_string(config->camera_fps)); + k4a_depth_mode_to_string(config->depth_mode_id), + k4a_fps_to_string(config->fps_mode_id)); } } } @@ -817,8 +817,8 @@ static k4a_result_t validate_configuration(k4a_context_t *device, const k4a_devi bool color_fps_and_res_and_format_supported = false; for (unsigned int x = 0; x < COUNTOF(supported_color_configs); x++) { - if (supported_color_configs[x].res == config->color_resolution && - supported_color_configs[x].max_fps >= config->camera_fps && + if (supported_color_configs[x].res == (k4a_color_resolution_t)config->color_mode_id && + supported_color_configs[x].max_fps >= (k4a_fps_t)config->fps_mode_id && supported_color_configs[x].format == config->color_format) { color_fps_and_res_and_format_supported = true; @@ -831,9 +831,9 @@ static k4a_result_t validate_configuration(k4a_context_t *device, const k4a_devi result = K4A_RESULT_FAILED; LOG_ERROR("The combination of color_resolution at %s, color_format at %s, and camera_fps at %s is not " "supported.", - k4a_color_resolution_to_string(config->color_resolution), + k4a_color_resolution_to_string(config->color_mode_id), k4a_image_format_to_string(config->color_format), - k4a_fps_to_string(config->camera_fps)); + k4a_fps_to_string(config->fps_mode_id)); } } } @@ -867,9 +867,9 @@ k4a_result_t k4a_device_start_cameras(k4a_device_t device_handle, const k4a_devi { LOG_INFO("Starting camera's with the following config.", 0); LOG_INFO(" color_format:%d", config->color_format); - LOG_INFO(" color_resolution:%d", config->color_resolution); - LOG_INFO(" depth_mode:%d", config->depth_mode); - LOG_INFO(" camera_fps:%d", config->camera_fps); + LOG_INFO(" color_resolution:%d", config->color_mode_id); + LOG_INFO(" depth_mode:%d", config->depth_mode_id); + LOG_INFO(" camera_fps:%d", config->fps_mode_id); LOG_INFO(" synchronized_images_only:%d", config->synchronized_images_only); LOG_INFO(" depth_delay_off_color_usec:%d", config->depth_delay_off_color_usec); LOG_INFO(" wired_sync_mode:%d", config->wired_sync_mode); @@ -890,7 +890,7 @@ k4a_result_t k4a_device_start_cameras(k4a_device_t device_handle, const k4a_devi if (K4A_SUCCEEDED(result)) { - if (config->depth_mode != K4A_DEPTH_MODE_OFF) + if (config->depth_mode_id != K4A_DEPTH_MODE_OFF) { result = TRACE_CALL(depth_start(device->depth, config)); } @@ -902,7 +902,7 @@ k4a_result_t k4a_device_start_cameras(k4a_device_t device_handle, const k4a_devi if (K4A_SUCCEEDED(result)) { - if (config->color_resolution != K4A_COLOR_RESOLUTION_OFF) + if (config->color_mode_id != K4A_COLOR_RESOLUTION_OFF) { // NOTE: Color must be started before depth and IMU as it triggers the sync of PTS. If it starts after // depth or IMU, the user will see timestamps reset back to zero when the color camera is started. @@ -1028,8 +1028,8 @@ k4a_buffer_result_t k4a_device_get_raw_calibration(k4a_device_t device_handle, u } k4a_result_t k4a_device_get_calibration(k4a_device_t device_handle, - const k4a_depth_mode_t depth_mode, - const k4a_color_resolution_t color_resolution, + const uint32_t depth_mode_id, + const uint32_t color_mode_id, k4a_calibration_t *calibration) { RETURN_VALUE_IF_HANDLE_INVALID(K4A_RESULT_FAILED, k4a_device_t, device_handle); @@ -1056,15 +1056,15 @@ k4a_result_t k4a_device_get_calibration(k4a_device_t device_handle, &color_calibration, gyro_extrinsics, accel_extrinsics, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, calibration)); } k4a_result_t k4a_calibration_get_from_raw(char *raw_calibration, size_t raw_calibration_size, - const k4a_depth_mode_t depth_mode, - const k4a_color_resolution_t color_resolution, + const uint32_t depth_mode_id, + const uint32_t color_mode_id, k4a_calibration_t *calibration) { k4a_calibration_camera_t depth_calibration; @@ -1086,8 +1086,8 @@ k4a_result_t k4a_calibration_get_from_raw(char *raw_calibration, &color_calibration, &gyro_calibration.depth_to_imu, &accel_calibration.depth_to_imu, - depth_mode, - color_resolution, + depth_mode_id, + color_mode_id, calibration)); } return result; @@ -1286,6 +1286,180 @@ k4a_result_t k4a_transformation_depth_image_to_point_cloud(k4a_transformation_t &xyz_image_descriptor)); } +k4a_result_t k4a_device_get_info(k4a_device_t device_handle, k4a_device_info_t *device_info) +{ + if (!device_info) + { + return K4A_RESULT_FAILED; + } + if (device_info->struct_version != (uint32_t)K4A_ABI_VERSION) + { + return K4A_RESULT_UNSUPPORTED; + } + + RETURN_VALUE_IF_HANDLE_INVALID(K4A_RESULT_FAILED, k4a_device_t, device_handle); + k4a_result_t result = K4A_RESULT_SUCCEEDED; + + k4a_device_info_t info = { (uint32_t)sizeof(k4a_device_info_t), + K4A_ABI_VERSION, + K4A_MSFT_VID, + K4A_DEPTH_PID, + { K4A_CAPABILITY_DEPTH | K4A_CAPABILITY_COLOR | K4A_CAPABILITY_IMU | + K4A_CAPABILITY_MICROPHONE } }; + + SAFE_COPY_STRUCT(device_info, &info); + + return result; +} + +k4a_result_t k4a_device_get_color_mode_count(k4a_device_t device_handle, uint32_t *mode_count) +{ + RETURN_VALUE_IF_HANDLE_INVALID(K4A_RESULT_FAILED, k4a_device_t, device_handle); + + k4a_result_t result = K4A_RESULT_FAILED; + if (NULL != mode_count) + { + *mode_count = k4a_get_device_color_modes_count(); + result = K4A_RESULT_SUCCEEDED; + } + + return result; +} + +k4a_result_t k4a_device_get_color_mode(k4a_device_t device_handle, + uint32_t mode_index, + k4a_color_mode_info_t *mode_info) +{ + RETURN_VALUE_IF_HANDLE_INVALID(K4A_RESULT_FAILED, k4a_device_t, device_handle); + + // Check mode info. + if (!mode_info) + { + return K4A_RESULT_FAILED; + } + + // If the struct size or version is not recognized, return unsupported status. + if (mode_info->struct_size != (uint32_t)sizeof(k4a_color_mode_info_t) || + mode_info->struct_version != (uint32_t)K4A_ABI_VERSION) + { + return K4A_RESULT_UNSUPPORTED; + } + + // Check mode index. + uint32_t mode_count; + if (k4a_device_get_color_mode_count(device_handle, &mode_count) != K4A_RESULT_SUCCEEDED) + { + return K4A_RESULT_FAILED; + } + if (mode_index >= mode_count) + { + return K4A_RESULT_FAILED; + } + + // Get the corresponding color mode info. + k4a_color_mode_info_t color_mode_info = k4a_get_device_color_mode(mode_index); + SAFE_COPY_STRUCT(mode_info, &color_mode_info); + return K4A_RESULT_SUCCEEDED; +} + +k4a_result_t k4a_device_get_depth_mode_count(k4a_device_t device_handle, uint32_t *mode_count) +{ + RETURN_VALUE_IF_HANDLE_INVALID(K4A_RESULT_FAILED, k4a_device_t, device_handle); + + k4a_result_t result = K4A_RESULT_FAILED; + if (NULL != mode_count) + { + *mode_count = k4a_get_device_depth_modes_count(); + result = K4A_RESULT_SUCCEEDED; + } + + return result; +} + +k4a_result_t k4a_device_get_depth_mode(k4a_device_t device_handle, + uint32_t mode_index, + k4a_depth_mode_info_t *mode_info) +{ + RETURN_VALUE_IF_HANDLE_INVALID(K4A_RESULT_FAILED, k4a_device_t, device_handle); + + // Check mode info. + if (!mode_info) + { + return K4A_RESULT_FAILED; + } + + // If the struct size or version is not recognized, return unsupported status. + if (mode_info->struct_size != (uint32_t)sizeof(k4a_depth_mode_info_t) || + mode_info->struct_version != (uint32_t)K4A_ABI_VERSION) + { + return K4A_RESULT_UNSUPPORTED; + } + + // Check mode index. + uint32_t mode_count; + if (k4a_device_get_depth_mode_count(device_handle, &mode_count) != K4A_RESULT_SUCCEEDED) + { + return K4A_RESULT_FAILED; + } + if (mode_index >= mode_count) + { + return K4A_RESULT_FAILED; + } + + // Get the corresponding depth mode info. + k4a_depth_mode_info_t depth_mode_info = k4a_get_device_depth_mode(mode_index); + SAFE_COPY_STRUCT(mode_info, &depth_mode_info); + return K4A_RESULT_SUCCEEDED; +} + +k4a_result_t k4a_device_get_fps_mode_count(k4a_device_t device_handle, uint32_t *mode_count) +{ + RETURN_VALUE_IF_HANDLE_INVALID(K4A_RESULT_FAILED, k4a_device_t, device_handle); + + k4a_result_t result = K4A_RESULT_FAILED; + if (NULL != mode_count) + { + *mode_count = k4a_get_device_fps_modes_count(); + result = K4A_RESULT_SUCCEEDED; + } + + return result; +} + +k4a_result_t k4a_device_get_fps_mode(k4a_device_t device_handle, uint32_t mode_index, k4a_fps_mode_info_t *mode_info) +{ + RETURN_VALUE_IF_HANDLE_INVALID(K4A_RESULT_FAILED, k4a_device_t, device_handle); + + // Check mode info. + if (!mode_info) + { + return K4A_RESULT_FAILED; + } + + // If the struct size or version is not recognized, return unsupported status. + if (mode_info->struct_size != (uint32_t)sizeof(k4a_fps_mode_info_t) || + mode_info->struct_version != (uint32_t)K4A_ABI_VERSION) + { + return K4A_RESULT_UNSUPPORTED; + } + + // Check mode index. + uint32_t mode_count; + if (k4a_device_get_fps_mode_count(device_handle, &mode_count) != K4A_RESULT_SUCCEEDED) + { + return K4A_RESULT_FAILED; + } + if (mode_index >= mode_count) + { + return K4A_RESULT_FAILED; + } + + // Get the corresponding fps mode info. + k4a_fps_mode_info_t fps_mode_info = k4a_get_device_fps_mode(mode_index); + SAFE_COPY_STRUCT(mode_info, &fps_mode_info); + return K4A_RESULT_SUCCEEDED; +} + #ifdef __cplusplus } #endif diff --git a/src/transformation/CMakeLists.txt b/src/transformation/CMakeLists.txt index efb1ac912..b3bb7b45b 100644 --- a/src/transformation/CMakeLists.txt +++ b/src/transformation/CMakeLists.txt @@ -12,6 +12,7 @@ add_library(k4a_transformation STATIC # Dependencies of this library target_link_libraries(k4a_transformation PUBLIC k4ainternal::math + k4ainternal::modes k4ainternal::deloader k4ainternal::tewrapper ) diff --git a/src/transformation/mode_specific_calibration.c b/src/transformation/mode_specific_calibration.c index f2e8b542b..1411cbb55 100644 --- a/src/transformation/mode_specific_calibration.c +++ b/src/transformation/mode_specific_calibration.c @@ -3,6 +3,7 @@ #include "k4ainternal/transformation.h" #include +#include k4a_result_t transformation_get_mode_specific_camera_calibration(const k4a_calibration_camera_t *raw_camera_calibration, @@ -63,11 +64,11 @@ transformation_get_mode_specific_camera_calibration(const k4a_calibration_camera k4a_result_t transformation_get_mode_specific_depth_camera_calibration(const k4a_calibration_camera_t *raw_camera_calibration, - const k4a_depth_mode_t depth_mode, + const uint32_t depth_mode_id, k4a_calibration_camera_t *mode_specific_camera_calibration) { RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, raw_camera_calibration == NULL); - // TODO: Read this from calibration data instead of hardcoding. + if (K4A_FAILED(K4A_RESULT_FROM_BOOL(raw_camera_calibration->resolution_width == 1024 && raw_camera_calibration->resolution_height == 1024))) { @@ -79,7 +80,7 @@ transformation_get_mode_specific_depth_camera_calibration(const k4a_calibration_ return K4A_RESULT_FAILED; } - switch (depth_mode) + switch (depth_mode_id) { case K4A_DEPTH_MODE_NFOV_2X2BINNED: { @@ -127,7 +128,7 @@ transformation_get_mode_specific_depth_camera_calibration(const k4a_calibration_ k4a_result_t transformation_get_mode_specific_color_camera_calibration(const k4a_calibration_camera_t *raw_camera_calibration, - const k4a_color_resolution_t color_resolution, + const uint32_t color_mode_id, k4a_calibration_camera_t *mode_specific_camera_calibration) { if (raw_camera_calibration->resolution_width * 9 / 16 == raw_camera_calibration->resolution_height) @@ -157,7 +158,7 @@ transformation_get_mode_specific_color_camera_calibration(const k4a_calibration_ return K4A_RESULT_FAILED; } - switch (color_resolution) + switch (color_mode_id) { case K4A_COLOR_RESOLUTION_720P: { @@ -215,7 +216,7 @@ transformation_get_mode_specific_color_camera_calibration(const k4a_calibration_ } default: { - LOG_ERROR("Unexpected color resolution type %d.", color_resolution); + LOG_ERROR("Unexpected color resolution type %d.", color_mode_id); return K4A_RESULT_FAILED; } } diff --git a/src/transformation/transformation.c b/src/transformation/transformation.c index fcd2523b5..47d370dbf 100644 --- a/src/transformation/transformation.c +++ b/src/transformation/transformation.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include // System dependencies #include @@ -19,33 +21,33 @@ k4a_result_t transformation_get_mode_specific_calibration(const k4a_calibration_ const k4a_calibration_camera_t *color_camera_calibration, const k4a_calibration_extrinsics_t *gyro_extrinsics, const k4a_calibration_extrinsics_t *accel_extrinsics, - const k4a_depth_mode_t depth_mode, - const k4a_color_resolution_t color_resolution, + const uint32_t depth_mode_id, + const uint32_t color_mode_id, k4a_calibration_t *calibration) { memset(&calibration->color_camera_calibration, 0, sizeof(k4a_calibration_camera_t)); memset(&calibration->depth_camera_calibration, 0, sizeof(k4a_calibration_camera_t)); if (K4A_FAILED( - K4A_RESULT_FROM_BOOL(color_resolution != K4A_COLOR_RESOLUTION_OFF || depth_mode != K4A_DEPTH_MODE_OFF))) + K4A_RESULT_FROM_BOOL(color_mode_id != K4A_COLOR_RESOLUTION_OFF || depth_mode_id != K4A_DEPTH_MODE_OFF))) { LOG_ERROR("Expect color or depth camera is running.", 0); return K4A_RESULT_FAILED; } - if (depth_mode != K4A_DEPTH_MODE_OFF) + if (depth_mode_id != K4A_DEPTH_MODE_OFF) { if (K4A_FAILED(TRACE_CALL(transformation_get_mode_specific_depth_camera_calibration( - depth_camera_calibration, depth_mode, &calibration->depth_camera_calibration)))) + depth_camera_calibration, depth_mode_id, &calibration->depth_camera_calibration)))) { return K4A_RESULT_FAILED; } } - if (color_resolution != K4A_COLOR_RESOLUTION_OFF) + if (color_mode_id != K4A_COLOR_RESOLUTION_OFF) { if (K4A_FAILED(TRACE_CALL(transformation_get_mode_specific_color_camera_calibration( - color_camera_calibration, color_resolution, &calibration->color_camera_calibration)))) + color_camera_calibration, color_mode_id, &calibration->color_camera_calibration)))) { return K4A_RESULT_FAILED; } @@ -71,8 +73,8 @@ k4a_result_t transformation_get_mode_specific_calibration(const k4a_calibration_ } } - calibration->depth_mode = depth_mode; - calibration->color_resolution = color_resolution; + calibration->depth_mode_id = depth_mode_id; + calibration->color_mode_id = color_mode_id; return K4A_RESULT_SUCCEEDED; } @@ -85,12 +87,12 @@ static k4a_result_t transformation_possible(const k4a_calibration_t *camera_cali LOG_ERROR("Unexpected camera calibration type %d.", camera); return K4A_RESULT_FAILED; } - if (camera == K4A_CALIBRATION_TYPE_DEPTH && camera_calibration->depth_mode == K4A_DEPTH_MODE_OFF) + if (camera == K4A_CALIBRATION_TYPE_DEPTH && camera_calibration->depth_mode_id == K4A_DEPTH_MODE_OFF) { LOG_ERROR("Expect depth camera is running to perform transformation.", 0); return K4A_RESULT_FAILED; } - if (camera == K4A_CALIBRATION_TYPE_COLOR && camera_calibration->color_resolution == K4A_COLOR_RESOLUTION_OFF) + if (camera == K4A_CALIBRATION_TYPE_COLOR && camera_calibration->color_mode_id == K4A_COLOR_RESOLUTION_OFF) { LOG_ERROR("Expect color camera is running to perform transformation.", 0); return K4A_RESULT_FAILED; @@ -113,24 +115,23 @@ static k4a_result_t transformation_create_depth_camera_pinhole(const k4a_calibra k4a_transformation_pinhole_t *pinhole) { float fov_degrees[2]; - switch (calibration->depth_mode) - { - case K4A_DEPTH_MODE_NFOV_2X2BINNED: - case K4A_DEPTH_MODE_NFOV_UNBINNED: + + bool fov_found = false; + k4a_depth_mode_info_t depth_mode; + for (size_t n = 0; n < k4a_get_device_depth_modes_count(); ++n) { - fov_degrees[0] = 75; - fov_degrees[1] = 65; - break; + depth_mode = k4a_get_device_depth_mode((uint32_t)n); + if (depth_mode.mode_id == calibration->depth_mode_id) + { + fov_degrees[0] = depth_mode.horizontal_fov; + fov_degrees[1] = depth_mode.vertical_fov; + fov_found = true; + break; + } } - case K4A_DEPTH_MODE_WFOV_2X2BINNED: - case K4A_DEPTH_MODE_WFOV_UNBINNED: - case K4A_DEPTH_MODE_PASSIVE_IR: + + if (!fov_found) { - fov_degrees[0] = 120; - fov_degrees[1] = 120; - break; - } - default: LOG_ERROR("Invalid depth mode.", 0); return K4A_RESULT_FAILED; } @@ -609,9 +610,9 @@ k4a_transformation_t transformation_create(const k4a_calibration_t *calibration, } transformation_context->enable_gpu_optimization = gpu_optimization; - transformation_context->enable_depth_color_transform = transformation_context->calibration.color_resolution != + transformation_context->enable_depth_color_transform = transformation_context->calibration.color_mode_id != K4A_COLOR_RESOLUTION_OFF && - transformation_context->calibration.depth_mode != + transformation_context->calibration.depth_mode_id != K4A_DEPTH_MODE_OFF; if (transformation_context->enable_gpu_optimization && transformation_context->enable_depth_color_transform) { diff --git a/src/usbcommand/usb_cmd_priv.h b/src/usbcommand/usb_cmd_priv.h index 0aa502c9d..d6a6365a4 100644 --- a/src/usbcommand/usb_cmd_priv.h +++ b/src/usbcommand/usb_cmd_priv.h @@ -12,7 +12,7 @@ #include // This library #include -#include +#include // Dependent libraries #include @@ -45,9 +45,6 @@ extern "C" { #define USB_MAX_TX_DATA 128 #define USB_CMD_PACKET_TYPE 0x06022009 #define USB_CMD_PACKET_TYPE_RESPONSE 0x0A6FE000 -#define K4A_MSFT_VID 0x045E -#define K4A_RGB_PID 0x097D -#define K4A_DEPTH_PID 0x097C #define USB_CMD_DEFAULT_CONFIG 1 #define USB_CMD_DEPTH_INTERFACE 0 diff --git a/tests/Calibration/calibration.cpp b/tests/Calibration/calibration.cpp index eb48b69f8..a797de7ea 100644 --- a/tests/Calibration/calibration.cpp +++ b/tests/Calibration/calibration.cpp @@ -7,7 +7,6 @@ // Module being tested #include #include -#include using namespace testing; diff --git a/tests/CaptureSync/capturesync.cpp b/tests/CaptureSync/capturesync.cpp index c01b1be9a..1227c212c 100644 --- a/tests/CaptureSync/capturesync.cpp +++ b/tests/CaptureSync/capturesync.cpp @@ -45,9 +45,9 @@ TEST(capturesync_ut, capturesync) k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config.color_resolution = K4A_COLOR_RESOLUTION_1080P; - config.depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED; - config.camera_fps = K4A_FRAMES_PER_SECOND_5; + config.color_mode_id = K4A_COLOR_RESOLUTION_1080P; + config.depth_mode_id = K4A_DEPTH_MODE_NFOV_2X2BINNED; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_5; ASSERT_EQ(capturesync_create(&sync), K4A_RESULT_SUCCEEDED); ASSERT_EQ(capturesync_start(NULL, NULL), K4A_RESULT_FAILED); @@ -523,9 +523,9 @@ static void capturesync_validate_synchronization(capturesync_test_timing_t *test ASSERT_NE(depth_test.condition = Condition_Init(), (COND_HANDLE)NULL); config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config.color_resolution = K4A_COLOR_RESOLUTION_720P; - config.depth_mode = K4A_DEPTH_MODE_WFOV_2X2BINNED; - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + config.color_mode_id = K4A_COLOR_RESOLUTION_720P; + config.depth_mode_id = K4A_DEPTH_MODE_WFOV_2X2BINNED; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_30; config.synchronized_images_only = synchd_images_only; if (color_first) { diff --git a/tests/ColorTests/FunctionalTest/CMakeLists.txt b/tests/ColorTests/FunctionalTest/CMakeLists.txt index 1e65ad739..49fdb26b9 100644 --- a/tests/ColorTests/FunctionalTest/CMakeLists.txt +++ b/tests/ColorTests/FunctionalTest/CMakeLists.txt @@ -5,6 +5,7 @@ add_executable(color_ft color_ft.cpp) target_link_libraries(color_ft PRIVATE k4a::k4a + k4ainternal::modes k4ainternal::utcommon gtest::gtest azure::aziotsharedutil) diff --git a/tests/ColorTests/FunctionalTest/color_ft.cpp b/tests/ColorTests/FunctionalTest/color_ft.cpp index 8a9df2692..88b52530d 100644 --- a/tests/ColorTests/FunctionalTest/color_ft.cpp +++ b/tests/ColorTests/FunctionalTest/color_ft.cpp @@ -4,6 +4,7 @@ //************************ Includes ***************************** #include #include +#include #include #include #include @@ -57,8 +58,8 @@ struct color_mode_parameter { uint32_t test_index; k4a_image_format_t color_format; - k4a_color_resolution_t color_resolution; - k4a_fps_t color_rate; + uint32_t color_mode_id; + uint32_t color_rate; size_t expected_image_size; uint32_t expected_fps; @@ -124,10 +125,10 @@ TEST_P(color_functional_test, color_streaming_test) stream_count = STREAM_RUN_TIME_SEC * as.expected_fps; // Configure the stream - config.camera_fps = as.color_rate; + config.fps_mode_id = as.color_rate; config.color_format = as.color_format; - config.color_resolution = as.color_resolution; - config.depth_mode = K4A_DEPTH_MODE_OFF; + config.color_mode_id = as.color_mode_id; + config.depth_mode_id = K4A_DEPTH_MODE_OFF; // start streaming. ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_cameras(m_device, &config)); @@ -238,66 +239,77 @@ INSTANTIATE_TEST_CASE_P(color_streaming, K4A_FRAMES_PER_SECOND_30, K4A_COLOR_MODE_NV12_720P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_30 }, + color_mode_parameter{ 1, K4A_IMAGE_FORMAT_COLOR_YUY2, K4A_COLOR_RESOLUTION_720P, K4A_FRAMES_PER_SECOND_30, K4A_COLOR_MODE_YUY2_720P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_30 }, + color_mode_parameter{ 2, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_2160P, K4A_FRAMES_PER_SECOND_30, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_30 }, + color_mode_parameter{ 3, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_1440P, K4A_FRAMES_PER_SECOND_30, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_30 }, + color_mode_parameter{ 4, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_1080P, K4A_FRAMES_PER_SECOND_30, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_30 }, + color_mode_parameter{ 5, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_720P, K4A_FRAMES_PER_SECOND_30, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_30 }, + color_mode_parameter{ 6, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_1536P, K4A_FRAMES_PER_SECOND_30, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_30 }, + color_mode_parameter{ 7, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_2160P, K4A_FRAMES_PER_SECOND_30, K4A_COLOR_MODE_RGB_2160P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_30 }, + color_mode_parameter{ 8, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_1440P, K4A_FRAMES_PER_SECOND_30, K4A_COLOR_MODE_RGB_1440P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_30 }, + color_mode_parameter{ 9, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_1080P, K4A_FRAMES_PER_SECOND_30, K4A_COLOR_MODE_RGB_1080P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_30 }, + color_mode_parameter{ 10, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_720P, K4A_FRAMES_PER_SECOND_30, K4A_COLOR_MODE_RGB_720P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_30 }, + color_mode_parameter{ 11, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_1536P, @@ -312,78 +324,91 @@ INSTANTIATE_TEST_CASE_P(color_streaming, K4A_FRAMES_PER_SECOND_15, K4A_COLOR_MODE_NV12_720P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_15 }, + color_mode_parameter{ 13, K4A_IMAGE_FORMAT_COLOR_YUY2, K4A_COLOR_RESOLUTION_720P, K4A_FRAMES_PER_SECOND_15, K4A_COLOR_MODE_YUY2_720P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_15 }, + color_mode_parameter{ 14, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_2160P, K4A_FRAMES_PER_SECOND_15, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_15 }, + color_mode_parameter{ 15, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_1440P, K4A_FRAMES_PER_SECOND_15, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_15 }, + color_mode_parameter{ 16, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_1080P, K4A_FRAMES_PER_SECOND_15, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_15 }, + color_mode_parameter{ 17, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_720P, K4A_FRAMES_PER_SECOND_15, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_15 }, + color_mode_parameter{ 18, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_3072P, K4A_FRAMES_PER_SECOND_15, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_15 }, + color_mode_parameter{ 19, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_1536P, K4A_FRAMES_PER_SECOND_15, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_15 }, + color_mode_parameter{ 20, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_2160P, K4A_FRAMES_PER_SECOND_15, K4A_COLOR_MODE_RGB_2160P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_15 }, + color_mode_parameter{ 21, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_1440P, K4A_FRAMES_PER_SECOND_15, K4A_COLOR_MODE_RGB_1440P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_15 }, + color_mode_parameter{ 22, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_1080P, K4A_FRAMES_PER_SECOND_15, K4A_COLOR_MODE_RGB_1080P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_15 }, + color_mode_parameter{ 23, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_720P, K4A_FRAMES_PER_SECOND_15, K4A_COLOR_MODE_RGB_720P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_15 }, + color_mode_parameter{ 24, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_3072P, K4A_FRAMES_PER_SECOND_15, K4A_COLOR_MODE_RGB_3072P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_15 }, + color_mode_parameter{ 25, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_1536P, @@ -398,78 +423,91 @@ INSTANTIATE_TEST_CASE_P(color_streaming, K4A_FRAMES_PER_SECOND_5, K4A_COLOR_MODE_NV12_720P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_5 }, + color_mode_parameter{ 27, K4A_IMAGE_FORMAT_COLOR_YUY2, K4A_COLOR_RESOLUTION_720P, K4A_FRAMES_PER_SECOND_5, K4A_COLOR_MODE_YUY2_720P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_5 }, + color_mode_parameter{ 28, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_2160P, K4A_FRAMES_PER_SECOND_5, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_5 }, + color_mode_parameter{ 29, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_1440P, K4A_FRAMES_PER_SECOND_5, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_5 }, + color_mode_parameter{ 30, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_1080P, K4A_FRAMES_PER_SECOND_5, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_5 }, + color_mode_parameter{ 31, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_720P, K4A_FRAMES_PER_SECOND_5, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_5 }, + color_mode_parameter{ 32, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_3072P, K4A_FRAMES_PER_SECOND_5, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_5 }, + color_mode_parameter{ 33, K4A_IMAGE_FORMAT_COLOR_MJPG, K4A_COLOR_RESOLUTION_1536P, K4A_FRAMES_PER_SECOND_5, K4A_COLOR_MODE_MJPG_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_5 }, + color_mode_parameter{ 34, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_2160P, K4A_FRAMES_PER_SECOND_5, K4A_COLOR_MODE_RGB_2160P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_5 }, + color_mode_parameter{ 35, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_1440P, K4A_FRAMES_PER_SECOND_5, K4A_COLOR_MODE_RGB_1440P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_5 }, + color_mode_parameter{ 36, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_1080P, K4A_FRAMES_PER_SECOND_5, K4A_COLOR_MODE_RGB_1080P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_5 }, + color_mode_parameter{ 37, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_720P, K4A_FRAMES_PER_SECOND_5, K4A_COLOR_MODE_RGB_720P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_5 }, + color_mode_parameter{ 38, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_3072P, K4A_FRAMES_PER_SECOND_5, K4A_COLOR_MODE_RGB_3072P_EXPECTED_SIZE, K4A_COLOR_MODE_EXPECTED_FPS_5 }, + color_mode_parameter{ 39, K4A_IMAGE_FORMAT_COLOR_BGRA32, K4A_COLOR_RESOLUTION_1536P, @@ -499,15 +537,15 @@ TEST_F(color_functional_test, colorModeChange) // Create two valid configs that are expected to yield different-sized color payloads // - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_30; config.color_format = K4A_IMAGE_FORMAT_COLOR_NV12; - config.color_resolution = K4A_COLOR_RESOLUTION_720P; - config.depth_mode = K4A_DEPTH_MODE_OFF; + config.color_mode_id = K4A_COLOR_RESOLUTION_720P; + config.depth_mode_id = K4A_DEPTH_MODE_OFF; - config2.camera_fps = K4A_FRAMES_PER_SECOND_30; + config2.fps_mode_id = K4A_FRAMES_PER_SECOND_30; config2.color_format = K4A_IMAGE_FORMAT_COLOR_YUY2; - config2.color_resolution = K4A_COLOR_RESOLUTION_720P; - config2.depth_mode = K4A_DEPTH_MODE_OFF; + config2.color_mode_id = K4A_COLOR_RESOLUTION_720P; + config2.depth_mode_id = K4A_DEPTH_MODE_OFF; // Start device in first mode and check frame size // @@ -567,10 +605,10 @@ TEST_F(color_functional_test, colorExposureTest) // Create two valid configs that are expected to yield different-sized color payloads // - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_30; config.color_format = K4A_IMAGE_FORMAT_COLOR_NV12; - config.color_resolution = K4A_COLOR_RESOLUTION_720P; - config.depth_mode = K4A_DEPTH_MODE_OFF; + config.color_mode_id = K4A_COLOR_RESOLUTION_720P; + config.depth_mode_id = K4A_DEPTH_MODE_OFF; // Exposure set test ASSERT_EQ(K4A_RESULT_SUCCEEDED, @@ -785,10 +823,10 @@ void color_control_test::control_test_worker(const k4a_color_control_command_t c if ((rand() * 2 / RAND_MAX) >= 1) { config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; - config.camera_fps = K4A_FRAMES_PER_SECOND_5; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_5; config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config.color_resolution = K4A_COLOR_RESOLUTION_1080P; - config.depth_mode = K4A_DEPTH_MODE_WFOV_2X2BINNED; + config.color_mode_id = K4A_COLOR_RESOLUTION_1080P; + config.depth_mode_id = K4A_DEPTH_MODE_WFOV_2X2BINNED; config.synchronized_images_only = true; ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_cameras(m_device, &config)); std::cout << "control_test_worker: k4a_device_start_cameras called\n"; @@ -855,7 +893,8 @@ void color_control_test::control_test_worker(const k4a_color_control_command_t c ASSERT_EQ(value, map_manual_exposure(testValue, b_sixty_hertz)) << testValue << " was the value tested\n"; if (cameras_running) { - ASSERT_TRUE(validate_image_exposure_setting(value, b_sixty_hertz, config.camera_fps)) << "1"; + ASSERT_TRUE(validate_image_exposure_setting(value, b_sixty_hertz, (k4a_fps_t)config.fps_mode_id)) + << "1"; } testValue = threshold; @@ -865,7 +904,8 @@ void color_control_test::control_test_worker(const k4a_color_control_command_t c ASSERT_EQ(value, map_manual_exposure(testValue, b_sixty_hertz)) << testValue << " was the value tested\n"; if (cameras_running) { - ASSERT_TRUE(validate_image_exposure_setting(value, b_sixty_hertz, config.camera_fps)) << "2"; + ASSERT_TRUE(validate_image_exposure_setting(value, b_sixty_hertz, (k4a_fps_t)config.fps_mode_id)) + << "2"; } testValue = threshold + 1; @@ -875,7 +915,8 @@ void color_control_test::control_test_worker(const k4a_color_control_command_t c ASSERT_EQ(value, map_manual_exposure(testValue, b_sixty_hertz)) << testValue << " was the value tested\n"; if (cameras_running) { - ASSERT_TRUE(validate_image_exposure_setting(value, b_sixty_hertz, config.camera_fps)) << "3"; + ASSERT_TRUE(validate_image_exposure_setting(value, b_sixty_hertz, (k4a_fps_t)config.fps_mode_id)) + << "3"; } ASSERT_EQ(current_mode, manual); @@ -958,6 +999,56 @@ TEST_P(color_control_test, control_test) } } +/** + * Functional test for verifying color modes. + * + * @Test criteria + * Pass conditions; + * Calling k4a_device_get_color_mode_count() and k4a_device_get_color_mode() has proper return values. + * + */ +TEST_F(color_functional_test, colorModeInfo) +{ + K4A_INIT_STRUCT(k4a_color_mode_info_t, colorModeInfo) + uint32_t colorModeCount = 0; + + // Test invalid arguments. + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_color_mode_count(NULL, &colorModeCount)) + << "Unexpected return value for invalid device handle.\n"; + + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_color_mode_count(m_device, NULL)) + << "Unexpected return value for invalid depth mode count pointer.\n"; + + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_color_mode(NULL, 0, &colorModeInfo)) + << "Unexpected return value for invalid device handle.\n"; + + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_color_mode(m_device, 0, NULL)) + << "Unexpected return value for invalid device handle.\n"; + + // Get the color mode count. + ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_get_color_mode_count(m_device, &colorModeCount)) + << "Couldn't get color mode count.\n"; + + // Test invalid color mode index. + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_color_mode(m_device, colorModeCount, &colorModeInfo)) + << "Unexpected return value for color mode index greater than number of depth modes.\n"; + + // Get color mode info. + for (uint32_t d = 0; d < colorModeCount; ++d) + { + colorModeInfo = { colorModeInfo.struct_size, colorModeInfo.struct_version, 0 }; + + ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_get_color_mode(m_device, d, &colorModeInfo)) + << "Couldn't get color mode info.\n"; + + EXPECT_EQ(colorModeInfo.struct_version, static_cast(K4A_ABI_VERSION)) + << "Color mode struct version invalid\n"; + + EXPECT_EQ(colorModeInfo.struct_size, static_cast(sizeof(k4a_color_mode_info_t))) + << "Color mode struct size invalid\n"; + } +} + INSTANTIATE_TEST_CASE_P( color_control, color_control_test, diff --git a/tests/ColorTests/UnitTest/CMakeLists.txt b/tests/ColorTests/UnitTest/CMakeLists.txt index f8f49c1e5..d5e77ff7d 100644 --- a/tests/ColorTests/UnitTest/CMakeLists.txt +++ b/tests/ColorTests/UnitTest/CMakeLists.txt @@ -29,6 +29,7 @@ target_link_libraries(color_ut PRIVATE # Link k4ainternal::color without transitive dependencies $ k4ainternal::image + k4ainternal::modes k4ainternal::queue) if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") diff --git a/tests/ColorTests/UnitTest/color_mock_libuvc.cpp b/tests/ColorTests/UnitTest/color_mock_libuvc.cpp index cec460061..3b9813f38 100644 --- a/tests/ColorTests/UnitTest/color_mock_libuvc.cpp +++ b/tests/ColorTests/UnitTest/color_mock_libuvc.cpp @@ -1,3 +1,5 @@ +#include + #include "color_mock_libuvc.h" using namespace testing; @@ -87,7 +89,7 @@ void EXPECT_uvc_find_device(MockLibUVC &mockLibUVC, const char *serial_number) } else { - if (vid == 0x045e && pid == 0x097d && strcmp(sn, serial_number) == 0) + if (vid == K4A_MSFT_VID && pid == K4A_RGB_PID && strcmp(sn, serial_number) == 0) { *dev = g_uvc_device; g_device_ref_count++; diff --git a/tests/ColorTests/UnitTest/color_ut.cpp b/tests/ColorTests/UnitTest/color_ut.cpp index 1d77e0457..d971c69a4 100644 --- a/tests/ColorTests/UnitTest/color_ut.cpp +++ b/tests/ColorTests/UnitTest/color_ut.cpp @@ -164,10 +164,10 @@ TEST_F(color_ut, streaming) color_create(tick, &guid_FakeGoodContainerId, str_FakeGoodSerialNumber, NULL, NULL, &color_handle)); ASSERT_NE(color_handle, (color_t)NULL); - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_30; config.color_format = K4A_IMAGE_FORMAT_COLOR_NV12; - config.color_resolution = K4A_COLOR_RESOLUTION_720P; - config.depth_mode = K4A_DEPTH_MODE_OFF; + config.color_mode_id = K4A_COLOR_RESOLUTION_720P; + config.depth_mode_id = K4A_DEPTH_MODE_OFF; // test color_start() ASSERT_EQ(K4A_RESULT_SUCCEEDED, color_start(color_handle, &config)); @@ -192,10 +192,10 @@ TEST_F(color_ut, exposure_control) color_create(tick, &guid_FakeGoodContainerId, str_FakeGoodSerialNumber, NULL, NULL, &color_handle)); ASSERT_NE(color_handle, (color_t)NULL); - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_30; config.color_format = K4A_IMAGE_FORMAT_COLOR_NV12; - config.color_resolution = K4A_COLOR_RESOLUTION_720P; - config.depth_mode = K4A_DEPTH_MODE_OFF; + config.color_mode_id = K4A_COLOR_RESOLUTION_720P; + config.depth_mode_id = K4A_DEPTH_MODE_OFF; // set exposure to 500 uSec ASSERT_EQ(K4A_RESULT_SUCCEEDED, diff --git a/tests/DepthTests/FunctionalTest/depth_ft.cpp b/tests/DepthTests/FunctionalTest/depth_ft.cpp index 6d5a78892..6d343272a 100644 --- a/tests/DepthTests/FunctionalTest/depth_ft.cpp +++ b/tests/DepthTests/FunctionalTest/depth_ft.cpp @@ -3,6 +3,7 @@ //************************ Includes ***************************** #include +#include #include #include #include @@ -137,9 +138,9 @@ static void RunStreamConfig(k4a_device_t device, // Configure the stream config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config.color_resolution = K4A_COLOR_RESOLUTION_OFF; - config.depth_mode = depth_mode; - config.camera_fps = depth_fps; + config.color_mode_id = K4A_COLOR_RESOLUTION_OFF; + config.depth_mode_id = depth_mode; + config.fps_mode_id = depth_fps; // start streaming. ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_cameras(device, &config)); @@ -487,14 +488,14 @@ TEST_F(depth_ft, depthModeChange) // Create two valid configs that are expected to yield different-sized depth payloads // config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config.color_resolution = K4A_COLOR_RESOLUTION_OFF; - config.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; - config.camera_fps = K4A_FRAMES_PER_SECOND_15; + config.color_mode_id = K4A_COLOR_RESOLUTION_OFF; + config.depth_mode_id = K4A_DEPTH_MODE_NFOV_UNBINNED; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_15; config2.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config2.color_resolution = K4A_COLOR_RESOLUTION_OFF; - config2.depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED; - config2.camera_fps = K4A_FRAMES_PER_SECOND_15; + config2.color_mode_id = K4A_COLOR_RESOLUTION_OFF; + config2.depth_mode_id = K4A_DEPTH_MODE_NFOV_2X2BINNED; + config2.fps_mode_id = K4A_FRAMES_PER_SECOND_15; // Start device in first mode and check frame size // @@ -502,7 +503,7 @@ TEST_F(depth_ft, depthModeChange) ASSERT_EQ(K4A_WAIT_RESULT_SUCCEEDED, k4a_device_get_capture(m_device, &depth_capture, timeout_ms)); - if (config.depth_mode != K4A_DEPTH_MODE_PASSIVE_IR) + if (config.depth_mode_id != K4A_DEPTH_MODE_PASSIVE_IR) { image = k4a_capture_get_depth_image(depth_capture); ASSERT_NE(k4a_image_get_buffer(image), (uint8_t *)NULL); @@ -525,7 +526,7 @@ TEST_F(depth_ft, depthModeChange) ASSERT_EQ(K4A_WAIT_RESULT_SUCCEEDED, k4a_device_get_capture(m_device, &depth_capture, timeout_ms)); - if (config2.depth_mode != K4A_DEPTH_MODE_PASSIVE_IR) + if (config2.depth_mode_id != K4A_DEPTH_MODE_PASSIVE_IR) { image = k4a_capture_get_depth_image(depth_capture); ASSERT_NE(k4a_image_get_buffer(image), (uint8_t *)NULL); @@ -543,6 +544,137 @@ TEST_F(depth_ft, depthModeChange) k4a_device_stop_cameras(m_device); } +/** + * Functional test for verifying correct device info. + * + * @Test criteria + * Pass conditions; + * Device info has non-zero VID, PID, and capabilities. + * Capabilities shall only be composed of binary bitmap allowed values. + * + */ +TEST_F(depth_ft, deviceInfo) +{ + K4A_INIT_STRUCT(k4a_device_info_t, deviceInfo) + + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_info(NULL, &deviceInfo)) + << "Unexpected return value for invalid device handle."; + + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_info(m_device, NULL)) + << "Unexpected return value for invalid device info pointer."; + + ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_get_info(m_device, &deviceInfo)) << "Couldn't get device information\n"; + + EXPECT_EQ(deviceInfo.struct_version, static_cast(K4A_ABI_VERSION)) + << "Device info struct version invalid\n"; + EXPECT_EQ(deviceInfo.struct_size, static_cast(sizeof(k4a_device_info_t))) + << "Device info struct size invalid\n"; + EXPECT_NE(deviceInfo.vendor_id, static_cast(0)) << "Device info vendor id invalid\n"; + EXPECT_NE(deviceInfo.device_id, static_cast(0)) << "Device info device id invalid\n"; + EXPECT_GT(deviceInfo.capabilities.value, static_cast(0)) + << "Device info capabilities must be greater than 0.\n"; +} + +/** + * Functional test for verifying depth modes. + * + * @Test criteria + * Pass conditions; + * Calling k4a_device_get_depth_mode_count() and k4a_device_get_depth_mode() has proper return values. + * + */ +TEST_F(depth_ft, deviceModeInfo) +{ + K4A_INIT_STRUCT(k4a_depth_mode_info_t, depthModeInfo) + uint32_t depthModeCount = 0; + + // Test invalid arguments. + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_depth_mode_count(NULL, &depthModeCount)) + << "Unexpected return value for invalid device handle.\n"; + + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_depth_mode_count(m_device, NULL)) + << "Unexpected return value for invalid depth mode count pointer.\n"; + + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_depth_mode(NULL, 0, &depthModeInfo)) + << "Unexpected return value for invalid device handle.\n"; + + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_depth_mode(m_device, 0, NULL)) + << "Unexpected return value for invalid device handle.\n"; + + // Get the depth mode count. + ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_get_depth_mode_count(m_device, &depthModeCount)) + << "Couldn't get depth mode count.\n"; + + // Test invalid depth mode index. + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_depth_mode(m_device, depthModeCount, &depthModeInfo)) + << "Unexpected return value for depth mode index greater than number of depth modes.\n"; + + // Get depth mode info. + for (uint32_t d = 0; d < depthModeCount; ++d) + { + depthModeInfo = { depthModeInfo.struct_size, depthModeInfo.struct_version, 0 }; + + ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_get_depth_mode(m_device, d, &depthModeInfo)) + << "Couldn't get depth mode info.\n"; + + EXPECT_EQ(depthModeInfo.struct_version, static_cast(K4A_ABI_VERSION)) + << "Depth mode struct version invalid\n"; + + EXPECT_EQ(depthModeInfo.struct_size, static_cast(sizeof(k4a_depth_mode_info_t))) + << "Depth mode struct size invalid\n"; + } +} + +/** + * Functional test for verifying fps modes. + * + * @Test criteria + * Pass conditions; + * Calling k4a_device_get_fps_mode_count() and k4a_device_get_fps_mode() has proper return values. + * + */ +TEST_F(depth_ft, fpsModeInfo) +{ + K4A_INIT_STRUCT(k4a_fps_mode_info_t, fpsModeInfo) + uint32_t fpsModeCount = 0; + + // Test invalid arguments. + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_fps_mode_count(NULL, &fpsModeCount)) + << "Unexpected return value for invalid device handle.\n"; + + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_fps_mode_count(m_device, NULL)) + << "Unexpected return value for invalid depth mode count pointer.\n"; + + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_fps_mode(NULL, 0, &fpsModeInfo)) + << "Unexpected return value for invalid device handle.\n"; + + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_fps_mode(m_device, 0, NULL)) + << "Unexpected return value for invalid device handle.\n"; + + // Get the depth mode count. + ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_get_fps_mode_count(m_device, &fpsModeCount)) + << "Couldn't get fps mode count.\n"; + + // Test invalid depth mode index. + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_get_fps_mode(m_device, fpsModeCount, &fpsModeInfo)) + << "Unexpected return value for fps mode index greater than number of depth modes.\n"; + + // Get fps mode info. + for (uint32_t d = 0; d < fpsModeCount; ++d) + { + fpsModeInfo = { fpsModeInfo.struct_size, fpsModeInfo.struct_version, 0 }; + + ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_get_fps_mode(m_device, d, &fpsModeInfo)) + << "Couldn't get fps mode info.\n"; + + EXPECT_EQ(fpsModeInfo.struct_version, static_cast(K4A_ABI_VERSION)) + << "FPS mode struct version invalid\n"; + + EXPECT_EQ(fpsModeInfo.struct_size, static_cast(sizeof(k4a_fps_mode_info_t))) + << "FPS mode struct size invalid\n"; + } +} + int main(int argc, char **argv) { return k4a_test_common_main(argc, argv); diff --git a/tests/DepthTests/UnitTest/CMakeLists.txt b/tests/DepthTests/UnitTest/CMakeLists.txt index cf9f3cf21..4252c261f 100644 --- a/tests/DepthTests/UnitTest/CMakeLists.txt +++ b/tests/DepthTests/UnitTest/CMakeLists.txt @@ -12,6 +12,7 @@ target_link_libraries(depth_ut PRIVATE k4ainternal::calibration k4ainternal::image k4ainternal::logging + k4ainternal::modes k4ainternal::queue) # Include the PUBLIC and INTERFACE directories specified by k4ainternal::depth diff --git a/tests/DepthTests/UnitTest/depth_ut.cpp b/tests/DepthTests/UnitTest/depth_ut.cpp index db4c07d5e..9c3545bc2 100644 --- a/tests/DepthTests/UnitTest/depth_ut.cpp +++ b/tests/DepthTests/UnitTest/depth_ut.cpp @@ -5,7 +5,6 @@ #include // Module being tested -#include #include #include #include @@ -28,9 +27,9 @@ class MockDepthMcu k4a_result_t(depthmcu_t depthmcu_handle, depthmcu_firmware_versions_t *version)); MOCK_CONST_METHOD2(depthmcu_depth_set_capture_mode, - k4a_result_t(depthmcu_t depthmcu_handle, k4a_depth_mode_t capture_mode)); + k4a_result_t(depthmcu_t depthmcu_handle, uint32_t depth_mode_id)); - MOCK_CONST_METHOD2(depthmcu_depth_set_fps, k4a_result_t(depthmcu_t depthmcu_handle, k4a_fps_t capture_fps)); + MOCK_CONST_METHOD2(depthmcu_depth_set_fps, k4a_result_t(depthmcu_t depthmcu_handle, uint32_t fps_mode_id)); MOCK_CONST_METHOD3(depthmcu_depth_start_streaming, k4a_result_t(depthmcu_t depthmcu_handle, @@ -66,14 +65,14 @@ k4a_result_t depthmcu_get_version(depthmcu_t depthmcu_handle, depthmcu_firmware_ return g_MockDepthMcu->depthmcu_get_version(depthmcu_handle, version); } -k4a_result_t depthmcu_depth_set_capture_mode(depthmcu_t depthmcu_handle, k4a_depth_mode_t capture_mode) +k4a_result_t depthmcu_depth_set_capture_mode(depthmcu_t depthmcu_handle, uint32_t depth_mode_id) { - return g_MockDepthMcu->depthmcu_depth_set_capture_mode(depthmcu_handle, capture_mode); + return g_MockDepthMcu->depthmcu_depth_set_capture_mode(depthmcu_handle, depth_mode_id); } -k4a_result_t depthmcu_depth_set_fps(depthmcu_t depthmcu_handle, k4a_fps_t capture_fps) +k4a_result_t depthmcu_depth_set_fps(depthmcu_t depthmcu_handle, uint32_t fps_mode_id) { - return g_MockDepthMcu->depthmcu_depth_set_fps(depthmcu_handle, capture_fps); + return g_MockDepthMcu->depthmcu_depth_set_fps(depthmcu_handle, fps_mode_id); } k4a_result_t depthmcu_depth_start_streaming(depthmcu_t depthmcu_handle, diff --git a/tests/IMUTests/FunctionalTest/imu_ft.cpp b/tests/IMUTests/FunctionalTest/imu_ft.cpp index 9d09841f3..cd8855b74 100644 --- a/tests/IMUTests/FunctionalTest/imu_ft.cpp +++ b/tests/IMUTests/FunctionalTest/imu_ft.cpp @@ -100,7 +100,8 @@ static void RunStreamConfig(k4a_device_t device, uint32_t expected_fps) // will go backwards if started while the free running timestamp on the firmware is under 5s from the previous // start. This is directly related to how the IMU module uses "color_camera_start_tick" config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; - config.depth_mode = K4A_DEPTH_MODE_PASSIVE_IR; + config.depth_mode_id = K4A_DEPTH_MODE_PASSIVE_IR; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_30; ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_cameras(device, &config)); ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_imu(device)); ASSERT_EQ(K4A_WAIT_RESULT_SUCCEEDED, k4a_device_get_imu_sample(device, &imu_sample, timeout_ms)); @@ -114,9 +115,9 @@ static void RunStreamConfig(k4a_device_t device, uint32_t expected_fps) config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config.color_resolution = K4A_COLOR_RESOLUTION_2160P; - config.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + config.color_mode_id = K4A_COLOR_RESOLUTION_2160P; + config.depth_mode_id = K4A_DEPTH_MODE_NFOV_UNBINNED; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_30; config.synchronized_images_only = false; ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_cameras(device, &config)); @@ -241,9 +242,9 @@ TEST_F(imu_ft, imu_start) k4a_device_configuration_t config_all_running = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; config_all_running.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config_all_running.color_resolution = K4A_COLOR_RESOLUTION_2160P; - config_all_running.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; - config_all_running.camera_fps = K4A_FRAMES_PER_SECOND_30; + config_all_running.color_mode_id = K4A_COLOR_RESOLUTION_2160P; + config_all_running.depth_mode_id = K4A_DEPTH_MODE_NFOV_UNBINNED; + config_all_running.fps_mode_id = K4A_FRAMES_PER_SECOND_30; config = config_all_running; ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_start_imu(m_device)); // Sensor not running @@ -279,7 +280,7 @@ TEST_F(imu_ft, imu_start) // Start only if running depth camera config = config_all_running; - config.color_resolution = K4A_COLOR_RESOLUTION_OFF; + config.color_mode_id = K4A_COLOR_RESOLUTION_OFF; ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_cameras(m_device, &config)); ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_imu(m_device)); k4a_device_stop_cameras(m_device); @@ -287,7 +288,7 @@ TEST_F(imu_ft, imu_start) // Start only if running color camera config = config_all_running; - config.depth_mode = K4A_DEPTH_MODE_OFF; + config.depth_mode_id = K4A_DEPTH_MODE_OFF; ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_cameras(m_device, &config)); ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_imu(m_device)); k4a_device_stop_cameras(m_device); diff --git a/tests/RecordTests/FunctionalTest/k4a_cpp_ft.cpp b/tests/RecordTests/FunctionalTest/k4a_cpp_ft.cpp index 819284ddb..8601e0ddc 100644 --- a/tests/RecordTests/FunctionalTest/k4a_cpp_ft.cpp +++ b/tests/RecordTests/FunctionalTest/k4a_cpp_ft.cpp @@ -81,22 +81,38 @@ TEST_F(k4a_cpp_ft, k4a) (void)kinect.is_sync_in_connected(); { + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_device_get_depth_mode(kinect.handle(), 1, &depth_mode_info); // K4A_DEPTH_MODE_NFOV_2X2BINNED + + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_device_get_color_mode(kinect.handle(), 3, &color_mode_info); // K4A_COLOR_RESOLUTION_1440P + // should not throw exception - calibration cal = kinect.get_calibration(K4A_DEPTH_MODE_NFOV_2X2BINNED, K4A_COLOR_RESOLUTION_1440P); + calibration cal = kinect.get_calibration(depth_mode_info.mode_id, color_mode_info.mode_id); calibration cal2 = cal; - ASSERT_EQ(cal.color_resolution, cal2.color_resolution); + + ASSERT_EQ(cal.color_mode_id, cal2.color_mode_id); } { + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_device_get_depth_mode(kinect.handle(), 1, &depth_mode_info); // K4A_DEPTH_MODE_NFOV_2X2BINNED + + k4a_color_mode_info_t color_mode_info3 = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_device_get_color_mode(kinect.handle(), 3, &color_mode_info3); // K4A_COLOR_RESOLUTION_1440P + std::vector raw_cal = kinect.get_raw_calibration(); - calibration cal = kinect.get_calibration(K4A_DEPTH_MODE_NFOV_2X2BINNED, K4A_COLOR_RESOLUTION_1440P); - ASSERT_EQ(cal.color_resolution, K4A_COLOR_RESOLUTION_1440P); + calibration cal = kinect.get_calibration(depth_mode_info.mode_id, color_mode_info3.mode_id); + ASSERT_EQ(cal.color_mode_id, (uint32_t)3); + + k4a_color_mode_info_t color_mode_info2 = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_device_get_color_mode(kinect.handle(), 2, &color_mode_info2); // K4A_COLOR_RESOLUTION_1080P cal = calibration::get_from_raw(raw_cal.data(), raw_cal.size(), - K4A_DEPTH_MODE_NFOV_2X2BINNED, - K4A_COLOR_RESOLUTION_1080P); - ASSERT_EQ(cal.color_resolution, K4A_COLOR_RESOLUTION_1080P); + depth_mode_info.mode_id, + color_mode_info2.mode_id); + ASSERT_EQ(cal.color_mode_id, (uint32_t)2); } { @@ -115,8 +131,9 @@ TEST_F(k4a_cpp_ft, k4a) k4a_imu_sample_t sample = { 0 }; capture cap1, cap2; k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; - config.color_resolution = K4A_COLOR_RESOLUTION_1080P; - config.depth_mode = K4A_DEPTH_MODE_PASSIVE_IR; + config.color_mode_id = 2; // K4A_COLOR_RESOLUTION_1080P + config.depth_mode_id = 5; // K4A_DEPTH_MODE_PASSIVE_IR + config.fps_mode_id = 30; // K4A_FRAMES_PER_SECOND_30 config.synchronized_images_only = true; kinect.start_cameras(&config); kinect.start_imu(); @@ -255,8 +272,9 @@ static void test_record(void) record recorder; device kinect = device::open(0); k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; - config.color_resolution = K4A_COLOR_RESOLUTION_1080P; - config.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; + config.color_mode_id = 2; // K4A_COLOR_RESOLUTION_1080P + config.depth_mode_id = 2; // K4A_DEPTH_MODE_NFOV_UNBINNED + config.fps_mode_id = 30; // K4A_FRAMES_PER_SECOND_30 config.synchronized_images_only = true; kinect.start_cameras(&config); kinect.start_imu(); @@ -392,9 +410,9 @@ static void test_playback(void) calibration cal = pback.get_calibration(); { device kinect = device::open(0); - calibration device_cal = kinect.get_calibration(config.depth_mode, config.color_resolution); - ASSERT_TRUE(cal.color_resolution == device_cal.color_resolution); - ASSERT_TRUE(cal.depth_mode == device_cal.depth_mode); + calibration device_cal = kinect.get_calibration(config.depth_mode_info.mode_id, config.color_mode_info.mode_id); + ASSERT_TRUE(cal.color_mode_id == device_cal.color_mode_id); + ASSERT_TRUE(cal.depth_mode_id == device_cal.depth_mode_id); } pback.set_color_conversion(K4A_IMAGE_FORMAT_COLOR_NV12); diff --git a/tests/RecordTests/UnitTest/CMakeLists.txt b/tests/RecordTests/UnitTest/CMakeLists.txt index 394facb84..cc855eddc 100644 --- a/tests/RecordTests/UnitTest/CMakeLists.txt +++ b/tests/RecordTests/UnitTest/CMakeLists.txt @@ -13,12 +13,14 @@ target_link_libraries(record_ut PRIVATE ) target_link_libraries(playback_ut PRIVATE + k4ainternal::modes k4ainternal::utcommon k4ainternal::playback k4a::k4arecord ) target_link_libraries(playback_perf PRIVATE + k4ainternal::modes k4ainternal::utcommon k4ainternal::playback k4a::k4arecord diff --git a/tests/RecordTests/UnitTest/custom_track_ut.cpp b/tests/RecordTests/UnitTest/custom_track_ut.cpp index 37005cadb..21e0db4d6 100644 --- a/tests/RecordTests/UnitTest/custom_track_ut.cpp +++ b/tests/RecordTests/UnitTest/custom_track_ut.cpp @@ -29,9 +29,9 @@ TEST_F(custom_track_ut, open_custom_track_file) result = k4a_playback_get_record_configuration(handle, &config); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); ASSERT_EQ(config.color_format, K4A_IMAGE_FORMAT_CUSTOM); - ASSERT_EQ(config.color_resolution, K4A_COLOR_RESOLUTION_OFF); - ASSERT_EQ(config.depth_mode, K4A_DEPTH_MODE_NFOV_UNBINNED); - ASSERT_EQ(config.camera_fps, K4A_FRAMES_PER_SECOND_30); + ASSERT_EQ(config.color_mode_info.mode_id, (uint32_t)K4A_COLOR_RESOLUTION_OFF); + ASSERT_EQ(config.depth_mode_info.mode_id, (uint32_t)K4A_DEPTH_MODE_NFOV_UNBINNED); + ASSERT_EQ(config.fps_mode_info.mode_id, (uint32_t)K4A_FRAMES_PER_SECOND_30); ASSERT_FALSE(config.color_track_enabled); ASSERT_TRUE(config.depth_track_enabled); ASSERT_TRUE(config.ir_track_enabled); @@ -52,7 +52,7 @@ TEST_F(custom_track_ut, open_custom_track_file) timestamps_usec, config.color_format, K4A_COLOR_RESOLUTION_OFF, - config.depth_mode)); + config.depth_mode_info.mode_id)); k4a_capture_release(capture); timestamps_usec[0] += test_timestamp_delta_usec; timestamps_usec[1] += test_timestamp_delta_usec; @@ -76,9 +76,9 @@ TEST_F(custom_track_ut, list_available_tracks) result = k4a_playback_get_record_configuration(handle, &config); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); ASSERT_EQ(config.color_format, K4A_IMAGE_FORMAT_CUSTOM); - ASSERT_EQ(config.color_resolution, K4A_COLOR_RESOLUTION_OFF); - ASSERT_EQ(config.depth_mode, K4A_DEPTH_MODE_NFOV_UNBINNED); - ASSERT_EQ(config.camera_fps, K4A_FRAMES_PER_SECOND_30); + ASSERT_EQ(config.color_mode_info.mode_id, (uint32_t)K4A_COLOR_RESOLUTION_OFF); + ASSERT_EQ(config.depth_mode_info.mode_id, (uint32_t)K4A_DEPTH_MODE_NFOV_UNBINNED); + ASSERT_EQ(config.fps_mode_info.mode_id, (uint32_t)K4A_FRAMES_PER_SECOND_30); ASSERT_FALSE(config.color_track_enabled); ASSERT_TRUE(config.depth_track_enabled); ASSERT_TRUE(config.ir_track_enabled); diff --git a/tests/RecordTests/UnitTest/playback_perf.cpp b/tests/RecordTests/UnitTest/playback_perf.cpp index bd76cb906..4f8244477 100644 --- a/tests/RecordTests/UnitTest/playback_perf.cpp +++ b/tests/RecordTests/UnitTest/playback_perf.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include "test_helpers.h" @@ -51,9 +50,9 @@ TEST_F(playback_perf, test_open) } std::cout << std::endl; std::cout << " Color format: " << format_names[config.color_format] << std::endl; - std::cout << " Color resolution: " << resolution_names[config.color_resolution] << std::endl; - std::cout << " Depth mode: " << depth_names[config.depth_mode] << std::endl; - std::cout << " Frame rate: " << fps_names[config.camera_fps] << std::endl; + std::cout << " Color resolution: " << resolution_names[config.color_mode_info.mode_id] << std::endl; + std::cout << " Depth mode: " << depth_names[config.depth_mode_info.mode_id] << std::endl; + std::cout << " Frame rate: " << fps_names[config.fps_mode_info.mode_id] << std::endl; std::cout << " Depth delay: " << config.depth_delay_off_color_usec << " usec" << std::endl; std::cout << " Start offset: " << config.start_timestamp_offset_usec << " usec" << std::endl; diff --git a/tests/RecordTests/UnitTest/playback_ut.cpp b/tests/RecordTests/UnitTest/playback_ut.cpp index ced7e36d1..4f39acf04 100644 --- a/tests/RecordTests/UnitTest/playback_ut.cpp +++ b/tests/RecordTests/UnitTest/playback_ut.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include "test_helpers.h" @@ -77,9 +76,9 @@ TEST_F(playback_ut, open_large_file) result = k4a_playback_get_record_configuration(handle, &config); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); ASSERT_EQ(config.color_format, K4A_IMAGE_FORMAT_COLOR_MJPG); - ASSERT_EQ(config.color_resolution, K4A_COLOR_RESOLUTION_1080P); - ASSERT_EQ(config.depth_mode, K4A_DEPTH_MODE_NFOV_UNBINNED); - ASSERT_EQ(config.camera_fps, K4A_FRAMES_PER_SECOND_30); + ASSERT_EQ(config.color_mode_info.mode_id, (uint32_t)K4A_COLOR_RESOLUTION_1080P); + ASSERT_EQ(config.depth_mode_info.mode_id, (uint32_t)K4A_DEPTH_MODE_NFOV_UNBINNED); + ASSERT_EQ(config.fps_mode_info.mode_id, (uint32_t)K4A_FRAMES_PER_SECOND_30); ASSERT_TRUE(config.color_track_enabled); ASSERT_TRUE(config.depth_track_enabled); ASSERT_TRUE(config.ir_track_enabled); @@ -92,7 +91,7 @@ TEST_F(playback_ut, open_large_file) k4a_capture_t capture = NULL; k4a_stream_result_t stream_result = K4A_STREAM_RESULT_FAILED; uint64_t timestamps[3] = { 0, 1000, 1000 }; - uint64_t timestamp_delta = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(config.camera_fps)); + uint64_t timestamp_delta = HZ_TO_PERIOD_US(config.fps_mode_info.fps); size_t i = 0; for (; i < 50; i++) { @@ -101,8 +100,8 @@ TEST_F(playback_ut, open_large_file) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); timestamps[0] += timestamp_delta; timestamps[1] += timestamp_delta; @@ -122,8 +121,8 @@ TEST_F(playback_ut, open_large_file) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); } timestamps[0] += timestamp_delta; @@ -137,8 +136,8 @@ TEST_F(playback_ut, open_large_file) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); timestamps[0] += timestamp_delta; timestamps[1] += timestamp_delta; @@ -162,9 +161,9 @@ TEST_F(playback_ut, open_delay_offset_file) result = k4a_playback_get_record_configuration(handle, &config); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); ASSERT_EQ(config.color_format, K4A_IMAGE_FORMAT_COLOR_MJPG); - ASSERT_EQ(config.color_resolution, K4A_COLOR_RESOLUTION_1080P); - ASSERT_EQ(config.depth_mode, K4A_DEPTH_MODE_NFOV_UNBINNED); - ASSERT_EQ(config.camera_fps, K4A_FRAMES_PER_SECOND_30); + ASSERT_EQ(config.color_mode_info.mode_id, (uint32_t)K4A_COLOR_RESOLUTION_1080P); + ASSERT_EQ(config.depth_mode_info.mode_id, (uint32_t)K4A_DEPTH_MODE_NFOV_UNBINNED); + ASSERT_EQ(config.fps_mode_info.mode_id, (uint32_t)K4A_FRAMES_PER_SECOND_30); ASSERT_TRUE(config.color_track_enabled); ASSERT_TRUE(config.depth_track_enabled); ASSERT_TRUE(config.ir_track_enabled); @@ -177,7 +176,7 @@ TEST_F(playback_ut, open_delay_offset_file) k4a_capture_t capture = NULL; k4a_stream_result_t stream_result = K4A_STREAM_RESULT_FAILED; uint64_t timestamps[3] = { 0, 10000, 10000 }; - uint64_t timestamp_delta = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(config.camera_fps)); + uint64_t timestamp_delta = HZ_TO_PERIOD_US(config.fps_mode_info.fps); // Read forward for (size_t i = 0; i < test_frame_count; i++) @@ -187,8 +186,8 @@ TEST_F(playback_ut, open_delay_offset_file) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); timestamps[0] += timestamp_delta; timestamps[1] += timestamp_delta; @@ -209,8 +208,8 @@ TEST_F(playback_ut, open_delay_offset_file) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); } stream_result = k4a_playback_get_previous_capture(handle, &capture); @@ -231,9 +230,9 @@ TEST_F(playback_ut, open_subordinate_delay_file) result = k4a_playback_get_record_configuration(handle, &config); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); ASSERT_EQ(config.color_format, K4A_IMAGE_FORMAT_COLOR_MJPG); - ASSERT_EQ(config.color_resolution, K4A_COLOR_RESOLUTION_1080P); - ASSERT_EQ(config.depth_mode, K4A_DEPTH_MODE_NFOV_UNBINNED); - ASSERT_EQ(config.camera_fps, K4A_FRAMES_PER_SECOND_30); + ASSERT_EQ(config.color_mode_info.mode_id, (uint32_t)K4A_COLOR_RESOLUTION_1080P); + ASSERT_EQ(config.depth_mode_info.mode_id, (uint32_t)K4A_DEPTH_MODE_NFOV_UNBINNED); + ASSERT_EQ(config.fps_mode_info.mode_id, (uint32_t)K4A_FRAMES_PER_SECOND_30); ASSERT_TRUE(config.color_track_enabled); ASSERT_TRUE(config.depth_track_enabled); ASSERT_TRUE(config.ir_track_enabled); @@ -248,8 +247,11 @@ TEST_F(playback_ut, open_subordinate_delay_file) k4a_capture_t capture = NULL; k4a_stream_result_t stream_result = k4a_playback_get_next_capture(handle, &capture); ASSERT_EQ(stream_result, K4A_STREAM_RESULT_SUCCEEDED); - ASSERT_TRUE( - validate_test_capture(capture, timestamps, config.color_format, config.color_resolution, config.depth_mode)); + ASSERT_TRUE(validate_test_capture(capture, + timestamps, + config.color_format, + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); k4a_playback_close(handle); @@ -266,9 +268,9 @@ TEST_F(playback_ut, playback_seek_test) result = k4a_playback_get_record_configuration(handle, &config); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); ASSERT_EQ(config.color_format, K4A_IMAGE_FORMAT_COLOR_MJPG); - ASSERT_EQ(config.color_resolution, K4A_COLOR_RESOLUTION_1080P); - ASSERT_EQ(config.depth_mode, K4A_DEPTH_MODE_NFOV_UNBINNED); - ASSERT_EQ(config.camera_fps, K4A_FRAMES_PER_SECOND_30); + ASSERT_EQ(config.color_mode_info.mode_id, (uint32_t)K4A_COLOR_RESOLUTION_1080P); + ASSERT_EQ(config.depth_mode_info.mode_id, (uint32_t)K4A_DEPTH_MODE_NFOV_UNBINNED); + ASSERT_EQ(config.fps_mode_info.mode_id, (uint32_t)K4A_FRAMES_PER_SECOND_30); ASSERT_TRUE(config.color_track_enabled); ASSERT_TRUE(config.depth_track_enabled); ASSERT_TRUE(config.ir_track_enabled); @@ -281,7 +283,7 @@ TEST_F(playback_ut, playback_seek_test) k4a_capture_t capture = NULL; k4a_stream_result_t stream_result = K4A_STREAM_RESULT_FAILED; uint64_t timestamps[3] = { 0, 1000, 1000 }; - uint64_t timestamp_delta = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(config.camera_fps)); + uint64_t timestamp_delta = HZ_TO_PERIOD_US(config.fps_mode_info.fps); k4a_imu_sample_t imu_sample = { 0 }; uint64_t imu_timestamp = 1150; @@ -297,8 +299,11 @@ TEST_F(playback_ut, playback_seek_test) stream_result = k4a_playback_get_next_capture(handle, &capture); ASSERT_EQ(stream_result, K4A_STREAM_RESULT_SUCCEEDED); - ASSERT_TRUE( - validate_test_capture(capture, timestamps, config.color_format, config.color_resolution, config.depth_mode)); + ASSERT_TRUE(validate_test_capture(capture, + timestamps, + config.color_format, + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); stream_result = k4a_playback_get_next_imu_sample(handle, &imu_sample); @@ -355,8 +360,8 @@ TEST_F(playback_ut, playback_seek_test) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); stream_result = k4a_playback_get_previous_imu_sample(handle, &imu_sample); @@ -376,8 +381,8 @@ TEST_F(playback_ut, playback_seek_test) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); stream_result = k4a_playback_get_next_imu_sample(handle, &imu_sample); @@ -409,8 +414,8 @@ TEST_F(playback_ut, playback_seek_test) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); stream_result = k4a_playback_get_next_imu_sample(handle, &imu_sample); @@ -430,8 +435,8 @@ TEST_F(playback_ut, playback_seek_test) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); stream_result = k4a_playback_get_previous_imu_sample(handle, &imu_sample); @@ -459,8 +464,8 @@ TEST_F(playback_ut, playback_seek_test) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); stream_result = k4a_playback_get_next_imu_sample(handle, &imu_sample); @@ -477,8 +482,8 @@ TEST_F(playback_ut, playback_seek_test) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); stream_result = k4a_playback_get_previous_imu_sample(handle, &imu_sample); @@ -494,8 +499,8 @@ TEST_F(playback_ut, playback_seek_test) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); stream_result = k4a_playback_get_previous_imu_sample(handle, &imu_sample); @@ -512,8 +517,8 @@ TEST_F(playback_ut, playback_seek_test) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); stream_result = k4a_playback_get_next_imu_sample(handle, &imu_sample); @@ -535,9 +540,9 @@ TEST_F(playback_ut, open_skipped_frames_file) result = k4a_playback_get_record_configuration(handle, &config); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); ASSERT_EQ(config.color_format, K4A_IMAGE_FORMAT_COLOR_MJPG); - ASSERT_EQ(config.color_resolution, K4A_COLOR_RESOLUTION_1080P); - ASSERT_EQ(config.depth_mode, K4A_DEPTH_MODE_NFOV_UNBINNED); - ASSERT_EQ(config.camera_fps, K4A_FRAMES_PER_SECOND_30); + ASSERT_EQ(config.color_mode_info.mode_id, (uint32_t)K4A_COLOR_RESOLUTION_1080P); + ASSERT_EQ(config.depth_mode_info.mode_id, (uint32_t)K4A_DEPTH_MODE_NFOV_UNBINNED); + ASSERT_EQ(config.fps_mode_info.mode_id, (uint32_t)K4A_FRAMES_PER_SECOND_30); ASSERT_EQ(config.depth_delay_off_color_usec, 0); ASSERT_EQ(config.wired_sync_mode, K4A_WIRED_SYNC_MODE_STANDALONE); ASSERT_EQ(config.subordinate_delay_off_master_usec, (uint32_t)0); @@ -546,7 +551,7 @@ TEST_F(playback_ut, open_skipped_frames_file) k4a_capture_t capture = NULL; k4a_stream_result_t stream_result = K4A_STREAM_RESULT_FAILED; uint64_t timestamps[3] = { 1000000, 1001000, 1001000 }; - uint64_t timestamp_delta = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(config.camera_fps)); + uint64_t timestamp_delta = HZ_TO_PERIOD_US(config.fps_mode_info.fps); // Test initial state stream_result = k4a_playback_get_previous_capture(handle, &capture); @@ -557,8 +562,11 @@ TEST_F(playback_ut, open_skipped_frames_file) ASSERT_EQ(stream_result, K4A_STREAM_RESULT_SUCCEEDED); // According to the generated sample sequence, the first capture is missing a Color image // i == 0 in generation loop (see sample_recordings.cpp) - ASSERT_TRUE( - validate_test_capture(capture, timestamps, config.color_format, K4A_COLOR_RESOLUTION_OFF, config.depth_mode)); + ASSERT_TRUE(validate_test_capture(capture, + timestamps, + config.color_format, + K4A_COLOR_RESOLUTION_OFF, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); // Test seek to beginning @@ -572,8 +580,11 @@ TEST_F(playback_ut, open_skipped_frames_file) stream_result = k4a_playback_get_next_capture(handle, &capture); ASSERT_EQ(stream_result, K4A_STREAM_RESULT_SUCCEEDED); // i == 0, Color image is dropped - ASSERT_TRUE( - validate_test_capture(capture, timestamps, config.color_format, K4A_COLOR_RESOLUTION_OFF, config.depth_mode)); + ASSERT_TRUE(validate_test_capture(capture, + timestamps, + config.color_format, + K4A_COLOR_RESOLUTION_OFF, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); // Test seek past beginning @@ -585,8 +596,11 @@ TEST_F(playback_ut, open_skipped_frames_file) stream_result = k4a_playback_get_next_capture(handle, &capture); ASSERT_EQ(stream_result, K4A_STREAM_RESULT_SUCCEEDED); // i == 0, Color image is dropped - ASSERT_TRUE( - validate_test_capture(capture, timestamps, config.color_format, K4A_COLOR_RESOLUTION_OFF, config.depth_mode)); + ASSERT_TRUE(validate_test_capture(capture, + timestamps, + config.color_format, + K4A_COLOR_RESOLUTION_OFF, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); // Test seek to end @@ -603,8 +617,11 @@ TEST_F(playback_ut, open_skipped_frames_file) stream_result = k4a_playback_get_previous_capture(handle, &capture); ASSERT_EQ(stream_result, K4A_STREAM_RESULT_SUCCEEDED); // i == 99, No images are dropped - ASSERT_TRUE( - validate_test_capture(capture, timestamps, config.color_format, config.color_resolution, config.depth_mode)); + ASSERT_TRUE(validate_test_capture(capture, + timestamps, + config.color_format, + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); // Test seek to end, relative to start @@ -620,8 +637,11 @@ TEST_F(playback_ut, open_skipped_frames_file) stream_result = k4a_playback_get_previous_capture(handle, &capture); ASSERT_EQ(stream_result, K4A_STREAM_RESULT_SUCCEEDED); // i == 99, No images are dropped - ASSERT_TRUE( - validate_test_capture(capture, timestamps, config.color_format, config.color_resolution, config.depth_mode)); + ASSERT_TRUE(validate_test_capture(capture, + timestamps, + config.color_format, + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); // Test seek to middle of the recording, then read forward @@ -634,8 +654,11 @@ TEST_F(playback_ut, open_skipped_frames_file) stream_result = k4a_playback_get_next_capture(handle, &capture); ASSERT_EQ(stream_result, K4A_STREAM_RESULT_SUCCEEDED); // i == 49, Depth image is dropped - ASSERT_TRUE( - validate_test_capture(capture, timestamps, config.color_format, config.color_resolution, K4A_DEPTH_MODE_OFF)); + ASSERT_TRUE(validate_test_capture(capture, + timestamps, + config.color_format, + config.color_mode_info.mode_id, + K4A_DEPTH_MODE_OFF)); k4a_capture_release(capture); // Test seek to middle of the recording, then read backward @@ -649,8 +672,11 @@ TEST_F(playback_ut, open_skipped_frames_file) stream_result = k4a_playback_get_previous_capture(handle, &capture); ASSERT_EQ(stream_result, K4A_STREAM_RESULT_SUCCEEDED); // i == 48, Color image is dropped - ASSERT_TRUE( - validate_test_capture(capture, timestamps, config.color_format, K4A_COLOR_RESOLUTION_OFF, config.depth_mode)); + ASSERT_TRUE(validate_test_capture(capture, + timestamps, + config.color_format, + K4A_COLOR_RESOLUTION_OFF, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); // Read the rest of the file @@ -670,13 +696,13 @@ TEST_F(playback_ut, open_skipped_frames_file) timestamps, config.color_format, K4A_COLOR_RESOLUTION_OFF, - config.depth_mode)); + config.depth_mode_info.mode_id)); break; case 1: // Color Only ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, + config.color_mode_info.mode_id, K4A_DEPTH_MODE_OFF)); break; case 2: // No frames, advance timestamp and read as next index. @@ -689,8 +715,8 @@ TEST_F(playback_ut, open_skipped_frames_file) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); break; } k4a_capture_release(capture); @@ -714,9 +740,9 @@ TEST_F(playback_ut, open_imu_playback_file) result = k4a_playback_get_record_configuration(handle, &config); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); ASSERT_EQ(config.color_format, K4A_IMAGE_FORMAT_COLOR_MJPG); - ASSERT_EQ(config.color_resolution, K4A_COLOR_RESOLUTION_1080P); - ASSERT_EQ(config.depth_mode, K4A_DEPTH_MODE_NFOV_UNBINNED); - ASSERT_EQ(config.camera_fps, K4A_FRAMES_PER_SECOND_30); + ASSERT_EQ(config.color_mode_info.mode_id, (uint32_t)K4A_COLOR_RESOLUTION_1080P); + ASSERT_EQ(config.depth_mode_info.mode_id, (uint32_t)K4A_DEPTH_MODE_NFOV_UNBINNED); + ASSERT_EQ(config.fps_mode_info.mode_id, (uint32_t)K4A_FRAMES_PER_SECOND_30); ASSERT_TRUE(config.color_track_enabled); ASSERT_TRUE(config.depth_track_enabled); ASSERT_TRUE(config.ir_track_enabled); @@ -800,9 +826,9 @@ TEST_F(playback_ut, open_start_offset_file) result = k4a_playback_get_record_configuration(handle, &config); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); ASSERT_EQ(config.color_format, K4A_IMAGE_FORMAT_COLOR_MJPG); - ASSERT_EQ(config.color_resolution, K4A_COLOR_RESOLUTION_1080P); - ASSERT_EQ(config.depth_mode, K4A_DEPTH_MODE_NFOV_UNBINNED); - ASSERT_EQ(config.camera_fps, K4A_FRAMES_PER_SECOND_30); + ASSERT_EQ(config.color_mode_info.mode_id, (uint32_t)K4A_COLOR_RESOLUTION_1080P); + ASSERT_EQ(config.depth_mode_info.mode_id, (uint32_t)K4A_DEPTH_MODE_NFOV_UNBINNED); + ASSERT_EQ(config.fps_mode_info.mode_id, (uint32_t)K4A_FRAMES_PER_SECOND_30); ASSERT_TRUE(config.color_track_enabled); ASSERT_TRUE(config.depth_track_enabled); ASSERT_TRUE(config.ir_track_enabled); @@ -817,7 +843,7 @@ TEST_F(playback_ut, open_start_offset_file) k4a_stream_result_t stream_result = K4A_STREAM_RESULT_FAILED; uint64_t timestamps[3] = { 1000000, 1000000, 1000000 }; uint64_t imu_timestamp = 1001150; - uint64_t timestamp_delta = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(config.camera_fps)); + uint64_t timestamp_delta = HZ_TO_PERIOD_US(config.fps_mode_info.fps); uint64_t last_timestamp = k4a_playback_get_recording_length_usec(handle) + (uint64_t)config.start_timestamp_offset_usec; ASSERT_EQ(last_timestamp, (uint64_t)config.start_timestamp_offset_usec + 3333150); @@ -830,8 +856,8 @@ TEST_F(playback_ut, open_start_offset_file) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); timestamps[0] += timestamp_delta; timestamps[1] += timestamp_delta; @@ -852,8 +878,8 @@ TEST_F(playback_ut, open_start_offset_file) ASSERT_TRUE(validate_test_capture(capture, timestamps, config.color_format, - config.color_resolution, - config.depth_mode)); + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); } stream_result = k4a_playback_get_previous_capture(handle, &capture); @@ -928,9 +954,9 @@ TEST_F(playback_ut, open_color_only_file) result = k4a_playback_get_record_configuration(handle, &config); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); ASSERT_EQ(config.color_format, K4A_IMAGE_FORMAT_COLOR_MJPG); - ASSERT_EQ(config.color_resolution, K4A_COLOR_RESOLUTION_1080P); - ASSERT_EQ(config.depth_mode, K4A_DEPTH_MODE_OFF); - ASSERT_EQ(config.camera_fps, K4A_FRAMES_PER_SECOND_30); + ASSERT_EQ(config.color_mode_info.mode_id, (uint32_t)K4A_COLOR_RESOLUTION_1080P); + ASSERT_EQ(config.depth_mode_info.mode_id, (uint32_t)K4A_DEPTH_MODE_OFF); + ASSERT_EQ(config.fps_mode_info.mode_id, (uint32_t)K4A_FRAMES_PER_SECOND_30); ASSERT_TRUE(config.color_track_enabled); ASSERT_FALSE(config.depth_track_enabled); ASSERT_FALSE(config.ir_track_enabled); @@ -945,8 +971,11 @@ TEST_F(playback_ut, open_color_only_file) k4a_capture_t capture = NULL; k4a_stream_result_t stream_result = k4a_playback_get_next_capture(handle, &capture); ASSERT_EQ(stream_result, K4A_STREAM_RESULT_SUCCEEDED); - ASSERT_TRUE( - validate_test_capture(capture, timestamps, config.color_format, config.color_resolution, config.depth_mode)); + ASSERT_TRUE(validate_test_capture(capture, + timestamps, + config.color_format, + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); k4a_playback_close(handle); @@ -963,9 +992,9 @@ TEST_F(playback_ut, open_depth_only_file) result = k4a_playback_get_record_configuration(handle, &config); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); ASSERT_EQ(config.color_format, K4A_IMAGE_FORMAT_CUSTOM); - ASSERT_EQ(config.color_resolution, K4A_COLOR_RESOLUTION_OFF); - ASSERT_EQ(config.depth_mode, K4A_DEPTH_MODE_NFOV_UNBINNED); - ASSERT_EQ(config.camera_fps, K4A_FRAMES_PER_SECOND_30); + ASSERT_EQ(config.color_mode_info.mode_id, (uint32_t)K4A_COLOR_RESOLUTION_OFF); + ASSERT_EQ(config.depth_mode_info.mode_id, (uint32_t)K4A_DEPTH_MODE_NFOV_UNBINNED); + ASSERT_EQ(config.fps_mode_info.mode_id, (uint32_t)K4A_FRAMES_PER_SECOND_30); ASSERT_FALSE(config.color_track_enabled); ASSERT_TRUE(config.depth_track_enabled); ASSERT_TRUE(config.ir_track_enabled); @@ -980,8 +1009,11 @@ TEST_F(playback_ut, open_depth_only_file) k4a_capture_t capture = NULL; k4a_stream_result_t stream_result = k4a_playback_get_next_capture(handle, &capture); ASSERT_EQ(stream_result, K4A_STREAM_RESULT_SUCCEEDED); - ASSERT_TRUE( - validate_test_capture(capture, timestamps, config.color_format, config.color_resolution, config.depth_mode)); + ASSERT_TRUE(validate_test_capture(capture, + timestamps, + config.color_format, + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); k4a_playback_close(handle); @@ -998,9 +1030,9 @@ TEST_F(playback_ut, open_bgra_color_file) result = k4a_playback_get_record_configuration(handle, &config); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); ASSERT_EQ(config.color_format, K4A_IMAGE_FORMAT_COLOR_BGRA32); - ASSERT_EQ(config.color_resolution, K4A_COLOR_RESOLUTION_1080P); - ASSERT_EQ(config.depth_mode, K4A_DEPTH_MODE_OFF); - ASSERT_EQ(config.camera_fps, K4A_FRAMES_PER_SECOND_30); + ASSERT_EQ(config.color_mode_info.mode_id, (uint32_t)K4A_COLOR_RESOLUTION_1080P); + ASSERT_EQ(config.depth_mode_info.mode_id, (uint32_t)K4A_DEPTH_MODE_OFF); + ASSERT_EQ(config.fps_mode_info.mode_id, (uint32_t)K4A_FRAMES_PER_SECOND_30); ASSERT_TRUE(config.color_track_enabled); ASSERT_FALSE(config.depth_track_enabled); ASSERT_FALSE(config.ir_track_enabled); @@ -1015,8 +1047,11 @@ TEST_F(playback_ut, open_bgra_color_file) k4a_capture_t capture = NULL; k4a_stream_result_t stream_result = k4a_playback_get_next_capture(handle, &capture); ASSERT_EQ(stream_result, K4A_STREAM_RESULT_SUCCEEDED); - ASSERT_TRUE( - validate_test_capture(capture, timestamps, config.color_format, config.color_resolution, config.depth_mode)); + ASSERT_TRUE(validate_test_capture(capture, + timestamps, + config.color_format, + config.color_mode_info.mode_id, + config.depth_mode_info.mode_id)); k4a_capture_release(capture); k4a_playback_close(handle); diff --git a/tests/RecordTests/UnitTest/record_ut.cpp b/tests/RecordTests/UnitTest/record_ut.cpp index d45b0c4af..0acaf8892 100644 --- a/tests/RecordTests/UnitTest/record_ut.cpp +++ b/tests/RecordTests/UnitTest/record_ut.cpp @@ -139,9 +139,9 @@ TEST_F(record_ut, DISABLED_bgra_color_max_disk_write) { k4a_device_configuration_t record_config = {}; record_config.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32; - record_config.color_resolution = K4A_COLOR_RESOLUTION_2160P; - record_config.depth_mode = K4A_DEPTH_MODE_OFF; - record_config.camera_fps = K4A_FRAMES_PER_SECOND_30; + record_config.color_mode_id = K4A_COLOR_RESOLUTION_2160P; + record_config.depth_mode_id = K4A_DEPTH_MODE_OFF; + record_config.fps_mode_id = K4A_FRAMES_PER_SECOND_30; std::cout << "A 'Disk write speed is too low, write queue is filling up.' log message is expected after about 4 seconds." diff --git a/tests/RecordTests/UnitTest/sample_recordings.cpp b/tests/RecordTests/UnitTest/sample_recordings.cpp index bdf6998ef..4102260b0 100644 --- a/tests/RecordTests/UnitTest/sample_recordings.cpp +++ b/tests/RecordTests/UnitTest/sample_recordings.cpp @@ -5,7 +5,6 @@ #include #include -#include #include using namespace testing; @@ -13,14 +12,15 @@ using namespace testing; void SampleRecordings::SetUp() { k4a_device_configuration_t record_config_empty = {}; - record_config_empty.color_resolution = K4A_COLOR_RESOLUTION_OFF; - record_config_empty.depth_mode = K4A_DEPTH_MODE_OFF; + record_config_empty.color_mode_id = K4A_COLOR_RESOLUTION_OFF; + record_config_empty.depth_mode_id = K4A_DEPTH_MODE_OFF; + record_config_empty.fps_mode_id = K4A_FRAMES_PER_SECOND_30; k4a_device_configuration_t record_config_full = {}; record_config_full.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - record_config_full.color_resolution = K4A_COLOR_RESOLUTION_1080P; - record_config_full.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; - record_config_full.camera_fps = K4A_FRAMES_PER_SECOND_30; + record_config_full.color_mode_id = K4A_COLOR_RESOLUTION_1080P; + record_config_full.depth_mode_id = K4A_DEPTH_MODE_NFOV_UNBINNED; + record_config_full.fps_mode_id = K4A_FRAMES_PER_SECOND_30; k4a_device_configuration_t record_config_delay = record_config_full; record_config_delay.depth_delay_off_color_usec = 10000; // 10ms @@ -30,14 +30,14 @@ void SampleRecordings::SetUp() record_config_sub.subordinate_delay_off_master_usec = 10000; // 10ms k4a_device_configuration_t record_config_color_only = record_config_full; - record_config_color_only.depth_mode = K4A_DEPTH_MODE_OFF; + record_config_color_only.depth_mode_id = K4A_DEPTH_MODE_OFF; k4a_device_configuration_t record_config_depth_only = record_config_full; - record_config_depth_only.color_resolution = K4A_COLOR_RESOLUTION_OFF; + record_config_depth_only.color_mode_id = K4A_COLOR_RESOLUTION_OFF; k4a_device_configuration_t record_config_bgra_color = record_config_full; record_config_bgra_color.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32; - record_config_bgra_color.depth_mode = K4A_DEPTH_MODE_OFF; + record_config_bgra_color.depth_mode_id = K4A_DEPTH_MODE_OFF; { k4a_record_t handle = NULL; @@ -65,14 +65,15 @@ void SampleRecordings::SetUp() uint64_t timestamps[3] = { 0, 1000, 1000 }; // Offset the Depth and IR tracks by 1ms to test uint64_t imu_timestamp = 1150; - uint32_t timestamp_delta = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(record_config_full.camera_fps)); + uint32_t timestamp_delta = HZ_TO_PERIOD_US( + k4a_convert_fps_to_uint(static_cast(record_config_full.fps_mode_id))); k4a_capture_t capture = NULL; for (size_t i = 0; i < test_frame_count; i++) { capture = create_test_capture(timestamps, record_config_full.color_format, - record_config_full.color_resolution, - record_config_full.depth_mode); + (k4a_color_resolution_t)record_config_full.color_mode_id, + (k4a_depth_mode_t)record_config_full.depth_mode_id); result = k4a_record_write_capture(handle, capture); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); k4a_capture_release(capture); @@ -108,14 +109,15 @@ void SampleRecordings::SetUp() uint64_t timestamps[3] = { 0, (uint64_t)record_config_delay.depth_delay_off_color_usec, (uint64_t)record_config_delay.depth_delay_off_color_usec }; - uint32_t timestamp_delta = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(record_config_delay.camera_fps)); + uint32_t timestamp_delta = HZ_TO_PERIOD_US( + k4a_convert_fps_to_uint(static_cast(record_config_delay.fps_mode_id))); k4a_capture_t capture = NULL; for (size_t i = 0; i < test_frame_count; i++) { capture = create_test_capture(timestamps, record_config_delay.color_format, - record_config_delay.color_resolution, - record_config_delay.depth_mode); + (k4a_color_resolution_t)record_config_delay.color_mode_id, + (k4a_depth_mode_t)record_config_delay.depth_mode_id); result = k4a_record_write_capture(handle, capture); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); k4a_capture_release(capture); @@ -143,8 +145,8 @@ void SampleRecordings::SetUp() record_config_sub.subordinate_delay_off_master_usec }; k4a_capture_t capture = create_test_capture(timestamps, record_config_sub.color_format, - record_config_sub.color_resolution, - record_config_sub.depth_mode); + (k4a_color_resolution_t)record_config_sub.color_mode_id, + (k4a_depth_mode_t)record_config_sub.depth_mode_id); result = k4a_record_write_capture(handle, capture); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); k4a_capture_release(capture); @@ -169,7 +171,8 @@ void SampleRecordings::SetUp() } uint64_t timestamps[3] = { 1000000, 1001000, 1001000 }; // Start recording at 1s - uint32_t timestamp_delta = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(record_config_full.camera_fps)); + uint32_t timestamp_delta = HZ_TO_PERIOD_US( + k4a_convert_fps_to_uint(static_cast(record_config_full.fps_mode_id))); for (size_t i = 0; i < test_frame_count; i++) { // Create a known pattern of dropped / missing frames that can be tested against @@ -181,12 +184,12 @@ void SampleRecordings::SetUp() capture = create_test_capture(timestamps, record_config_full.color_format, K4A_COLOR_RESOLUTION_OFF, - record_config_full.depth_mode); + (k4a_depth_mode_t)record_config_full.depth_mode_id); break; case 1: // Color Only capture = create_test_capture(timestamps, record_config_full.color_format, - record_config_full.color_resolution, + (k4a_color_resolution_t)record_config_full.color_mode_id, K4A_DEPTH_MODE_OFF); break; case 2: // No frames @@ -194,8 +197,8 @@ void SampleRecordings::SetUp() case 3: // Both Depth + Color capture = create_test_capture(timestamps, record_config_full.color_format, - record_config_full.color_resolution, - record_config_full.depth_mode); + (k4a_color_resolution_t)record_config_full.color_mode_id, + (k4a_depth_mode_t)record_config_full.depth_mode_id); break; } if (capture) @@ -235,14 +238,15 @@ void SampleRecordings::SetUp() uint64_t timestamps[3] = { 1000000, 1000000, 1000000 }; uint64_t imu_timestamp = 1001150; - uint32_t timestamp_delta = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(record_config_delay.camera_fps)); + uint32_t timestamp_delta = HZ_TO_PERIOD_US( + k4a_convert_fps_to_uint(static_cast(record_config_delay.fps_mode_id))); k4a_capture_t capture = NULL; for (size_t i = 0; i < test_frame_count; i++) { capture = create_test_capture(timestamps, record_config_delay.color_format, - record_config_delay.color_resolution, - record_config_delay.depth_mode); + (k4a_color_resolution_t)record_config_delay.color_mode_id, + (k4a_depth_mode_t)record_config_delay.depth_mode_id); result = k4a_record_write_capture(handle, capture); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); k4a_capture_release(capture); @@ -278,8 +282,8 @@ void SampleRecordings::SetUp() uint64_t timestamps[3] = { 0, 0, 0 }; k4a_capture_t capture = create_test_capture(timestamps, record_config_color_only.color_format, - record_config_color_only.color_resolution, - record_config_color_only.depth_mode); + (k4a_color_resolution_t)record_config_color_only.color_mode_id, + (k4a_depth_mode_t)record_config_color_only.depth_mode_id); result = k4a_record_write_capture(handle, capture); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); k4a_capture_release(capture); @@ -300,8 +304,8 @@ void SampleRecordings::SetUp() uint64_t timestamps[3] = { 0, 0, 0 }; k4a_capture_t capture = create_test_capture(timestamps, record_config_depth_only.color_format, - record_config_depth_only.color_resolution, - record_config_depth_only.depth_mode); + (k4a_color_resolution_t)record_config_depth_only.color_mode_id, + (k4a_depth_mode_t)record_config_depth_only.depth_mode_id); result = k4a_record_write_capture(handle, capture); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); k4a_capture_release(capture); @@ -322,8 +326,8 @@ void SampleRecordings::SetUp() uint64_t timestamps[3] = { 0, 0, 0 }; k4a_capture_t capture = create_test_capture(timestamps, record_config_bgra_color.color_format, - record_config_bgra_color.color_resolution, - record_config_bgra_color.depth_mode); + (k4a_color_resolution_t)record_config_bgra_color.color_mode_id, + (k4a_depth_mode_t)record_config_bgra_color.depth_mode_id); result = k4a_record_write_capture(handle, capture); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); k4a_capture_release(capture); diff --git a/tests/RecordTests/UnitTest/test_helpers.cpp b/tests/RecordTests/UnitTest/test_helpers.cpp index 783dcf7b4..e94570e8f 100644 --- a/tests/RecordTests/UnitTest/test_helpers.cpp +++ b/tests/RecordTests/UnitTest/test_helpers.cpp @@ -28,8 +28,8 @@ k4a_capture_t create_test_capture(uint64_t timestamp_us[3], k4a_image_format_t color_format, - k4a_color_resolution_t resolution, - k4a_depth_mode_t mode) + uint32_t color_mode_id, + uint32_t depth_mode_id) { k4a_capture_t capture = NULL; k4a_result_t result = k4a_capture_create(&capture); @@ -37,9 +37,9 @@ k4a_capture_t create_test_capture(uint64_t timestamp_us[3], uint32_t width = 0; uint32_t height = 0; - if (resolution != K4A_COLOR_RESOLUTION_OFF) + if (color_mode_id != K4A_COLOR_RESOLUTION_OFF) { - EXIT_IF_FALSE(k4a_convert_resolution_to_width_height(resolution, &width, &height)); + EXIT_IF_FALSE(k4a_convert_resolution_to_width_height((k4a_color_resolution_t)color_mode_id, &width, &height)); uint32_t color_stride = 0; if (color_format == K4A_IMAGE_FORMAT_COLOR_NV12) @@ -55,10 +55,10 @@ k4a_capture_t create_test_capture(uint64_t timestamp_us[3], k4a_image_release(color_image); } - if (mode != K4A_DEPTH_MODE_OFF) + if (depth_mode_id != K4A_DEPTH_MODE_OFF) { - EXIT_IF_FALSE(k4a_convert_depth_mode_to_width_height(mode, &width, &height)); - if (mode != K4A_DEPTH_MODE_PASSIVE_IR) + EXIT_IF_FALSE(k4a_convert_depth_mode_to_width_height((k4a_depth_mode_t)depth_mode_id, &width, &height)); + if (depth_mode_id != K4A_DEPTH_MODE_PASSIVE_IR) { k4a_image_t depth_image = create_test_image(timestamp_us[1], K4A_IMAGE_FORMAT_DEPTH16, width, height, width * 2); @@ -75,17 +75,18 @@ k4a_capture_t create_test_capture(uint64_t timestamp_us[3], bool validate_test_capture(k4a_capture_t capture, uint64_t timestamp_us[3], k4a_image_format_t color_format, - k4a_color_resolution_t resolution, - k4a_depth_mode_t mode) + uint32_t color_mode_id, + uint32_t depth_mode_id) { if (capture != NULL) { - if (resolution != K4A_COLOR_RESOLUTION_OFF) + if (color_mode_id != K4A_COLOR_RESOLUTION_OFF) { uint32_t width = 0; uint32_t height = 0; - EXIT_IF_FALSE(k4a_convert_resolution_to_width_height(resolution, &width, &height)); + EXIT_IF_FALSE( + k4a_convert_resolution_to_width_height((k4a_color_resolution_t)color_mode_id, &width, &height)); uint32_t color_stride = 0; if (color_format == K4A_IMAGE_FORMAT_COLOR_NV12) @@ -122,13 +123,13 @@ bool validate_test_capture(k4a_capture_t capture, return false; } - if (mode != K4A_DEPTH_MODE_OFF) + if (depth_mode_id != K4A_DEPTH_MODE_OFF) { uint32_t width = 0; uint32_t height = 0; - EXIT_IF_FALSE(k4a_convert_depth_mode_to_width_height(mode, &width, &height)); + EXIT_IF_FALSE(k4a_convert_depth_mode_to_width_height((k4a_depth_mode_t)depth_mode_id, &width, &height)); - if (mode != K4A_DEPTH_MODE_PASSIVE_IR) + if (depth_mode_id != K4A_DEPTH_MODE_PASSIVE_IR) { k4a_image_t depth_image = k4a_capture_get_depth_image(capture); if (depth_image == NULL) diff --git a/tests/RecordTests/UnitTest/test_helpers.h b/tests/RecordTests/UnitTest/test_helpers.h index 4e8a2fc75..d6aa3f3f9 100644 --- a/tests/RecordTests/UnitTest/test_helpers.h +++ b/tests/RecordTests/UnitTest/test_helpers.h @@ -20,7 +20,8 @@ static const char *const resolution_names[] = { "K4A_COLOR_RESOLUTION_OFF", "K static const char *const depth_names[] = { "K4A_DEPTH_MODE_OFF", "K4A_DEPTH_MODE_NFOV_2X2BINNED", "K4A_DEPTH_MODE_NFOV_UNBINNED", "K4A_DEPTH_MODE_WFOV_2X2BINNED", "K4A_DEPTH_MODE_WFOV_UNBINNED", "K4A_DEPTH_MODE_PASSIVE_IR" }; -static const char *const fps_names[] = { "K4A_FRAMES_PER_SECOND_5", +static const char *const fps_names[] = { "K4A_FRAMES_PER_SECOND_0", + "K4A_FRAMES_PER_SECOND_5", "K4A_FRAMES_PER_SECOND_15", "K4A_FRAMES_PER_SECOND_30" }; @@ -33,13 +34,14 @@ static const size_t test_frame_count = 100; k4a_capture_t create_test_capture(uint64_t timestamp_us[3], k4a_image_format_t color_format, - k4a_color_resolution_t resolution, - k4a_depth_mode_t mode); + uint32_t color_mode_id, + uint32_t depth_mode_id); + bool validate_test_capture(k4a_capture_t capture, uint64_t timestamp_us[3], k4a_image_format_t color_format, - k4a_color_resolution_t resolution, - k4a_depth_mode_t mode); + uint32_t color_mode_id, + uint32_t depth_mode_id); k4a_image_t create_test_image(uint64_t timestamp_us, k4a_image_format_t format, uint32_t width, uint32_t height, uint32_t stride); diff --git a/tests/TestUtil/Capture.cpp b/tests/TestUtil/Capture.cpp index ca8e9ee35..b60e9d2b0 100644 --- a/tests/TestUtil/Capture.cpp +++ b/tests/TestUtil/Capture.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "Cli.h" diff --git a/tests/TestUtil/UsbCmd.c b/tests/TestUtil/UsbCmd.c index 1511b04e2..5498dd742 100644 --- a/tests/TestUtil/UsbCmd.c +++ b/tests/TestUtil/UsbCmd.c @@ -4,6 +4,7 @@ //************************ Includes ***************************** #include #include +#include #include #include #include diff --git a/tests/TestUtil/k4aCmd.c b/tests/TestUtil/k4aCmd.c index a7fd0aa3d..2ccd02236 100644 --- a/tests/TestUtil/k4aCmd.c +++ b/tests/TestUtil/k4aCmd.c @@ -3,6 +3,7 @@ //************************ Includes ***************************** #include +#include #include #include "Cli.h" #include "Main.h" @@ -210,9 +211,9 @@ static CLI_STATUS k4a_record_depth(int Argc, char **Argv) #endif // start the stream config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config.color_resolution = K4A_COLOR_RESOLUTION_OFF; - config.depth_mode = mode; - config.camera_fps = fps; + config.color_mode_id = K4A_COLOR_RESOLUTION_OFF; + config.depth_mode_id = mode; + config.fps_mode_id = fps; // start streaming. if (K4A_FAILED(k4a_device_start_cameras(device, &config))) diff --git a/tests/Transformation/CMakeLists.txt b/tests/Transformation/CMakeLists.txt index 7f11a2f88..4776262ac 100644 --- a/tests/Transformation/CMakeLists.txt +++ b/tests/Transformation/CMakeLists.txt @@ -7,6 +7,7 @@ target_link_libraries(transformation_ut PRIVATE azure::aziotsharedutil gtest::gtest k4ainternal::image + k4ainternal::modes k4ainternal::transformation k4ainternal::utcommon k4a::k4a) diff --git a/tests/Transformation/transformation.cpp b/tests/Transformation/transformation.cpp index f5e4bd14f..5c5342dd1 100644 --- a/tests/Transformation/transformation.cpp +++ b/tests/Transformation/transformation.cpp @@ -7,8 +7,8 @@ // Module being tested #include #include -#include #include +#include using namespace testing; @@ -39,13 +39,20 @@ class transformation_ut : public ::testing::Test m_accel_point3d_reference[1] = 4.92006636f; m_accel_point3d_reference[2] = 108.398674f; - k4a_depth_mode_t depth_mode = K4A_DEPTH_MODE_WFOV_2X2BINNED; - k4a_color_resolution_t color_resolution = K4A_COLOR_RESOLUTION_2160P; + // device_depth_modes is statically defined in . + // device_depth_modes[3] is the mode for K4A_DEPTH_MODE_WFOV_2X2BINNED. + k4a_depth_mode_info_t depth_mode_info = k4a_get_device_depth_mode(3); + depth_mode_info.struct_size = sizeof(k4a_depth_mode_info_t); + + // device_color_modes is statically defined in . + // device_color_modes[5] is the mode for K4A_COLOR_RESOLUTION_2160P. + k4a_color_mode_info_t color_mode_info = k4a_get_device_color_mode(5); + color_mode_info.struct_size = sizeof(k4a_color_mode_info_t); k4a_result_t result = k4a_calibration_get_from_raw(g_test_json, sizeof(g_test_json), - depth_mode, - color_resolution, + depth_mode_info.mode_id, + color_mode_info.mode_id, &m_calibration); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); }; @@ -560,35 +567,40 @@ TEST_F(transformation_ut, transformation_all_image_functions_with_failure_cases) for (int i = 0; i < 5; i++) { - k4a_depth_mode_t depth_mode = K4A_DEPTH_MODE_OFF; - k4a_color_resolution_t color_resolution = K4A_COLOR_RESOLUTION_OFF; + k4a_depth_mode_t depth_mode; + k4a_color_resolution_t color_mode; switch (i) { case 0: depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; - color_resolution = K4A_COLOR_RESOLUTION_OFF; + color_mode = K4A_COLOR_RESOLUTION_OFF; break; + case 1: depth_mode = K4A_DEPTH_MODE_OFF; - color_resolution = K4A_COLOR_RESOLUTION_720P; + color_mode = K4A_COLOR_RESOLUTION_720P; break; + case 2: depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED; - color_resolution = K4A_COLOR_RESOLUTION_720P; + color_mode = K4A_COLOR_RESOLUTION_720P; break; + case 3: depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; - color_resolution = K4A_COLOR_RESOLUTION_2160P; + color_mode = K4A_COLOR_RESOLUTION_2160P; break; + default: depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; - color_resolution = K4A_COLOR_RESOLUTION_720P; + color_mode = K4A_COLOR_RESOLUTION_720P; + break; } k4a_calibration_t calibration; k4a_result_t result = - k4a_calibration_get_from_raw(g_test_json, sizeof(g_test_json), depth_mode, color_resolution, &calibration); + k4a_calibration_get_from_raw(g_test_json, sizeof(g_test_json), depth_mode, color_mode, &calibration); ASSERT_EQ(result, K4A_RESULT_SUCCEEDED); k4a_transformation_t transformation_handle = transformation_create(&calibration, false); diff --git a/tests/UnitTests/depthmcu_ut/CMakeLists.txt b/tests/UnitTests/depthmcu_ut/CMakeLists.txt index a07d64d79..06204b0b7 100644 --- a/tests/UnitTests/depthmcu_ut/CMakeLists.txt +++ b/tests/UnitTests/depthmcu_ut/CMakeLists.txt @@ -12,6 +12,7 @@ target_link_libraries(depthmcu_ut PRIVATE k4ainternal::allocator k4ainternal::image k4ainternal::logging + k4ainternal::modes ) # Include the PUBLIC and INTERFACE directories specified by k4ainternal::depth_mcu diff --git a/tests/UnitTests/queue_ut/queue.cpp b/tests/UnitTests/queue_ut/queue.cpp index 7595e0f24..add038658 100644 --- a/tests/UnitTests/queue_ut/queue.cpp +++ b/tests/UnitTests/queue_ut/queue.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/tests/UnitTests/utcommon/inc/utcommon.h b/tests/UnitTests/utcommon/inc/utcommon.h index c42446846..08b715631 100644 --- a/tests/UnitTests/utcommon/inc/utcommon.h +++ b/tests/UnitTests/utcommon/inc/utcommon.h @@ -10,6 +10,8 @@ #include #include +#include + // Define the output operator for k4a_result_t types for clean test output std::ostream &operator<<(std::ostream &s, const k4a_result_t &val); std::ostream &operator<<(std::ostream &s, const k4a_wait_result_t &val); diff --git a/tests/UnitTests/utcommon/utcommon.cpp b/tests/UnitTests/utcommon/utcommon.cpp index 7ddc5df60..e974bf98b 100644 --- a/tests/UnitTests/utcommon/utcommon.cpp +++ b/tests/UnitTests/utcommon/utcommon.cpp @@ -21,6 +21,8 @@ std::ostream &operator<<(std::ostream &s, const k4a_result_t &val) return s << "K4A_RESULT_SUCCEEDED"; case K4A_RESULT_FAILED: return s << "K4A_RESULT_FAILED"; + case K4A_RESULT_UNSUPPORTED: + return s << "K4A_RESULT_UNSUPPORTED"; } return s; @@ -36,6 +38,8 @@ std::ostream &operator<<(std::ostream &s, const k4a_buffer_result_t &val) return s << "K4A_BUFFER_RESULT_FAILED"; case K4A_BUFFER_RESULT_TOO_SMALL: return s << "K4A_BUFFER_RESULT_TOO_SMALL"; + case K4A_BUFFER_RESULT_UNSUPPORTED: + return s << "K4A_BUFFER_RESULT_UNSUPPORTED"; } return s; @@ -51,6 +55,8 @@ std::ostream &operator<<(std::ostream &s, const k4a_wait_result_t &val) return s << "K4A_WAIT_RESULT_FAILED"; case K4A_WAIT_RESULT_TIMEOUT: return s << "K4A_WAIT_RESULT_TIMEOUT"; + case K4A_WAIT_RESULT_UNSUPPORTED: + return s << "K4A_WAIT_RESULT_UNSUPPORTED"; } return s; @@ -122,6 +128,9 @@ int64_t k4a_unittest_get_max_sync_delay_ms(k4a_fps_t fps) case K4A_FRAMES_PER_SECOND_30: max_delay = 110; break; + default: + max_delay = 0; + break; } return max_delay; } diff --git a/tests/global/global.cpp b/tests/global/global.cpp index 530b843ca..2976b1f52 100644 --- a/tests/global/global.cpp +++ b/tests/global/global.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include diff --git a/tests/latency/latency_perf.cpp b/tests/latency/latency_perf.cpp index 5986d0687..23f74fa33 100644 --- a/tests/latency/latency_perf.cpp +++ b/tests/latency/latency_perf.cpp @@ -7,7 +7,6 @@ #endif #include -#include #include #include #include @@ -153,7 +152,7 @@ static const char *get_string_from_color_resolution(k4a_color_resolution_t resol switch (resolution) { case K4A_COLOR_RESOLUTION_OFF: - return "OFF"; + return "K4A_COLOR_RESOLUTION_OFF"; break; case K4A_COLOR_RESOLUTION_720P: return "1280 * 720 16:9"; @@ -173,6 +172,9 @@ static const char *get_string_from_color_resolution(k4a_color_resolution_t resol case K4A_COLOR_RESOLUTION_3072P: return "4096 * 3072 4:3"; break; + case K4A_COLOR_RESOLUTION_COUNT: + return "K4A_COLOR_RESOLUTION_INVALID"; + break; } assert(0); return "Unknown resolution"; @@ -200,6 +202,9 @@ static const char *get_string_from_depth_mode(k4a_depth_mode_t mode) case K4A_DEPTH_MODE_PASSIVE_IR: return "K4A_DEPTH_MODE_PASSIVE_IR"; break; + case K4A_DEPTH_MODE_COUNT: + return "K4A_DEPTH_MODE_INVALID"; + break; } assert(0); return "Unknown Depth"; @@ -557,9 +562,9 @@ TEST_P(latency_perf, testTest) } config.color_format = as.color_format; - config.color_resolution = as.color_resolution; - config.depth_mode = as.depth_mode; - config.camera_fps = as.fps; + config.color_mode_id = as.color_resolution; + config.depth_mode_id = as.depth_mode; + config.fps_mode_id = as.fps; config.depth_delay_off_color_usec = g_depth_delay_off_color_usec; config.wired_sync_mode = g_wired_sync_mode; config.synchronized_images_only = g_synchronized_images_only; @@ -567,9 +572,9 @@ TEST_P(latency_perf, testTest) printf("Config being used is:\n"); printf(" color_format:%d\n", config.color_format); - printf(" color_resolution:%d\n", config.color_resolution); - printf(" depth_mode:%d\n", config.depth_mode); - printf(" camera_fps:%d\n", config.camera_fps); + printf(" color_resolution:%d\n", config.color_mode_id); + printf(" depth_mode:%d\n", config.depth_mode_id); + printf(" camera_fps:%d\n", config.fps_mode_id); printf(" synchronized_images_only:%d\n", config.synchronized_images_only); printf(" depth_delay_off_color_usec:%d\n", config.depth_delay_off_color_usec); printf(" wired_sync_mode:%d\n", config.wired_sync_mode); @@ -732,7 +737,7 @@ TEST_P(latency_perf, testTest) disable_synchronization ? disable_synchronization : "0", get_string_from_color_format(as.color_format), get_string_from_color_resolution(as.color_resolution), - k4a_convert_fps_to_uint(as.fps), + (uint32_t)as.fps, get_string_from_depth_mode(as.depth_mode), g_capture_count, g_manual_exposure, @@ -804,7 +809,7 @@ TEST_P(latency_perf, testTest) } ir_system_latency_ave = ir_system_latency_ave / ir_system_latency.size(); print_and_log(" IR System Time Latency", - get_string_from_depth_mode(config.depth_mode), + get_string_from_depth_mode((k4a_depth_mode_t)config.depth_mode_id), STS_TO_MS(ir_system_latency_ave), STS_TO_MS(min), STS_TO_MS(max)); @@ -827,7 +832,7 @@ TEST_P(latency_perf, testTest) } ir_system_latency_from_pts_ave = ir_system_latency_from_pts_ave / ir_system_latency_from_pts.size(); print_and_log(" IR System Time PTS", - get_string_from_depth_mode(config.depth_mode), + get_string_from_depth_mode((k4a_depth_mode_t)config.depth_mode_id), STS_TO_MS(ir_system_latency_from_pts_ave), STS_TO_MS(min), STS_TO_MS(max)); diff --git a/tests/logging/logging_ut.cpp b/tests/logging/logging_ut.cpp index 1e26caeb0..4abaf657c 100644 --- a/tests/logging/logging_ut.cpp +++ b/tests/logging/logging_ut.cpp @@ -4,7 +4,6 @@ #include // Module being tested -#include #include #include #include diff --git a/tests/multidevice/CMakeLists.txt b/tests/multidevice/CMakeLists.txt index 3fe044b6c..de325f2a1 100644 --- a/tests/multidevice/CMakeLists.txt +++ b/tests/multidevice/CMakeLists.txt @@ -7,6 +7,7 @@ target_link_libraries(multidevice_ft PRIVATE azure::aziotsharedutil gtest::gtest k4a::k4a + k4ainternal::modes k4ainternal::utcommon) k4a_add_tests(TARGET multidevice_ft TEST_TYPE FUNCTIONAL_CUSTOM) diff --git a/tests/multidevice/multidevice.cpp b/tests/multidevice/multidevice.cpp index 9ea14d7a6..709a97fe6 100644 --- a/tests/multidevice/multidevice.cpp +++ b/tests/multidevice/multidevice.cpp @@ -26,7 +26,7 @@ static int32_t g_sample_count = 100; static uint32_t g_subordinate_delay = 0; static int32_t g_m_depth_delay = 0; static int32_t g_s_depth_delay = 0; -static k4a_fps_t g_frame_rate = (k4a_fps_t)-1; +static k4a_fps_t g_frame_rate = K4A_FRAMES_PER_SECOND_0; int main(int argc, char **argv) { @@ -92,31 +92,17 @@ int main(int argc, char **argv) { int32_t frame_rate; frame_rate = (int32_t)strtol(argv[i + 1], NULL, 10); - if (frame_rate == 5) - { - g_frame_rate = K4A_FRAMES_PER_SECOND_5; - } - else if (frame_rate == 15) - { - g_frame_rate = K4A_FRAMES_PER_SECOND_15; - } - else if (frame_rate == 30) - { - g_frame_rate = K4A_FRAMES_PER_SECOND_30; - } - else if (frame_rate == K4A_FRAMES_PER_SECOND_5 || frame_rate == K4A_FRAMES_PER_SECOND_15 || - frame_rate == K4A_FRAMES_PER_SECOND_30) - { - g_frame_rate = (k4a_fps_t)frame_rate; - } - else + g_frame_rate = k4a_convert_uint_to_fps(static_cast(frame_rate)); + + if (g_frame_rate == K4A_FRAMES_PER_SECOND_0) { printf("Error: --fps parameter invalid: %d\n", frame_rate); error = true; } + if (!error) { - printf("Setting frame_rate = %d\n", g_frame_rate); + printf("Setting frame_rate = %d\n", frame_rate); i++; } } @@ -240,9 +226,9 @@ TEST_F(multidevice_ft, stream_two_1_then_2) k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config.color_resolution = K4A_COLOR_RESOLUTION_1080P; - config.depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED; - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + config.color_mode_id = K4A_COLOR_RESOLUTION_1080P; + config.depth_mode_id = K4A_DEPTH_MODE_NFOV_2X2BINNED; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_30; ASSERT_LE((uint32_t)2, k4a_device_get_installed_count()); @@ -282,9 +268,9 @@ TEST_F(multidevice_ft, stream_two_2_then_1) k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config.color_resolution = K4A_COLOR_RESOLUTION_1080P; - config.depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED; - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + config.color_mode_id = K4A_COLOR_RESOLUTION_1080P; + config.depth_mode_id = K4A_DEPTH_MODE_NFOV_2X2BINNED; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_30; ASSERT_LE((uint32_t)2, k4a_device_get_installed_count()); @@ -526,17 +512,17 @@ TEST_F(multidevice_sync_ft, multi_sync_validation) #if defined(__aarch64__) || defined(_M_ARM64) // Jetson Nano can't handle 2 30FPS streams printf("Using 5 or 15FPS for ARM64 build\n"); - int frame_rate_rand = (int)RAND_VALUE(0, 1); + int frame_rate_rand = (int)RAND_VALUE(0, 1) + 1; // +1 because 0 is reserved for K4A_FRAMES_PER_SECOND_0 #else printf("Using 5, 15, or 30FPS for AMD64/x86 build\n"); - int frame_rate_rand = (int)RAND_VALUE(0, 2); + int frame_rate_rand = (int)RAND_VALUE(0, 2) + 1; // +1 because 0 is reserved for K4A_FRAMES_PER_SECOND_0 #endif switch (frame_rate_rand) { - case 0: + case 1: g_frame_rate = K4A_FRAMES_PER_SECOND_5; break; - case 1: + case 2: g_frame_rate = K4A_FRAMES_PER_SECOND_15; break; default: @@ -545,7 +531,7 @@ TEST_F(multidevice_sync_ft, multi_sync_validation) } } - int32_t fps_in_usec = 1000000 / (int32_t)k4a_convert_fps_to_uint(g_frame_rate); + int32_t fps_in_usec = 1000000 / static_cast(k4a_convert_fps_to_uint(g_frame_rate)); if (g_m_depth_delay == 0) { g_m_depth_delay = (int32_t)RAND_VALUE(-fps_in_usec, fps_in_usec); @@ -566,9 +552,9 @@ TEST_F(multidevice_sync_ft, multi_sync_validation) k4a_device_configuration_t default_config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; default_config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - default_config.color_resolution = K4A_COLOR_RESOLUTION_2160P; - default_config.depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED; - default_config.camera_fps = g_frame_rate; + default_config.color_mode_id = K4A_COLOR_RESOLUTION_2160P; + default_config.depth_mode_id = K4A_DEPTH_MODE_NFOV_2X2BINNED; + default_config.fps_mode_id = g_frame_rate; default_config.subordinate_delay_off_master_usec = 0; default_config.depth_delay_off_color_usec = 0; default_config.synchronized_images_only = true; @@ -707,9 +693,9 @@ TEST_F(multidevice_ft, ensure_color_camera_is_enabled) k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config.color_resolution = K4A_COLOR_RESOLUTION_OFF; - config.depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED; - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + config.color_mode_id = K4A_COLOR_RESOLUTION_OFF; + config.depth_mode_id = K4A_DEPTH_MODE_NFOV_2X2BINNED; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_30; ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_get_sync_jack(m_device1, &sync_in_cable_present, &sync_out_cable_present)); @@ -815,9 +801,9 @@ TEST_F(multidevice_ft, start_parallel) k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config.color_resolution = K4A_COLOR_RESOLUTION_2160P; - config.depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED; - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + config.color_mode_id = K4A_COLOR_RESOLUTION_2160P; + config.depth_mode_id = K4A_DEPTH_MODE_NFOV_2X2BINNED; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_30; // prevent the threads from running Lock(lock); @@ -866,9 +852,9 @@ TEST_F(multidevice_ft, close_parallel) k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - config.color_resolution = K4A_COLOR_RESOLUTION_2160P; - config.depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED; - config.camera_fps = K4A_FRAMES_PER_SECOND_30; + config.color_mode_id = K4A_COLOR_RESOLUTION_2160P; + config.depth_mode_id = K4A_DEPTH_MODE_NFOV_2X2BINNED; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_30; data2.config = data1.config = &config; data1.lock = data2.lock = lock; @@ -922,16 +908,16 @@ TEST_F(multidevice_sync_ft, multi_sync_no_color) k4a_device_configuration_t default_config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; default_config.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - default_config.color_resolution = K4A_COLOR_RESOLUTION_2160P; - default_config.depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED; - default_config.camera_fps = frame_rate; + default_config.color_mode_id = K4A_COLOR_RESOLUTION_2160P; + default_config.depth_mode_id = K4A_DEPTH_MODE_NFOV_2X2BINNED; + default_config.fps_mode_id = frame_rate; default_config.subordinate_delay_off_master_usec = 0; default_config.depth_delay_off_color_usec = 0; default_config.synchronized_images_only = true; k4a_device_configuration_t s_config = default_config; s_config.wired_sync_mode = K4A_WIRED_SYNC_MODE_SUBORDINATE; - s_config.color_resolution = K4A_COLOR_RESOLUTION_OFF; + s_config.color_mode_id = K4A_COLOR_RESOLUTION_OFF; s_config.synchronized_images_only = false; ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_cameras(subordinate, &s_config)); diff --git a/tests/projections/cpp/cpp_projection_ft.cpp b/tests/projections/cpp/cpp_projection_ft.cpp index 21af5ea4a..b5bd35dbd 100644 --- a/tests/projections/cpp/cpp_projection_ft.cpp +++ b/tests/projections/cpp/cpp_projection_ft.cpp @@ -108,13 +108,13 @@ void test_camera(k4a::device *device, camera_type type) if (type == camera_type::color) { config.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32; - config.color_resolution = K4A_COLOR_RESOLUTION_720P; + config.color_mode_id = K4A_COLOR_RESOLUTION_720P; } if (type == camera_type::depth) { - config.depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED; + config.depth_mode_id = K4A_DEPTH_MODE_NFOV_2X2BINNED; } - config.camera_fps = K4A_FRAMES_PER_SECOND_15; + config.fps_mode_id = K4A_FRAMES_PER_SECOND_15; device->start_cameras(&config); diff --git a/tests/rwlock/rwlock.cpp b/tests/rwlock/rwlock.cpp index 0b63d190d..079752982 100644 --- a/tests/rwlock/rwlock.cpp +++ b/tests/rwlock/rwlock.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include diff --git a/tests/throughput/CMakeLists.txt b/tests/throughput/CMakeLists.txt index c544e1ea4..38cbe54e4 100644 --- a/tests/throughput/CMakeLists.txt +++ b/tests/throughput/CMakeLists.txt @@ -10,6 +10,7 @@ target_link_libraries(throughput_perf PRIVATE gtest::gtest k4a::k4a k4ainternal::logging + k4ainternal::modes k4ainternal::utcommon) k4a_add_tests(TARGET throughput_perf HARDWARE_REQUIRED TEST_TYPE PERF) diff --git a/tests/throughput/throughput_perf.cpp b/tests/throughput/throughput_perf.cpp index 5863c9c48..cd23f4103 100644 --- a/tests/throughput/throughput_perf.cpp +++ b/tests/throughput/throughput_perf.cpp @@ -3,7 +3,6 @@ //************************ Includes ***************************** #include -#include #include #include #include @@ -120,7 +119,7 @@ static const char *get_string_from_color_resolution(k4a_color_resolution_t resol switch (resolution) { case K4A_COLOR_RESOLUTION_OFF: - return "OFF"; + return "K4A_COLOR_RESOLUTION_OFF"; break; case K4A_COLOR_RESOLUTION_720P: return "1280 * 720 16:9"; @@ -140,6 +139,9 @@ static const char *get_string_from_color_resolution(k4a_color_resolution_t resol case K4A_COLOR_RESOLUTION_3072P: return "4096 * 3072 4:3"; break; + case K4A_COLOR_RESOLUTION_COUNT: + return "K4A_COLOR_RESOLUTION_INVALID"; + break; } assert(0); return "Unknown resolution"; @@ -167,6 +169,9 @@ static const char *get_string_from_depth_mode(k4a_depth_mode_t mode) case K4A_DEPTH_MODE_PASSIVE_IR: return "K4A_DEPTH_MODE_PASSIVE_IR"; break; + case K4A_DEPTH_MODE_COUNT: + return "K4A_DEPTH_MODE_INVALID"; + break; } assert(0); return "Unknown Depth"; @@ -293,9 +298,9 @@ TEST_P(throughput_perf, testTest) fps_in_usec = HZ_TO_PERIOD_US(k4a_convert_fps_to_uint(as.fps)); config.color_format = as.color_format; - config.color_resolution = as.color_resolution; - config.depth_mode = as.depth_mode; - config.camera_fps = as.fps; + config.color_mode_id = as.color_resolution; + config.depth_mode_id = as.depth_mode; + config.fps_mode_id = as.fps; config.depth_delay_off_color_usec = g_depth_delay_off_color_usec; config.wired_sync_mode = g_wired_sync_mode; config.synchronized_images_only = g_synchronized_images_only; @@ -310,9 +315,9 @@ TEST_P(throughput_perf, testTest) printf("Config being used is:\n"); printf(" color_format:%d\n", config.color_format); - printf(" color_resolution:%d\n", config.color_resolution); - printf(" depth_mode:%d\n", config.depth_mode); - printf(" camera_fps:%d\n", config.camera_fps); + printf(" color_resolution:%d\n", config.color_mode_id); + printf(" depth_mode:%d\n", config.depth_mode_id); + printf(" camera_fps:%d\n", config.fps_mode_id); printf(" synchronized_images_only:%d\n", config.synchronized_images_only); printf(" depth_delay_off_color_usec:%d\n", config.depth_delay_off_color_usec); printf(" wired_sync_mode:%d\n", config.wired_sync_mode); @@ -641,7 +646,7 @@ TEST_P(throughput_perf, testTest) as.test_name, get_string_from_color_format(as.color_format), get_string_from_color_resolution(as.color_resolution), - k4a_convert_fps_to_uint(as.fps), + (uint32_t)as.fps, get_string_from_depth_mode(as.depth_mode), g_capture_count, both_count, diff --git a/tools/k4afastcapture_streaming/k4afastcapture.cpp b/tools/k4afastcapture_streaming/k4afastcapture.cpp index 56e86aec5..a44267f34 100644 --- a/tools/k4afastcapture_streaming/k4afastcapture.cpp +++ b/tools/k4afastcapture_streaming/k4afastcapture.cpp @@ -3,6 +3,7 @@ #include "k4afastcapture.h" #include +#include #include using namespace k4afastcapture; @@ -86,9 +87,9 @@ bool K4AFastCapture::Configure(const char *fileDirectory, int32_t exposureValue, } m_deviceConfig.color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - m_deviceConfig.color_resolution = K4A_COLOR_RESOLUTION_3072P; - m_deviceConfig.depth_mode = K4A_DEPTH_MODE_PASSIVE_IR; - m_deviceConfig.camera_fps = K4A_FRAMES_PER_SECOND_15; + m_deviceConfig.color_mode_id = K4A_COLOR_RESOLUTION_3072P; + m_deviceConfig.depth_mode_id = K4A_DEPTH_MODE_PASSIVE_IR; + m_deviceConfig.fps_mode_id = K4A_FRAMES_PER_SECOND_15; m_deviceConfig.synchronized_images_only = true; if (K4A_RESULT_SUCCEEDED != k4a_device_start_cameras(m_device, &m_deviceConfig)) @@ -191,7 +192,25 @@ void K4AFastCapture::Run(int streamingLength) k4a_image_t depth_image = NULL; k4a_image_t color_image = NULL; - uint32_t camera_fps = k4a_convert_fps_to_uint(m_deviceConfig.camera_fps); + uint32_t camera_fps = 0; + + // Get the camera fps that corresponds to the fps mode id. + k4a_fps_mode_info_t fps_mode = { static_cast(sizeof(k4a_fps_mode_info_t)), K4A_ABI_VERSION }; + uint32_t mode_count = 0; + k4a_result_t status = k4a_device_get_fps_mode_count(m_device, &mode_count); + if (status == K4A_RESULT_SUCCEEDED) + { + for (uint32_t mode_index = 0; mode_index < mode_count; ++mode_index) + { + status = k4a_device_get_fps_mode(m_device, mode_index, &fps_mode); + if (status == K4A_RESULT_SUCCEEDED) + { + camera_fps = fps_mode.fps; + break; + } + } + } + uint32_t remainingFrames = UINT32_MAX; if (streamingLength >= 0) { @@ -226,6 +245,7 @@ void K4AFastCapture::Run(int streamingLength) // std::cout << "[Streaming Service] Timed out waiting for the capture" << std::endl; continue; case K4A_WAIT_RESULT_FAILED: + case K4A_WAIT_RESULT_UNSUPPORTED: std::cout << "[Streaming Service] Failed to get the capture" << std::endl; return; } @@ -240,7 +260,7 @@ void K4AFastCapture::Run(int streamingLength) if (0 == result) #endif { - if (m_deviceConfig.depth_mode == K4A_DEPTH_MODE_PASSIVE_IR) + if (m_deviceConfig.depth_mode_id == K4A_DEPTH_MODE_PASSIVE_IR) { // for the passive IR mode, there is no depth image. Only IR image is available in the capture. ir_image = k4a_capture_get_ir_image(m_capture); diff --git a/tools/k4arecorder/CMakeLists.txt b/tools/k4arecorder/CMakeLists.txt index 8edc8b2fc..0b2edf896 100644 --- a/tools/k4arecorder/CMakeLists.txt +++ b/tools/k4arecorder/CMakeLists.txt @@ -6,6 +6,7 @@ add_executable(k4arecorder main.cpp recorder.cpp ${CMAKE_CURRENT_BINARY_DIR}/ver target_link_libraries(k4arecorder PRIVATE k4a::k4a k4a::k4arecord + k4a_math ) # Include ${CMAKE_CURRENT_BINARY_DIR}/version.rc in the target's sources diff --git a/tools/k4arecorder/main.cpp b/tools/k4arecorder/main.cpp index 3cd9ea7cf..660e82632 100644 --- a/tools/k4arecorder/main.cpp +++ b/tools/k4arecorder/main.cpp @@ -16,9 +16,13 @@ #include #include #include +#include +#include static time_t exiting_timestamp; +#define INVALID_AND_NOT_USER_DEFINED -1 + static void signal_handler(int s) { (void)s; // Unused @@ -66,7 +70,8 @@ static int string_compare(const char *s1, const char *s2) { for (uint8_t i = 0; i < device_count; i++) { - std::cout << "Index:" << (int)i; + std::cout << std::endl; + std::cout << "Index: " << (int)i << std::endl << std::endl; k4a_device_t device; if (K4A_SUCCEEDED(k4a_device_open(i, &device))) { @@ -75,21 +80,169 @@ static int string_compare(const char *s1, const char *s2) if (k4a_device_get_serialnum(device, serial_number_buffer, &serial_number_buffer_size) == K4A_BUFFER_RESULT_SUCCEEDED) { - std::cout << "\tSerial:" << serial_number_buffer; + std::cout << "\tSerial: " << serial_number_buffer << std::endl << std::endl; } else { - std::cout << "\tSerial:ERROR"; + std::cout << "\tSerial: ERROR" << std::endl << std::endl; } - k4a_hardware_version_t version_info; - if (K4A_SUCCEEDED(k4a_device_get_version(device, &version_info))) + // device info + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + if (k4a_device_get_info(device, &device_info) == K4A_RESULT_SUCCEEDED) { - std::cout << "\tColor:" << version_info.rgb.major << "." << version_info.rgb.minor << "." - << version_info.rgb.iteration; - std::cout << "\tDepth:" << version_info.depth.major << "." << version_info.depth.minor << "." - << version_info.depth.iteration; + bool hasColorDevice = false; + bool hasDepthDevice = false; + bool hasIMUDevice = false; + + hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + hasIMUDevice = (device_info.capabilities.bitmap.bHasIMU == 1); + + k4a_hardware_version_t version_info; + if (K4A_SUCCEEDED(k4a_device_get_version(device, &version_info))) + { + if (hasColorDevice) + { + std::cout << "\tColor: Supported (" << version_info.rgb.major << "." + << version_info.rgb.minor << "." << version_info.rgb.iteration << ")" + << std::endl; + } + else + { + std::cout << "\tColor: Unsupported"; + } + if (hasDepthDevice) + { + std::cout << "\tDepth: Supported (" << version_info.depth.major << "." + << version_info.depth.minor << "." << version_info.depth.iteration << ")" + << std::endl; + } + else + { + std::cout << "\tDepth: Unsupported"; + } + if (hasIMUDevice) + { + std::cout << "\tIMU: Supported"; + } + else + { + std::cout << "\tIMU: Unsupported"; + } + + std::cout << std::endl; + + if (hasColorDevice) + { + uint32_t color_mode_count = 0; + k4a_device_get_color_mode_count(device, &color_mode_count); + if (color_mode_count > 0) + { + std::cout << std::endl; + std::cout << "\tColor modes: \tid = description" << std::endl; + std::cout << "\t\t\t----------------" << std::endl; + for (uint32_t j = 0; j < color_mode_count; j++) + { + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), + K4A_ABI_VERSION, + 0 }; + if (k4a_device_get_color_mode(device, j, &color_mode_info) == K4A_RESULT_SUCCEEDED) + { + std::cout << "\t\t\t" << color_mode_info.mode_id << " = "; + if (j == 0) + { + std::cout << "OFF" << std::endl; + } + else + { + int width = color_mode_info.width; + int height = color_mode_info.height; + int common_factor = math_get_common_factor(width, height); + if (height < 1000) + { + std::cout << " "; + } + std::cout << height << "p "; + std::cout << width / common_factor << ":"; + std::cout << height / common_factor << std::endl; + } + } + } + } + } + + if (hasDepthDevice) + { + uint32_t depth_mode_count = 0; + k4a_device_get_depth_mode_count(device, &depth_mode_count); + if (depth_mode_count > 0) + { + std::cout << std::endl; + std::cout << "\tDepth modes: \tid = description" << std::endl; + std::cout << "\t\t\t----------------" << std::endl; + for (uint32_t j = 0; j < depth_mode_count; j++) + { + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), + K4A_ABI_VERSION, + 0 }; + if (k4a_device_get_depth_mode(device, j, &depth_mode_info) == K4A_RESULT_SUCCEEDED) + { + std::cout << "\t\t\t" << depth_mode_info.mode_id << " = "; + if (j == 0) + { + std::cout << "OFF" << std::endl; + } + else + { + int width = depth_mode_info.width; + int height = depth_mode_info.height; + float hfov = depth_mode_info.horizontal_fov; + float vfov = depth_mode_info.vertical_fov; + if (depth_mode_info.passive_ir_only) + { + std::cout << "Passive IR" << std::endl; + } + else + { + std::cout << width << "x"; + std::cout << height << ", "; + std::cout << hfov << " Deg hfov x " << vfov << " Deg vfov" << std::endl; + } + } + } + } + } + } + + if (hasColorDevice || hasDepthDevice) + { + uint32_t fps_mode_count = 0; + k4a_device_get_fps_mode_count(device, &fps_mode_count); + if (fps_mode_count > 0) + { + std::cout << std::endl; + std::cout << "\tFPS modes: \tid = description" << std::endl; + std::cout << "\t\t\t----------------" << std::endl; + for (uint32_t j = 0; j < fps_mode_count; j++) + { + k4a_fps_mode_info_t fps_mode_info = { sizeof(k4a_fps_mode_info_t), + K4A_ABI_VERSION, + 0 }; + if (k4a_device_get_fps_mode(device, j, &fps_mode_info) == K4A_RESULT_SUCCEEDED) + { + if (fps_mode_info.fps > 0) + { + std::cout << "\t\t\t" << fps_mode_info.mode_id << " = " << fps_mode_info.fps + << " frames per second" << std::endl; + } + } + } + } + } + } } + k4a_device_close(device); } else @@ -106,15 +259,175 @@ static int string_compare(const char *s1, const char *s2) exit(0); } +static k4a_result_t get_device_info(k4a_device_t device, bool *hasDepthDevice, bool *hasColorDevice, bool *hasIMUDevice) +{ + k4a_device_info_t device_info = { sizeof(k4a_device_info_t), K4A_ABI_VERSION, 0 }; + if (k4a_device_get_info(device, &device_info) == K4A_RESULT_SUCCEEDED) + { + *hasDepthDevice = (device_info.capabilities.bitmap.bHasDepth == 1); + *hasColorDevice = (device_info.capabilities.bitmap.bHasColor == 1); + *hasIMUDevice = (device_info.capabilities.bitmap.bHasIMU == 1); + + return K4A_RESULT_SUCCEEDED; + } + else + { + std::cout << "Device Get Info Failed" << std::endl; + } + return K4A_RESULT_FAILED; +} + +static k4a_result_t get_color_mode_info(k4a_device_t device, + int32_t *mode_id, + k4a_image_format_t image_format, + k4a_color_mode_info_t *color_mode_info) +{ + k4a_result_t result = K4A_RESULT_FAILED; + color_mode_info->mode_id = 0; + + uint32_t mode_count = 0; + result = k4a_device_get_color_mode_count(device, &mode_count); + if (K4A_SUCCEEDED(result) && mode_count > 0) + { + if (image_format == K4A_IMAGE_FORMAT_COLOR_NV12 || image_format == K4A_IMAGE_FORMAT_COLOR_YUY2) + { + *mode_id = INVALID_AND_NOT_USER_DEFINED; + } + + // Go through the list of color modes and find the one that matches the mode_id. + k4a_color_mode_info_t mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + for (uint32_t n = 0; n < mode_count; ++n) + { + result = k4a_device_get_color_mode(device, n, &mode_info); + if (K4A_SUCCEEDED(result) && mode_info.height > 0) + { + // If the mode_id is not provided by the user, just use the first non-zero height mode. + if (*mode_id == INVALID_AND_NOT_USER_DEFINED || static_cast(*mode_id) == mode_info.mode_id) + { + SAFE_COPY_STRUCT(color_mode_info, &mode_info); + *mode_id = mode_info.mode_id; + break; + } + } + } + } + + return result; +} + +static k4a_result_t get_depth_mode_info(k4a_device_t device, int32_t *mode_id, k4a_depth_mode_info_t *depth_mode_info) +{ + k4a_result_t result = K4A_RESULT_FAILED; + depth_mode_info->mode_id = 0; + + uint32_t mode_count = 0; + result = k4a_device_get_depth_mode_count(device, &mode_count); + if (K4A_SUCCEEDED(result) && mode_count > 0) + { + // Go through the list of depth modes and find the one that matches the mode_id. + k4a_depth_mode_info_t mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + for (uint32_t n = 0; n < mode_count; ++n) + { + result = k4a_device_get_depth_mode(device, n, &mode_info); + if (K4A_SUCCEEDED(result) && mode_info.height > 0) + { + // If the mode_id is not provided by the user, just use the first non-zero height mode. + if (*mode_id == INVALID_AND_NOT_USER_DEFINED || static_cast(*mode_id) == mode_info.mode_id) + { + SAFE_COPY_STRUCT(depth_mode_info, &mode_info); + *mode_id = mode_info.mode_id; + break; + } + } + } + } + + return result; +} + +static k4a_result_t get_fps_mode_info(k4a_device_t device, + int32_t *fps_mode_id, + k4a_color_mode_info_t *color_mode_info, + k4a_depth_mode_info_t *depth_mode_info, + k4a_fps_mode_info_t *fps_mode_info) +{ + k4a_result_t result = K4A_RESULT_FAILED; + fps_mode_info->mode_id = 0; + + uint32_t mode_count = 0; + result = k4a_device_get_fps_mode_count(device, &mode_count); + if (K4A_SUCCEEDED(result) && mode_count > 0) + { + // Go through the list of fps modes and find the one that matches the mode_id. + for (uint32_t n = 0; n < mode_count; ++n) + { + k4a_fps_mode_info_t mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + result = k4a_device_get_fps_mode(device, n, &mode_info); + if (K4A_SUCCEEDED(result) && mode_info.fps > 0) + { + // If the mode_id is not provided by the user, just use the first non-zero fps mode. + if (*fps_mode_id == INVALID_AND_NOT_USER_DEFINED || + static_cast(*fps_mode_id) == mode_info.mode_id) + { + SAFE_COPY_STRUCT(fps_mode_info, &mode_info); + *fps_mode_id = mode_info.mode_id; + break; + } + } + } + + // There may be some contraint on the fps modes for a given color and depth modes. + // These are specific for Azure Kinect device. + if (K4A_SUCCEEDED(result) && static_cast(*fps_mode_id) == fps_mode_info->mode_id) + { + if ((color_mode_info->height >= 3072 || + (depth_mode_info->height >= 1024 && depth_mode_info->horizontal_fov >= 120.0f && + depth_mode_info->vertical_fov >= 120.0f && depth_mode_info->min_range >= 250 && + depth_mode_info->max_range >= 2500)) && + fps_mode_info->fps > 15) + { + // Find the maximum FPS available that is less than or equal to 15 FPS. + uint32_t fps = 0; + for (uint32_t n = 0; n < mode_count; ++n) + { + k4a_fps_mode_info_t mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + result = k4a_device_get_fps_mode(device, n, &mode_info); + if (K4A_SUCCEEDED(result) && mode_info.fps <= 15) + { + if (mode_info.fps > fps) + { + SAFE_COPY_STRUCT(fps_mode_info, &mode_info); + *fps_mode_id = mode_info.mode_id; + fps = mode_info.fps; + break; + } + } + } + + if (fps == 0) + { + std::cout << "Error: a fps mode with a framerate greater than 0 has not been found." << std::endl; + result = K4A_RESULT_FAILED; + } + else + { + std::cout << "Warning: reduced frame rate down to " << fps << "." << std::endl; + } + } + } + } + + return result; +} + int main(int argc, char **argv) { int device_index = 0; - int recording_length = -1; + int recording_length = INVALID_AND_NOT_USER_DEFINED; k4a_image_format_t recording_color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; - k4a_color_resolution_t recording_color_resolution = K4A_COLOR_RESOLUTION_1080P; - k4a_depth_mode_t recording_depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; - k4a_fps_t recording_rate = K4A_FRAMES_PER_SECOND_30; - bool recording_rate_set = false; + int32_t recording_color_mode = INVALID_AND_NOT_USER_DEFINED; + int32_t recording_depth_mode = INVALID_AND_NOT_USER_DEFINED; + int32_t recording_fps_mode = INVALID_AND_NOT_USER_DEFINED; bool recording_imu_enabled = true; k4a_wired_sync_mode_t wired_sync_mode = K4A_WIRED_SYNC_MODE_STANDALONE; int32_t depth_delay_off_color_usec = 0; @@ -129,105 +442,96 @@ int main(int argc, char **argv) cmd_parser.PrintOptions(); exit(0); }); - cmd_parser.RegisterOption("--list", "List the currently connected K4A devices", list_devices); + cmd_parser.RegisterOption("--list", + "List the currently connected devices (includes color, depth and fps modes)", + list_devices); cmd_parser.RegisterOption("--device", "Specify the device index to use (default: 0)", 1, [&](const std::vector &args) { - device_index = std::stoi(args[0]); - if (device_index < 0 || device_index > 255) - throw std::runtime_error("Device index must 0-255"); + try + { + device_index = std::stoi(args[0]); + if (device_index < 0 || device_index > 255) + throw std::runtime_error("Device index must 0-255"); + } + catch (const std::exception &) + { + std::ostringstream str; + str << "Unknown device index specified: " << args[0]; + throw std::runtime_error(str.str()); + } }); cmd_parser.RegisterOption("-l|--record-length", "Limit the recording to N seconds (default: infinite)", 1, [&](const std::vector &args) { - recording_length = std::stoi(args[0]); - if (recording_length < 0) - throw std::runtime_error("Recording length must be positive"); - }); - cmd_parser.RegisterOption("-c|--color-mode", - "Set the color sensor mode (default: 1080p), Available options:\n" - "3072p, 2160p, 1536p, 1440p, 1080p, 720p, 720p_NV12, 720p_YUY2, OFF", - 1, - [&](const std::vector &args) { - if (string_compare(args[0], "3072p") == 0) - { - recording_color_resolution = K4A_COLOR_RESOLUTION_3072P; - } - else if (string_compare(args[0], "2160p") == 0) + try { - recording_color_resolution = K4A_COLOR_RESOLUTION_2160P; + recording_length = std::stoi(args[0]); + if (recording_length < 0) + throw std::runtime_error("Recording length must be positive"); } - else if (string_compare(args[0], "1536p") == 0) + catch (const std::exception &) { - recording_color_resolution = K4A_COLOR_RESOLUTION_1536P; + std::ostringstream str; + str << "Unknown record length specified: " << args[0]; + throw std::runtime_error(str.str()); } - else if (string_compare(args[0], "1440p") == 0) + }); + cmd_parser.RegisterOption("-c|--color-mode", + "Set the color sensor mode (default: 0 for OFF), Use --list to see the available modes.", + 1, + [&](const std::vector &args) { + try { - recording_color_resolution = K4A_COLOR_RESOLUTION_1440P; + recording_color_mode = std::stoi(args[0]); + if (recording_color_mode < 0) + throw std::runtime_error("Color mode must be positive"); } - else if (string_compare(args[0], "1080p") == 0) + catch (const std::exception &) { - recording_color_resolution = K4A_COLOR_RESOLUTION_1080P; + std::ostringstream str; + str << "Unknown color mode specified: " << args[0]; + throw std::runtime_error(str.str()); } - else if (string_compare(args[0], "720p") == 0) + }); + cmd_parser.RegisterOption("-i|--image-format", + "Set the image format (default: MJPG), Available options:\n" + "MJPG, NV12, YUY2\n" + "Note that for NV12 and YUY2, the color resolution must not be greater than 720p.", + 1, + [&](const std::vector &args) { + if (string_compare(args[0], "MJPG") == 0) { - recording_color_resolution = K4A_COLOR_RESOLUTION_720P; + recording_color_format = K4A_IMAGE_FORMAT_COLOR_MJPG; } - else if (string_compare(args[0], "720p_NV12") == 0) + else if (string_compare(args[0], "NV12") == 0) { recording_color_format = K4A_IMAGE_FORMAT_COLOR_NV12; - recording_color_resolution = K4A_COLOR_RESOLUTION_720P; } - else if (string_compare(args[0], "720p_YUY2") == 0) + else if (string_compare(args[0], "YUY2") == 0) { recording_color_format = K4A_IMAGE_FORMAT_COLOR_YUY2; - recording_color_resolution = K4A_COLOR_RESOLUTION_720P; - } - else if (string_compare(args[0], "off") == 0) - { - recording_color_resolution = K4A_COLOR_RESOLUTION_OFF; } else { - recording_color_resolution = K4A_COLOR_RESOLUTION_OFF; - std::ostringstream str; - str << "Unknown color mode specified: " << args[0]; + str << "Unknown image format specified: " << args[0]; throw std::runtime_error(str.str()); } }); cmd_parser.RegisterOption("-d|--depth-mode", - "Set the depth sensor mode (default: NFOV_UNBINNED), Available options:\n" - "NFOV_2X2BINNED, NFOV_UNBINNED, WFOV_2X2BINNED, WFOV_UNBINNED, PASSIVE_IR, OFF", + "Set the depth sensor mode (default: 0 for OFF), Use --list to see the available modes.", 1, [&](const std::vector &args) { - if (string_compare(args[0], "NFOV_2X2BINNED") == 0) - { - recording_depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED; - } - else if (string_compare(args[0], "NFOV_UNBINNED") == 0) + try { - recording_depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; + recording_depth_mode = std::stoi(args[0]); + if (recording_depth_mode < 0) + throw std::runtime_error("Depth mode must be positive"); } - else if (string_compare(args[0], "WFOV_2X2BINNED") == 0) - { - recording_depth_mode = K4A_DEPTH_MODE_WFOV_2X2BINNED; - } - else if (string_compare(args[0], "WFOV_UNBINNED") == 0) - { - recording_depth_mode = K4A_DEPTH_MODE_WFOV_UNBINNED; - } - else if (string_compare(args[0], "PASSIVE_IR") == 0) - { - recording_depth_mode = K4A_DEPTH_MODE_PASSIVE_IR; - } - else if (string_compare(args[0], "off") == 0) - { - recording_depth_mode = K4A_DEPTH_MODE_OFF; - } - else + catch (const std::exception &) { std::ostringstream str; str << "Unknown depth mode specified: " << args[0]; @@ -240,28 +544,32 @@ int main(int argc, char **argv) "The delay must be less than 1 frame period.", 1, [&](const std::vector &args) { - depth_delay_off_color_usec = std::stoi(args[0]); + try + { + depth_delay_off_color_usec = std::stoi(args[0]); + if (depth_delay_off_color_usec < 1) + throw std::runtime_error("Depth delay must be less than 1 frame period"); + } + catch (const std::exception &) + { + std::ostringstream str; + str << "Unknown depth delay specified: " << args[0]; + throw std::runtime_error(str.str()); + } }); cmd_parser.RegisterOption("-r|--rate", "Set the camera frame rate in Frames per Second\n" "Default is the maximum rate supported by the camera modes.\n" - "Available options: 30, 15, 5", + "Use --list to see the available modes.", 1, [&](const std::vector &args) { - recording_rate_set = true; - if (string_compare(args[0], "30") == 0) - { - recording_rate = K4A_FRAMES_PER_SECOND_30; - } - else if (string_compare(args[0], "15") == 0) - { - recording_rate = K4A_FRAMES_PER_SECOND_15; - } - else if (string_compare(args[0], "5") == 0) + try { - recording_rate = K4A_FRAMES_PER_SECOND_5; + recording_fps_mode = std::stoi(args[0]); + if (recording_fps_mode < 0) + throw std::runtime_error("Frame rate must be positive"); } - else + catch (const std::exception &) { std::ostringstream str; str << "Unknown frame rate specified: " << args[0]; @@ -316,43 +624,74 @@ int main(int argc, char **argv) "This setting is only valid if the camera is in Subordinate mode.", 1, [&](const std::vector &args) { - int delay = std::stoi(args[0]); - if (delay < 0) + try { - throw std::runtime_error("External sync delay must be positive."); + int subordinate_delay_off_master_usec_value = std::stoi(args[0]); + if (subordinate_delay_off_master_usec_value < 0) + { + throw std::runtime_error("External sync delay must be positive."); + } + else + { + subordinate_delay_off_master_usec = static_cast( + subordinate_delay_off_master_usec_value); + } + } + catch (const std::exception &) + { + std::ostringstream str; + str << "Unknown sync delay specified: " << args[0]; + throw std::runtime_error(str.str()); } - subordinate_delay_off_master_usec = (uint32_t)delay; }); cmd_parser.RegisterOption("-e|--exposure-control", "Set manual exposure value from 2 us to 200,000us for the RGB camera (default: \n" "auto exposure). This control also supports MFC settings of -11 to 1).", 1, [&](const std::vector &args) { - int exposureValue = std::stoi(args[0]); - if (exposureValue >= -11 && exposureValue <= 1) - { - absoluteExposureValue = static_cast(exp2f((float)exposureValue) * - 1000000.0f); - } - else if (exposureValue >= 2 && exposureValue <= 200000) + try + { + int exposureValue = std::stoi(args[0]); + if (exposureValue >= -11 && exposureValue <= 1) + { + absoluteExposureValue = static_cast(exp2f((float)exposureValue) * + 1000000.0f); + } + else if (exposureValue >= 2 && exposureValue <= 200000) + { + absoluteExposureValue = exposureValue; + } + else + { + throw std::runtime_error("Exposure value range is 2 to 5s, or -11 to 1."); + } + } + catch (const std::exception &) { - absoluteExposureValue = exposureValue; - } - else - { - throw std::runtime_error("Exposure value range is 2 to 5s, or -11 to 1."); + std::ostringstream str; + str << "Unknown specified: " << args[0]; + throw std::runtime_error(str.str()); } }); cmd_parser.RegisterOption("-g|--gain", "Set cameras manual gain. The valid range is 0 to 255. (default: auto)", 1, [&](const std::vector &args) { - int gainSetting = std::stoi(args[0]); - if (gainSetting < 0 || gainSetting > 255) + try + { + int gainSetting = std::stoi(args[0]); + if (gainSetting < 0 || gainSetting > 255) + { + throw std::runtime_error("Gain value must be between 0 and 255."); + } + gain = gainSetting; + } + catch (const std::exception &) { - throw std::runtime_error("Gain value must be between 0 and 255."); + std::ostringstream str; + str << "Unknown specified: " << args[0]; + throw std::runtime_error(str.str()); } - gain = gainSetting; }); int args_left = 0; @@ -376,20 +715,125 @@ int main(int argc, char **argv) return 0; } - if (recording_rate == K4A_FRAMES_PER_SECOND_30 && (recording_depth_mode == K4A_DEPTH_MODE_WFOV_UNBINNED || - recording_color_resolution == K4A_COLOR_RESOLUTION_3072P)) + if (recording_color_mode == INVALID_AND_NOT_USER_DEFINED && recording_depth_mode == INVALID_AND_NOT_USER_DEFINED) + { + std::cout << "A recording requires either a color or a depth device." << std::endl; + return 1; + } + + uint32_t device_count = k4a_device_get_installed_count(); + if (device_count > 0) { - if (!recording_rate_set) + k4a_device_t device; + if (K4A_SUCCEEDED(k4a_device_open(device_index, &device))) { - // Default to max supported frame rate - recording_rate = K4A_FRAMES_PER_SECOND_15; + bool hasColorDevice = false; + bool hasDepthDevice = false; + bool hasIMUDevice = false; + + k4a_color_mode_info_t color_mode_info = { sizeof(k4a_color_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_depth_mode_info_t depth_mode_info = { sizeof(k4a_depth_mode_info_t), K4A_ABI_VERSION, 0 }; + k4a_fps_mode_info_t fps_mode_info = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + + k4a_result_t device_info_result = get_device_info(device, &hasDepthDevice, &hasColorDevice, &hasIMUDevice); + + if (K4A_SUCCEEDED(device_info_result)) + { + if (hasColorDevice) + { + if (!K4A_SUCCEEDED(get_color_mode_info(device, + &recording_color_mode, + recording_color_format, + &color_mode_info))) + { + recording_color_mode = 0; + } + } + else + { + recording_color_mode = 0; + } + + if (hasDepthDevice) + { + if (!K4A_SUCCEEDED(get_depth_mode_info(device, &recording_depth_mode, &depth_mode_info))) + { + recording_depth_mode = 0; + } + } + else + { + recording_depth_mode = 0; + } + + if (recording_color_mode == 0 && recording_depth_mode == 0) + { + std::cout << "A recording requires either a color or a depth device." << std::endl; + return 1; + } + + if (recording_fps_mode == INVALID_AND_NOT_USER_DEFINED) + { + uint32_t fps_mode_count = 0; + + if (!k4a_device_get_fps_mode_count(device, &fps_mode_count) == K4A_RESULT_SUCCEEDED) + { + printf("Failed to get fps mode count\n"); + exit(-1); + } + + if (fps_mode_count > 1) + { + uint32_t fps_mode_id = 0; + uint32_t max_fps = 0; + for (uint32_t f = 1; f < fps_mode_count; f++) + { + k4a_fps_mode_info_t fps_mode = { sizeof(k4a_fps_mode_info_t), K4A_ABI_VERSION, 0 }; + if (k4a_device_get_fps_mode(device, f, &fps_mode) == K4A_RESULT_SUCCEEDED) + { + if (fps_mode.fps >= max_fps) + { + max_fps = (uint32_t)fps_mode.fps; + fps_mode_id = fps_mode.mode_id; + } + } + } + recording_fps_mode = fps_mode_id; + } + } + + if (!K4A_SUCCEEDED(get_fps_mode_info( + device, &recording_fps_mode, &color_mode_info, &depth_mode_info, &fps_mode_info))) + { + std::cout << "Error finding valid framerate for recording camera settings." << std::endl; + return 1; + } + + // validate imu + if (recording_imu_enabled && !hasIMUDevice) + { + recording_imu_enabled = false; + std::cout << "Warning: device " << device_index + << " does not support IMU, so, IMU has been disabled." << std::endl; + } + } + else + { + return 1; + } + + k4a_device_close(device); } else { - std::cerr << "Error: 30 Frames per second is not supported by this camera mode." << std::endl; - return 1; + std::cout << device_index << "Device Open Failed" << std::endl; } } + else + { + std::cout << "No devices connected or unkown device specified." << std::endl; + } + if (subordinate_delay_off_master_usec > 0 && wired_sync_mode != K4A_WIRED_SYNC_MODE_SUBORDINATE) { std::cerr << "--sync-delay is only valid if --external-sync is set to Subordinate." << std::endl; @@ -417,9 +861,9 @@ int main(int argc, char **argv) k4a_device_configuration_t device_config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; device_config.color_format = recording_color_format; - device_config.color_resolution = recording_color_resolution; - device_config.depth_mode = recording_depth_mode; - device_config.camera_fps = recording_rate; + device_config.color_mode_id = recording_color_mode; + device_config.depth_mode_id = recording_depth_mode; + device_config.fps_mode_id = recording_fps_mode; device_config.wired_sync_mode = wired_sync_mode; device_config.depth_delay_off_color_usec = depth_delay_off_color_usec; device_config.subordinate_delay_off_master_usec = subordinate_delay_off_master_usec; diff --git a/tools/k4arecorder/recorder.cpp b/tools/k4arecorder/recorder.cpp index 9f3bcf86a..c12d135e8 100644 --- a/tools/k4arecorder/recorder.cpp +++ b/tools/k4arecorder/recorder.cpp @@ -8,29 +8,9 @@ #include #include +#include #include -inline static uint32_t k4a_convert_fps_to_uint(k4a_fps_t fps) -{ - uint32_t fps_int; - switch (fps) - { - case K4A_FRAMES_PER_SECOND_5: - fps_int = 5; - break; - case K4A_FRAMES_PER_SECOND_15: - fps_int = 15; - break; - case K4A_FRAMES_PER_SECOND_30: - fps_int = 30; - break; - default: - fps_int = 0; - break; - } - return fps_int; -} - // call k4a_device_close on every failed CHECK #define CHECK(x, device) \ { \ @@ -83,10 +63,25 @@ int do_recording(uint8_t device_index, << "; A: " << version_info.audio.major << "." << version_info.audio.minor << "." << version_info.audio.iteration << std::endl; - uint32_t camera_fps = k4a_convert_fps_to_uint(device_config->camera_fps); + // Get the camera fps that corresponds to the fps mode id. + uint32_t camera_fps = 0; + uint32_t fps_mode_count = 0; + k4a_fps_mode_info_t fps_mode_info = { static_cast(sizeof(k4a_fps_mode_info_t)), K4A_ABI_VERSION }; + if (K4A_SUCCEEDED(k4a_device_get_fps_mode_count(device, &fps_mode_count))) + { + for (uint32_t mode_index = 0; mode_index < fps_mode_count; ++mode_index) + { + if (K4A_SUCCEEDED(k4a_device_get_fps_mode(device, mode_index, &fps_mode_info)) && + fps_mode_info.mode_id == device_config->fps_mode_id) + { + camera_fps = fps_mode_info.fps; + break; + } + } + } - if (camera_fps <= 0 || (device_config->color_resolution == K4A_COLOR_RESOLUTION_OFF && - device_config->depth_mode == K4A_DEPTH_MODE_OFF)) + if (camera_fps <= 0 || (device_config->color_mode_id == K4A_COLOR_RESOLUTION_OFF && + device_config->depth_mode_id == K4A_DEPTH_MODE_OFF)) { std::cerr << "Either the color or depth modes must be enabled to record." << std::endl; return 1; diff --git a/tools/k4aviewer/CMakeLists.txt b/tools/k4aviewer/CMakeLists.txt index 98578c034..87b27c70b 100644 --- a/tools/k4aviewer/CMakeLists.txt +++ b/tools/k4aviewer/CMakeLists.txt @@ -1,12 +1,26 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +# Include ${CMAKE_CURRENT_BINARY_DIR}/version.rc in the target's sources +# to embed version information +set(K4A_FILEDESCRIPTION "Azure Kinect Viewer") +set(K4A_ORIGINALFILENAME "k4aviewer.exe") +set(K4A_USE_ICON 1) +configure_file( + ${K4A_VERSION_RC} + ${CMAKE_CURRENT_BINARY_DIR}/version.rc + @ONLY + ) + +find_package(OpenGL REQUIRED) +include_directories( + ${OPENGL_INCLUDE_DIRS} + ${CMAKE_CURRENT_LIST_DIR} +) + set(SOURCE_FILES main.cpp gpudepthtopointcloudconverter.cpp - k4aaudiochanneldatagraph.cpp - k4aaudiomanager.cpp - k4aaudiowindow.cpp k4acolorimageconverter.cpp k4adevicedockcontrol.cpp k4afilepicker.cpp @@ -15,8 +29,6 @@ set(SOURCE_FILES k4aimugraphdatagenerator.cpp k4aimuwindow.cpp k4alogdockcontrol.cpp - k4amicrophone.cpp - k4amicrophonelistener.cpp k4apointcloudrenderer.cpp k4apointcloudviewcontrol.cpp k4apointcloudvisualizer.cpp @@ -37,69 +49,83 @@ set(SOURCE_FILES ${CMAKE_CURRENT_BINARY_DIR}/version.rc ) -# Include ${CMAKE_CURRENT_BINARY_DIR}/version.rc in the target's sources -# to embed version information -set(K4A_FILEDESCRIPTION "Azure Kinect Viewer") -set(K4A_ORIGINALFILENAME "k4aviewer.exe") -set(K4A_USE_ICON 1) -configure_file( - ${K4A_VERSION_RC} - ${CMAKE_CURRENT_BINARY_DIR}/version.rc - @ONLY - ) - -find_package(OpenGL REQUIRED) -include_directories( - ${OPENGL_INCLUDE_DIRS} - ${CMAKE_CURRENT_LIST_DIR} -) - set(EXTERNAL_LIBRARIES k4a::k4a k4a::k4arecord + k4a_math imgui::imgui libjpeg-turbo::libjpeg-turbo - libsoundio::libsoundio LibUSB::LibUSB libyuv::libyuv glfw::glfw ${OPENGL_LIBRARIES} ) -# On Windows, we need to call into setupapi to get USB container ID information -# so we can correlate K4A microphone arrays and K4A depth cameras/sensors -# if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - list(APPEND SOURCE_FILES - platform/windows/filesystem17.cpp - platform/windows/k4adevicecorrelator.cpp - platform/windows/wmain.cpp - ) + list(APPEND SOURCE_FILES + platform/windows/filesystem17.cpp + platform/windows/wmain.cpp + ) - list(APPEND EXTERNAL_LIBRARIES - setupapi.lib - pathcch.lib - Shlwapi.lib - ) + list(APPEND EXTERNAL_LIBRARIES + setupapi.lib + pathcch.lib + Shlwapi.lib + ) else() - list(APPEND SOURCE_FILES - platform/linux/filesystem17.cpp - platform/linux/k4adevicecorrelator.cpp + list(APPEND SOURCE_FILES + platform/linux/filesystem17.cpp + ) +endif() + + +# Set K4A_INCLUDE_AUDIO to 1 for audio support. +set(K4A_INCLUDE_AUDIO 0) +if (K4A_INCLUDE_AUDIO) + + add_compile_definitions(K4A_INCLUDE_AUDIO) + + list(APPEND SOURCE_FILES + k4aaudiochanneldatagraph.cpp + k4aaudiomanager.cpp + k4aaudiowindow.cpp + k4amicrophone.cpp + k4amicrophonelistener.cpp ) - # This is a bit gross, but libsoundio has a file called endian.h in its - # include path, which conflicts with a system file with the same name on - # Linux. On Ubuntu 16.04, this causes a struct in waitstatus.h to have - # all its members defined twice (once for each endianness), which results - # in a build break. It looks like there's not a built-in way to pass - # idirafter in cmake like you can with target_include_directories, so - # anyone that uses libsoundio has to do this. Fortunately, that should - # just be k4aviewer - # - add_compile_options("-idirafter/usr/include/soundio") + list(APPEND EXTERNAL_LIBRARIES + libsoundio::libsoundio + ) + + # On Windows, we need to call into setupapi to get USB container ID information + # so we can correlate K4A microphone arrays and K4A depth cameras/sensors + # + if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + list(APPEND SOURCE_FILES + platform/windows/k4adevicecorrelator.cpp + ) + + else() + list(APPEND SOURCE_FILES + platform/linux/k4adevicecorrelator.cpp + ) + + # This is a bit gross, but libsoundio has a file called endian.h in its + # include path, which conflicts with a system file with the same name on + # Linux. On Ubuntu 16.04, this causes a struct in waitstatus.h to have + # all its members defined twice (once for each endianness), which results + # in a build break. It looks like there's not a built-in way to pass + # idirafter in cmake like you can with target_include_directories, so + # anyone that uses libsoundio has to do this. Fortunately, that should + # just be k4aviewer + # + add_compile_options("-idirafter/usr/include/soundio") + + endif() endif() + add_executable(k4aviewer WIN32 ${SOURCE_FILES}) target_link_libraries(k4aviewer PRIVATE ${EXTERNAL_LIBRARIES}) diff --git a/tools/k4aviewer/k4acolorimageconverter.cpp b/tools/k4aviewer/k4acolorimageconverter.cpp index 378c881f0..b807a640c 100644 --- a/tools/k4aviewer/k4acolorimageconverter.cpp +++ b/tools/k4aviewer/k4acolorimageconverter.cpp @@ -49,8 +49,8 @@ template class K4AColorImageConverterBase : publ } protected: - explicit K4AColorImageConverterBase(k4a_color_resolution_t colorResolution) : - m_dimensions(GetColorDimensions(colorResolution)) + explicit K4AColorImageConverterBase(k4a_color_mode_info_t color_mode_info) : + m_dimensions(GetColorDimensions(color_mode_info)) { m_expectedBufferSize = sizeof(BgraPixel) * static_cast(m_dimensions.Width * m_dimensions.Height); } @@ -118,7 +118,7 @@ class K4AYUY2ImageConverter : public K4AColorImageConverterBase @@ -165,7 +165,7 @@ class K4ANV12ImageConverter : public K4AColorImageConverterBase @@ -184,7 +184,7 @@ class K4ABGRA32ImageConverter : public K4AColorImageConverterBase @@ -220,8 +220,8 @@ class K4AMJPGImageConverter : public K4AColorImageConverterBase std::unique_ptr> -K4AColorImageConverterFactory::Create(k4a_color_resolution_t resolution) +K4AColorImageConverterFactory::Create(k4a_color_mode_info_t color_mode_info) { - return std14::make_unique(resolution); + return std14::make_unique(color_mode_info); } template<> std::unique_ptr> -K4AColorImageConverterFactory::Create(k4a_color_resolution_t resolution) +K4AColorImageConverterFactory::Create(k4a_color_mode_info_t color_mode_info) { - return std14::make_unique(resolution); + return std14::make_unique(color_mode_info); } template<> std::unique_ptr> -K4AColorImageConverterFactory::Create(k4a_color_resolution_t resolution) +K4AColorImageConverterFactory::Create(k4a_color_mode_info_t color_mode_info) { - return std14::make_unique(resolution); + return std14::make_unique(color_mode_info); } template<> std::unique_ptr> -K4AColorImageConverterFactory::Create(k4a_color_resolution_t resolution) +K4AColorImageConverterFactory::Create(k4a_color_mode_info_t color_mode_info) { - return std14::make_unique(resolution); + return std14::make_unique(color_mode_info); } diff --git a/tools/k4aviewer/k4acolorimageconverter.h b/tools/k4aviewer/k4acolorimageconverter.h index a74b18ff3..8c6b86c2d 100644 --- a/tools/k4aviewer/k4acolorimageconverter.h +++ b/tools/k4aviewer/k4acolorimageconverter.h @@ -25,24 +25,24 @@ class K4AColorImageConverterFactory { public: template - static std::unique_ptr> Create(k4a_color_resolution_t resolution); + static std::unique_ptr> Create(k4a_color_mode_info_t color_mode_info); }; template<> std::unique_ptr> -K4AColorImageConverterFactory::Create(k4a_color_resolution_t resolution); +K4AColorImageConverterFactory::Create(k4a_color_mode_info_t color_mode_info); template<> std::unique_ptr> -K4AColorImageConverterFactory::Create(k4a_color_resolution_t resolution); +K4AColorImageConverterFactory::Create(k4a_color_mode_info_t color_mode_info); template<> std::unique_ptr> -K4AColorImageConverterFactory::Create(k4a_color_resolution_t resolution); +K4AColorImageConverterFactory::Create(k4a_color_mode_info_t color_mode_info); template<> std::unique_ptr> -K4AColorImageConverterFactory::Create(k4a_color_resolution_t resolution); +K4AColorImageConverterFactory::Create(k4a_color_mode_info_t color_mode_info); } // namespace k4aviewer #endif diff --git a/tools/k4aviewer/k4adepthimageconverter.h b/tools/k4aviewer/k4adepthimageconverter.h index 744b99459..70d7adc24 100644 --- a/tools/k4aviewer/k4adepthimageconverter.h +++ b/tools/k4aviewer/k4adepthimageconverter.h @@ -23,8 +23,8 @@ class K4ADepthImageConverter : public K4ADepthImageConverterBase { public: - explicit K4ADepthImageConverter(k4a_depth_mode_t depthMode) : - K4ADepthImageConverterBase(depthMode, GetDepthModeRange(depthMode)) + explicit K4ADepthImageConverter(k4a_depth_mode_info_t depth_mode_info) : + K4ADepthImageConverterBase(depth_mode_info, GetDepthModeRange(depth_mode_info)) { } diff --git a/tools/k4aviewer/k4adepthimageconverterbase.h b/tools/k4aviewer/k4adepthimageconverterbase.h index a2bc90683..b70673be1 100644 --- a/tools/k4aviewer/k4adepthimageconverterbase.h +++ b/tools/k4aviewer/k4adepthimageconverterbase.h @@ -26,9 +26,9 @@ template { public: - explicit K4ADepthImageConverterBase(const k4a_depth_mode_t depthMode, + explicit K4ADepthImageConverterBase(const k4a_depth_mode_info_t depth_mode_info, const std::pair expectedValueRange) : - m_dimensions(GetDepthDimensions(depthMode)), + m_dimensions(GetDepthDimensions(depth_mode_info)), m_expectedValueRange(expectedValueRange), m_expectedBufferSize(static_cast(m_dimensions.Width * m_dimensions.Height) * sizeof(BgraPixel)) { diff --git a/tools/k4aviewer/k4adevicedockcontrol.cpp b/tools/k4aviewer/k4adevicedockcontrol.cpp index 8fe56879e..fb6801f3e 100644 --- a/tools/k4aviewer/k4adevicedockcontrol.cpp +++ b/tools/k4aviewer/k4adevicedockcontrol.cpp @@ -14,16 +14,22 @@ // Library headers // +#include +#include // Project headers // -#include "k4aaudiomanager.h" #include "k4aimguiextensions.h" #include "k4atypeoperators.h" #include "k4aviewererrormanager.h" #include "k4aviewerutil.h" #include "k4awindowmanager.h" +#ifdef K4A_INCLUDE_AUDIO +#include "k4aaudiomanager.h" +#endif +#include + using namespace k4aviewer; namespace @@ -271,7 +277,11 @@ void K4ADeviceDockControl::RefreshSyncCableStatus() bool K4ADeviceDockControl::DeviceIsStarted() const { +#ifdef K4A_INCLUDE_AUDIO return m_camerasStarted || m_imuStarted || (m_microphone && m_microphone->IsStarted()); +#else + return m_camerasStarted || m_imuStarted; +#endif } K4ADeviceDockControl::K4ADeviceDockControl(k4a::device &&device) : m_device(std::move(device)) @@ -281,7 +291,9 @@ K4ADeviceDockControl::K4ADeviceDockControl(k4a::device &&device) : m_device(std: m_deviceSerialNumber = m_device.get_serialnum(); m_windowTitle = m_deviceSerialNumber + ": Configuration"; +#ifdef K4A_INCLUDE_AUDIO m_microphone = K4AAudioManager::Instance().GetMicrophoneForDevice(m_deviceSerialNumber); +#endif LoadColorSettingsCache(); RefreshSyncCableStatus(); @@ -310,6 +322,7 @@ K4ADockControlStatus K4ADeviceDockControl::Show() const bool deviceIsStarted = DeviceIsStarted(); +#ifdef K4A_INCLUDE_AUDIO // Check microphone health // if (m_microphone && m_microphone->GetStatusCode() != SoundIoErrorNone) @@ -320,6 +333,7 @@ K4ADockControlStatus K4ADeviceDockControl::Show() StopMicrophone(); m_microphone->ClearStatusCode(); } +#endif // Draw controls // @@ -341,30 +355,48 @@ K4ADockControlStatus K4ADeviceDockControl::Show() if (ImGui::TreeNode("Depth Configuration")) { const bool depthSettingsEditable = !deviceIsStarted && m_config.EnableDepthCamera; - auto *pDepthMode = reinterpret_cast(&m_config.DepthMode); - ImGui::Text("Depth mode"); - depthModeUpdated |= ImGuiExtensions::K4ARadioButton("NFOV Binned", - pDepthMode, - K4A_DEPTH_MODE_NFOV_2X2BINNED, - depthSettingsEditable); - ImGui::SameLine(); - depthModeUpdated |= ImGuiExtensions::K4ARadioButton("NFOV Unbinned ", - pDepthMode, - K4A_DEPTH_MODE_NFOV_UNBINNED, - depthSettingsEditable); - // New line - depthModeUpdated |= ImGuiExtensions::K4ARadioButton("WFOV Binned", - pDepthMode, - K4A_DEPTH_MODE_WFOV_2X2BINNED, - depthSettingsEditable); - ImGui::SameLine(); - depthModeUpdated |= ImGuiExtensions::K4ARadioButton("WFOV Unbinned ", - pDepthMode, - K4A_DEPTH_MODE_WFOV_UNBINNED, - depthSettingsEditable); - // New line - depthModeUpdated |= - ImGuiExtensions::K4ARadioButton("Passive IR", pDepthMode, K4A_DEPTH_MODE_PASSIVE_IR, depthSettingsEditable); + auto *pDepthModeInfo = reinterpret_cast(&m_config.depth_mode_id); + + std::vector> depth_mode_items; + std::vector depth_modes = m_device.get_depth_modes(); + size_t depth_modes_size = depth_modes.size(); + for (size_t d = 1; d < depth_modes_size; d++) // Start at index = 1 (0 is off). + { + k4a_depth_mode_info_t depth_mode = depth_modes[d]; + int width = static_cast(depth_mode.width); + int height = static_cast(depth_mode.height); + float fov = depth_mode.horizontal_fov; + + std::string description = ""; + if (depth_mode.passive_ir_only) + { + description += "Passive IR"; + } + else + { + if (width < 1000) + { + description += " "; + } + if (height < 1000) + { + description += " "; + } + description += std::to_string(width) + "x"; + description += std::to_string(height) + ", "; + description += std::to_string(fov); + description += " Deg"; + } + + depth_mode_items.push_back({ depth_mode.mode_id, (const std::string)description }); + } + + depthModeUpdated |= ImGuiExtensions::K4AComboBox("##Depth", + "", + ImGuiComboFlags_None, + depth_mode_items, + pDepthModeInfo, + depthSettingsEditable); ImGui::TreePop(); } @@ -387,6 +419,7 @@ K4ADockControlStatus K4ADeviceDockControl::Show() bool colorFormatUpdated = false; auto *pColorFormat = reinterpret_cast(&m_config.ColorFormat); + ImGui::Text("Format"); colorFormatUpdated |= ImGuiExtensions::K4ARadioButton("BGRA", pColorFormat, K4A_IMAGE_FORMAT_COLOR_BGRA32, colorSettingsEditable); @@ -401,70 +434,54 @@ K4ADockControlStatus K4ADeviceDockControl::Show() ImGuiExtensions::K4ARadioButton("YUY2", pColorFormat, K4A_IMAGE_FORMAT_COLOR_YUY2, colorSettingsEditable); // Uncompressed formats are only supported at 720p. - // - const char *imageFormatHelpMessage = "Not supported in NV12 or YUY2 mode!"; + const bool imageFormatSupportsHighResolution = m_config.ColorFormat != K4A_IMAGE_FORMAT_COLOR_NV12 && m_config.ColorFormat != K4A_IMAGE_FORMAT_COLOR_YUY2; if (colorFormatUpdated || m_firstRun) { if (!imageFormatSupportsHighResolution) { - m_config.ColorResolution = K4A_COLOR_RESOLUTION_720P; + m_config.color_mode_id = K4A_COLOR_RESOLUTION_720P; + K4AViewerLogManager::Instance() + .Log(K4A_LOG_LEVEL_WARNING, + __FILE__, + __LINE__, + "The selected image format only supports color mode resolution up to 720p."); } } - auto *pColorResolution = reinterpret_cast(&m_config.ColorResolution); + auto *pColorModeInfo = reinterpret_cast(&m_config.color_mode_id); ImGui::Text("Resolution"); - ImGui::Indent(); - ImGui::Text("16:9"); - ImGui::Indent(); - colorResolutionUpdated |= ImGuiExtensions::K4ARadioButton(" 720p", - pColorResolution, - K4A_COLOR_RESOLUTION_720P, - colorSettingsEditable); - ImGui::SameLine(); - colorResolutionUpdated |= ImGuiExtensions::K4ARadioButton("1080p", - pColorResolution, - K4A_COLOR_RESOLUTION_1080P, - colorSettingsEditable && - imageFormatSupportsHighResolution); - ImGuiExtensions::K4AShowTooltip(imageFormatHelpMessage, !imageFormatSupportsHighResolution); - // New line - colorResolutionUpdated |= ImGuiExtensions::K4ARadioButton("1440p", - pColorResolution, - K4A_COLOR_RESOLUTION_1440P, - colorSettingsEditable && - imageFormatSupportsHighResolution); - ImGuiExtensions::K4AShowTooltip(imageFormatHelpMessage, !imageFormatSupportsHighResolution); - ImGui::SameLine(); - colorResolutionUpdated |= ImGuiExtensions::K4ARadioButton("2160p", - pColorResolution, - K4A_COLOR_RESOLUTION_2160P, - colorSettingsEditable && - imageFormatSupportsHighResolution); - ImGuiExtensions::K4AShowTooltip(imageFormatHelpMessage, !imageFormatSupportsHighResolution); - ImGui::Unindent(); - ImGui::Text("4:3"); - ImGui::Indent(); - - colorResolutionUpdated |= ImGuiExtensions::K4ARadioButton("1536p", - pColorResolution, - K4A_COLOR_RESOLUTION_1536P, - colorSettingsEditable && - imageFormatSupportsHighResolution); - ImGuiExtensions::K4AShowTooltip(imageFormatHelpMessage, !imageFormatSupportsHighResolution); - ImGui::SameLine(); - colorResolutionUpdated |= ImGuiExtensions::K4ARadioButton("3072p", - pColorResolution, - K4A_COLOR_RESOLUTION_3072P, - colorSettingsEditable && - imageFormatSupportsHighResolution); - ImGuiExtensions::K4AShowTooltip(imageFormatHelpMessage, !imageFormatSupportsHighResolution); - - ImGui::Unindent(); - ImGui::Unindent(); + std::vector> color_mode_items; + std::vector color_modes = m_device.get_color_modes(); + size_t color_modes_size = color_modes.size(); + for (size_t c = 1; c < color_modes_size; c++) // Start at index = 1 (0 is off). + { + k4a_color_mode_info_t color_mode = color_modes[c]; + int width = static_cast(color_mode.width); + int height = static_cast(color_mode.height); + int common_factor = math_get_common_factor(width, height); + + std::string description = ""; + if (height < 1000) + { + description += " "; + } + description += std::to_string(height) + "p "; + description += std::to_string(width / common_factor) + ":" + std::to_string(height / common_factor); + + color_mode_items.push_back({ color_mode.mode_id, (const std::string)description }); + } + + colorResolutionUpdated |= ImGuiExtensions::K4AComboBox("##Resolution", + "", + ImGuiComboFlags_None, + color_mode_items, + pColorModeInfo, + colorSettingsEditable); + ImGui::TreePop(); } if (ImGui::TreeNode("Color Controls")) @@ -606,40 +623,63 @@ K4ADockControlStatus K4ADeviceDockControl::Show() if (colorResolutionUpdated || m_firstRun) { - if (m_config.ColorResolution == K4A_COLOR_RESOLUTION_3072P) + if (m_config.color_mode_id == K4A_COLOR_RESOLUTION_3072P) { - // 4K supports up to 15FPS - // - m_config.Framerate = K4A_FRAMES_PER_SECOND_15; + K4AViewerLogManager::Instance().Log(K4A_LOG_LEVEL_WARNING, + __FILE__, + __LINE__, + "The selected color mode only supports up to 15 FPS."); } } if (depthModeUpdated || m_firstRun) { - if (m_config.DepthMode == K4A_DEPTH_MODE_WFOV_UNBINNED) + if (m_config.depth_mode_id == K4A_DEPTH_MODE_WFOV_UNBINNED) { - m_config.Framerate = K4A_FRAMES_PER_SECOND_15; + m_config.fps_mode_id = K4A_FRAMES_PER_SECOND_15; + K4AViewerLogManager::Instance().Log(K4A_LOG_LEVEL_WARNING, + __FILE__, + __LINE__, + "The selected depth mode only supports up to 15 FPS."); } } - const bool supports30fps = !(m_config.EnableColorCamera && - m_config.ColorResolution == K4A_COLOR_RESOLUTION_3072P) && - !(m_config.EnableDepthCamera && m_config.DepthMode == K4A_DEPTH_MODE_WFOV_UNBINNED); + // TODO: Uncomment supports30fps if it is going to be used. + // It is commented out for now to allow compilation in Linux without warning/error. + // const bool supports30fps = !(m_config.EnableColorCamera && m_config.color_mode_id == K4A_COLOR_RESOLUTION_3072P) + // && + // !(m_config.EnableDepthCamera && m_config.depth_mode_id == + // K4A_DEPTH_MODE_WFOV_UNBINNED); const bool enableFramerate = !deviceIsStarted && (m_config.EnableColorCamera || m_config.EnableDepthCamera); - ImGui::Text("Framerate"); - auto *pFramerate = reinterpret_cast(&m_config.Framerate); bool framerateUpdated = false; - framerateUpdated |= ImGuiExtensions::K4ARadioButton("30 FPS", - pFramerate, - K4A_FRAMES_PER_SECOND_30, - enableFramerate && supports30fps); - ImGuiExtensions::K4AShowTooltip("Not supported with WFOV Unbinned or 3072p!", !supports30fps); - ImGui::SameLine(); - framerateUpdated |= - ImGuiExtensions::K4ARadioButton("15 FPS", pFramerate, K4A_FRAMES_PER_SECOND_15, enableFramerate); - ImGui::SameLine(); - framerateUpdated |= ImGuiExtensions::K4ARadioButton(" 5 FPS", pFramerate, K4A_FRAMES_PER_SECOND_5, enableFramerate); + + auto *pFPSModeInfo = reinterpret_cast(&m_config.fps_mode_id); + + ImGui::Text("Framerate"); + + ImGui::Indent(); + + std::vector> fps_mode_items; + std::vector fps_modes = m_device.get_fps_modes(); + size_t fps_modes_size = fps_modes.size(); + for (size_t f = 1; f < fps_modes_size; f++) // Start at index 1; index 0 is reserved for 0 FPS. + { + k4a_fps_mode_info_t fps_mode = fps_modes[f]; + int fps = (int)fps_mode.fps; + std::string description = std::to_string(fps) + " FPS"; + + fps_mode_items.push_back({ fps_mode.mode_id, (const std::string)description }); + } + + framerateUpdated |= ImGuiExtensions::K4AComboBox("##Framerate", + "", + ImGuiComboFlags_None, + fps_mode_items, + pFPSModeInfo, + enableFramerate); + + ImGui::Unindent(); ImGuiExtensions::K4ACheckbox("Disable streaming LED", &m_config.DisableStreamingIndicator, !deviceIsStarted); @@ -653,6 +693,7 @@ K4ADockControlStatus K4ADeviceDockControl::Show() const bool synchronizedImagesAvailable = m_config.EnableColorCamera && m_config.EnableDepthCamera; m_config.SynchronizedImagesOnly &= synchronizedImagesAvailable; +#ifdef K4A_INCLUDE_AUDIO if (m_microphone) { ImGuiExtensions::K4ACheckbox("Enable Microphone", &m_config.EnableMicrophone, !deviceIsStarted); @@ -662,6 +703,7 @@ K4ADockControlStatus K4ADeviceDockControl::Show() m_config.EnableMicrophone = false; ImGui::Text("Microphone not detected!"); } +#endif ImGui::Separator(); @@ -680,26 +722,18 @@ K4ADockControlStatus K4ADeviceDockControl::Show() nullptr, "%d", !deviceIsStarted); + if (framerateUpdated || depthDelayUpdated) { // InputScalar doesn't do bounds-checks, so we have to do it ourselves whenever // the user interacts with the control - // - int maxDepthDelay = 0; - switch (m_config.Framerate) + uint32_t fps_int = m_config.fps_mode_id; + if (fps_int == 0) { - case K4A_FRAMES_PER_SECOND_30: - maxDepthDelay = std::micro::den / 30; - break; - case K4A_FRAMES_PER_SECOND_15: - maxDepthDelay = std::micro::den / 15; - break; - case K4A_FRAMES_PER_SECOND_5: - maxDepthDelay = std::micro::den / 5; - break; - default: throw std::logic_error("Invalid framerate!"); } + + int maxDepthDelay = std::micro::den / fps_int; m_config.DepthDelayOffColorUsec = std::max(m_config.DepthDelayOffColorUsec, -maxDepthDelay); m_config.DepthDelayOffColorUsec = std::min(m_config.DepthDelayOffColorUsec, maxDepthDelay); } @@ -826,7 +860,7 @@ K4ADockControlStatus K4ADeviceDockControl::Show() ImGui::Separator(); const bool pointCloudViewerAvailable = m_config.EnableDepthCamera && - m_config.DepthMode != K4A_DEPTH_MODE_PASSIVE_IR && m_camerasStarted; + m_config.depth_mode_id != K4A_DEPTH_MODE_PASSIVE_IR && m_camerasStarted; K4AWindowSet::ShowModeSelector(&m_currentViewType, true, @@ -866,10 +900,13 @@ void K4ADeviceDockControl::Start() StartImu(); } } + +#ifdef K4A_INCLUDE_AUDIO if (m_config.EnableMicrophone) { StartMicrophone(); } +#endif SetViewType(K4AWindowSet::ViewType::Normal); m_paused = false; @@ -881,7 +918,10 @@ void K4ADeviceDockControl::Stop() StopCameras(); StopImu(); + +#ifdef K4A_INCLUDE_AUDIO StopMicrophone(); +#endif } bool K4ADeviceDockControl::StartCameras() @@ -891,7 +931,7 @@ bool K4ADeviceDockControl::StartCameras() return false; } - k4a_device_configuration_t deviceConfig = m_config.ToK4ADeviceConfiguration(); + k4a_device_configuration_t deviceConfig = m_config.ToK4ADeviceConfiguration(&m_device); try { @@ -951,6 +991,7 @@ void K4ADeviceDockControl::StopCameras() &m_camerasAbortInProgress); } +#ifdef K4A_INCLUDE_AUDIO bool K4ADeviceDockControl::StartMicrophone() { if (!m_microphone) @@ -985,6 +1026,7 @@ void K4ADeviceDockControl::StopMicrophone() m_microphone->Stop(); } } +#endif bool K4ADeviceDockControl::StartImu() { @@ -1054,6 +1096,7 @@ void K4ADeviceDockControl::SetViewType(K4AWindowSet::ViewType viewType) { K4AWindowManager::Instance().ClearWindows(); +#ifdef K4A_INCLUDE_AUDIO std::shared_ptr micListener = nullptr; if (m_config.EnableMicrophone) { @@ -1065,6 +1108,10 @@ void K4ADeviceDockControl::SetViewType(K4AWindowSet::ViewType viewType) K4AViewerErrorManager::Instance().SetErrorStatus(errorBuilder.str()); } } +#endif + + k4a_depth_mode_info_t depth_mode_info = m_device.get_depth_mode(m_config.depth_mode_id); + k4a_color_mode_info_t color_mode_info = m_device.get_color_mode(m_config.color_mode_id); switch (viewType) { @@ -1072,22 +1119,25 @@ void K4ADeviceDockControl::SetViewType(K4AWindowSet::ViewType viewType) K4AWindowSet::StartNormalWindows(m_deviceSerialNumber.c_str(), &m_cameraDataSource, m_config.EnableImu ? &m_imuDataSource : nullptr, +#ifdef K4A_INCLUDE_AUDIO std::move(micListener), +#endif m_config.EnableDepthCamera, - m_config.DepthMode, + depth_mode_info, m_config.EnableColorCamera, m_config.ColorFormat, - m_config.ColorResolution); + color_mode_info); break; case K4AWindowSet::ViewType::PointCloudViewer: try { - k4a::calibration calib = m_device.get_calibration(m_config.DepthMode, m_config.ColorResolution); + k4a::calibration calib = m_device.get_calibration(depth_mode_info.mode_id, color_mode_info.mode_id); bool rgbPointCloudAvailable = m_config.EnableColorCamera && m_config.ColorFormat == K4A_IMAGE_FORMAT_COLOR_BGRA32; K4AWindowSet::StartPointCloudWindow(m_deviceSerialNumber.c_str(), calib, + depth_mode_info, &m_cameraDataSource, rgbPointCloudAvailable); } @@ -1116,4 +1166,4 @@ void K4ADeviceDockControl::ResetDefaultConfiguration() { m_config = K4ADeviceConfiguration(); SaveDefaultConfiguration(); -} +} \ No newline at end of file diff --git a/tools/k4aviewer/k4adevicedockcontrol.h b/tools/k4aviewer/k4adevicedockcontrol.h index 04bce8026..08caac83f 100644 --- a/tools/k4aviewer/k4adevicedockcontrol.h +++ b/tools/k4aviewer/k4adevicedockcontrol.h @@ -16,11 +16,14 @@ // #include "ik4adockcontrol.h" #include "k4adatasource.h" -#include "k4amicrophone.h" #include "k4apollingthread.h" #include "k4aviewersettingsmanager.h" #include "k4awindowset.h" +#ifdef K4A_INCLUDE_AUDIO +#include "k4amicrophone.h" +#endif + namespace k4aviewer { class K4ADeviceDockControl : public IK4ADockControl @@ -84,8 +87,10 @@ class K4ADeviceDockControl : public IK4ADockControl bool StartCameras(); void StopCameras(); +#ifdef K4A_INCLUDE_AUDIO bool StartMicrophone(); void StopMicrophone(); +#endif bool StartImu(); void StopImu(); @@ -110,7 +115,10 @@ class K4ADeviceDockControl : public IK4ADockControl bool m_imuAbortInProgress = false; std::string m_deviceSerialNumber; + +#ifdef K4A_INCLUDE_AUDIO std::shared_ptr m_microphone; +#endif K4ADataSource m_cameraDataSource; K4ADataSource m_imuDataSource; diff --git a/tools/k4aviewer/k4ainfraredimageconverter.h b/tools/k4aviewer/k4ainfraredimageconverter.h index a02fb598e..9d402285f 100644 --- a/tools/k4aviewer/k4ainfraredimageconverter.h +++ b/tools/k4aviewer/k4ainfraredimageconverter.h @@ -21,10 +21,10 @@ class K4AInfraredImageConverter : public K4ADepthImageConverterBase { public: - explicit K4AInfraredImageConverter(k4a_depth_mode_t depthMode) : - K4ADepthImageConverterBase(depthMode, - GetIrLevels( - depthMode)){}; + explicit K4AInfraredImageConverter(k4a_depth_mode_info_t depth_mode_info) : + K4ADepthImageConverterBase( + depth_mode_info, + GetIrLevels(depth_mode_info)){}; ~K4AInfraredImageConverter() override = default; diff --git a/tools/k4aviewer/k4apointcloudvisualizer.cpp b/tools/k4aviewer/k4apointcloudvisualizer.cpp index 8e8b75af5..3cd64370b 100644 --- a/tools/k4aviewer/k4apointcloudvisualizer.cpp +++ b/tools/k4aviewer/k4apointcloudvisualizer.cpp @@ -172,12 +172,13 @@ void K4APointCloudVisualizer::SetPointSize(int size) } K4APointCloudVisualizer::K4APointCloudVisualizer(const bool enableColorPointCloud, - const k4a::calibration &calibrationData) : + const k4a::calibration &calibrationData, + k4a_depth_mode_info_t depth_mode_info) : m_dimensions(PointCloudVisualizerTextureDimensions), m_enableColorPointCloud(enableColorPointCloud), m_calibrationData(calibrationData) { - m_expectedValueRange = GetDepthModeRange(m_calibrationData.depth_mode); + m_expectedValueRange = GetDepthModeRange(depth_mode_info); m_transformation = k4a::transformation(m_calibrationData); glBindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer.Id()); diff --git a/tools/k4aviewer/k4apointcloudvisualizer.h b/tools/k4aviewer/k4apointcloudvisualizer.h index 2d41a98fd..3a937c863 100644 --- a/tools/k4aviewer/k4apointcloudvisualizer.h +++ b/tools/k4aviewer/k4apointcloudvisualizer.h @@ -57,7 +57,9 @@ class K4APointCloudVisualizer PointCloudVisualizationResult SetColorizationStrategy(ColorizationStrategy strategy); void SetPointSize(int size); - K4APointCloudVisualizer(bool enableColorPointCloud, const k4a::calibration &calibrationData); + K4APointCloudVisualizer(bool enableColorPointCloud, + const k4a::calibration &calibrationData, + k4a_depth_mode_info_t depth_mode_info); ~K4APointCloudVisualizer() = default; K4APointCloudVisualizer(const K4APointCloudVisualizer &) = delete; diff --git a/tools/k4aviewer/k4apointcloudwindow.cpp b/tools/k4aviewer/k4apointcloudwindow.cpp index eb3fc1f3e..6a338ba84 100644 --- a/tools/k4aviewer/k4apointcloudwindow.cpp +++ b/tools/k4aviewer/k4apointcloudwindow.cpp @@ -132,9 +132,10 @@ const char *K4APointCloudWindow::GetTitle() const K4APointCloudWindow::K4APointCloudWindow(std::string &&windowTitle, bool enableColorPointCloud, std::shared_ptr &&captureSource, - const k4a::calibration &calibrationData) : + const k4a::calibration &calibrationData, + k4a_depth_mode_info_t depth_mode_info) : m_title(std::move(windowTitle)), - m_pointCloudVisualizer(enableColorPointCloud, calibrationData), + m_pointCloudVisualizer(enableColorPointCloud, calibrationData, depth_mode_info), m_captureSource(std::move(captureSource)), m_pointSize(DefaultPointSize), m_enableColorPointCloud(enableColorPointCloud) diff --git a/tools/k4aviewer/k4apointcloudwindow.h b/tools/k4aviewer/k4apointcloudwindow.h index 8ebb4aa0c..902d42582 100644 --- a/tools/k4aviewer/k4apointcloudwindow.h +++ b/tools/k4aviewer/k4apointcloudwindow.h @@ -28,7 +28,8 @@ class K4APointCloudWindow : public IK4AVisualizationWindow K4APointCloudWindow(std::string &&windowTitle, bool enableColorPointCloud, std::shared_ptr &&captureSource, - const k4a::calibration &calibrationData); + const k4a::calibration &calibrationData, + k4a_depth_mode_info_t depth_mode_info); ~K4APointCloudWindow() override = default; K4APointCloudWindow(const K4APointCloudWindow &) = delete; diff --git a/tools/k4aviewer/k4arecordingdockcontrol.cpp b/tools/k4aviewer/k4arecordingdockcontrol.cpp index f5e21b656..50c94cb07 100644 --- a/tools/k4aviewer/k4arecordingdockcontrol.cpp +++ b/tools/k4aviewer/k4arecordingdockcontrol.cpp @@ -22,6 +22,8 @@ #include "k4aviewerutil.h" #include "k4awindowmanager.h" #include "k4aimugraphdatagenerator.h" +#include +#include using namespace k4aviewer; namespace @@ -49,24 +51,14 @@ K4ARecordingDockControl::K4ARecordingDockControl(std::string &&path, k4a::playba // m_recordConfiguration = recording.get_record_configuration(); std::stringstream fpsSS; - fpsSS << m_recordConfiguration.camera_fps; - m_fpsLabel = fpsSS.str(); - switch (m_recordConfiguration.camera_fps) - { - case K4A_FRAMES_PER_SECOND_5: - m_playbackThreadState.TimePerFrame = std::chrono::microseconds(std::micro::den / (std::micro::num * 5)); - break; + fpsSS << m_recordConfiguration.fps_mode_info.fps; - case K4A_FRAMES_PER_SECOND_15: - m_playbackThreadState.TimePerFrame = std::chrono::microseconds(std::micro::den / (std::micro::num * 15)); - break; + m_fpsLabel = fpsSS.str(); - case K4A_FRAMES_PER_SECOND_30: - default: - m_playbackThreadState.TimePerFrame = std::chrono::microseconds(std::micro::den / (std::micro::num * 30)); - break; - } + // Get fps value from the fps mode. + uint32_t fps_int = m_recordConfiguration.fps_mode_info.mode_id; + m_playbackThreadState.TimePerFrame = std::chrono::microseconds(std::micro::den / (std::micro::num * fps_int)); constexpr char noneStr[] = "(None)"; @@ -77,7 +69,18 @@ K4ARecordingDockControl::K4ARecordingDockControl(std::string &&path, k4a::playba std::stringstream depthSS; if (m_recordingHasDepth || m_recordingHasIR) { - depthSS << m_recordConfiguration.depth_mode; + int width = static_cast(m_recordConfiguration.depth_mode_info.width); + int height = static_cast(m_recordConfiguration.depth_mode_info.height); + float fov = m_recordConfiguration.depth_mode_info.horizontal_fov; + + if (m_recordConfiguration.depth_mode_info.passive_ir_only) + { + depthSS << "Passive IR"; + } + else + { + depthSS << std::to_string(width) << "x" << std::to_string(height) << ", " << std::to_string(fov) << " Deg"; + } } else { @@ -91,7 +94,13 @@ K4ARecordingDockControl::K4ARecordingDockControl(std::string &&path, k4a::playba if (m_recordingHasColor) { colorFormatSS << m_recordConfiguration.color_format; - colorResolutionSS << m_recordConfiguration.color_resolution; + + int width = static_cast(m_recordConfiguration.color_mode_info.width); + int height = static_cast(m_recordConfiguration.color_mode_info.height); + int common_factor = math_get_common_factor(width, height); + + colorResolutionSS << (height < 1000 ? " " : "") << std::to_string(height) << "p " + << std::to_string(width / common_factor) << ":" << std::to_string(height / common_factor); recording.set_color_conversion(K4A_IMAGE_FORMAT_COLOR_BGRA32); m_recordConfiguration.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32; @@ -133,6 +142,14 @@ K4ARecordingDockControl::K4ARecordingDockControl(std::string &&path, k4a::playba K4ADockControlStatus K4ARecordingDockControl::Show() { + bool hasColorDevice = false; + bool hasDepthDevice = false; + bool hasIMUDevice = false; + + hasDepthDevice = (m_recordConfiguration.device_info.capabilities.bitmap.bHasDepth == 1); + hasColorDevice = (m_recordConfiguration.device_info.capabilities.bitmap.bHasColor == 1); + hasIMUDevice = (m_recordConfiguration.device_info.capabilities.bitmap.bHasIMU == 1); + ImGui::TextUnformatted(m_filenameLabel.c_str()); ImGui::SameLine(); ImGuiExtensions::ButtonColorChanger cc(ImGuiExtensions::ButtonColor::Red); @@ -146,14 +163,31 @@ K4ADockControlStatus K4ARecordingDockControl::Show() ImGui::TextUnformatted("Recording Settings"); ImGui::Text("FPS: %s", m_fpsLabel.c_str()); - ImGui::Text("Depth mode: %s", m_depthModeLabel.c_str()); - ImGui::Text("Color format: %s", m_colorFormatLabel.c_str()); - ImGui::Text("Color resolution: %s", m_colorResolutionLabel.c_str()); - ImGui::Text("IMU enabled: %s", m_recordConfiguration.imu_track_enabled ? "Yes" : "No"); + + if (hasDepthDevice) + { + ImGui::Text("Depth mode: %s", m_depthModeLabel.c_str()); + } + + if (hasColorDevice) + { + ImGui::Text("Color format: %s", m_colorFormatLabel.c_str()); + ImGui::Text("Color resolution: %s", m_colorResolutionLabel.c_str()); + } + + if (hasIMUDevice) + { + ImGui::Text("IMU enabled: %s", m_recordConfiguration.imu_track_enabled ? "Yes" : "No"); + } + ImGui::Separator(); ImGui::TextUnformatted("Sync settings"); - ImGui::Text("Depth/color delay (us): %d", m_depthDelayOffColorUsec); + + std::string delay_description = hasColorDevice && hasDepthDevice ? "Depth/color" : + hasDepthDevice ? "Depth" : "Color"; + ImGui::Text("%s delay (us): %d", delay_description.c_str(), m_depthDelayOffColorUsec); + ImGui::Text("Sync mode: %s", m_wiredSyncModeLabel.c_str()); ImGui::Text("Subordinate delay (us): %d", m_subordinateDelayOffMasterUsec); ImGui::Text("Start timestamp offset: %d", m_startTimestampOffsetUsec); @@ -162,8 +196,17 @@ K4ADockControlStatus K4ARecordingDockControl::Show() ImGui::TextUnformatted("Device info"); ImGui::Text("Device S/N: %s", m_deviceSerialNumber.c_str()); - ImGui::Text("RGB camera FW: %s", m_colorFirmwareVersion.c_str()); - ImGui::Text("Depth camera FW: %s", m_depthFirmwareVersion.c_str()); + + if (hasColorDevice) + { + ImGui::Text("RGB camera FW: %s", m_colorFirmwareVersion.c_str()); + } + + if (hasDepthDevice) + { + ImGui::Text("Depth camera FW: %s", m_depthFirmwareVersion.c_str()); + } + ImGui::Separator(); if (!m_playbackThread->IsRunning()) @@ -465,20 +508,26 @@ void K4ARecordingDockControl::SetViewType(K4AWindowSet::ViewType viewType) K4AWindowSet::StartNormalWindows(m_filenameLabel.c_str(), &m_playbackThreadState.CaptureDataSource, imuDataSource, +#ifdef K4A_INCLUDE_AUDIO nullptr, // Audio source - sound is not supported in recordings +#endif m_recordingHasDepth || m_recordingHasIR, - m_recordConfiguration.depth_mode, + m_recordConfiguration.depth_mode_info, m_recordingHasColor, m_recordConfiguration.color_format, - m_recordConfiguration.color_resolution); + m_recordConfiguration.color_mode_info); break; case K4AWindowSet::ViewType::PointCloudViewer: try { k4a::calibration calibration = m_playbackThreadState.Recording.get_calibration(); + k4a_record_configuration_t record_configuration = + m_playbackThreadState.Recording.get_record_configuration(); + k4a_depth_mode_info_t depth_mode_info = record_configuration.depth_mode_info; K4AWindowSet::StartPointCloudWindow(m_filenameLabel.c_str(), std::move(calibration), + depth_mode_info, &m_playbackThreadState.CaptureDataSource, m_recordConfiguration.color_track_enabled); } diff --git a/tools/k4aviewer/k4asourceselectiondockcontrol.cpp b/tools/k4aviewer/k4asourceselectiondockcontrol.cpp index 812608b0c..e49e619ec 100644 --- a/tools/k4aviewer/k4asourceselectiondockcontrol.cpp +++ b/tools/k4aviewer/k4asourceselectiondockcontrol.cpp @@ -18,13 +18,16 @@ // Project headers // #include "filesystem17.h" -#include "k4aaudiomanager.h" #include "k4aimguiextensions.h" #include "k4aviewererrormanager.h" #include "k4arecordingdockcontrol.h" #include "k4aviewerutil.h" #include "k4awindowmanager.h" +#ifdef K4A_INCLUDE_AUDIO +#include "k4aaudiomanager.h" +#endif + using namespace k4aviewer; K4ASourceSelectionDockControl::K4ASourceSelectionDockControl() @@ -108,6 +111,7 @@ void K4ASourceSelectionDockControl::RefreshDevices() m_selectedDevice = m_connectedDevices[0].first; } +#ifdef K4A_INCLUDE_AUDIO const int audioRefreshStatus = K4AAudioManager::Instance().RefreshDevices(); if (audioRefreshStatus != SoundIoErrorNone) { @@ -117,6 +121,7 @@ void K4ASourceSelectionDockControl::RefreshDevices() K4AViewerErrorManager::Instance().SetErrorStatus(errorBuilder.str()); } +#endif } void K4ASourceSelectionDockControl::OpenDevice() diff --git a/tools/k4aviewer/k4asourceselectiondockcontrol.h b/tools/k4aviewer/k4asourceselectiondockcontrol.h index 153e21173..40b089a78 100644 --- a/tools/k4aviewer/k4asourceselectiondockcontrol.h +++ b/tools/k4aviewer/k4asourceselectiondockcontrol.h @@ -29,6 +29,7 @@ class K4ASourceSelectionDockControl : public IK4ADockControl ~K4ASourceSelectionDockControl() override = default; K4ADockControlStatus Show() override; + static int SelectedDevice; K4ASourceSelectionDockControl(const K4ASourceSelectionDockControl &) = delete; K4ASourceSelectionDockControl(const K4ASourceSelectionDockControl &&) = delete; @@ -41,8 +42,8 @@ class K4ASourceSelectionDockControl : public IK4ADockControl void OpenDevice(); void OpenRecording(const std17::filesystem::path &path); - int m_selectedDevice = -1; std::vector> m_connectedDevices; + int m_selectedDevice; K4AFilePicker m_filePicker; }; diff --git a/tools/k4aviewer/k4astaticimageproperties.h b/tools/k4aviewer/k4astaticimageproperties.h index 053742edb..a73bff782 100644 --- a/tools/k4aviewer/k4astaticimageproperties.h +++ b/tools/k4aviewer/k4astaticimageproperties.h @@ -8,6 +8,8 @@ #include #include +#include +#include "k4asourceselectiondockcontrol.h" namespace k4aviewer { @@ -15,69 +17,30 @@ namespace k4aviewer // Gets the dimensions of the color images that the color camera will produce for a // given color resolution // -inline std::pair GetColorDimensions(const k4a_color_resolution_t resolution) +inline std::pair GetColorDimensions(k4a_color_mode_info_t color_mode_info) { - switch (resolution) - { - case K4A_COLOR_RESOLUTION_720P: - return { 1280, 720 }; - case K4A_COLOR_RESOLUTION_2160P: - return { 3840, 2160 }; - case K4A_COLOR_RESOLUTION_1440P: - return { 2560, 1440 }; - case K4A_COLOR_RESOLUTION_1080P: - return { 1920, 1080 }; - case K4A_COLOR_RESOLUTION_3072P: - return { 4096, 3072 }; - case K4A_COLOR_RESOLUTION_1536P: - return { 2048, 1536 }; - - default: - throw std::logic_error("Invalid color dimensions value!"); - } + return { (int)color_mode_info.width, (int)color_mode_info.height }; } // Gets the dimensions of the depth images that the depth camera will produce for a // given depth mode // -inline std::pair GetDepthDimensions(const k4a_depth_mode_t depthMode) +inline std::pair GetDepthDimensions(k4a_depth_mode_info_t depth_mode_info) { - switch (depthMode) - { - case K4A_DEPTH_MODE_NFOV_2X2BINNED: - return { 320, 288 }; - case K4A_DEPTH_MODE_NFOV_UNBINNED: - return { 640, 576 }; - case K4A_DEPTH_MODE_WFOV_2X2BINNED: - return { 512, 512 }; - case K4A_DEPTH_MODE_WFOV_UNBINNED: - return { 1024, 1024 }; - case K4A_DEPTH_MODE_PASSIVE_IR: - return { 1024, 1024 }; - - default: - throw std::logic_error("Invalid depth dimensions value!"); - } + return { (int)depth_mode_info.width, (int)depth_mode_info.height }; } // Gets the range of values that we expect to see from the depth camera // when using a given depth mode, in millimeters // -inline std::pair GetDepthModeRange(const k4a_depth_mode_t depthMode) +inline std::pair GetDepthModeRange(k4a_depth_mode_info_t depth_mode_info) { - switch (depthMode) + if (!depth_mode_info.passive_ir_only) + { + return { (uint16_t)depth_mode_info.min_range, (uint16_t)depth_mode_info.max_range }; + } + else { - case K4A_DEPTH_MODE_NFOV_2X2BINNED: - return { (uint16_t)500, (uint16_t)5800 }; - case K4A_DEPTH_MODE_NFOV_UNBINNED: - return { (uint16_t)500, (uint16_t)4000 }; - case K4A_DEPTH_MODE_WFOV_2X2BINNED: - return { (uint16_t)250, (uint16_t)3000 }; - case K4A_DEPTH_MODE_WFOV_UNBINNED: - return { (uint16_t)250, (uint16_t)2500 }; - - case K4A_DEPTH_MODE_PASSIVE_IR: - default: throw std::logic_error("Invalid depth mode!"); } } @@ -85,17 +48,18 @@ inline std::pair GetDepthModeRange(const k4a_depth_mode_t de // Gets the expected min/max IR brightness levels that we expect to see // from the IR camera when using a given depth mode // -inline std::pair GetIrLevels(const k4a_depth_mode_t depthMode) +inline std::pair GetIrLevels(k4a_depth_mode_info_t depth_mode_info) { - switch (depthMode) + if (depth_mode_info.mode_id == K4A_DEPTH_MODE_OFF) { - case K4A_DEPTH_MODE_PASSIVE_IR: - return { (uint16_t)0, (uint16_t)100 }; - - case K4A_DEPTH_MODE_OFF: throw std::logic_error("Invalid depth mode!"); - - default: + } + else if (depth_mode_info.passive_ir_only) + { + return { (uint16_t)depth_mode_info.min_range, (uint16_t)depth_mode_info.max_range }; + } + else + { return { (uint16_t)0, (uint16_t)1000 }; } } diff --git a/tools/k4aviewer/k4atypeoperators.cpp b/tools/k4aviewer/k4atypeoperators.cpp index d4cb60b79..28433a17b 100644 --- a/tools/k4aviewer/k4atypeoperators.cpp +++ b/tools/k4aviewer/k4atypeoperators.cpp @@ -34,6 +34,8 @@ std::ostream &operator<<(std::ostream &s, const k4a_result_t &val) return s << "K4A_RESULT_SUCCEEDED"; case K4A_RESULT_FAILED: return s << "K4A_RESULT_FAILED"; + case K4A_RESULT_UNSUPPORTED: + return s << "K4A_RESULT_UNSUPPORTED"; } return s; } @@ -48,6 +50,8 @@ std::ostream &operator<<(std::ostream &s, const k4a_wait_result_t &val) return s << "K4A_WAIT_RESULT_FAILED"; case K4A_WAIT_RESULT_TIMEOUT: return s << "K4A_WAIT_RESULT_TIMEOUT"; + case K4A_WAIT_RESULT_UNSUPPORTED: + return s << "K4A_WAIT_RESULT_UNSUPPORTED"; } return s; } @@ -62,6 +66,8 @@ std::ostream &operator<<(std::ostream &s, const k4a_buffer_result_t &val) return s << "K4A_BUFFER_RESULT_FAILED"; case K4A_BUFFER_RESULT_TOO_SMALL: return s << "K4A_BUFFER_RESULT_TOO_SMALL"; + case K4A_BUFFER_RESULT_UNSUPPORTED: + return s << "K4A_BUFFER_RESULT_UNSUPPORTED"; } return s; } @@ -143,209 +149,6 @@ std::istream &operator>>(std::istream &s, k4a_wired_sync_mode_t &val) return s; } -namespace -{ -constexpr char FramesPerSecond5[] = "K4A_FRAMES_PER_SECOND_5"; -constexpr char FramesPerSecond15[] = "K4A_FRAMES_PER_SECOND_15"; -constexpr char FramesPerSecond30[] = "K4A_FRAMES_PER_SECOND_30"; -} // namespace - -std::ostream &operator<<(std::ostream &s, const k4a_fps_t &val) -{ - switch (val) - { - case K4A_FRAMES_PER_SECOND_5: - s << FramesPerSecond5; - break; - case K4A_FRAMES_PER_SECOND_15: - s << FramesPerSecond15; - break; - case K4A_FRAMES_PER_SECOND_30: - s << FramesPerSecond30; - break; - default: - throw std::logic_error("Unrecognized fps"); - } - return s; -} - -std::istream &operator>>(std::istream &s, k4a_fps_t &val) -{ - std::string str; - s >> str; - if (str == FramesPerSecond5) - { - val = K4A_FRAMES_PER_SECOND_5; - } - else if (str == FramesPerSecond15) - { - val = K4A_FRAMES_PER_SECOND_15; - } - else if (str == FramesPerSecond30) - { - val = K4A_FRAMES_PER_SECOND_30; - } - else - { - s.setstate(std::ios::failbit); - } - return s; -} - -namespace -{ -constexpr char DepthModeOff[] = "K4A_DEPTH_MODE_OFF"; -constexpr char DepthModeNfov2x2Binned[] = "K4A_DEPTH_MODE_NFOV_2X2BINNED"; -constexpr char DepthModeNfovUnbinned[] = "K4A_DEPTH_MODE_NFOV_UNBINNED"; -constexpr char DepthModeWfov2x2Binned[] = "K4A_DEPTH_MODE_WFOV_2X2BINNED"; -constexpr char DepthModeWfovUnbinned[] = "K4A_DEPTH_MODE_WFOV_UNBINNED"; -constexpr char DepthModePassiveIr[] = "K4A_DEPTH_MODE_PASSIVE_IR"; -} // namespace - -std::ostream &operator<<(std::ostream &s, const k4a_depth_mode_t &val) -{ - switch (val) - { - case K4A_DEPTH_MODE_OFF: - s << DepthModeOff; - break; - case K4A_DEPTH_MODE_NFOV_2X2BINNED: - s << DepthModeNfov2x2Binned; - break; - case K4A_DEPTH_MODE_NFOV_UNBINNED: - s << DepthModeNfovUnbinned; - break; - case K4A_DEPTH_MODE_WFOV_2X2BINNED: - s << DepthModeWfov2x2Binned; - break; - case K4A_DEPTH_MODE_WFOV_UNBINNED: - s << DepthModeWfovUnbinned; - break; - case K4A_DEPTH_MODE_PASSIVE_IR: - s << DepthModePassiveIr; - break; - default: - throw std::logic_error("Unrecognized depth mode"); - } - return s; -} - -std::istream &operator>>(std::istream &s, k4a_depth_mode_t &val) -{ - std::string str; - s >> str; - if (str == DepthModeOff) - { - val = K4A_DEPTH_MODE_OFF; - } - else if (str == DepthModeNfov2x2Binned) - { - val = K4A_DEPTH_MODE_NFOV_2X2BINNED; - } - else if (str == DepthModeNfovUnbinned) - { - val = K4A_DEPTH_MODE_NFOV_UNBINNED; - } - else if (str == DepthModeWfov2x2Binned) - { - val = K4A_DEPTH_MODE_WFOV_2X2BINNED; - } - else if (str == DepthModeWfovUnbinned) - { - val = K4A_DEPTH_MODE_WFOV_UNBINNED; - } - else if (str == DepthModePassiveIr) - { - val = K4A_DEPTH_MODE_PASSIVE_IR; - } - else - { - s.setstate(std::ios::failbit); - } - return s; -} - -namespace -{ -constexpr char ColorResolutionOff[] = "K4A_COLOR_RESOLUTION_OFF"; -constexpr char ColorResolution720p[] = "K4A_COLOR_RESOLUTION_720P"; -constexpr char ColorResolution1080p[] = "K4A_COLOR_RESOLUTION_1080P"; -constexpr char ColorResolution1440p[] = "K4A_COLOR_RESOLUTION_1440P"; -constexpr char ColorResolution1536p[] = "K4A_COLOR_RESOLUTION_1536P"; -constexpr char ColorResolution2160p[] = "K4A_COLOR_RESOLUTION_2160P"; -constexpr char ColorResolution3072p[] = "K4A_COLOR_RESOLUTION_3072P"; -} // namespace - -std::ostream &operator<<(std::ostream &s, const k4a_color_resolution_t &val) -{ - switch (val) - { - case K4A_COLOR_RESOLUTION_OFF: - s << ColorResolutionOff; - break; - case K4A_COLOR_RESOLUTION_720P: - s << ColorResolution720p; - break; - case K4A_COLOR_RESOLUTION_1080P: - s << ColorResolution1080p; - break; - case K4A_COLOR_RESOLUTION_1440P: - s << ColorResolution1440p; - break; - case K4A_COLOR_RESOLUTION_1536P: - s << ColorResolution1536p; - break; - case K4A_COLOR_RESOLUTION_2160P: - s << ColorResolution2160p; - break; - case K4A_COLOR_RESOLUTION_3072P: - s << ColorResolution3072p; - break; - default: - throw std::logic_error("Unrecognized color resolution"); - } - return s; -} - -std::istream &operator>>(std::istream &s, k4a_color_resolution_t &val) -{ - std::string str; - s >> str; - if (str == ColorResolutionOff) - { - val = K4A_COLOR_RESOLUTION_OFF; - } - else if (str == ColorResolution720p) - { - val = K4A_COLOR_RESOLUTION_720P; - } - else if (str == ColorResolution1080p) - { - val = K4A_COLOR_RESOLUTION_1080P; - } - else if (str == ColorResolution1440p) - { - val = K4A_COLOR_RESOLUTION_1440P; - } - else if (str == ColorResolution1536p) - { - val = K4A_COLOR_RESOLUTION_1536P; - } - else if (str == ColorResolution2160p) - { - val = K4A_COLOR_RESOLUTION_2160P; - } - else if (str == ColorResolution3072p) - { - val = K4A_COLOR_RESOLUTION_3072P; - } - else - { - s.setstate(std::ios::failbit); - } - return s; -} - namespace { constexpr char ImageFormatColorMJPG[] = "K4A_IMAGE_FORMAT_COLOR_MJPG"; diff --git a/tools/k4aviewer/k4atypeoperators.h b/tools/k4aviewer/k4atypeoperators.h index 64e37d585..bd559518d 100644 --- a/tools/k4aviewer/k4atypeoperators.h +++ b/tools/k4aviewer/k4atypeoperators.h @@ -31,15 +31,6 @@ std::ostream &operator<<(std::ostream &s, const k4a_color_control_command_t &val std::ostream &operator<<(std::ostream &s, const k4a_wired_sync_mode_t &val); std::istream &operator>>(std::istream &s, k4a_wired_sync_mode_t &val); -std::ostream &operator<<(std::ostream &s, const k4a_fps_t &val); -std::istream &operator>>(std::istream &s, k4a_fps_t &val); - -std::ostream &operator<<(std::ostream &s, const k4a_depth_mode_t &val); -std::istream &operator>>(std::istream &s, k4a_depth_mode_t &val); - -std::ostream &operator<<(std::ostream &s, const k4a_color_resolution_t &val); -std::istream &operator>>(std::istream &s, k4a_color_resolution_t &val); - std::ostream &operator<<(std::ostream &s, const k4a_image_format_t &val); std::istream &operator>>(std::istream &s, k4a_image_format_t &val); diff --git a/tools/k4aviewer/k4aviewer.cpp b/tools/k4aviewer/k4aviewer.cpp index 29ad10429..c57d7c45f 100644 --- a/tools/k4aviewer/k4aviewer.cpp +++ b/tools/k4aviewer/k4aviewer.cpp @@ -16,7 +16,6 @@ // Project headers // -#include "k4aaudiomanager.h" #include "k4alogdockcontrol.h" #include "k4asourceselectiondockcontrol.h" #include "k4aviewererrormanager.h" @@ -24,6 +23,10 @@ #include "k4awindowmanager.h" #include "perfcounter.h" +#ifdef K4A_INCLUDE_AUDIO +#include "k4aaudiomanager.h" +#endif + using namespace k4aviewer; namespace @@ -142,6 +145,7 @@ K4AViewer::K4AViewer(const K4AViewerArgs &args) SetHighDpi(); } +#ifdef K4A_INCLUDE_AUDIO const int audioInitStatus = K4AAudioManager::Instance().Initialize(); if (audioInitStatus != SoundIoErrorNone) { @@ -149,6 +153,7 @@ K4AViewer::K4AViewer(const K4AViewerArgs &args) errorBuilder << "Failed to initialize audio backend: " << soundio_strerror(audioInitStatus) << "!"; K4AViewerErrorManager::Instance().SetErrorStatus(errorBuilder.str().c_str()); } +#endif K4AWindowManager::Instance().PushLeftDockControl(std14::make_unique()); K4AWindowManager::Instance().PushBottomDockControl(std14::make_unique()); diff --git a/tools/k4aviewer/k4aviewersettingsmanager.cpp b/tools/k4aviewer/k4aviewersettingsmanager.cpp index 666054d7a..ab7ebcd63 100644 --- a/tools/k4aviewer/k4aviewersettingsmanager.cpp +++ b/tools/k4aviewer/k4aviewersettingsmanager.cpp @@ -13,6 +13,7 @@ // Library headers // +#include // Project headers // @@ -33,9 +34,11 @@ constexpr char EndDeviceConfigurationTag[] = "EndDeviceConfiguration"; constexpr char EnableColorCameraTag[] = "EnableColorCamera"; constexpr char EnableDepthCameraTag[] = "EnableDepthCamera"; constexpr char ColorFormatTag[] = "ColorFormat"; + constexpr char ColorResolutionTag[] = "ColorResolution"; constexpr char DepthModeTag[] = "DepthMode"; constexpr char FramerateTag[] = "Framerate"; + constexpr char DepthDelayOffColorUsecTag[] = "DepthDelayOffColorUsec"; constexpr char WiredSyncModeTag[] = "WiredSyncMode"; constexpr char SubordinateDelayOffMasterUsecTag[] = "SubordinateDelayOffMasterUsec"; @@ -51,9 +54,11 @@ std::ostream &operator<<(std::ostream &s, const K4ADeviceConfiguration &val) s << Separator << EnableColorCameraTag << Separator << val.EnableColorCamera << std::endl; s << Separator << EnableDepthCameraTag << Separator << val.EnableDepthCamera << std::endl; s << Separator << ColorFormatTag << Separator << val.ColorFormat << std::endl; - s << Separator << ColorResolutionTag << Separator << val.ColorResolution << std::endl; - s << Separator << DepthModeTag << Separator << val.DepthMode << std::endl; - s << Separator << FramerateTag << Separator << val.Framerate << std::endl; + + s << Separator << ColorResolutionTag << Separator << val.color_mode_id << std::endl; + s << Separator << DepthModeTag << Separator << val.depth_mode_id << std::endl; + s << Separator << FramerateTag << Separator << val.fps_mode_id << std::endl; + s << Separator << DepthDelayOffColorUsecTag << Separator << val.DepthDelayOffColorUsec << std::endl; s << Separator << WiredSyncModeTag << Separator << val.WiredSyncMode << std::endl; s << Separator << SubordinateDelayOffMasterUsecTag << Separator << val.SubordinateDelayOffMasterUsec << std::endl; @@ -79,7 +84,7 @@ std::istream &operator>>(std::istream &s, K4ADeviceConfiguration &val) while (variableTag != EndDeviceConfigurationTag && s) { - static_assert(sizeof(K4ADeviceConfiguration) == 36, "Need to add a new setting"); + // static_assert(sizeof(K4ADeviceConfiguration) == 36, "Need to add a new setting"); variableTag.clear(); s >> variableTag; @@ -98,15 +103,15 @@ std::istream &operator>>(std::istream &s, K4ADeviceConfiguration &val) } else if (variableTag == ColorResolutionTag) { - s >> val.ColorResolution; + s >> val.color_mode_id; } else if (variableTag == DepthModeTag) { - s >> val.DepthMode; + s >> val.depth_mode_id; } else if (variableTag == FramerateTag) { - s >> val.Framerate; + s >> val.fps_mode_id; } else if (variableTag == DepthDelayOffColorUsecTag) { @@ -276,14 +281,57 @@ std::ostream &operator<<(std::ostream &s, const ViewerOption &val) // The UI doesn't quite line up with the struct we actually need to give to the K4A API, so // we have to do a bit of conversion. // -k4a_device_configuration_t K4ADeviceConfiguration::ToK4ADeviceConfiguration() const +k4a_device_configuration_t K4ADeviceConfiguration::ToK4ADeviceConfiguration(k4a::device *device) const { k4a_device_configuration_t deviceConfig; deviceConfig.color_format = ColorFormat; - deviceConfig.color_resolution = EnableColorCamera ? ColorResolution : K4A_COLOR_RESOLUTION_OFF; - deviceConfig.depth_mode = EnableDepthCamera ? DepthMode : K4A_DEPTH_MODE_OFF; - deviceConfig.camera_fps = Framerate; + + // Translate depth_mode_id to the device's available depth modes. + k4a_depth_mode_t depth_mode_to_find = (EnableDepthCamera) ? static_cast(depth_mode_id) : + K4A_DEPTH_MODE_OFF; + std::vector depthModes = device->get_depth_modes(); + k4a_depth_mode_info_t depth_mode_info = depthModes[0]; // Default to the first one on the list (Depth OFF). + for (auto &depthMode : depthModes) + { + if (depthMode.mode_id == static_cast(depth_mode_to_find)) + { + depth_mode_info = depthMode; + break; + } + } + + // Translate color_mode_id to the device's available color modes. + k4a_color_resolution_t color_mode_to_find = (EnableColorCamera) ? + static_cast(color_mode_id) : + K4A_COLOR_RESOLUTION_OFF; + std::vector colorModes = device->get_color_modes(); + k4a_color_mode_info_t color_mode_info = colorModes[0]; // Default to the first one on the list (Color OFF). + for (auto &colorMode : colorModes) + { + if (colorMode.mode_id == static_cast(color_mode_to_find)) + { + color_mode_info = colorMode; + break; + } + } + + // Translate fps_mode_id to the device's available fps modes. + k4a_fps_t fps_mode_to_find = static_cast(fps_mode_id); + std::vector fpsModes = device->get_fps_modes(); + k4a_fps_mode_info_t fps_mode_info = fpsModes[0]; // Default to the first one on the list. + for (auto &fpsMode : fpsModes) + { + if (fpsMode.mode_id == static_cast(fps_mode_to_find)) + { + fps_mode_info = fpsMode; + break; + } + } + + deviceConfig.color_mode_id = color_mode_info.mode_id; + deviceConfig.depth_mode_id = depth_mode_info.mode_id; + deviceConfig.fps_mode_id = fps_mode_info.mode_id; deviceConfig.depth_delay_off_color_usec = DepthDelayOffColorUsec; deviceConfig.wired_sync_mode = WiredSyncMode; diff --git a/tools/k4aviewer/k4aviewersettingsmanager.h b/tools/k4aviewer/k4aviewersettingsmanager.h index a5fbfe32f..bf7e68f6f 100644 --- a/tools/k4aviewer/k4aviewersettingsmanager.h +++ b/tools/k4aviewer/k4aviewersettingsmanager.h @@ -13,6 +13,7 @@ // Library headers // #include +#include // Project headers // @@ -27,9 +28,10 @@ struct K4ADeviceConfiguration bool EnableColorCamera = true; bool EnableDepthCamera = true; k4a_image_format_t ColorFormat = K4A_IMAGE_FORMAT_COLOR_BGRA32; - k4a_color_resolution_t ColorResolution = K4A_COLOR_RESOLUTION_720P; - k4a_depth_mode_t DepthMode = K4A_DEPTH_MODE_NFOV_UNBINNED; - k4a_fps_t Framerate = K4A_FRAMES_PER_SECOND_30; + + uint32_t color_mode_id = K4A_COLOR_RESOLUTION_720P; + uint32_t depth_mode_id = K4A_DEPTH_MODE_NFOV_UNBINNED; + uint32_t fps_mode_id = K4A_FRAMES_PER_SECOND_30; int32_t DepthDelayOffColorUsec = 0; k4a_wired_sync_mode_t WiredSyncMode = K4A_WIRED_SYNC_MODE_STANDALONE; @@ -44,7 +46,7 @@ struct K4ADeviceConfiguration // Convert to a k4a_device_configuration_t suitable for passing to the K4A API // - k4a_device_configuration_t ToK4ADeviceConfiguration() const; + k4a_device_configuration_t ToK4ADeviceConfiguration(k4a::device *device) const; }; std::istream &operator>>(std::istream &s, K4ADeviceConfiguration &val); diff --git a/tools/k4aviewer/k4awindowset.cpp b/tools/k4aviewer/k4awindowset.cpp index 3e5645a8f..b7c8e1245 100644 --- a/tools/k4aviewer/k4awindowset.cpp +++ b/tools/k4aviewer/k4awindowset.cpp @@ -13,7 +13,6 @@ // Project headers // -#include "k4aaudiowindow.h" #include "k4acolorimageconverter.h" #include "k4adepthimageconverter.h" #include "k4aimguiextensions.h" @@ -23,6 +22,10 @@ #include "k4apointcloudwindow.h" #include "k4awindowmanager.h" +#ifdef K4A_INCLUDE_AUDIO +#include "k4aaudiowindow.h" +#endif + using namespace k4aviewer; namespace @@ -74,12 +77,14 @@ void K4AWindowSet::ShowModeSelector(ViewType *viewType, void K4AWindowSet::StartNormalWindows(const char *sourceIdentifier, K4ADataSource *cameraDataSource, K4ADataSource *imuDataSource, +#ifdef K4A_INCLUDE_AUDIO std::shared_ptr &µphoneDataSource, +#endif bool enableDepthCamera, - k4a_depth_mode_t depthMode, + k4a_depth_mode_info_t depth_mode_info, bool enableColorCamera, k4a_image_format_t colorFormat, - k4a_color_resolution_t colorResolution) + k4a_color_mode_info_t color_mode_info) { if (cameraDataSource != nullptr) { @@ -89,17 +94,17 @@ void K4AWindowSet::StartNormalWindows(const char *sourceIdentifier, "Infrared Camera", *cameraDataSource, std::make_shared>( - std14::make_unique(depthMode))); + std14::make_unique(depth_mode_info))); // K4A_DEPTH_MODE_PASSIVE_IR doesn't support actual depth // - if (depthMode != K4A_DEPTH_MODE_PASSIVE_IR) + if (!depth_mode_info.passive_ir_only) { CreateVideoWindow(sourceIdentifier, "Depth Camera", *cameraDataSource, std::make_shared>( - std14::make_unique(depthMode))); + std14::make_unique(depth_mode_info))); } } @@ -115,7 +120,7 @@ void K4AWindowSet::StartNormalWindows(const char *sourceIdentifier, colorWindowTitle, *cameraDataSource, std::make_shared>( - K4AColorImageConverterFactory::Create(colorResolution))); + K4AColorImageConverterFactory::Create(color_mode_info))); break; case K4A_IMAGE_FORMAT_COLOR_MJPG: @@ -124,7 +129,7 @@ void K4AWindowSet::StartNormalWindows(const char *sourceIdentifier, colorWindowTitle, *cameraDataSource, std::make_shared>( - K4AColorImageConverterFactory::Create(colorResolution))); + K4AColorImageConverterFactory::Create(color_mode_info))); break; case K4A_IMAGE_FORMAT_COLOR_BGRA32: @@ -133,7 +138,7 @@ void K4AWindowSet::StartNormalWindows(const char *sourceIdentifier, colorWindowTitle, *cameraDataSource, std::make_shared>( - K4AColorImageConverterFactory::Create(colorResolution))); + K4AColorImageConverterFactory::Create(color_mode_info))); break; case K4A_IMAGE_FORMAT_COLOR_NV12: @@ -142,7 +147,7 @@ void K4AWindowSet::StartNormalWindows(const char *sourceIdentifier, colorWindowTitle, *cameraDataSource, std::make_shared>( - K4AColorImageConverterFactory::Create(colorResolution))); + K4AColorImageConverterFactory::Create(color_mode_info))); break; default: @@ -165,6 +170,7 @@ void K4AWindowSet::StartNormalWindows(const char *sourceIdentifier, graphWindows.emplace_back(std14::make_unique(std::move(title), std::move(imuGraphDataGenerator))); } +#ifdef K4A_INCLUDE_AUDIO if (microphoneDataSource != nullptr) { std::string micTitle = std::string(sourceIdentifier) + ": Microphone Data"; @@ -172,6 +178,7 @@ void K4AWindowSet::StartNormalWindows(const char *sourceIdentifier, graphWindows.emplace_back(std::unique_ptr( std14::make_unique(std::move(micTitle), std::move(microphoneDataSource)))); } +#endif if (!graphWindows.empty()) { @@ -181,6 +188,7 @@ void K4AWindowSet::StartNormalWindows(const char *sourceIdentifier, void K4AWindowSet::StartPointCloudWindow(const char *sourceIdentifier, const k4a::calibration &calibrationData, + k4a_depth_mode_info_t depth_mode_info, K4ADataSource *cameraDataSource, bool enableColorPointCloud) { @@ -192,5 +200,6 @@ void K4AWindowSet::StartPointCloudWindow(const char *sourceIdentifier, wm.AddWindow(std14::make_unique(std::move(pointCloudTitle), enableColorPointCloud, std::move(captureSource), - calibrationData)); + calibrationData, + depth_mode_info)); } diff --git a/tools/k4aviewer/k4awindowset.h b/tools/k4aviewer/k4awindowset.h index 2e2f093e1..968473c1f 100644 --- a/tools/k4aviewer/k4awindowset.h +++ b/tools/k4aviewer/k4awindowset.h @@ -20,9 +20,12 @@ // Project headers // #include "k4adatasource.h" -#include "k4amicrophonelistener.h" #include "k4avideowindow.h" +#ifdef K4A_INCLUDE_AUDIO +#include "k4amicrophonelistener.h" +#endif + namespace k4aviewer { class K4AWindowSet @@ -41,15 +44,18 @@ class K4AWindowSet static void StartNormalWindows(const char *sourceIdentifier, K4ADataSource *cameraDataSource, K4ADataSource *imuDataSource, +#ifdef K4A_INCLUDE_AUDIO std::shared_ptr &µphoneDataSource, +#endif bool enableDepthCamera, - k4a_depth_mode_t depthMode, + k4a_depth_mode_info_t depth_mode_info, bool enableColorCamera, k4a_image_format_t colorFormat, - k4a_color_resolution_t colorResolution); + k4a_color_mode_info_t color_mode_info); static void StartPointCloudWindow(const char *sourceIdentifier, const k4a::calibration &calibrationData, + k4a_depth_mode_info_t depth_mode_info, K4ADataSource *cameraDataSource, bool enableColorPointCloud); }; diff --git a/tools/k4aviewer/platform/windows/k4adevicecorrelator.cpp b/tools/k4aviewer/platform/windows/k4adevicecorrelator.cpp index 8f5c0dd43..4ed718c6c 100644 --- a/tools/k4aviewer/platform/windows/k4adevicecorrelator.cpp +++ b/tools/k4aviewer/platform/windows/k4adevicecorrelator.cpp @@ -16,6 +16,7 @@ // Library headers // +#include // Shut off windows.h's min/max macros so they don't conflict with the STL min/max functions, which // are used in some of the k4aviewer headers @@ -230,8 +231,8 @@ HRESULT GetSerialNumberToContainerIdMap(std::map *result) const auto vid = uint16_t(std::stoul(vidStr, nullptr, baseHex)); const auto pid = uint16_t(std::stoul(pidStr, nullptr, baseHex)); - constexpr uint16_t depthCameraVid = 0x045E; - constexpr uint16_t depthCameraPid = 0x097C; + constexpr uint16_t depthCameraVid = K4A_MSFT_VID; + constexpr uint16_t depthCameraPid = K4A_DEPTH_PID; if (vid != depthCameraVid || pid != depthCameraPid) {