diff --git a/.gitmodules b/.gitmodules index 2e116b29..33cb9380 100644 --- a/.gitmodules +++ b/.gitmodules @@ -37,5 +37,5 @@ url = https://github.com/libusb/libusb [submodule "extern/libuvc/src"] path = extern/libuvc/src - url = https://github.com/wes-b/libuvc.git + url = https://github.com/microsoft/libuvc.git branch = Azure-Kinect-Sensor-SDK diff --git a/CMakeLists.txt b/CMakeLists.txt index a20107fc..d01674fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,10 @@ include(GitCommands) # Set the project version include(K4AProjectVersion) +# Default to not embed an icon in resources +set(K4A_USE_ICON 0) +set(K4A_ICON_PATH ${CMAKE_CURRENT_LIST_DIR}/kinect-viewer.ico) + set(PROJ_DIR ${CMAKE_CURRENT_LIST_DIR}) set(INCLUDE_DIR ${PROJ_DIR}/include) @@ -59,12 +63,18 @@ if ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /ZH:SHA_256") endif() -# If using clang or GCC only linked shared libraries if needed +# If using clang or GCC, only linked shared libraries if needed if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--as-needed") endif() +# If using clang or GCC, be sure to include a build id +if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--build-id") +endif() + # Find all dependencies add_subdirectory(extern) @@ -282,4 +292,4 @@ cpack_add_component( "Tools for Azure Kinect Development" REQUIRED DEPENDS - runtime) \ No newline at end of file + runtime) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 33e00fc3..84472180 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -7,9 +7,9 @@ variables: - name: 'skipComponentGovernaceDetection' value: true - name: 'linux_firmware_version' - value: '1.6.987014' + value: '1.6.102075014' - name: 'windows_firmware_version' - value: '1.6.987014' + value: '1.6.102075014' trigger: batch: false @@ -147,7 +147,6 @@ jobs: steps: - checkout: self clean: true - fetchDepth: 20 lfs: false persistCredentials: true submodules: true @@ -385,7 +384,6 @@ jobs: steps: - checkout: self clean: true - fetchDepth: 20 lfs: false persistCredentials: true submodules: true @@ -463,7 +461,6 @@ jobs: steps: - checkout: self clean: true - fetchDepth: 20 lfs: false persistCredentials: true submodules: true diff --git a/include/k4a/k4atypes.h b/include/k4a/k4atypes.h index 439c7a70..0c4446e6 100644 --- a/include/k4a/k4atypes.h +++ b/include/k4a/k4atypes.h @@ -587,7 +587,9 @@ typedef enum { K4A_WIRED_SYNC_MODE_STANDALONE, /**< Neither 'Sync In' or 'Sync Out' connections are used. */ K4A_WIRED_SYNC_MODE_MASTER, /**< The 'Sync Out' jack is enabled and synchronization data it driven out the - connected wire.*/ + connected wire. While in master mode the color camera must be enabled as part of the + multi device sync signalling logic. Even if the color image is not needed, the color + camera must be running.*/ K4A_WIRED_SYNC_MODE_SUBORDINATE /**< The 'Sync In' jack is used for synchronization and 'Sync Out' is driven for the next device in the chain. 'Sync Out' is a mirror of 'Sync In' for this mode. */ @@ -705,13 +707,19 @@ typedef enum * * The SDK can log data to the console, files, or to a custom handler. * - * Environment Variables + * Environment Variables: + * + * K4A_ENABLE_LOG_TO_A_FILE / K4A_RECORD_ENABLE_LOG_TO_A_FILE + * Specifies the log file to save the log to. K4a.dll and k4arecord.dll can not log to the same file. * * K4A_ENABLE_LOG_TO_A_FILE = + * K4A_RECORD_ENABLE_LOG_TO_A_FILE = * 0 - completely disable logging to a file * log\custom.log - log all messages to the path and file specified - must end in '.log' to * be considered a valid entry - * ** When enabled this takes precedence over the value of K4A_ENABLE_LOG_TO_STDOUT + * NOTE 1: When enabled this takes precedence over the value of K4A_ENABLE_LOG_TO_STDOUT. + * NOTE 2: This can not be set to the same value as K4A_RECORD_ENABLE_LOG_TO_A_FILE as they represent separate + * logger instance that do not allowed shared access to the file being written to. * * K4A_ENABLE_LOG_TO_STDOUT = * 0 - disable logging to stdout diff --git a/include/k4ainternal/logging.h b/include/k4ainternal/logging.h index 16667be1..29513412 100644 --- a/include/k4ainternal/logging.h +++ b/include/k4ainternal/logging.h @@ -41,6 +41,8 @@ K4A_DECLARE_HANDLE(logger_t); #define K4A_LOG_FILE_NAME "k4a.log" #define K4A_LOG_FILE_50MB_MAX_SIZE (1048576 * 50) +#define K4A_RECORD_ENABLE_LOG_TO_A_FILE "K4A_RECORD_ENABLE_LOG_TO_A_FILE" + /** Logger configuration - allows logger to be used in seperate DLL's and provide different ENV vars for processes that need to load both instances. For example Azure Kinect SDK and potentially Azure Kinect playback. diff --git a/kinect-viewer.ico b/kinect-viewer.ico new file mode 100644 index 00000000..cf4dc0e1 Binary files /dev/null and b/kinect-viewer.ico differ diff --git a/scripts/bootstrap-ubuntu.sh b/scripts/bootstrap-ubuntu.sh index 7e8c2e59..7aec413e 100755 --- a/scripts/bootstrap-ubuntu.sh +++ b/scripts/bootstrap-ubuntu.sh @@ -19,7 +19,8 @@ sudo apt install -y \ g++-multilib \ python3 \ git-lfs \ - nasm + nasm \ + cmake # Install libraries needed to build sudo apt install -y \ diff --git a/src/logging/logging.cpp b/src/logging/logging.cpp index e472d59b..21b827bd 100644 --- a/src/logging/logging.cpp +++ b/src/logging/logging.cpp @@ -134,6 +134,7 @@ k4a_result_t logger_create(logger_config_t *config, logger_t *logger_handle) const char *enable_file_logging = nullptr; const char *enable_stdout_logging = nullptr; const char *logging_level = nullptr; + k4a_result_t result = K4A_RESULT_SUCCEEDED; // environment_get_variable will return null or "\0" if the env var is not set - depends on the OS. if (config->env_var_log_to_a_file) @@ -189,17 +190,28 @@ k4a_result_t logger_create(logger_config_t *config, logger_t *logger_handle) if (log_file) { - // Create a file rotating logger with 50mb size max and 3 rotated files - g_env_logger = spdlog::rotating_logger_mt(K4A_LOGGER, log_file, config->max_log_size, LOG_FILE_MAX_FILES); + try + { + // Create a file rotating logger with 50mb size max and 3 rotated files + g_env_logger = + spdlog::rotating_logger_mt(K4A_LOGGER, log_file, config->max_log_size, LOG_FILE_MAX_FILES); - spdlog::set_pattern("%v"); - g_env_logger->info("\n\nNew logging session started\n"); - g_env_logger_is_file_based = true; + spdlog::set_pattern("%v"); + g_env_logger->info("\n\nNew logging session started\n"); + g_env_logger_is_file_based = true; + } + catch (...) + { + // Probably trying to use a file that is already opened by another instance. + g_env_logger = nullptr; + printf("ERROR: Unable to open log file \"%s\".\n", log_file); + result = K4A_RESULT_FAILED; + } } } // log to stdout if enabled via ENV var AND if file logging is not enabled. - if (g_env_logger == NULL) + if (K4A_SUCCEEDED(result) && (g_env_logger == NULL)) { bool enable_stdout_logger = false; @@ -225,7 +237,7 @@ k4a_result_t logger_create(logger_config_t *config, logger_t *logger_handle) } } - if (g_env_logger) + if (K4A_SUCCEEDED(result) && (g_env_logger)) { context->logger = g_env_logger; g_env_log_level = K4A_LOG_LEVEL_ERROR; @@ -269,7 +281,7 @@ k4a_result_t logger_create(logger_config_t *config, logger_t *logger_handle) g_env_logger->flush_on(spdlog::level::warn); } - return K4A_RESULT_SUCCEEDED; + return result; } void logger_destroy(logger_t logger_handle) diff --git a/src/record/sdk/CMakeLists.txt b/src/record/sdk/CMakeLists.txt index 211086e1..1e952d01 100644 --- a/src/record/sdk/CMakeLists.txt +++ b/src/record/sdk/CMakeLists.txt @@ -56,6 +56,11 @@ set_target_properties( SOVERSION "${K4A_VERSION_MAJOR}.${K4A_VERSION_MINOR}") +set(NAMELINK_IF_AVAILABLE) +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12.0") + set(NAMELINK_IF_AVAILABLE NAMELINK_COMPONENT development) +endif() + # Setup install include(GNUInstallDirs) install( @@ -68,7 +73,7 @@ install( ${CMAKE_INSTALL_LIBDIR} COMPONENT runtime - NAMELINK_SKIP + ${NAMELINK_IF_AVAILABLE} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/src/record/sdk/playback.cpp b/src/record/sdk/playback.cpp index 5a4815dd..38fe7a1f 100644 --- a/src/record/sdk/playback.cpp +++ b/src/record/sdk/playback.cpp @@ -25,6 +25,7 @@ k4a_result_t k4a_playback_open(const char *path, k4a_playback_t *playback_handle // Instantiate the logger as early as possible logger_config_t logger_config; logger_config_init_default(&logger_config); + logger_config.env_var_log_to_a_file = K4A_RECORD_ENABLE_LOG_TO_A_FILE; result = TRACE_CALL(logger_create(&logger_config, &logger_handle)); if (K4A_SUCCEEDED(result)) diff --git a/src/record/sdk/record.cpp b/src/record/sdk/record.cpp index 94b9f955..61c4a110 100644 --- a/src/record/sdk/record.cpp +++ b/src/record/sdk/record.cpp @@ -28,6 +28,7 @@ k4a_result_t k4a_record_create(const char *path, // Instantiate the logger as early as possible logger_config_t logger_config; logger_config_init_default(&logger_config); + logger_config.env_var_log_to_a_file = K4A_RECORD_ENABLE_LOG_TO_A_FILE; result = TRACE_CALL(logger_create(&logger_config, &logger_handle)); if (K4A_SUCCEEDED(result)) diff --git a/src/sdk/CMakeLists.txt b/src/sdk/CMakeLists.txt index f906106f..3616f400 100644 --- a/src/sdk/CMakeLists.txt +++ b/src/sdk/CMakeLists.txt @@ -65,6 +65,10 @@ set_target_properties( SOVERSION "${K4A_VERSION_MAJOR}.${K4A_VERSION_MINOR}") +set(NAMELINK_IF_AVAILABLE) +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12.0") + set(NAMELINK_IF_AVAILABLE NAMELINK_COMPONENT development) +endif() # Setup install include(GNUInstallDirs) @@ -78,7 +82,7 @@ install( ${CMAKE_INSTALL_LIBDIR} COMPONENT runtime - NAMELINK_SKIP + ${NAMELINK_IF_AVAILABLE} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/src/sdk/k4a.c b/src/sdk/k4a.c index 0e0632b5..5c388ad3 100644 --- a/src/sdk/k4a.c +++ b/src/sdk/k4a.c @@ -570,6 +570,14 @@ static k4a_result_t validate_configuration(k4a_context_t *device, const k4a_devi if (K4A_SUCCEEDED(result) && config->wired_sync_mode == K4A_WIRED_SYNC_MODE_MASTER) { result = K4A_RESULT_FROM_BOOL(sync_out_cable_present == true); + + if (K4A_SUCCEEDED(result) && config->color_resolution == K4A_COLOR_RESOLUTION_OFF) + { + LOG_ERROR("Device wired_sync_mode is set to K4A_WIRED_SYNC_MODE_MASTER, so color camera must be used " + "on master device. Color_resolution can not be set to K4A_COLOR_RESOLUTION_OFF.", + 0); + return K4A_RESULT_FAILED; + } } } diff --git a/tests/multidevice/multidevice.cpp b/tests/multidevice/multidevice.cpp index 58b05724..832bac20 100644 --- a/tests/multidevice/multidevice.cpp +++ b/tests/multidevice/multidevice.cpp @@ -156,3 +156,72 @@ TEST_F(multidevice_ft, DISABLED_stream_two_2_then_1) k4a_device_close(m_device1); m_device1 = NULL; } + +TEST_F(multidevice_ft, DISABLED_ensure_color_camera_is_enabled) +{ + bool master_device_found = false; + bool subordinate_device_found = false; + uint32_t devices_present = k4a_device_get_installed_count(); + ASSERT_LE((uint32_t)2, devices_present); + + for (uint32_t x = 0; x < devices_present; x++) + { + ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_open(x, &m_device1)); + + bool sync_in_cable_present; + bool sync_out_cable_present; + + 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; + + ASSERT_EQ(K4A_RESULT_SUCCEEDED, + k4a_device_get_sync_jack(m_device1, &sync_in_cable_present, &sync_out_cable_present)); + + if (sync_out_cable_present) + { + // Negative test + config.wired_sync_mode = K4A_WIRED_SYNC_MODE_MASTER; + ASSERT_EQ(K4A_RESULT_FAILED, k4a_device_start_cameras(m_device1, &config)); + k4a_device_stop_cameras(m_device1); + + // Positive Test + config.wired_sync_mode = K4A_WIRED_SYNC_MODE_STANDALONE; + ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_cameras(m_device1, &config)); + k4a_device_stop_cameras(m_device1); + + master_device_found = true; + } + + if (sync_in_cable_present) + { + // Positive Test + config.wired_sync_mode = K4A_WIRED_SYNC_MODE_SUBORDINATE; + ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_cameras(m_device1, &config)); + k4a_device_stop_cameras(m_device1); + + // Positive Test + config.wired_sync_mode = K4A_WIRED_SYNC_MODE_STANDALONE; + ASSERT_EQ(K4A_RESULT_SUCCEEDED, k4a_device_start_cameras(m_device1, &config)); + k4a_device_stop_cameras(m_device1); + + subordinate_device_found = true; + } + + if (subordinate_device_found && sync_out_cable_present) + { + // Done with the test + break; + } + + k4a_device_close(m_device1); + m_device1 = NULL; + } + + // Make sure we found both devices. + ASSERT_EQ(master_device_found, true); + ASSERT_EQ(subordinate_device_found, true); +} \ No newline at end of file diff --git a/tools/k4aviewer/CMakeLists.txt b/tools/k4aviewer/CMakeLists.txt index 1c272429..98578c03 100644 --- a/tools/k4aviewer/CMakeLists.txt +++ b/tools/k4aviewer/CMakeLists.txt @@ -41,6 +41,7 @@ set(SOURCE_FILES # 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 diff --git a/version.rc.in b/version.rc.in index 4ea707d2..a9f81445 100644 --- a/version.rc.in +++ b/version.rc.in @@ -24,6 +24,10 @@ #define VER_PRIVATEBUILD 0 #define VER_PRERELEASE 0 +#if @K4A_USE_ICON@ +APP_ICON ICON "@K4A_ICON_PATH@" +#endif + VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION PRODUCTVERSION VER_PRODUCTVERSION