mv_machine_learning: add gaze tracking task group
authorInki Dae <inki.dae@samsung.com>
Mon, 15 Jul 2024 05:07:39 +0000 (14:07 +0900)
committerInki Dae <inki.dae@samsung.com>
Tue, 24 Sep 2024 02:07:18 +0000 (11:07 +0900)
Change-Id: Ieb2fdd6f599bba70c81849820151cc6a9eb8d087
Signed-off-by: Inki Dae <inki.dae@samsung.com>
23 files changed:
CMakeLists.txt
include/mv_gaze_tracking.h [new file with mode: 0644]
include/mv_gaze_tracking_internal.h [new file with mode: 0644]
include/mv_gaze_tracking_type.h [new file with mode: 0644]
mv_machine_learning/CMakeLists.txt
mv_machine_learning/common/include/AsyncManager.h
mv_machine_learning/common/src/MvMlConfig.cpp
mv_machine_learning/gaze_tracking/CMakeLists.txt [new file with mode: 0644]
mv_machine_learning/gaze_tracking/include/GazeTracking.h [new file with mode: 0644]
mv_machine_learning/gaze_tracking/include/GazeTrackingAdapter.h [new file with mode: 0644]
mv_machine_learning/gaze_tracking/include/GazeTrackingParser.h [new file with mode: 0644]
mv_machine_learning/gaze_tracking/include/IGazeTracking.h [new file with mode: 0644]
mv_machine_learning/gaze_tracking/include/L2CSNet.h [new file with mode: 0644]
mv_machine_learning/gaze_tracking/include/gaze_tracking_type.h [new file with mode: 0644]
mv_machine_learning/gaze_tracking/include/mv_gaze_tracking_config.h [new file with mode: 0644]
mv_machine_learning/gaze_tracking/meta/gaze_tracking.json [new file with mode: 0644]
mv_machine_learning/gaze_tracking/meta/gaze_tracking_plugin.json [new file with mode: 0644]
mv_machine_learning/gaze_tracking/src/GazeTracking.cpp [new file with mode: 0644]
mv_machine_learning/gaze_tracking/src/GazeTrackingAdapter.cpp [new file with mode: 0644]
mv_machine_learning/gaze_tracking/src/GazeTrackingParser.cpp [new file with mode: 0644]
mv_machine_learning/gaze_tracking/src/L2CSNet.cpp [new file with mode: 0644]
mv_machine_learning/gaze_tracking/src/mv_gaze_tracking.cpp [new file with mode: 0644]
packaging/capi-media-vision.spec

index c31e8f5b4c952b3437add42c37912c49245e074c..a7cc4f677b7b352be364d52fda650a1f3be22bc4 100644 (file)
@@ -52,6 +52,8 @@ set(MV_IMAGE_CLASSIFICATION_LIB_NAME "mv_image_classification" CACHE STRING
        "Name of the library will be built for image classification module (without extension).")
 set(MV_IMAGE_SEGMENTATION_LIB_NAME "mv_image_segmentation" CACHE STRING
        "Name of the library will be built for image segmentation module (without extension).")
+set(MV_GAZE_TRACKING_LIB_NAME "mv_gaze_tracking" CACHE STRING
+       "Name of the library will be built for gaze tracking module (without extension).")
 
 include(FindPkgConfig)
 include(GNUInstallDirs)
@@ -281,6 +283,22 @@ if (${ENABLE_ML_IMAGE_SEGMENTATION})
        list(APPEND TOTAL_LDFLAGS ${PC_LDFLAGS})
 endif()
 
