303 lines
13 KiB
C++
303 lines
13 KiB
C++
#include "ANSLIB.h"
|
|
#include "ANSLibsLoader.h"
|
|
#include <memory>
|
|
#include <mutex>
|
|
#define LOAD_FUNC(name) \
|
|
name##Func = (name##FuncT)GetProcAddress(dllHandle, #name); \
|
|
if (!name##Func) { success = false; }
|
|
namespace ANSCENTER
|
|
{
|
|
namespace {
|
|
// Function-pointer typedefs for the ANSLicensingSystem C-facade exports.
|
|
// Resolved exactly once during PreloadSharedDllsOnce(); after that the
|
|
// pointers are write-once globals — concurrent reads are race-free.
|
|
using ANSLogger_LogFnT = void(*)(const char*, const char*, const char*, int);
|
|
using ANSCENTER_IsDbgEnFnT = int (*)(void);
|
|
ANSLogger_LogFnT g_ANSLogger_LogInfo = nullptr;
|
|
ANSLogger_LogFnT g_ANSLogger_LogError = nullptr;
|
|
ANSLogger_LogFnT g_ANSLogger_LogFatal = nullptr;
|
|
ANSCENTER_IsDbgEnFnT g_ANSCENTER_IsDebugViewEnabled = nullptr;
|
|
|
|
// Pre-load all ANSCORE DLLs from the Shared folder using full paths.
|
|
// This ensures the correct versions are loaded regardless of PATH order
|
|
// (e.g., DLHUB_Runtime_Engine may contain older copies on some machines).
|
|
// Run exactly once per process so LoadLibrary refcounts don't grow per
|
|
// ANSLIB instance. The DLLs are intentionally pinned for process lifetime.
|
|
void PreloadSharedDllsOnce() {
|
|
static std::once_flag s_preloadFlag;
|
|
std::call_once(s_preloadFlag, []() {
|
|
const char* sharedDir = "C:\\ProgramData\\ANSCENTER\\Shared\\";
|
|
const char* preloadDlls[] = {
|
|
"ANSLicensingSystem.dll",
|
|
"anslicensing.dll",
|
|
"ANSMOT.dll",
|
|
"ANSODEngine.dll",
|
|
nullptr
|
|
};
|
|
for (int i = 0; preloadDlls[i] != nullptr; i++) {
|
|
std::string fullPath = std::string(sharedDir) + preloadDlls[i];
|
|
LoadLibraryA(fullPath.c_str());
|
|
}
|
|
// Ensure all shared DLLs (OpenCV, OpenVINO, TRT, ORT) are pre-loaded
|
|
ANSCENTER::ANSLibsLoader::Initialize();
|
|
|
|
// Resolve logging C-facade symbols from the (now-pinned) licensing DLL.
|
|
// Use GetModuleHandleA — the DLL is already in this process's module
|
|
// list courtesy of the LoadLibraryA above, so refcount is unchanged.
|
|
if (HMODULE lic = GetModuleHandleA("ANSLicensingSystem.dll")) {
|
|
g_ANSLogger_LogInfo = (ANSLogger_LogFnT) GetProcAddress(lic, "ANSLogger_LogInfo");
|
|
g_ANSLogger_LogError = (ANSLogger_LogFnT) GetProcAddress(lic, "ANSLogger_LogError");
|
|
g_ANSLogger_LogFatal = (ANSLogger_LogFnT) GetProcAddress(lic, "ANSLogger_LogFatal");
|
|
g_ANSCENTER_IsDebugViewEnabled = (ANSCENTER_IsDbgEnFnT)GetProcAddress(lic, "ANSCENTER_IsDebugViewEnabled");
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
ANSLIB::ANSLIB() {
|
|
PreloadSharedDllsOnce();
|
|
|
|
const char* dllPath = "C:\\ProgramData\\ANSCENTER\\Shared\\ANSODEngine.dll";
|
|
dllHandle = LoadLibraryA(dllPath);
|
|
if (!dllHandle) {
|
|
return;
|
|
}
|
|
bool success = true;
|
|
LOAD_FUNC(CreateANSODHandle_CS);
|
|
LOAD_FUNC(RunInference_CPP);
|
|
LOAD_FUNC(RunInferenceComplete_CPP);
|
|
LOAD_FUNC(OptimizeModelStr_CS);
|
|
LOAD_FUNC(GetEngineType);
|
|
LOAD_FUNC(LoadModelFromFolder);
|
|
LOAD_FUNC(GetActiveRect);
|
|
LOAD_FUNC(DetectMovement);
|
|
LOAD_FUNC(Optimize);
|
|
LOAD_FUNC(GetODParameters);
|
|
LOAD_FUNC(ReleaseANSODHandle);
|
|
LOAD_FUNC(UpdateDetectionMinScore);
|
|
LOAD_FUNC(SetPrompt);
|
|
LOAD_FUNC(SetTracker);
|
|
LOAD_FUNC(SetTrackerParameters);
|
|
loaded = success;
|
|
if (!loaded) {
|
|
FreeLibrary(dllHandle);
|
|
dllHandle = nullptr;
|
|
}
|
|
}
|
|
|
|
ANSLIB* ANSLIB::Create() {
|
|
try {
|
|
auto ptr = std::make_unique<ANSLIB>();
|
|
return ptr.release();
|
|
}
|
|
catch (...) { return nullptr; }
|
|
}
|
|
|
|
void ANSLIB::Destroy(ANSLIB* instance) {
|
|
std::unique_ptr<ANSLIB> ptr(instance);
|
|
}
|
|
|
|
ANSLIB::~ANSLIB() noexcept {
|
|
try {
|
|
if (ANSHandle && ReleaseANSODHandleFunc) {
|
|
ReleaseANSODHandleFunc(&ANSHandle);
|
|
ANSHandle = nullptr;
|
|
}
|
|
if (dllHandle) {
|
|
FreeLibrary(dllHandle);
|
|
dllHandle = nullptr;
|
|
}
|
|
}
|
|
catch (...) {}
|
|
}
|
|
|
|
bool ANSLIB::IsLoaded() const {
|
|
return loaded;
|
|
}
|
|
|
|
// Public APIs
|
|
int ANSLIB::Initialize(const char* licenseKey,
|
|
const char* modelFilePath,
|
|
const char* modelFileZipPassword,
|
|
float modelThreshold,
|
|
float modelConfThreshold,
|
|
float modelNMSThreshold,
|
|
int modelType,
|
|
int detectionType, int loadEngineOnCreation,std::string& labels)
|
|
{
|
|
if (!loaded) {
|
|
return -1;
|
|
}
|
|
if (CreateANSODHandle_CSFunc) {
|
|
if (ANSHandle && ReleaseANSODHandleFunc) {
|
|
ReleaseANSODHandleFunc(&ANSHandle);
|
|
ANSHandle = nullptr;
|
|
}
|
|
const char* result = CreateANSODHandle_CSFunc(&ANSHandle, licenseKey, modelFilePath, modelFileZipPassword,
|
|
modelThreshold, modelConfThreshold, modelNMSThreshold,
|
|
1, modelType, detectionType, loadEngineOnCreation);
|
|
labels = (result != nullptr) ? std::string(result) : std::string();
|
|
if (labels.empty()) {
|
|
return -1;
|
|
}
|
|
else {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int ANSLIB::RunInference(cv::Mat cvImage, const char* cameraId, std::vector<ANSCENTER::Object>& detectionResult) {
|
|
if (!loaded) {
|
|
return -1;
|
|
}
|
|
if (RunInference_CPPFunc) {
|
|
try {
|
|
cv::Mat* rawPtr = &cvImage;
|
|
int result = RunInference_CPPFunc(&ANSHandle, &rawPtr, cameraId, detectionResult);
|
|
return result;
|
|
}
|
|
catch (...) {
|
|
return -1;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
int ANSLIB::RunInferenceWithOptions(cv::Mat cvImage, const char* cameraId, const char* activeROIMode, std::vector<ANSCENTER::Object>& detectionResult) {
|
|
if (!loaded) {
|
|
return -1;
|
|
}
|
|
if (RunInferenceComplete_CPPFunc) {
|
|
try {
|
|
cv::Mat* rawPtr = &cvImage;
|
|
int result = RunInferenceComplete_CPPFunc(&ANSHandle, &rawPtr, cameraId, activeROIMode,detectionResult);
|
|
return result;
|
|
}
|
|
catch (...) {
|
|
return -1;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
int ANSLIB::OptimizeModel(const char* modelFilePath, const char* modelFileZipPassword, int modelType, int modelDetectionType,int fp16) {
|
|
if (!loaded) {
|
|
return -1;
|
|
}
|
|
if (OptimizeModelStr_CSFunc) {
|
|
const char* result = OptimizeModelStr_CSFunc(modelFilePath, modelFileZipPassword, modelType, modelDetectionType, fp16);
|
|
if (result) {
|
|
return 1;
|
|
}
|
|
else {
|
|
return -1;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
const char* ANSLIB::CreateANSODHandle_CS(void** Handle, const char* licenseKey, const char* modelFilePath,
|
|
const char* modelFileZipPassword, float modelThreshold, float modelConfThreshold,
|
|
float modelNMSThreshold, int autoDetectEngine, int modelType, int detectionType, int loadEngineOnCreation) {
|
|
return CreateANSODHandle_CSFunc ? CreateANSODHandle_CSFunc(Handle, licenseKey, modelFilePath, modelFileZipPassword,
|
|
modelThreshold, modelConfThreshold, modelNMSThreshold,
|
|
autoDetectEngine, modelType, detectionType, loadEngineOnCreation)
|
|
: "Function not loaded";
|
|
}
|
|
|
|
const char* ANSLIB::OptimizeModelStr_CS(const char* modelFilePath, const char* modelFileZipPassword, int modelType, int modelDetectionType,int fp16) {
|
|
return OptimizeModelStr_CSFunc ? OptimizeModelStr_CSFunc(modelFilePath, modelFileZipPassword, modelType, modelDetectionType,fp16)
|
|
: "Function not loaded";
|
|
}
|
|
|
|
int ANSLIB::RunInference_CPP(void** Handle, cv::Mat** cvImage, const char* cameraId, std::vector<ANSCENTER::Object>& detectionResult) {
|
|
return RunInference_CPPFunc ? RunInference_CPPFunc(Handle, cvImage, cameraId, detectionResult) : -1;
|
|
}
|
|
int ANSLIB::RunInferenceComplete_CPP(void** Handle, cv::Mat** cvImage, const char* cameraId, const char* activeROIMode, std::vector<ANSCENTER::Object>& detectionResult) {
|
|
return RunInferenceComplete_CPPFunc ? RunInferenceComplete_CPPFunc(Handle, cvImage, cameraId, activeROIMode, detectionResult) : -1;
|
|
}
|
|
int ANSLIB::GetEngineType() {
|
|
if (!loaded || !GetEngineTypeFunc) return -1;
|
|
return GetEngineTypeFunc();
|
|
}
|
|
|
|
int ANSLIB::LoadModelFromFolder(const char* licenseKey, const char* modelName, const char* className,
|
|
float detectionScoreThreshold, float modelConfThreshold, float modelMNSThreshold,
|
|
int autoDetectEngine, int modelType, int detectionType, int loadEngineOnCreation, const char* modelFolder,std::string& labelMap)
|
|
{
|
|
if (!loaded || !LoadModelFromFolderFunc) return -1;
|
|
if (ANSHandle && ReleaseANSODHandleFunc) {
|
|
ReleaseANSODHandleFunc(&ANSHandle);
|
|
ANSHandle = nullptr;
|
|
}
|
|
return LoadModelFromFolderFunc(&ANSHandle, licenseKey, modelName, className,
|
|
detectionScoreThreshold, modelConfThreshold, modelMNSThreshold,
|
|
autoDetectEngine, modelType, detectionType, loadEngineOnCreation,modelFolder, labelMap);
|
|
}
|
|
|
|
int ANSLIB::GetActiveRect(cv::Mat cvImage, cv::Rect& activeWindow) {
|
|
if (!loaded || !GetActiveRectFunc) return -1;
|
|
return GetActiveRectFunc(&ANSHandle, cvImage, activeWindow);
|
|
}
|
|
|
|
int ANSLIB::DetectMovement(cv::Mat image, const char* cameraId, std::vector<Object>& results) {
|
|
if (!loaded || !DetectMovementFunc) return -1;
|
|
return DetectMovementFunc(&ANSHandle, image, cameraId, results);
|
|
}
|
|
int ANSLIB::ReleaseANSODHandle(void** Handle) {
|
|
return ReleaseANSODHandleFunc ? ReleaseANSODHandleFunc(Handle) : -1;
|
|
}
|
|
cv::Rect ANSLIB::GetActiveWindow(cv::Mat cvImage) {
|
|
cv::Rect activeWindow;
|
|
if (GetActiveRect(cvImage, activeWindow) == 0) {
|
|
return activeWindow;
|
|
}
|
|
return cv::Rect(); // Return an empty rectangle if failed
|
|
}
|
|
int ANSLIB::GetODParameters(ANSCENTER::Params& param) {
|
|
if (!loaded || !GetODParametersFunc) return -1;
|
|
return GetODParametersFunc(&ANSHandle, param);
|
|
}
|
|
int ANSLIB::Optimize(bool fp16) {
|
|
if (!loaded || !OptimizeFunc) return -1;
|
|
return OptimizeFunc(&ANSHandle, fp16);
|
|
}
|
|
int ANSLIB::UpdateDetectionMinScore(float scoreThreshold) {
|
|
if (!loaded || !UpdateDetectionMinScoreFunc) return -1;
|
|
return UpdateDetectionMinScoreFunc(&ANSHandle, scoreThreshold);
|
|
}
|
|
int ANSLIB::SetPrompt(const char* text) {
|
|
if (!loaded || !SetPromptFunc) return -1;
|
|
return SetPromptFunc(&ANSHandle, text);
|
|
}
|
|
int ANSLIB::SetTracker(int trackerType, int enableTracker) {
|
|
if (!loaded || !SetTrackerFunc) return -1;
|
|
return SetTrackerFunc(&ANSHandle, trackerType, enableTracker);
|
|
}
|
|
int ANSLIB::SetTrackerParameters(const char* trackerParams) {
|
|
if (!loaded || !SetTrackerParametersFunc) return -1;
|
|
return SetTrackerParametersFunc(&ANSHandle, trackerParams);
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Static logging API. Each call ensures the DLL/symbols are resolved (cheap
|
|
// after the first call — std::call_once degenerates to an atomic load) then
|
|
// forwards to the C facade. Null-pointer guard makes missing symbols a
|
|
// silent no-op rather than a crash.
|
|
// ------------------------------------------------------------------------
|
|
int ANSLIB::IsDebugViewEnabled() {
|
|
PreloadSharedDllsOnce();
|
|
return g_ANSCENTER_IsDebugViewEnabled ? g_ANSCENTER_IsDebugViewEnabled() : 0;
|
|
}
|
|
void ANSLIB::LogInfo(const char* src, const char* msg, const char* file, int line) {
|
|
PreloadSharedDllsOnce();
|
|
if (g_ANSLogger_LogInfo) g_ANSLogger_LogInfo(src, msg, file, line);
|
|
}
|
|
void ANSLIB::LogError(const char* src, const char* msg, const char* file, int line) {
|
|
PreloadSharedDllsOnce();
|
|
if (g_ANSLogger_LogError) g_ANSLogger_LogError(src, msg, file, line);
|
|
}
|
|
void ANSLIB::LogFatal(const char* src, const char* msg, const char* file, int line) {
|
|
PreloadSharedDllsOnce();
|
|
if (g_ANSLogger_LogFatal) g_ANSLogger_LogFatal(src, msg, file, line);
|
|
}
|
|
} |