Apply self-registeration factory pattern to inference service.
With this patch, InferenceServiceDefault and InferenceServiceExternal classes
will be registered to inference factory table in build time, and
it will create InferenceServiceDefault or InferenceServiceExternal class
with a given class name in runtime. Regarding this, this patch
modifies existing build script so that inference service directory
can be built-in.
This patch is just a previous step for applying abstract factory pattern
as we discussed.
Change-Id: Icb21dc066bdf940926a9e764e40a48a82ffefed5
Signed-off-by: Inki Dae <inki.dae@samsung.com>
-PROJECT("singleo_inference")
CMAKE_MINIMUM_REQUIRED(VERSION 3.13)
-ADD_SUBDIRECTORY(backends)
+SET(INFERENCE_DIRECTORY ${ROOT_DIRECTORY}/inference)
IF (${USE_EXTERNAL_INFERENCE_SERVICE})
- SET(SINGLEO_INFERENCE_HEADER_DIRECTORY "")
- SET(SINGLEO_INFERENCE_SERVUCE_FILE "InferenceServiceExternal.cpp")
+ SET(SINGLEO_SERVICE_SOURCE_FILES ${SINGLEO_SERVICE_SOURCE_FILES} ${INFERENCE_DIRECTORY}/src/InferenceServiceExternal.cpp)
ELSE()
- SET(SINGLEO_INFERENCE_HEADER_DIRECTORY /usr/include/media backends/mediavision/include)
- SET(SINGLEO_INFERENCE_SERVUCE_FILE "InferenceServiceDefault.cpp")
+ SET(SINGLEO_SERVICE_SOURCE_FILES ${SINGLEO_SERVICE_SOURCE_FILES} ${INFERENCE_DIRECTORY}/src/InferenceServiceDefault.cpp)
ENDIF()
-FILE(GLOB SINGLEO_INFERENCE_SOURCE_FILES "${PROJECT_SOURCE_DIR}/src/${SINGLEO_INFERENCE_SERVUCE_FILE}")
-ADD_LIBRARY(${PROJECT_NAME} SHARED ${SINGLEO_INFERENCE_SOURCE_FILES})
+INCLUDE(${INFERENCE_DIRECTORY}/backends/mediavision/CMakeLists.txt)
-TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE include ../common/include ${SINGLEO_INFERENCE_HEADER_DIRECTORY})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE singleo_inference_backend)
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
\ No newline at end of file
+LIST(APPEND INFERENCE_HEADER_LIST ${INFERENCE_HEADER_LIST} ${INFERENCE_DIRECTORY}/include)
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 3.13)
-PROJECT("singleo_inference_backend")
-
-FILE(GLOB MEDIAVISION_SOURCE_FILES "${PROJECT_SOURCE_DIR}/mediavision/src/*.cpp")
-ADD_LIBRARY(${PROJECT_NAME} SHARED ${MEDIAVISION_SOURCE_FILES})
-
-FIND_PACKAGE(PkgConfig REQUIRED)
-PKG_CHECK_MODULES(${PROJECT_NAME}_DEP REQUIRED capi-media-vision)
-
-TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE ../include ../../common/include ../../log/include mediavision/include /usr/include/media)
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE mv_common singleo_log mv_inference mv_object_detection)
-
-# Install the library
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 3.13)
+
+FIND_PACKAGE(PkgConfig REQUIRED)
+PKG_CHECK_MODULES(${PROJECT_NAME}_DEP REQUIRED capi-media-vision)
+
+SET(INFERENCE_MEDIAVISION_BACKEND_DIRECTORY ${INFERENCE_DIRECTORY}/backends/mediavision)
+
+SET(SINGLEO_SERVICE_SOURCE_FILES
+ ${SINGLEO_SERVICE_SOURCE_FILES}
+ ${INFERENCE_MEDIAVISION_BACKEND_DIRECTORY}/src/MvFaceDetection.cpp
+ ${INFERENCE_MEDIAVISION_BACKEND_DIRECTORY}/src/MvObjectDetection.cpp
+)
+
+LIST(APPEND INFERENCE_LIBRARY_LIST ${INFERENCE_LIBRARY_LIST} mv_common mv_inference mv_object_detection)
+LIST(APPEND INFERENCE_HEADER_LIST ${INFERENCE_HEADER_LIST} ${INFERENCE_MEDIAVISION_BACKEND_DIRECTORY}/include /usr/include/media)
--- /dev/null
+/**
+ * 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 __MV_INFERENCE_SERVICE_FACTORY_H__
+#define __MV_INFERENCE_SERVICE_FACTORY_H__
+
+#include "IInferenceServiceFactory.h"
+
+namespace singleo
+{
+namespace inference
+{
+class MvInferenceServiceFactory : public IInferenceServiceFactory
+{
+private:
+ std::unique_ptr<IInferenceServiceInterface>createInferenceService(TaskType taskType);
+
+public:
+ MvInferenceServiceFactory() = default;
+ virtual ~MvInferenceServiceFactory() = default;
+
+ std::unique_ptr<IInferenceServiceInterface> createImageClassification() override;
+ std::unique_ptr<IInferenceServiceInterface> createObjectDetection() override;
+ std::unique_ptr<IInferenceServiceInterface> createFaceDetection() override;
+ std::unique_ptr<IInferenceServiceInterface> createFaceLandmarkDetection() override;
+};
+
+}
+}
+
+#endif
--- /dev/null
+/**
+ * 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 "MvInferenceServiceFactory.h"
+#include "InferenceServiceDefault.h"
+#include "SingleoLog.h"
+#include "SingleoException.h"
+
+using namespace std;
+using namespace singleo::exception;
+
+namespace singleo
+{
+namespace inference
+{
+namespace backends
+{
+
+std::unique_ptr<IInferenceServiceInterface>MvInferenceServiceFactory::createInferenceService(TaskType taskType)
+{
+ auto service = make_unique<InferenceServiceDefault>();
+
+ service->configure(taskType);
+
+ return service;
+}
+
+std::unique_ptr<IInferenceServiceInterface> MvInferenceServiceFactory::createImageClassification()
+{
+ throw InvalidOperation("Interface not supported yet.");
+}
+
+std::unique_ptr<IInferenceServiceInterface> MvInferenceServiceFactory::createObjectDetection()
+{
+ return createInferenceService(TaskType::OBJECT_DETECTION);
+}
+
+std::unique_ptr<IInferenceServiceInterface> MvInferenceServiceFactory::createFaceDetection()
+{
+ return createInferenceService(TaskType::FACE_DETECTION);
+}
+
+std::unique_ptr<IInferenceServiceInterface> MvInferenceServiceFactory::createFaceLandmarkDetection()
+{
+ throw InvalidOperation("Interface not supported yet.");
+}
+
+}
+}
+}
--- /dev/null
+/**
+ * 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 __IINFERENCE_SERVICE_FACTORY_H__
+#define __IINFERENCE_SERVICE_FACTORY_H__
+
+#include <memory>
+
+#include "IInferenceServiceInterface.h"
+
+namespace singleo
+{
+namespace inference
+{
+class IInferenceServiceFactory
+{
+public:
+ virtual ~IInferenceServiceFactory() {};
+
+ virtual std::unique_ptr<IInferenceServiceInterface> createImageClassification() = 0;
+ virtual std::unique_ptr<IInferenceServiceInterface> createObjectDetection() = 0;
+ virtual std::unique_ptr<IInferenceServiceInterface> createFaceDetection() = 0;
+ virtual std::unique_ptr<IInferenceServiceInterface> createFaceLandmarkDetection() = 0;
+}
+
+}
+}
+
+#endif
\ No newline at end of file
#ifndef __IINFERENCE_SERVICE_INTERFACE_H__
#define __IINFERENCE_SERVICE_INTERFACE_H__
-#include "IInferenceTaskInterface.h"
+#include "SingleoInferenceTypes.h"
+#include "SingleoCommonTypes.h"
namespace singleo
{
public:
virtual ~IInferenceServiceInterface() {};
- virtual void configure() = 0;
+ virtual void configure(TaskType task_type) = 0;
virtual void prepare() = 0;
virtual void invoke(BaseDataType &input, bool async = false) = 0;
virtual BaseResultType &result() = 0;
{
private:
std::unique_ptr<IInferenceTaskInterface> _task;
+ static bool _registered;
public:
- explicit InferenceServiceDefault(TaskType task_type);
- virtual ~InferenceServiceDefault();
+ InferenceServiceDefault() = default;
+ virtual ~InferenceServiceDefault() = default;
- void configure() override;
+ void configure(TaskType task_type) override;
void prepare() override;
void invoke(BaseDataType &input, bool async = false) override;
BaseResultType &result() override;
explicit InferenceServiceExternal(TaskType task_type);
virtual ~InferenceServiceExternal();
- void configure() override;
+ void configure(TaskType task_type) override;
void prepare() override;
void invoke(BaseDataType &input, bool async = false) override;
BaseResultType &result() override;
--- /dev/null
+/**
+ * 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 __INFERENCE_SERVICE_FACTORY_H__
+#define __INFERENCE_SERVICE_FACTORY_H__
+
+#include <unordered_map>
+#include <vector>
+#include <string>
+#include <memory>
+#include <stdexcept>
+#include "IInferenceServiceInterface.h"
+#include "SingleoException.h"
+#include "SingleoLog.h"
+
+namespace singleo
+{
+namespace inference
+{
+class InferenceServiceFactory
+{
+public:
+ using createFunc = std::unique_ptr<IInferenceServiceInterface> (*)();
+
+ static InferenceServiceFactory &instance()
+ {
+ static InferenceServiceFactory factory;
+ return factory;
+ }
+
+ std::unique_ptr<IInferenceServiceInterface> create(const std::string &name)
+ {
+ auto it = _inference_service_table.find(name);
+ if (it != _inference_service_table.end())
+ return it->second();
+
+ throw singleo::exception::InvalidParameter("Invalid inference service.");
+ }
+
+ void registerBackend(const std::string &name, const createFunc &func)
+ {
+ _inference_service_table[name] = func;
+ }
+
+private:
+ InferenceServiceFactory() = default;
+ ~InferenceServiceFactory() = default;
+
+ std::unordered_map<std::string, createFunc> _inference_service_table;
+};
+
+template<typename ServiceType> bool registerInferenceService(const std::string &name)
+{
+ InferenceServiceFactory::instance().registerBackend(name, []() {
+ return std::unique_ptr<IInferenceServiceInterface>(new ServiceType());
+ });
+
+ return true;
+}
+
+}
+}
+
+#endif
\ No newline at end of file
* limitations under the License.
*/
+#include "InferenceServiceFactory.h"
#include "InferenceServiceDefault.h"
#include "MvObjectDetection.h"
#include "MvFaceDetection.h"
{
namespace inference
{
-InferenceServiceDefault::InferenceServiceDefault(TaskType task_type)
+bool InferenceServiceDefault::_registered =
+ registerInferenceService<InferenceServiceDefault>("InferenceServiceDefault");
+
+void InferenceServiceDefault::configure(TaskType task_type)
{
// TODO. add other task types later.
if (task_type != TaskType::OBJECT_DETECTION && task_type != TaskType::FACE_DETECTION)
_task = make_unique<MvFaceDetection>();
break;
}
-}
-InferenceServiceDefault::~InferenceServiceDefault()
-{}
-
-void InferenceServiceDefault::configure()
-{
_task->configure();
}
InferenceServiceExternal::~InferenceServiceExternal()
{}
-void InferenceServiceExternal::configure()
+void InferenceServiceExternal::configure(TaskType task_type)
{
throw runtime_error("Not support yet.");
}
%files devel
%{_libdir}/pkgconfig/*.pc
%{_libdir}/libsingleo_log.so
-%{_libdir}/libsingleo_inference.so
-%{_libdir}/libsingleo_inference_backend.so
%{_libdir}/libsingleo_service.so
%{_libdir}/libsingleo_visualizer.so
"${PROJECT_SOURCE_DIR}/../common/src/*.cpp")
INCLUDE(${ROOT_DIRECTORY}/input/CMakeLists.txt)
+INCLUDE(${ROOT_DIRECTORY}/inference/CMakeLists.txt)
IF (${USE_AUTOZOOM_API})
INCLUDE(auto_zoom/CMakeLists.txt)
ADD_LIBRARY(${PROJECT_NAME} SHARED ${SINGLEO_SERVICE_SOURCE_FILES})
-TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE include common/include ${ROOT_DIRECTORY}/capi/ ${ROOT_DIRECTORY}/log/include ${ROOT_DIRECTORY}/inference/include ${ROOT_DIRECTORY}/common/include ${INPUT_HEADER_LIST} ${SERVICE_HEADER_LIST})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE opencv_core opencv_imgcodecs opencv_highgui opencv_videoio singleo_log ${SERVICE_LIBRARY_LIST})
+TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE include common/include ${ROOT_DIRECTORY}/capi/ ${ROOT_DIRECTORY}/log/include ${ROOT_DIRECTORY}/common/include ${INPUT_HEADER_LIST} ${INFERENCE_HEADER_LIST} ${SERVICE_HEADER_LIST})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE opencv_core opencv_imgcodecs opencv_highgui opencv_videoio singleo_log ${INFERENCE_LIBRARY_LIST} ${SERVICE_LIBRARY_LIST})
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
\ No newline at end of file
auto_zoom/src/Postprocessor.cpp
)
-LIST(APPEND SERVICE_LIBRARY_LIST ${SERVICE_LIBRARY_LIST} singleo_inference)
+LIST(APPEND SERVICE_LIBRARY_LIST ${SERVICE_LIBRARY_LIST})
LIST(APPEND SERVICE_HEADER_LIST ${SERVICE_HEADER_LIST} ${CMAKE_CURRENT_SOURCE_DIR}/auto_zoom/include)
\ No newline at end of file
#include <algorithm>
#include "SingleoException.h"
#include "AutoZoom.h"
-#include "InferenceServiceDefault.h"
+#include "InferenceServiceFactory.h"
#include "SingleoLog.h"
#include "ImagePreprocessor.h"
#include "ServiceFactory.h"
{
// In default, we will use InferenceServiceDefault class to use Mediavision framework
// for inference service. TODO. introduce meta config file approach later.
- _inference_service = make_unique<InferenceServiceDefault>(_task_type);
+ _inference_service = InferenceServiceFactory::instance().create("InferenceServiceDefault");
// Create InputCamera service if input service type is CAMERA.
if (config._input_feed_type == InputFeedType::CAMERA) {
SINGLEO_LOGD("Camera input service has been initialized.");
}
- _inference_service->configure();
+ _inference_service->configure(_task_type);
_inference_service->prepare();
_postprocessor = make_unique<Postprocessor>();
}