+set(PC_NAME ${fw_name}-gaze-tracking)
+set(PC_LDFLAGS "-l${MV_GAZE_TRACKING_LIB_NAME} -l${MV_COMMON_LIB_NAME}")
+configure_file(
+       ${fw_name}.pc.in
+       ${CMAKE_CURRENT_BINARY_DIR}/${fw_name}-gaze-tracking.pc
+       @ONLY
+)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${fw_name}-gaze-tracking.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+set(GAZE_TRACKING_JSON_FILES
+       "${CMAKE_CURRENT_SOURCE_DIR}/mv_machine_learning/gaze_tracking/meta/gaze_tracking.json"
+       "${CMAKE_CURRENT_SOURCE_DIR}/mv_machine_learning/gaze_tracking/meta/gaze_tracking_plugin.json"
+)
+install(FILES ${GAZE_TRACKING_JSON_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/${fw_name})
+list(APPEND TOTAL_REQUIRED ${PC_NAME})
+list(APPEND TOTAL_LDFLAGS ${PC_LDFLAGS})
+
 string(REPLACE ";" " " TOTAL_LDFLAGS "${TOTAL_LDFLAGS}")
 string(REPLACE " " ";" TOTAL_LDFLAGS_LIST "${TOTAL_LDFLAGS}")
 list(REMOVE_DUPLICATES TOTAL_LDFLAGS_LIST)
diff --git a/include/mv_gaze_tracking.h b/include/mv_gaze_tracking.h
new file mode 100644 (file)
index 0000000..f55333c
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_MV_GAZE_TRACKING_H__
+#define __TIZEN_MEDIAVISION_MV_GAZE_TRACKING_H__
+
+#include <mv_common.h>
+#include <mv_gaze_tracking_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file   mv_gaze_tracking.h
+ * @brief  This file contains the Inference based Media Vision API.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_GAZE_TRACKING_MODULE
+ * @{
+ */
+
+/**
+ * @brief Creates a inference handle for gaze tracking object.
+ * @details Use this function to create a inference handle. After the creation
+ *          the gaze tracking 3d task has to be prepared with
+ *          mv_gaze_tracking_prepare() function to prepare a network
+ *          for the inference.
+ *
+ * @since_tizen 9.0
+ *
+ * @remarks The @a infer should be released using mv_gaze_tracking_destroy().
+ *
+ * @param[out] infer    The handle to the inference to be created.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @code
+ * #include <mv_gaze_tracking.h>
+ * ...
+ * mv_gaze_tracking_h handle = NULL;
+ * mv_gaze_tracking_create(&handle);
+ * ...
+ * mv_gaze_tracking_destroy(handle);
+ * @endcode
+ *
+ * @see mv_gaze_tracking_destroy()
+ * @see mv_gaze_tracking_prepare()
+ */
+int mv_gaze_tracking_create(mv_gaze_tracking_h *infer);
+
+/**
+ * @brief Destroys inference handle and releases all its resources.
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] infer    The handle to the inference to be destroyed.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create inference handle by using mv_gaze_tracking_create()
+ *
+ * @see mv_gaze_tracking_create()
+ */
+int mv_gaze_tracking_destroy(mv_gaze_tracking_h infer);
+
+/**
+ * @brief Configures the backend for the gaze tracking inference.
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] infer         The handle to the inference
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int mv_gaze_tracking_configure(mv_gaze_tracking_h infer);
+
+/**
+ * @brief Prepares the gaze tracking inference.
+ * @details Use this function to prepare the gaze tracking inference based on
+ *          the configured network.
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] infer         The handle to the inference.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_DATA Invalid model data
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported format
+ */
+int mv_gaze_tracking_prepare(mv_gaze_tracking_h infer);
+
+/**
+ * @brief Performs the gaze tracking inference on the @a source.
+ *
+ * @since_tizen 9.0
+ * @remarks This function is synchronous and may take considerable time to run.
+ *
+ * @param[in] infer          The handle to the inference
+ * @param[in] source         The handle to the source of the media
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INTERNAL          Internal error
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ *
+ * @pre Create a source handle by calling mv_create_source()
+ * @pre Create an inference handle by calling mv_gaze_tracking_create()
+ * @pre Prepare an inference by calling mv_gaze_tracking_configure()
+ * @pre Prepare an inference by calling mv_gaze_tracking_prepare()
+ *
+ * @par Inference Example
+ * @snippet gaze_tracking_sync.c OD sync
+ */
+int mv_gaze_tracking_inference(mv_gaze_tracking_h infer, mv_source_h source);
+
+/**
+ * @brief Performs asynchronously the gaze tracking inference on the @a source.
+ *
+ * @since_tizen 9.0
+ * @remarks This function operates asynchronously, so it returns immediately upon invocation.
+ *          The inference results are inserted into the outgoing queue within the framework
+ *          in the order of processing, and the results can be obtained through
+ *          mv_gaze_tracking_get_result_count() and mv_gaze_tracking_get_label().
+ *
+ * @param[in] handle         The handle to the inference
+ * @param[in] source         The handle to the source of the media
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INTERNAL          Internal error
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ *
+ * @pre Create a source handle by calling mv_create_source()
+ * @pre Create an inference handle by calling mv_gaze_tracking_create()
+ * @pre Prepare an inference by calling mv_gaze_tracking_configure()
+ * @pre Prepare an inference by calling mv_gaze_tracking_prepare()
+ *
+ * @par Async Inference Example
+ * @snippet gaze_tracking_async.c OD async
+ */
+int mv_gaze_tracking_inference_async(mv_gaze_tracking_h handle, mv_source_h source);
+
+/**
+ * @brief Gets the gaze tracking inference result on the @a handle.
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle          The handle to the inference
+ * @param[out] frame_number   A frame number inferenced.
+ * @param[out] result_cnt     A number of results.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INTERNAL          Internal error
+ *
+ * @pre Create a source handle by calling mv_create_source()
+ * @pre Create an inference handle by calling mv_gaze_tracking_create()
+ * @pre Prepare an inference by calling mv_gaze_tracking_configure()
+ * @pre Prepare an inference by calling mv_gaze_tracking_prepare()
+ * @pre Request an inference by calling mv_gaze_tracking_inference()
+ */
+int mv_gaze_tracking_get_result_count(mv_gaze_tracking_h handle, unsigned long *frame_number, unsigned int *result_cnt);
+
+/**
+ * @brief Gets x and y-axis values to gazed position.
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle   The handle to the inference
+ * @param[in] index    A result index.
+ * @param[out] x       x-axis value array to gazed position.
+ * @param[out] y       y-axis value array to gazed position.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INTERNAL          Internal error
+ *
+ * @pre Create a source handle by calling mv_create_source()
+ * @pre Create an inference handle by calling mv_gaze_tracking_create()
+ * @pre Prepare an inference by calling mv_gaze_tracking_configure()
+ * @pre Prepare an inference by calling mv_gaze_tracking_prepare()
+ * @pre Prepare an inference by calling mv_gaze_tracking_inference()
+ */
+int mv_gaze_tracking_get_pos(mv_gaze_tracking_h handle, unsigned int index, float *x, float *y);
+
+/**
+ * @brief Gets a raw data to gazed position.
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle   The handle to the inference
+ * @param[in] index    A result index.
+ * @param[out] yaw     yaw value to gazed position.
+ * @param[out] pitch   pitch value to gazed position.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INTERNAL          Internal error
+ *
+ * @pre Create a source handle by calling mv_create_source()
+ * @pre Create an inference handle by calling mv_gaze_tracking_create()
+ * @pre Prepare an inference by calling mv_gaze_tracking_configure()
+ * @pre Prepare an inference by calling mv_gaze_tracking_prepare()
+ * @pre Prepare an inference by calling mv_gaze_tracking_inference()
+ */
+int mv_gaze_tracking_get_raw_data(mv_gaze_tracking_h handle, unsigned int index, float *yaw, float *pitch);
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_MV_GAZE_TRACKING_H__ */
diff --git a/include/mv_gaze_tracking_internal.h b/include/mv_gaze_tracking_internal.h
new file mode 100644 (file)
index 0000000..cb5619b
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_GAZE_TRACKING_INTERNAL_H__
+#define __TIZEN_MEDIAVISION_GAZE_TRACKING_INTERNAL_H__
+
+#include <mv_common.h>
+#include <mv_gaze_tracking_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file   mv_gaze_tracking.h
+ * @internal
+ * @brief  This file contains the Inference based Media Vision API.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_INFERENCE_MODULE
+ * @{
+ */
+
+/**
+ * @internal
+ * @brief Set user-given model information.
+ * @details Use this function to change the model information instead of default one after calling @ref mv_gaze_tracking_create().
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle        The handle to the gaze tracking object.
+ * @param[in] model_file    Model file name.
+ * @param[in] meta_file     Model meta file name.
+ * @param[in] label_file    Label file name.
+ * @param[in] model_name    Model name.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a gaze tracking handle by calling @ref mv_gaze_tracking_create()
+ */
+int mv_gaze_tracking_set_model(mv_gaze_tracking_h handle, const char *model_file, const char *meta_file,
+                                                          const char *label_file, const char *model_name);
+
+/**
+ * @internal
+ * @brief Set user-given inference engine and device types for inference.
+ * @details Use this function to change the inference engine and device types for inference instead of default ones after calling @ref mv_gaze_tracking_create().
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle        The handle to the gaze tracking object.
+ * @param[in] engine_type  A string of inference engine type.
+ * @param[in] device_type   A string of device type.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a gaze tracking handle by calling @ref mv_gaze_tracking_create()
+ */
+int mv_gaze_tracking_set_engine(mv_gaze_tracking_h handle, const char *engine_type, const char *device_type);
+
+/**
+ * @internal
+ * @brief Get a number of inference engines available for gaze tracking task API.
+ * @details Use this function to get how many inference engines are supported for gaze tracking after calling @ref mv_gaze_tracking_create().
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle         The handle to the gaze tracking object.
+ * @param[out] engine_count  A number of inference engines available for gaze tracking API.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a gaze tracking handle by calling @ref mv_gaze_tracking_create()
+ */
+int mv_gaze_tracking_get_engine_count(mv_gaze_tracking_h handle, unsigned int *engine_count);
+
+/**
+ * @internal
+ * @brief Get engine type to a given inference engine index.
+ * @details Use this function to get inference engine type with a given engine index after calling @ref mv_gaze_tracking_get_engine_count().
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle        The handle to the gaze tracking object.
+ * @param[in] engine_index  A inference engine index for getting the inference engine type.
+ * @param[out] engine_type  A string to inference engine.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Get a number of inference engines available for gaze tracking task API by calling @ref mv_gaze_tracking_get_engine_count()
+ */
+int mv_gaze_tracking_get_engine_type(mv_gaze_tracking_h handle, const unsigned int engine_index, char **engine_type);
+
+/**
+ * @internal
+ * @brief Get a number of device types available to a given inference engine.
+ * @details Use this function to get how many device types are supported for a given inference engine after calling @ref mv_gaze_tracking_create().
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle         The handle to the gaze tracking object.
+ * @param[in] engine_type    A inference engine string.
+ * @param[out] device_count  A number of device types available for a given inference engine.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a gaze tracking handle by calling @ref mv_gaze_tracking_create()
+ */
+int mv_gaze_tracking_get_device_count(mv_gaze_tracking_h handle, const char *engine_type, unsigned int *device_count);
+
+/**
+ * @internal
+ * @brief Get device type list available.
+ * @details Use this function to get what device types are supported for current inference engine type after calling @ref mv_gaze_tracking_configure().
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle         The handle to the gaze tracking object.
+ * @param[in] engine_type    A inference engine string.
+ * @param[in] device_index   A device index for getting the device type.
+ * @param[out] device_type   A string to device type.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a gaze tracking handle by calling @ref mv_gaze_tracking_create()
+ * @pre Configure gaze tracking task by calling @ref mv_gaze_tracking_configure()
+ */
+int mv_gaze_tracking_get_device_type(mv_gaze_tracking_h handle, const char *engine_type,
+                                                                        const unsigned int device_index, char **device_type);
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_GAZE_TRACKING_INTERNAL_H__ */
diff --git a/include/mv_gaze_tracking_type.h b/include/mv_gaze_tracking_type.h
new file mode 100644 (file)
index 0000000..9121e10
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIAVISION_MV_GAZE_TRACKING_TYPE_H__
+#define __TIZEN_MEDIAVISION_MV_GAZE_TRACKING_TYPE_H__
+
+#include <mv_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file   mv_gaze_tracking_type.h
+ * @brief  This file contains the gaze tracking handle for Mediavision.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_GAZE_TRACKING_MODULE
+ * @{
+ */
+
+/**
+ * @brief The gaze tracking object handle.
+ *
+ * @since_tizen 9.0
+ */
+typedef void *mv_gaze_tracking_h;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_MV_GAZE_TRACKING_TYPE_H__ */
index e9b8ad5d147994e5e2378f27bb2e293e092acb0f..5f15514d63d87f27db54c38b57a276c24fcce765 100644 (file)
@@ -25,4 +25,7 @@ endif()
 if (${ENABLE_ML_IMAGE_SEGMENTATION})
     message("Enabled machine learning image segmentation feature.")
     add_subdirectory(image_segmentation)
-endif()
\ No newline at end of file
+endif()
+
+message("Enabled machine learning gaze tracking feature.")
+add_subdirectory(gaze_tracking)
index 0f70c3765473c60a88da06cd6f6be8ea39f96f3d..89572585b7ceb7371445f2037b60dd9d3dfda984 100644 (file)
@@ -51,7 +51,7 @@ private:
        using CallbackType = std::function<void()>;
 
        const std::chrono::seconds _INPUT_QUEUE_WAIT_TIME_SEC { 1 };
-       const std::chrono::seconds _OUTPUT_QUEUE_WAIT_TIME_SEC { 3 };
+       const std::chrono::seconds _OUTPUT_QUEUE_WAIT_TIME_SEC { 7 };
        std::queue<AsyncInputQueue<T> > _incoming_queue;
        std::queue<R> _outgoing_queue;
        std::mutex _incoming_queue_mutex;
index 16233260cf89fdd3a58e0cecaffee76c763de894..67e8fb608b8186840b34797d28e4451ba2fc887a 100644 (file)
@@ -150,7 +150,7 @@ void Config::parseConfigFile(const std::string &configFilePath)
 
        ret = config->getStringAttribute(MV_MODEL_LABEL_FILE_NAME, &_modelLabelFilePath);
        if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get model label file path");
+               LOGW("Fail to get model label file path");
 
        _modelLabelFilePath = _modelDefaultPath + _modelLabelFilePath;
 
diff --git a/mv_machine_learning/gaze_tracking/CMakeLists.txt b/mv_machine_learning/gaze_tracking/CMakeLists.txt
new file mode 100644 (file)
index 0000000..88da62f
--- /dev/null
@@ -0,0 +1,28 @@
+project(${MV_GAZE_TRACKING_LIB_NAME})
+cmake_minimum_required(VERSION 3.13)
+
+pkg_check_modules(${PROJECT_NAME}_DEP REQUIRED inference-engine-interface-common iniparser json-glib-1.0)
+file(GLOB MV_GAZE_TRACKING_SOURCE_LIST  "${PROJECT_SOURCE_DIR}/src/*.c" "${PROJECT_SOURCE_DIR}/src/*.cpp")
+
+find_package(OpenCV REQUIRED dnn imgproc)
+if(NOT OpenCV_FOUND)
+       message(SEND_ERROR "OpenCV NOT FOUND")
+       return()
+endif()
+
+add_library(${PROJECT_NAME} SHARED ${MV_GAZE_TRACKING_SOURCE_LIST})
+target_link_libraries(${PROJECT_NAME} ${MV_COMMON_LIB_NAME} ${OpenCV_LIBS} ${${PROJECT_NAME}_DEP_LIBRARIES} mv_ml_common mv_inference)
+target_include_directories(${PROJECT_NAME} PRIVATE include ../inference/include ../common/include ../common/meta/include ${${PROJECT_NAME}_DEP_INCLUDE_DIRS})
+install(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
+install(
+       DIRECTORY ${PROJECT_SOURCE_DIR}/../../include/ DESTINATION include/media
+       FILES_MATCHING
+       PATTERN "mv_gaze_tracking_internal.h"
+       PATTERN "mv_gaze_tracking.h"
+       PATTERN "mv_gaze_tracking_type.h"
+       )
+install(
+       DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include/media
+       FILES_MATCHING
+       PATTERN "gaze_tracking_type.h"
+       )
diff --git a/mv_machine_learning/gaze_tracking/include/GazeTracking.h b/mv_machine_learning/gaze_tracking/include/GazeTracking.h
new file mode 100644 (file)
index 0000000..5f6c3c1
--- /dev/null
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __GAZE_TRACKING_H__
+#define __GAZE_TRACKING_H__
+
+#include <atomic>
+#include <mutex>
+#include <queue>
+#include <thread>
+
+#include "mv_private.h"
+#include <mv_common.h>
+#include <mv_inference_type.h>
+
+#include "AsyncManager.h"
+#include "EngineConfig.h"
+#include "GazeTrackingParser.h"
+#include "IGazeTracking.h"
+#include "Inference.h"
+#include "MetaParser.h"
+#include "MvMlConfig.h"
+#include "MvMlPreprocess.h"
+#include "gaze_tracking_type.h"
+#include "inference_engine_common_impl.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class GazeTracking : public IGazeTracking
+{
+private:
+       GazeTrackingTaskType _task_type { GazeTrackingTaskType::GAZE_TRACKINGION_TASK_NONE };
+       std::unique_ptr<AsyncManager<T, GazeTrackingResult> > _async_manager;
+       GazeTrackingResult _current_result;
+
+       void getEngineList();
+       void getDeviceList(const std::string &engine_type);
+       void configurePreprocess();
+       std::shared_ptr<MetaInfo> getInputMetaInfo();
+
+protected:
+       std::unique_ptr<mediavision::inference::Inference> _inference;
+       std::shared_ptr<Config> _config;
+       std::vector<std::string> _valid_backends;
+       std::vector<std::string> _valid_devices;
+       Preprocess _preprocess;
+
+       void getOutputNames(std::vector<std::string> &names);
+       void getOutputTensor(std::string target_name, std::vector<float> &tensor);
+       void inference(std::vector<std::vector<T> > &inputVectors);
+       virtual GazeTrackingResult &result() = 0;
+
+public:
+       explicit GazeTracking(GazeTrackingTaskType task_type, std::shared_ptr<Config> config);
+       virtual ~GazeTracking() = default;
+
+       void preDestroy() override;
+       GazeTrackingTaskType getTaskType() override;
+       void setUserModel(std::string model_file, std::string meta_file, std::string label_file);
+       void setEngineInfo(std::string engine_type_name, std::string device_type_name) override;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
+       void configure() override;
+       void prepare() override;
+       void perform(mv_source_h &mv_src) override;
+       void performAsync(GazeTrackingInput &input) override;
+       GazeTrackingResult &getOutput() override;
+       GazeTrackingResult &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/gaze_tracking/include/GazeTrackingAdapter.h b/mv_machine_learning/gaze_tracking/include/GazeTrackingAdapter.h
new file mode 100644 (file)
index 0000000..05389a5
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __GAZE_TRACKING_ADAPTER_H__
+#define __GAZE_TRACKING_ADAPTER_H__
+
+#include <dlog.h>
+
+#include "EngineConfig.h"
+#include "ITask.h"
+#include "L2CSNet.h"
+#include "MvMlConfig.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class GazeTrackingAdapter : public mediavision::common::ITask
+{
+private:
+       std::unique_ptr<IGazeTracking> _gaze_tracking;
+       std::shared_ptr<Config> _config;
+       const std::string _config_file_name = "gaze_tracking.json";
+       const std::string _plugin_config_file_name = "gaze_tracking_plugin.json";
+
+       void create(const std::string &model_name = "");
+       template<typename U> void create(GazeTrackingTaskType task_type);
+       GazeTrackingTaskType convertToTaskType(std::string model_name);
+
+public:
+       GazeTrackingAdapter();
+       ~GazeTrackingAdapter();
+
+       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
+                                         const std::string &model_name) override;
+       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
+       void configure() override;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
+       void prepare() override;
+       void perform(InputBaseType &input) override;
+       void performAsync(InputBaseType &input) override;
+       OutputBaseType &getOutput() override;
+       OutputBaseType &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/gaze_tracking/include/GazeTrackingParser.h b/mv_machine_learning/gaze_tracking/include/GazeTrackingParser.h
new file mode 100644 (file)
index 0000000..9739413
--- /dev/null
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __GAZE_TRACKING_PARSER_H__
+#define __GAZE_TRACKING_PARSER_H__
+
+#include "MetaParser.h"
+#include "PostprocessParser.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class GazeTrackingParser : public MetaParser
+{
+private:
+       PostprocessParser _postprocessParser;
+
+protected:
+       void parsePostprocess(std::shared_ptr<MetaInfo> meta_info, JsonObject *in_obj) override;
+
+public:
+       GazeTrackingParser(int task_type = 0);
+       ~GazeTrackingParser();
+};
+
+}
+}
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/gaze_tracking/include/IGazeTracking.h b/mv_machine_learning/gaze_tracking/include/IGazeTracking.h
new file mode 100644 (file)
index 0000000..6016823
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __IGAZE_TRACKING_H__
+#define __IGAZE_TRACKING_H__
+
+#include <mv_common.h>
+
+#include "gaze_tracking_type.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class IGazeTracking
+{
+public:
+       virtual ~IGazeTracking() {};
+
+       virtual void preDestroy() = 0;
+       virtual GazeTrackingTaskType getTaskType() = 0;
+       virtual void setEngineInfo(std::string engine_type, std::string device_type) = 0;
+       virtual unsigned int getNumberOfEngines() = 0;
+       virtual const std::string &getEngineType(unsigned int engine_index) = 0;
+       virtual unsigned int getNumberOfDevices(const std::string &engine_type) = 0;
+       virtual const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) = 0;
+       virtual void configure() = 0;
+       virtual void prepare() = 0;
+       virtual void perform(mv_source_h &mv_src) = 0;
+       virtual void performAsync(GazeTrackingInput &input) = 0;
+       virtual GazeTrackingResult &getOutput() = 0;
+       virtual GazeTrackingResult &getOutputCache() = 0;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/gaze_tracking/include/L2CSNet.h b/mv_machine_learning/gaze_tracking/include/L2CSNet.h
new file mode 100644 (file)
index 0000000..e59e18a
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __L2CSNet_H__
+#define __L2CSNet_H__
+
+#include "mv_private.h"
+#include <memory>
+#include <mv_common.h>
+#include <string>
+
+#include "GazeTracking.h"
+#include <mv_inference_type.h>
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class L2CSNet : public GazeTracking<T>
+{
+       using GazeTracking<T>::_config;
+       using GazeTracking<T>::_preprocess;
+
+private:
+       GazeTrackingResult _result;
+
+public:
+       L2CSNet(GazeTrackingTaskType task_type, std::shared_ptr<Config> config);
+       ~L2CSNet();
+
+       GazeTrackingResult &result() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/gaze_tracking/include/gaze_tracking_type.h b/mv_machine_learning/gaze_tracking/include/gaze_tracking_type.h
new file mode 100644 (file)
index 0000000..020f479
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __GAZE_TRACKINGION_TYPE_H__
+#define __GAZE_TRACKINGION_TYPE_H__
+
+#include <opencv2/core.hpp>
+
+#include "mv_ml_types.h"
+#include <mv_common.h>
+#include <mv_inference_type.h>
+
+namespace mediavision
+{
+namespace machine_learning
+{
+struct GazeTrackingInput : public InputBaseType {
+       GazeTrackingInput(mv_source_h src = nullptr) : InputBaseType(src)
+       {}
+};
+
+/**
+ * @brief The gaze_tracking result structure.
+ * @details Contains gaze_tracking result.
+ */
+struct GazeTrackingResult : public OutputBaseType {
+       unsigned int number_of_faces {};
+       std::vector<unsigned int> indices;
+       std::vector<float> confidences;
+       std::vector<float> yaws;
+       std::vector<float> pitches;
+       std::vector<float> x_pos;
+       std::vector<float> y_pos;
+};
+
+enum class GazeTrackingTaskType {
+       GAZE_TRACKINGION_TASK_NONE = 0,
+       L2CS_NET,
+       // TODO
+};
+
+}
+}
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/gaze_tracking/include/mv_gaze_tracking_config.h b/mv_machine_learning/gaze_tracking/include/mv_gaze_tracking_config.h
new file mode 100644 (file)
index 0000000..6f6508e
--- /dev/null
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MEDIA_VISION_GAZE_TRACKING_CONFIG_H__
+#define __MEDIA_VISION_GAZE_TRACKING_CONFIG_H__
+
+/**
+ * @brief Defines #MV_GAZE_TRACKING_MODEL_DEFAULT_PATH
+ *        to set the gaze_tracking default path.
+ *
+ * @since_tizen 9.0
+ */
+#define MV_GAZE_TRACKING_MODEL_DEFAULT_PATH "MODEL_DEFAULT_PATH"
+
+/**
+ * @brief Defines #MV_GAZE_TRACKING_MODEL_FILE_PATH
+ *        to set the gaze_tracking model file path.
+ *
+ * @since_tizen 9.0
+ */
+#define MV_GAZE_TRACKING_MODEL_FILE_PATH "MODEL_FILE_NAME"
+
+/**
+ * @brief Defines #MV_GAZE_TRACKING_DEFAULT_MODEL_NAME
+ *        to set the gaze_tracking default model name.
+ *
+ * @since_tizen 9.0
+ */
+#define MV_GAZE_TRACKING_DEFAULT_MODEL_NAME "DEFAULT_MODEL_NAME"
+
+/**
+ * @brief Defines #MV_GAZE_TRACKING_3D_MODEL_META_FILE_PATH to set inference
+ *        models's metadata file attribute of the engine configuration.
+ * @details The file includes inference model's metadata such as input and output
+ *          node names, input tensor's width and height,
+ *          mean and standard deviation values for pre-processing.
+ *
+ * @since_tizen 9.0
+ */
+#define MV_GAZE_TRACKING_MODEL_META_FILE_PATH "META_FILE_NAME"
+
+#define MV_GAZE_TRACKING_LABEL_FILE_NAME "LABEL_FILE_NAME"
+
+/**
+ * @brief Defines #MV_GAZE_TRACKING_BACKEND_TYPE
+ *        to set inference backend engine type. In default, tensorflow lite is used.
+ *
+ * @since_tizen 9.0
+ */
+#define MV_GAZE_TRACKING_BACKEND_TYPE "BACKEND_TYPE"
+
+/**
+ * @brief Defines #MV_GAZE_TRACKING_TARGET_DEVICE_TYPE
+ *        to set inference target device type. In default, CPU device is used.
+ *
+ * @since_tizen 9.0
+ */
+#define MV_GAZE_TRACKING_TARGET_DEVICE_TYPE "TARGET_DEVICE_TYPE"
+
+#endif /* __MEDIA_VISION_GAZE_TRACKING_CONFIG_H__ */
diff --git a/mv_machine_learning/gaze_tracking/meta/gaze_tracking.json b/mv_machine_learning/gaze_tracking/meta/gaze_tracking.json
new file mode 100644 (file)
index 0000000..aa81ae0
--- /dev/null
@@ -0,0 +1,35 @@
+{
+    "attributes":
+    [
+        {
+            "name" : "MODEL_DEFAULT_PATH",
+            "type" : "string",
+            "value" : "/opt/usr/globalapps/mediavision.gaze.tracking/models/tflite/"
+        },
+               {
+            "name"  : "MODEL_FILE_NAME",
+            "type"  : "string",
+            "value" : "l2cs_net_1x3x448x448_float32.tflite"
+        },
+        {
+            "name"  : "DEFAULT_MODEL_NAME",
+            "type"  : "string",
+            "value" : "L2CS_NET"
+        },
+        {
+            "name"  : "MODEL_META_FILE_NAME",
+            "type"  : "string",
+            "value" : "l2cs_net_1x3x448x448_float32.json"
+        },
+        {
+            "name"  : "BACKEND_TYPE",
+            "type"  : "integer",
+            "value" : 1
+        },
+        {
+            "name"  : "TARGET_DEVICE_TYPE",
+            "type"  : "integer",
+            "value" : 1
+        }
+    ]
+}
diff --git a/mv_machine_learning/gaze_tracking/meta/gaze_tracking_plugin.json b/mv_machine_learning/gaze_tracking/meta/gaze_tracking_plugin.json
new file mode 100644 (file)
index 0000000..bc56eee
--- /dev/null
@@ -0,0 +1,20 @@
+{
+    "attributes":
+    [
+        {
+            "name" : "PLUGIN_NAME",
+            "type" : "string",
+            "value" : "libgaze_tracking_plugin.so"
+        },
+        {
+            "name"  : "DEFAULT_MODEL_NAME",
+            "type"  : "string",
+            "value" : "L2CS_NET"
+        },
+        {
+            "name"  : "USE_PLUGIN",
+            "type"  : "boolean",
+            "value" : false
+        }
+    ]
+}
diff --git a/mv_machine_learning/gaze_tracking/src/GazeTracking.cpp b/mv_machine_learning/gaze_tracking/src/GazeTracking.cpp
new file mode 100644 (file)
index 0000000..455ab24
--- /dev/null
@@ -0,0 +1,316 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fstream>
+#include <map>
+#include <memory>
+#include <string.h>
+
+#include "GazeTracking.h"
+#include "MvMlException.h"
+#include "common.h"
+#include "mv_gaze_tracking_config.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace MediaVision::Common;
+using namespace mediavision::common;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T>
+GazeTracking<T>::GazeTracking(GazeTrackingTaskType task_type, shared_ptr<Config> config)
+               : _task_type(task_type), _config(config)
+{
+       _inference = make_unique<Inference>();
+}
+
+template<typename T> void GazeTracking<T>::preDestroy()
+{
+       if (!_async_manager)
+               return;
+
+       _async_manager->stop();
+}
+
+template<typename T> GazeTrackingTaskType GazeTracking<T>::getTaskType()
+{
+       return _task_type;
+}
+
+template<typename T> void GazeTracking<T>::getEngineList()
+{
+       for (auto idx = MV_INFERENCE_BACKEND_NONE + 1; idx < MV_INFERENCE_BACKEND_MAX; ++idx) {
+               auto backend = _inference->getSupportedInferenceBackend(idx);
+               // TODO. we need to describe what inference engines are supported by each Task API,
+               //       and based on it, below inference engine types should be checked
+               //       if a given type is supported by this Task API later. As of now, tflite only.
+               if (backend.second == true && backend.first.compare("tflite") == 0)
+                       _valid_backends.push_back(backend.first);
+       }
+}
+
+template<typename T> void GazeTracking<T>::getDeviceList(const string &engine_type)
+{
+       // TODO. add device types available for a given engine type later.
+       //       In default, cpu and gpu only.
+       _valid_devices.push_back("cpu");
+       _valid_devices.push_back("gpu");
+}
+
+template<typename T> void GazeTracking<T>::setEngineInfo(std::string engine_type_name, std::string device_type_name)
+{
+       if (engine_type_name.empty() || device_type_name.empty())
+               throw InvalidParameter("Invalid engine info.");
+
+       transform(engine_type_name.begin(), engine_type_name.end(), engine_type_name.begin(), ::toupper);
+       transform(device_type_name.begin(), device_type_name.end(), device_type_name.begin(), ::toupper);
+
+       int engine_type = GetBackendType(engine_type_name);
+       int device_type = GetDeviceType(device_type_name);
+
+       if (engine_type == MEDIA_VISION_ERROR_INVALID_PARAMETER || device_type == MEDIA_VISION_ERROR_INVALID_PARAMETER)
+               throw InvalidParameter("backend or target device type not found.");
+
+       _config->setBackendType(engine_type);
+       _config->setTargetDeviceType(device_type);
+
+       LOGI("Engine type : %s => %d, Device type : %s => %d", engine_type_name.c_str(), engine_type,
+                device_type_name.c_str(), device_type);
+}
+
+template<typename T> unsigned int GazeTracking<T>::getNumberOfEngines()
+{
+       if (!_valid_backends.empty()) {
+               return _valid_backends.size();
+       }
+
+       getEngineList();
+       return _valid_backends.size();
+}
+
+template<typename T> const string &GazeTracking<T>::getEngineType(unsigned int engine_index)
+{
+       if (!_valid_backends.empty()) {
+               if (_valid_backends.size() <= engine_index)
+                       throw InvalidParameter("Invalid engine index.");
+
+               return _valid_backends[engine_index];
+       }
+
+       getEngineList();
+
+       if (_valid_backends.size() <= engine_index)
+               throw InvalidParameter("Invalid engine index.");
+
+       return _valid_backends[engine_index];
+}
+
+template<typename T> unsigned int GazeTracking<T>::getNumberOfDevices(const string &engine_type)
+{
+       if (!_valid_devices.empty()) {
+               return _valid_devices.size();
+       }
+
+       getDeviceList(engine_type);
+       return _valid_devices.size();
+}
+
+template<typename T> const string &GazeTracking<T>::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       if (!_valid_devices.empty()) {
+               if (_valid_devices.size() <= device_index)
+                       throw InvalidParameter("Invalid device index.");
+
+               return _valid_devices[device_index];
+       }
+
+       getDeviceList(engine_type);
+
+       if (_valid_devices.size() <= device_index)
+               throw InvalidParameter("Invalid device index.");
+
+       return _valid_devices[device_index];
+}
+
+template<typename T> void GazeTracking<T>::configure()
+{
+       int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to bind a backend engine.");
+}
+
+template<typename T> void GazeTracking<T>::prepare()
+{
+       int ret = _inference->configureInputMetaInfo(_config->getInputMetaMap());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to configure input tensor info from meta file.");
+
+       ret = _inference->configureOutputMetaInfo(_config->getOutputMetaMap());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to configure output tensor info from meta file.");
+
+       _inference->configureModelFiles("", _config->getModelFilePath(), "");
+
+       // Request to load model files to a backend engine.
+       ret = _inference->load();
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to load model files.");
+
+       configurePreprocess();
+}
+
+template<typename T> shared_ptr<MetaInfo> GazeTracking<T>::getInputMetaInfo()
+{
+       TensorBuffer &tensor_buffer = _inference->getInputTensorBuffer();
+       IETensorBuffer &tensor_info_map = tensor_buffer.getIETensorBuffer();
+
+       // TODO. consider using multiple tensors later.
+       if (tensor_info_map.size() != 1)
+               throw InvalidOperation("Input tensor count not invalid.");
+
+       auto tensor_buffer_iter = tensor_info_map.begin();
+
+       // Get the meta information corresponding to a given input tensor name.
+       return _config->getInputMetaMap()[tensor_buffer_iter->first];
+}
+
+template<typename T> void GazeTracking<T>::configurePreprocess()
+{
+       LOGI("ENTER");
+
+       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
+
+       PreprocessConfig config = { false,
+                                                               metaInfo->colorSpace,
+                                                               metaInfo->dataType,
+                                                               metaInfo->getChannel(),
+                                                               metaInfo->getWidth(),
+                                                               metaInfo->getHeight() };
+
+       auto normalization = static_pointer_cast<DecodingNormal>(metaInfo->decodingTypeMap.at(DecodingType::NORMAL));
+       if (normalization) {
+               config.normalize = normalization->use;
+               config.mean = normalization->mean;
+               config.std = normalization->std;
+       }
+
+       auto quantization =
+                       static_pointer_cast<DecodingQuantization>(metaInfo->decodingTypeMap.at(DecodingType::QUANTIZATION));
+       if (quantization) {
+               config.quantize = quantization->use;
+               config.scale = quantization->scale;
+               config.zeropoint = quantization->zeropoint;
+       }
+
+       _preprocess.setConfig(config);
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void GazeTracking<T>::inference(vector<vector<T> > &inputVectors)
+{
+       LOGI("ENTER");
+
+       int ret = _inference->run<T>(inputVectors);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to run inference");
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void GazeTracking<T>::perform(mv_source_h &mv_src)
+{
+       vector<vector<T> > inputVectors(1);
+
+       _preprocess.run<T>(mv_src, inputVectors[0]);
+
+       inference(inputVectors);
+}
+
+template<typename T> void GazeTracking<T>::performAsync(GazeTrackingInput &input)
+{
+       if (!_async_manager) {
+               _async_manager = make_unique<AsyncManager<T, GazeTrackingResult> >([this]() {
+                       AsyncInputQueue<T> inputQueue = _async_manager->popFromInput();
+
+                       inference(inputQueue.inputs);
+
+                       GazeTrackingResult &resultQueue = result();
+
+                       resultQueue.frame_number = inputQueue.frame_number;
+                       _async_manager->pushToOutput(resultQueue);
+               });
+       }
+
+       vector<vector<T> > inputVectors(1);
+
+       _preprocess.run<T>(input.inference_src, inputVectors[0]);
+
+       _async_manager->push(inputVectors);
+}
+
+template<typename T> GazeTrackingResult &GazeTracking<T>::getOutput()
+{
+       if (_async_manager) {
+               if (!_async_manager->isWorking())
+                       throw InvalidOperation("Object detection has been already destroyed so invalid operation.");
+
+               _current_result = _async_manager->pop();
+       } else {
+               // TODO. Check if inference request is completed or not here.
+               //       If not then throw an exception.
+               _current_result = result();
+       }
+
+       return _current_result;
+}
+
+template<typename T> GazeTrackingResult &GazeTracking<T>::getOutputCache()
+{
+       return _current_result;
+}
+
+template<typename T> void GazeTracking<T>::getOutputNames(vector<string> &names)
+{
+       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
+       IETensorBuffer &ie_tensor_buffer = tensor_buffer_obj.getIETensorBuffer();
+
+       for (IETensorBuffer::iterator it = ie_tensor_buffer.begin(); it != ie_tensor_buffer.end(); it++)
+               names.push_back(it->first);
+}
+
+template<typename T> void GazeTracking<T>::getOutputTensor(string target_name, vector<float> &tensor)
+{
+       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
+
+       inference_engine_tensor_buffer *tensor_buffer = tensor_buffer_obj.getTensorBuffer(target_name);
+       if (!tensor_buffer)
+               throw InvalidOperation("Fail to get tensor buffer.");
+
+       auto raw_buffer = static_cast<float *>(tensor_buffer->buffer);
+
+       copy(&raw_buffer[0], &raw_buffer[tensor_buffer->size / sizeof(float)], back_inserter(tensor));
+}
+
+template class GazeTracking<float>;
+template class GazeTracking<unsigned char>;
+
+}
+}
diff --git a/mv_machine_learning/gaze_tracking/src/GazeTrackingAdapter.cpp b/mv_machine_learning/gaze_tracking/src/GazeTrackingAdapter.cpp
new file mode 100644 (file)
index 0000000..6c95f5d
--- /dev/null
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GazeTrackingAdapter.h"
+#include "MvMlException.h"
+#include "gaze_tracking_type.h"
+#include "mv_gaze_tracking_config.h"
+
+using namespace std;
+using namespace MediaVision::Common;
+using namespace mediavision::machine_learning;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+GazeTrackingAdapter::GazeTrackingAdapter()
+{
+       _config = make_shared<Config>();
+
+       // If the model type needs external plugin then bypass to load the meta file and just create the external plugin.
+       // In this case, external plugin will use its own meta file approach regardless of Mediavision's one.
+       _config->parsePluginConfigFile(_plugin_config_file_name);
+       if (!_config->isPluginUsed())
+               _config->parseConfigFile(_config_file_name);
+
+       create(_config->getDefaultModelName());
+}
+
+GazeTrackingAdapter::~GazeTrackingAdapter()
+{
+       _gaze_tracking->preDestroy();
+}
+
+template<typename U> void GazeTrackingAdapter::create(GazeTrackingTaskType task_type)
+{
+       switch (task_type) {
+       case GazeTrackingTaskType::L2CS_NET:
+               _gaze_tracking = make_unique<L2CSNet<U> >(task_type, _config);
+               break;
+       default:
+               throw InvalidOperation("Invalid gaze tracking task type.");
+       }
+       // TODO.
+}
+
+void GazeTrackingAdapter::create(const string &model_name)
+{
+       auto task_type = convertToTaskType(model_name.empty() ? _config->getDefaultModelName() : model_name);
+
+       _config->loadMetaFile(make_unique<GazeTrackingParser>(static_cast<int>(task_type)));
+       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
+
+       switch (dataType) {
+       case MV_INFERENCE_DATA_UINT8:
+               create<unsigned char>(task_type);
+               break;
+       case MV_INFERENCE_DATA_FLOAT32:
+               create<float>(task_type);
+               break;
+       default:
+               throw InvalidOperation("Invalid gaze tracking data type.");
+       }
+}
+
+GazeTrackingTaskType GazeTrackingAdapter::convertToTaskType(string model_name)
+{
+       if (model_name.empty())
+               throw InvalidParameter("model name is empty.");
+
+       transform(model_name.begin(), model_name.end(), model_name.begin(), ::toupper);
+
+       if (model_name == "L2CS_NET")
+               return GazeTrackingTaskType::L2CS_NET;
+       // TODO.
+
+       throw InvalidParameter("Invalid gaze tracking model name.");
+}
+
+void GazeTrackingAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
+                                                                          const string &model_name)
+{
+       try {
+               _config->setUserModel(model_file, meta_file, label_file);
+               create(model_name);
+       } catch (const BaseException &e) {
+               LOGW("A given model name is invalid so default task type will be used.");
+       }
+
+       if (model_file.empty() && meta_file.empty()) {
+               LOGW("Given model info is invalid so default model info will be used instead.");
+               return;
+       }
+}
+
+void GazeTrackingAdapter::setEngineInfo(const string &engine_type, const string &device_type)
+{
+       _gaze_tracking->setEngineInfo(string(engine_type), string(device_type));
+}
+
+void GazeTrackingAdapter::configure()
+{
+       _gaze_tracking->configure();
+}
+
+unsigned int GazeTrackingAdapter::getNumberOfEngines()
+{
+       return _gaze_tracking->getNumberOfEngines();
+}
+
+const string &GazeTrackingAdapter::getEngineType(unsigned int engine_index)
+{
+       return _gaze_tracking->getEngineType(engine_index);
+}
+
+unsigned int GazeTrackingAdapter::getNumberOfDevices(const string &engine_type)
+{
+       return _gaze_tracking->getNumberOfDevices(engine_type);
+}
+
+const string &GazeTrackingAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       return _gaze_tracking->getDeviceType(engine_type, device_index);
+}
+
+void GazeTrackingAdapter::prepare()
+{
+       _gaze_tracking->prepare();
+}
+
+void GazeTrackingAdapter::perform(InputBaseType &input)
+{
+       _gaze_tracking->perform(input.inference_src);
+}
+
+OutputBaseType &GazeTrackingAdapter::getOutput()
+{
+       return _gaze_tracking->getOutput();
+}
+
+OutputBaseType &GazeTrackingAdapter::getOutputCache()
+{
+       return _gaze_tracking->getOutputCache();
+}
+
+void GazeTrackingAdapter::performAsync(InputBaseType &input)
+{
+       _gaze_tracking->performAsync(static_cast<GazeTrackingInput &>(input));
+}
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/gaze_tracking/src/GazeTrackingParser.cpp b/mv_machine_learning/gaze_tracking/src/GazeTrackingParser.cpp
new file mode 100644 (file)
index 0000000..2c82d47
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <memory>
+
+#include "GazeTrackingParser.h"
+#include "MvMlException.h"
+#include "gaze_tracking_type.h"
+
+using namespace std;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+GazeTrackingParser::GazeTrackingParser(int task_type)
+{
+       LOGI("ENTER");
+
+       LOGI("LEAVE");
+}
+
+GazeTrackingParser::~GazeTrackingParser()
+{}
+
+void GazeTrackingParser::parsePostprocess(shared_ptr<MetaInfo> meta_info, JsonObject *in_obj)
+{
+       LOGI("ENTER");
+
+       LOGI("tensor name : %s", meta_info->name.c_str());
+
+       if (json_object_has_member(in_obj, "score"))
+               _postprocessParser.parseScore(meta_info, in_obj);
+
+       LOGI("LEAVE");
+}
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/gaze_tracking/src/L2CSNet.cpp b/mv_machine_learning/gaze_tracking/src/L2CSNet.cpp
new file mode 100644 (file)
index 0000000..ec53714
--- /dev/null
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cmath>
+#include <map>
+#include <string.h>
+
+#include "L2CSNet.h"
+#include "MvMlException.h"
+#include "Postprocess.h"
+#include "mv_gaze_tracking_config.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T>
+L2CSNet<T>::L2CSNet(GazeTrackingTaskType task_type, std::shared_ptr<Config> config)
+               : GazeTracking<T>(task_type, config), _result()
+{}
+
+template<typename T> L2CSNet<T>::~L2CSNet()
+{}
+
+template<typename T> GazeTrackingResult &L2CSNet<T>::result()
+{
+       // Clear _result object because result() function can be called every time user wants
+       // so make sure to clear existing result data before getting the data again.
+       _result = GazeTrackingResult();
+
+       vector<string> names;
+
+       GazeTracking<T>::getOutputNames(names);
+
+       vector<float> outputTensor;
+
+       GazeTracking<T>::getOutputTensor(names[0], outputTensor);
+       float yaw = outputTensor[0];
+       float pitch = outputTensor[1];
+
+       LOGD("L2CSNet: yaw: %f, pitch: %f", yaw, pitch);
+
+       _result.frame_number++;
+       _result.number_of_faces = 1;
+       _result.yaws.push_back(yaw);
+       _result.pitches.push_back(pitch);
+       _result.x_pos.push_back(tan(yaw));
+       _result.y_pos.push_back(acos(yaw) * tan(pitch));
+
+       return _result;
+}
+
+template class L2CSNet<float>;
+template class L2CSNet<unsigned char>;
+
+}
+}
diff --git a/mv_machine_learning/gaze_tracking/src/mv_gaze_tracking.cpp b/mv_machine_learning/gaze_tracking/src/mv_gaze_tracking.cpp
new file mode 100644 (file)
index 0000000..804d62e
--- /dev/null
@@ -0,0 +1,377 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_gaze_tracking.h"
+#include "Context.h"
+#include "GazeTrackingAdapter.h"
+#include "ITask.h"
+#include "MvMlException.h"
+#include "gaze_tracking_type.h"
+#include "mv_feature_key.h"
+#include "mv_gaze_tracking_internal.h"
+#include "mv_private.h"
+#include "native_capi.h"
+
+#include <algorithm>
+#include <exception>
+#include <iostream>
+#include <mutex>
+#include <new>
+#include <string>
+#include <unistd.h>
+
+#define TASK_NAME "gaze_tracking"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace mediavision::common;
+using namespace mediavision::machine_learning;
+using namespace MediaVision::Common;
+using namespace mediavision::machine_learning::exception;
+
+static const char *feature_keys[] = { "http://tizen.org/feature/vision.inference",
+                                                                         "http://tizen.org/feature/vision.inference.image" };
+static const size_t num_keys = sizeof(feature_keys) / sizeof(char *);
+
+int mv_gaze_tracking_create(mv_gaze_tracking_h *handle)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_NULL_ARG_CHECK(handle);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       mv_gaze_tracking_h ctx = nullptr;
+
+       try {
+               ctx = machine_learning_native_create();
+               machine_learning_native_add(ctx, TASK_NAME, new GazeTrackingAdapter());
+       } catch (const BaseException &e) {
+               return e.getError();
+       } catch (const std::exception &e) {
+               LOGE("%s", e.what());
+               return MEDIA_VISION_ERROR_INTERNAL;
+       }
+
+       *handle = ctx;
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_destroy(mv_gaze_tracking_h handle)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       machine_learning_native_destroy(handle);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_set_model(mv_gaze_tracking_h handle, const char *model_file, const char *meta_file,
+                                                          const char *label_file, const char *model_name)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_set_model(handle, TASK_NAME, model_file, meta_file, label_file, model_name);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_set_engine(mv_gaze_tracking_h handle, const char *backend_type, const char *device_type)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(backend_type);
+       MEDIA_VISION_NULL_ARG_CHECK(device_type);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_set_engine(handle, TASK_NAME, backend_type, device_type);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_get_engine_count(mv_gaze_tracking_h handle, unsigned int *engine_count)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(engine_count);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_get_engine_count(handle, TASK_NAME, engine_count);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_get_engine_type(mv_gaze_tracking_h handle, const unsigned int engine_index, char **engine_type)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(engine_type);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_get_engine_type(handle, TASK_NAME, engine_index, engine_type);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_get_device_count(mv_gaze_tracking_h handle, const char *engine_type, unsigned int *device_count)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(device_count);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_get_device_count(handle, TASK_NAME, engine_type, device_count);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_get_device_type(mv_gaze_tracking_h handle, const char *engine_type,
+                                                                        const unsigned int device_index, char **device_type)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(engine_type);
+       MEDIA_VISION_NULL_ARG_CHECK(device_type);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_get_device_type(handle, TASK_NAME, engine_type, device_index, device_type);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_configure(mv_gaze_tracking_h handle)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_configure(handle, TASK_NAME);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_prepare(mv_gaze_tracking_h handle)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_prepare(handle, TASK_NAME);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_inference(mv_gaze_tracking_h handle, mv_source_h source)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_INSTANCE_CHECK(source);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               GazeTrackingInput input(source);
+
+               machine_learning_native_inference(handle, TASK_NAME, input);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_inference_async(mv_gaze_tracking_h handle, mv_source_h source)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_INSTANCE_CHECK(source);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               GazeTrackingInput input(source);
+
+               machine_learning_native_inference_async(handle, TASK_NAME, input);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_get_result_count(mv_gaze_tracking_h handle, unsigned long *frame_number, unsigned int *result_cnt)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_INSTANCE_CHECK(frame_number);
+       MEDIA_VISION_INSTANCE_CHECK(result_cnt);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               auto &result = static_cast<GazeTrackingResult &>(machine_learning_native_get_result(handle, TASK_NAME));
+
+               *frame_number = result.frame_number;
+               *result_cnt = result.number_of_faces;
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_get_pos(mv_gaze_tracking_h handle, unsigned int index, float *x, float *y)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_INSTANCE_CHECK(x);
+       MEDIA_VISION_INSTANCE_CHECK(y);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               auto &result = static_cast<GazeTrackingResult &>(machine_learning_native_get_result_cache(handle, TASK_NAME));
+               if (index >= result.number_of_faces) {
+                       LOGE("Invalid index(index = %u, result count = %u).", index, result.number_of_faces);
+                       return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+               }
+
+               *x = result.x_pos[index];
+               *y = result.y_pos[index];
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_gaze_tracking_get_raw_data(mv_gaze_tracking_h handle, unsigned int index, float *yaw, float *pitch)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_INSTANCE_CHECK(yaw);
+       MEDIA_VISION_INSTANCE_CHECK(pitch);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               auto &result = static_cast<GazeTrackingResult &>(machine_learning_native_get_result_cache(handle, TASK_NAME));
+               if (index >= result.number_of_faces) {
+                       LOGE("Invalid index(index = %u, result count = %u).", index, result.number_of_faces);
+                       return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+               }
+
+               *yaw = result.yaws[index];
+               *pitch = result.pitches[index];
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
\ No newline at end of file
index e3c6528d7e686c1a197cd02d790ebb0f4d954256..943f9b66aaa0766eaa28ab75315cd99a4e4fd526 100644 (file)
@@ -411,6 +411,9 @@ find . -name '*.gcno' -not -path "./test/*" -not -path "./mv_machine_learning/*"
 %{_datadir}/%{name}/selfie_segmentation_plugin.json
 %{_libdir}/libmv_image_segmentation.so
 %endif
+%{_datadir}/%{name}/gaze_tracking.json
+%{_datadir}/%{name}/gaze_tracking_plugin.json
+%{_libdir}/libmv_gaze_tracking.so
 
 %files machine_learning-devel
 %{_includedir}/media/mv_infer*.h
@@ -469,6 +472,11 @@ find . -name '*.gcno' -not -path "./test/*" -not -path "./mv_machine_learning/*"
 %{_includedir}/media/image_segmentation_type.h
 %{_libdir}/pkgconfig/*image-segmentation.pc
 %endif
+%{_includedir}/media/mv_gaze_tracking.h
+%{_includedir}/media/mv_gaze_tracking_internal.h
+%{_includedir}/media/mv_gaze_tracking_type.h
+%{_includedir}/media/gaze_tracking_type.h
+%{_libdir}/pkgconfig/*gaze-tracking.pc
 
 %files roi_tracker
 %manifest %{name}.manifest