Fix mutex lock issues

This commit is contained in:
2026-04-13 19:48:32 +10:00
parent 56a8f09adf
commit 844d7396b2
30 changed files with 445 additions and 575 deletions

View File

@@ -1,4 +1,5 @@
#include "ANSLPR_OCR.h"
#include "ANSRTYOLO.h"
#include "ANSONNXYOLO.h"
#include "ANSOnnxOCR.h"
#include "ANSOCRBase.h"
@@ -20,6 +21,59 @@ static void WriteEventLog(const char* message, WORD eventType = EVENTLOG_INFORMA
OutputDebugStringA("\n");
}
// ---------------------------------------------------------------------------
// SEH wrapper for loading ANSRTYOLO (TensorRT) models — used when NVIDIA GPU
// is detected. Falls back to ANSONNXYOLO if TRT fails.
// ---------------------------------------------------------------------------
struct LoadRtParams_OCR {
const std::string* licenseKey;
ANSCENTER::ModelConfig* config;
const std::string* modelFolder;
const char* modelName;
const char* classFile;
std::string* labels;
std::unique_ptr<ANSCENTER::ANSODBase>* detector;
bool enableTracker;
bool disableStabilization;
};
static bool LoadRtModel_OCR_Impl(const LoadRtParams_OCR& p) {
try {
auto rtyolo = std::make_unique<ANSCENTER::ANSRTYOLO>();
bool ok = rtyolo->LoadModelFromFolder(
*p.licenseKey, *p.config, p.modelName, p.classFile,
*p.modelFolder, *p.labels);
if (!ok) {
return false;
}
if (p.enableTracker) {
rtyolo->SetTracker(ANSCENTER::TrackerType::BYTETRACK, true);
} else {
rtyolo->SetTracker(ANSCENTER::TrackerType::BYTETRACK, false);
}
if (p.disableStabilization) {
rtyolo->SetStabilization(false);
}
*p.detector = std::move(rtyolo);
return true;
}
catch (...) {
p.detector->reset();
return false;
}
}
static bool LoadRtModel_OCR_SEH(const LoadRtParams_OCR& p, DWORD* outCode) {
*outCode = 0;
__try {
return LoadRtModel_OCR_Impl(p);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
*outCode = GetExceptionCode();
return false;
}
}
struct LoadOnnxParams_OCR {
const std::string* licenseKey;
ANSCENTER::ModelConfig* config;
@@ -186,40 +240,81 @@ namespace ANSCENTER
bool valid = false;
// ── Step 2: Load LP detector with ONNX Runtime ───────────────
// ── Step 2: Load LP detector ─────────────────────────────────
if (FileExist(lprModel)) {
WriteEventLog("ANSALPR_OCR::LoadEngine: Step 2 - Loading LP detector with ONNX Runtime");
this->_logger.LogInfo("ANSALPR_OCR::LoadEngine", "Step 2: Loading LP detector with ONNX Runtime", __FILE__, __LINE__);
_lpdmodelConfig.detectionType = DetectionType::DETECTION;
_lpdmodelConfig.modelType = ModelType::ONNXYOLO;
std::string _lprClasses;
{
LoadOnnxParams_OCR p{};
p.licenseKey = &_licenseKey;
p.config = &_lpdmodelConfig;
p.modelFolder = &_modelFolder;
p.modelName = "lpd";
p.classFile = "lpd.names";
p.labels = &_lprClasses;
p.detector = &_lpDetector;
p.enableTracker = true;
p.disableStabilization = true;
// Try TensorRT (ANSRTYOLO) when NVIDIA GPU is detected
if (engineType == EngineType::NVIDIA_GPU) {
WriteEventLog("ANSALPR_OCR::LoadEngine: Step 2 - Loading LP detector with TensorRT");
this->_logger.LogInfo("ANSALPR_OCR::LoadEngine", "Step 2: Loading LP detector with TensorRT", __FILE__, __LINE__);
_lpdmodelConfig.detectionType = DetectionType::DETECTION;
_lpdmodelConfig.modelType = ModelType::RTYOLO;
std::string _lprClasses;
{
LoadRtParams_OCR p{};
p.licenseKey = &_licenseKey;
p.config = &_lpdmodelConfig;
p.modelFolder = &_modelFolder;
p.modelName = "lpd";
p.classFile = "lpd.names";
p.labels = &_lprClasses;
p.detector = &_lpDetector;
p.enableTracker = true;
p.disableStabilization = true;
DWORD sehCode = 0;
bool lpSuccess = LoadOnnxModel_OCR_SEH(p, &sehCode);
if (sehCode != 0) {
char buf[256];
snprintf(buf, sizeof(buf),
"ANSALPR_OCR::LoadEngine: Step 2 LPD SEH exception 0x%08X — LP detector disabled", sehCode);
WriteEventLog(buf, EVENTLOG_ERROR_TYPE);
this->_logger.LogFatal("ANSALPR_OCR::LoadEngine",
"Step 2: LP detector crashed (SEH). LP detector disabled.", __FILE__, __LINE__);
if (_lpDetector) _lpDetector.reset();
DWORD sehCode = 0;
bool lpSuccess = LoadRtModel_OCR_SEH(p, &sehCode);
if (sehCode != 0) {
char buf[256];
snprintf(buf, sizeof(buf),
"ANSALPR_OCR::LoadEngine: Step 2 LPD TRT SEH exception 0x%08X — falling back to ONNX Runtime", sehCode);
WriteEventLog(buf, EVENTLOG_ERROR_TYPE);
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
"Step 2: LP detector TensorRT crashed (SEH). Falling back to ONNX Runtime.", __FILE__, __LINE__);
if (_lpDetector) _lpDetector.reset();
}
else if (!lpSuccess) {
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
"Failed to load LP detector (TensorRT). Falling back to ONNX Runtime.", __FILE__, __LINE__);
if (_lpDetector) _lpDetector.reset();
}
}
else if (!lpSuccess) {
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
"Failed to load LP detector (ONNX Runtime).", __FILE__, __LINE__);
if (_lpDetector) _lpDetector.reset();
}
// Fallback to ONNX Runtime (ANSONNXYOLO) if TRT was not attempted or failed
if (!_lpDetector) {
WriteEventLog("ANSALPR_OCR::LoadEngine: Step 2 - Loading LP detector with ONNX Runtime");
this->_logger.LogInfo("ANSALPR_OCR::LoadEngine", "Step 2: Loading LP detector with ONNX Runtime", __FILE__, __LINE__);
_lpdmodelConfig.detectionType = DetectionType::DETECTION;
_lpdmodelConfig.modelType = ModelType::ONNXYOLO;
std::string _lprClasses;
{
LoadOnnxParams_OCR p{};
p.licenseKey = &_licenseKey;
p.config = &_lpdmodelConfig;
p.modelFolder = &_modelFolder;
p.modelName = "lpd";
p.classFile = "lpd.names";
p.labels = &_lprClasses;
p.detector = &_lpDetector;
p.enableTracker = true;
p.disableStabilization = true;
DWORD sehCode = 0;
bool lpSuccess = LoadOnnxModel_OCR_SEH(p, &sehCode);
if (sehCode != 0) {
char buf[256];
snprintf(buf, sizeof(buf),
"ANSALPR_OCR::LoadEngine: Step 2 LPD SEH exception 0x%08X — LP detector disabled", sehCode);
WriteEventLog(buf, EVENTLOG_ERROR_TYPE);
this->_logger.LogFatal("ANSALPR_OCR::LoadEngine",
"Step 2: LP detector crashed (SEH). LP detector disabled.", __FILE__, __LINE__);
if (_lpDetector) _lpDetector.reset();
}
else if (!lpSuccess) {
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
"Failed to load LP detector (ONNX Runtime).", __FILE__, __LINE__);
if (_lpDetector) _lpDetector.reset();
}
}
}
}
@@ -302,37 +397,77 @@ namespace ANSCENTER
// ── Step 4: Load colour classifier (optional) ────────────────
if (FileExist(colorModel) && (_lpColourModelConfig.detectionScoreThreshold > 0)) {
WriteEventLog("ANSALPR_OCR::LoadEngine: Step 4 - Loading colour classifier with ONNX Runtime");
this->_logger.LogInfo("ANSALPR_OCR::LoadEngine", "Step 4: Loading colour classifier with ONNX Runtime", __FILE__, __LINE__);
_lpColourModelConfig.detectionType = DetectionType::CLASSIFICATION;
_lpColourModelConfig.modelType = ModelType::ONNXYOLO;
{
LoadOnnxParams_OCR p{};
p.licenseKey = &_licenseKey;
p.config = &_lpColourModelConfig;
p.modelFolder = &_modelFolder;
p.modelName = "lpc";
p.classFile = "lpc.names";
p.labels = &_lpColourLabels;
p.detector = &_lpColourDetector;
p.enableTracker = false;
p.disableStabilization = false;
// Try TensorRT (ANSRTYOLO) when NVIDIA GPU is detected
if (engineType == EngineType::NVIDIA_GPU) {
WriteEventLog("ANSALPR_OCR::LoadEngine: Step 4 - Loading colour classifier with TensorRT");
this->_logger.LogInfo("ANSALPR_OCR::LoadEngine", "Step 4: Loading colour classifier with TensorRT", __FILE__, __LINE__);
_lpColourModelConfig.detectionType = DetectionType::CLASSIFICATION;
_lpColourModelConfig.modelType = ModelType::RTYOLO;
{
LoadRtParams_OCR p{};
p.licenseKey = &_licenseKey;
p.config = &_lpColourModelConfig;
p.modelFolder = &_modelFolder;
p.modelName = "lpc";
p.classFile = "lpc.names";
p.labels = &_lpColourLabels;
p.detector = &_lpColourDetector;
p.enableTracker = false;
p.disableStabilization = false;
DWORD sehCode = 0;
bool colourSuccess = LoadOnnxModel_OCR_SEH(p, &sehCode);
if (sehCode != 0) {
char buf[256];
snprintf(buf, sizeof(buf),
"ANSALPR_OCR::LoadEngine: Step 4 LPC SEH exception 0x%08X — colour detection disabled", sehCode);
WriteEventLog(buf, EVENTLOG_ERROR_TYPE);
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
"Step 4: Colour classifier crashed. Colour detection disabled.", __FILE__, __LINE__);
if (_lpColourDetector) _lpColourDetector.reset();
DWORD sehCode = 0;
bool colourSuccess = LoadRtModel_OCR_SEH(p, &sehCode);
if (sehCode != 0) {
char buf[256];
snprintf(buf, sizeof(buf),
"ANSALPR_OCR::LoadEngine: Step 4 LPC TRT SEH exception 0x%08X — falling back to ONNX Runtime", sehCode);
WriteEventLog(buf, EVENTLOG_ERROR_TYPE);
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
"Step 4: Colour classifier TensorRT crashed (SEH). Falling back to ONNX Runtime.", __FILE__, __LINE__);
if (_lpColourDetector) _lpColourDetector.reset();
}
else if (!colourSuccess) {
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
"Failed to load colour classifier (TensorRT). Falling back to ONNX Runtime.", __FILE__, __LINE__);
if (_lpColourDetector) _lpColourDetector.reset();
}
}
else if (!colourSuccess) {
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
"Failed to load colour detector (ONNX Runtime). Colour detection disabled.", __FILE__, __LINE__);
if (_lpColourDetector) _lpColourDetector.reset();
}
// Fallback to ONNX Runtime (ANSONNXYOLO) if TRT was not attempted or failed
if (!_lpColourDetector) {
WriteEventLog("ANSALPR_OCR::LoadEngine: Step 4 - Loading colour classifier with ONNX Runtime");
this->_logger.LogInfo("ANSALPR_OCR::LoadEngine", "Step 4: Loading colour classifier with ONNX Runtime", __FILE__, __LINE__);
_lpColourModelConfig.detectionType = DetectionType::CLASSIFICATION;
_lpColourModelConfig.modelType = ModelType::ONNXYOLO;
{
LoadOnnxParams_OCR p{};
p.licenseKey = &_licenseKey;
p.config = &_lpColourModelConfig;
p.modelFolder = &_modelFolder;
p.modelName = "lpc";
p.classFile = "lpc.names";
p.labels = &_lpColourLabels;
p.detector = &_lpColourDetector;
p.enableTracker = false;
p.disableStabilization = false;
DWORD sehCode = 0;
bool colourSuccess = LoadOnnxModel_OCR_SEH(p, &sehCode);
if (sehCode != 0) {
char buf[256];
snprintf(buf, sizeof(buf),
"ANSALPR_OCR::LoadEngine: Step 4 LPC SEH exception 0x%08X — colour detection disabled", sehCode);
WriteEventLog(buf, EVENTLOG_ERROR_TYPE);
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
"Step 4: Colour classifier crashed. Colour detection disabled.", __FILE__, __LINE__);
if (_lpColourDetector) _lpColourDetector.reset();
}
else if (!colourSuccess) {
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
"Failed to load colour detector (ONNX Runtime). Colour detection disabled.", __FILE__, __LINE__);
if (_lpColourDetector) _lpColourDetector.reset();
}
}
}
}

View File

@@ -14,13 +14,13 @@ namespace ANSCENTER { class ANSONNXOCR; struct OCRModelConfig; }
namespace ANSCENTER
{
/// ANSALPR_OCR — License plate recognition using ONNX YOLO for LP detection
/// ANSALPR_OCR — License plate recognition using YOLO for LP detection
/// and ANSONNXOCR (PaddleOCR v5) for text recognition.
///
/// Pipeline:
/// 1. Detect license plates using _lpDetector (ANSONNXYOLO)
/// 1. Detect license plates using _lpDetector (ANSRTYOLO on NVIDIA GPU, ANSONNXYOLO otherwise)
/// 2. For each detected plate, run OCR using _ocrEngine (ANSONNXOCR)
/// 3. Optionally classify plate colour using _lpColourDetector (ANSONNXYOLO)
/// 3. Optionally classify plate colour using _lpColourDetector (ANSRTYOLO on NVIDIA GPU, ANSONNXYOLO otherwise)
///
/// Supports multiple countries via the Country enum and ALPR post-processing
/// from ANSOCR's ANSOCRBase infrastructure.

View File

@@ -29,6 +29,7 @@ namespace ANSCENTER {
}
bool ANSANOMALIB::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -86,6 +87,7 @@ namespace ANSCENTER {
bool ANSANOMALIB::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -159,6 +161,7 @@ namespace ANSCENTER {
}
bool ANSANOMALIB::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
std::string openVINOVersion = ov::get_openvino_version().buildNumber;
//this->_logger.LogDebug("ANSANOMALIB::Initialize. OpenVINO version", openVINOVersion, __FILE__, __LINE__);
@@ -232,7 +235,7 @@ namespace ANSCENTER {
return RunInference(input, "ANSANOMALIBCAM");
}
std::vector<Object> ANSANOMALIB::RunInference(const cv::Mat& input, const std::string& camera_id) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!PreInferenceCheck("ANSANOMALIB::RunInference")) return {};
std::vector<Object> output;
output.clear();
if (!_licenseValid) {

View File

@@ -34,6 +34,7 @@ namespace ANSCENTER
}
bool ANSCUSTOMDETECTOR::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -50,6 +51,7 @@ namespace ANSCENTER
}
bool ANSCUSTOMDETECTOR::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
_modelFolder = modelFolder;
std::string labelMap;
@@ -242,6 +244,7 @@ namespace ANSCENTER
}
bool ANSCUSTOMDETECTOR::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
if (!result) return false;
@@ -268,7 +271,7 @@ namespace ANSCENTER
return RunInference(input, "CustomCam");
}
std::vector<Object> ANSCUSTOMDETECTOR::RunInference(const cv::Mat& input,const std::string& camera_id) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!PreInferenceCheck("ANSCUSTOMDETECTOR::RunInference")) return {};
std::vector<Object> result;
try {

View File

@@ -16,6 +16,8 @@
#include <vector>
#include <string>
#include <map>
#include <atomic>
#include <chrono>
#include "ANSMOT.h"
#include "onnxruntime_cxx_api.h"
@@ -729,6 +731,58 @@ namespace ANSCENTER
void LoadClassesFromString();
void LoadClassesFromFile();
std::recursive_mutex _mutex;
// Guard: true while Initialize/LoadModel is in progress on any thread.
// Inference callers can check this to fail-fast instead of blocking.
std::atomic<bool> _modelLoading{ false };
// Try to lock _mutex with a timeout. Returns a unique_lock that
// evaluates to true on success. On timeout, logs a warning with
// the caller name and returns an unlocked unique_lock.
std::unique_lock<std::recursive_mutex> TryLockWithTimeout(
const char* caller, unsigned int timeoutMs = 5000)
{
const auto deadline = std::chrono::steady_clock::now()
+ std::chrono::milliseconds(timeoutMs);
std::unique_lock<std::recursive_mutex> lk(_mutex, std::defer_lock);
while (!lk.try_lock()) {
if (std::chrono::steady_clock::now() >= deadline) {
_logger.LogWarn(caller,
"Mutex acquisition timed out after "
+ std::to_string(timeoutMs) + " ms"
+ (_modelLoading.load() ? " (model loading in progress)" : ""),
__FILE__, __LINE__);
return lk; // unlocked
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
return lk; // locked
}
// Pre-inference gate: checks _modelLoading, validates state
// (_modelLoadValid, _licenseValid, _isInitialized), and acquires
// _mutex with a timeout. Returns true if inference may proceed.
// On failure (loading in progress, timeout, or invalid state)
// returns false and the caller should return {}.
bool PreInferenceCheck(const char* caller) {
if (_modelLoading.load()) return false;
auto lk = TryLockWithTimeout(caller);
if (!lk.owns_lock()) return false;
if (!_licenseValid || !_isInitialized)
return false;
return true; // lock released here — caller proceeds unlocked
}
// RAII helper: sets _modelLoading=true on construction, false on destruction.
// Use in Initialize/LoadModel/LoadModelFromFolder to guarantee the flag
// is always cleared, even on exceptions or early returns.
struct ModelLoadingGuard {
std::atomic<bool>& flag;
explicit ModelLoadingGuard(std::atomic<bool>& f) : flag(f) { flag.store(true); }
~ModelLoadingGuard() { flag.store(false); }
ModelLoadingGuard(const ModelLoadingGuard&) = delete;
ModelLoadingGuard& operator=(const ModelLoadingGuard&) = delete;
};
MoveDetectsHandler _handler;
size_t QUEUE_SIZE = 20;

View File

@@ -2135,8 +2135,9 @@ namespace ANSCENTER
// Update model configuration with the new parameters (brief lock for config)
if (confidenceThreshold > 0) {
std::lock_guard<std::recursive_mutex> cfgLock(_mutex);
_modelConfig.detectionScoreThreshold = confidenceThreshold;
auto cfgLock = TryLockWithTimeout("ANSODBase::RunInferenceWithOption", 2000);
if (cfgLock.owns_lock())
_modelConfig.detectionScoreThreshold = confidenceThreshold;
}
switch (mode) {
case 0: // Normal mode

View File

@@ -21,6 +21,7 @@ namespace ANSCENTER
}
bool ODHUBAPI::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -77,6 +78,7 @@ namespace ANSCENTER
}
bool ODHUBAPI::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -147,6 +149,7 @@ namespace ANSCENTER
}
bool ODHUBAPI::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
@@ -218,7 +221,7 @@ namespace ANSCENTER
}
std::vector<Object> ODHUBAPI::RunInference(const cv::Mat& input, const std::string& camera_id)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!PreInferenceCheck("ODHUBAPI::RunInference")) return {};
std::vector<Object> result;
try {

View File

@@ -870,6 +870,7 @@ namespace ANSCENTER
}
bool ANSONNXCL::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
_modelLoadValid = false;
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
@@ -931,6 +932,7 @@ namespace ANSCENTER
}
bool ANSONNXCL::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -986,6 +988,7 @@ namespace ANSCENTER
}
bool ANSONNXCL::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -1056,25 +1059,7 @@ namespace ANSCENTER
Destroy();
}
std::vector<Object> ANSONNXCL::RunInference(const cv::Mat& input, const std::string& camera_id) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
this->_logger.LogFatal("ANSONNXCL::RunInference", "Cannot load the TensorRT model. Please check if it is exist", __FILE__, __LINE__);
std::vector<Object> result;
result.clear();
return result;
}
if (!_licenseValid) {
this->_logger.LogFatal("ANSONNXCL::RunInference", "Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
std::vector<Object> result;
result.clear();
return result;
}
if (!_isInitialized) {
this->_logger.LogFatal("ANSONNXCL::RunInference", "Model is not initialized", __FILE__, __LINE__);
std::vector<Object> result;
result.clear();
return result;
}
if (!PreInferenceCheck("ANSONNXCL::RunInference")) return {};
try {
std::vector<Object> result;
if (input.empty()) return result;

View File

@@ -1372,6 +1372,7 @@ namespace ANSCENTER {
}
bool ANSONNXOBB::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
_modelLoadValid = false;
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
@@ -1433,6 +1434,7 @@ namespace ANSCENTER {
}
bool ANSONNXOBB::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -1488,6 +1490,7 @@ namespace ANSCENTER {
}
bool ANSONNXOBB::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -1551,25 +1554,7 @@ namespace ANSCENTER {
}
}
std::vector<Object> ANSONNXOBB::RunInference(const cv::Mat& input, const std::string& camera_id) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
this->_logger.LogFatal("ANSONNXOBB::RunInference", "Cannot load the TensorRT model. Please check if it is exist", __FILE__, __LINE__);
std::vector<Object> result;
result.clear();
return result;
}
if (!_licenseValid) {
this->_logger.LogFatal("ANSONNXOBB::RunInference", "Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
std::vector<Object> result;
result.clear();
return result;
}
if (!_isInitialized) {
this->_logger.LogFatal("ANSONNXOBB::RunInference", "Model is not initialized", __FILE__, __LINE__);
std::vector<Object> result;
result.clear();
return result;
}
if (!PreInferenceCheck("ANSONNXOBB::RunInference")) return {};
try {
std::vector<Object> result;
if (input.empty()) return result;

View File

@@ -1262,6 +1262,7 @@ namespace ANSCENTER {
}
bool ANSONNXPOSE::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
_modelLoadValid = false;
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
@@ -1324,6 +1325,7 @@ namespace ANSCENTER {
}
bool ANSONNXPOSE::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -1380,6 +1382,7 @@ namespace ANSCENTER {
}
bool ANSONNXPOSE::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -1444,25 +1447,7 @@ namespace ANSCENTER {
}
}
std::vector<Object> ANSONNXPOSE::RunInference(const cv::Mat& input, const std::string& camera_id) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
this->_logger.LogFatal("ANSONNXPOSE::RunInference", "Cannot load the TensorRT model. Please check if it is exist", __FILE__, __LINE__);
std::vector<Object> result;
result.clear();
return result;
}
if (!_licenseValid) {
this->_logger.LogFatal("ANSONNXPOSE::RunInference", "Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
std::vector<Object> result;
result.clear();
return result;
}
if (!_isInitialized) {
this->_logger.LogFatal("ANSONNXPOSE::RunInference", "Model is not initialized", __FILE__, __LINE__);
std::vector<Object> result;
result.clear();
return result;
}
if (!PreInferenceCheck("ANSONNXPOSE::RunInference")) return {};
try {
std::vector<Object> result;
if (input.empty()) return result;

View File

@@ -37,6 +37,7 @@ namespace ANSCENTER
std::string& labelMap)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::Initialize(licenseKey, modelConfig,
modelZipFilePath, modelZipPassword, labelMap);
@@ -84,6 +85,7 @@ namespace ANSCENTER
const std::string& modelZipPassword)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -131,6 +133,7 @@ namespace ANSCENTER
const std::string& modelFolder, std::string& labelMap)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,
modelName, className, modelFolder, labelMap);
@@ -281,29 +284,7 @@ namespace ANSCENTER
std::vector<Object> ANSONNXSAM3::RunInference(const cv::Mat& input, const std::string& camera_id)
{
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
_logger.LogError("ANSONNXSAM3::RunInference", "Model not loaded", __FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
_logger.LogError("ANSONNXSAM3::RunInference", "Invalid license", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogError("ANSONNXSAM3::RunInference", "Model not initialized", __FILE__, __LINE__);
return {};
}
if (!m_promptSet) {
_logger.LogError("ANSONNXSAM3::RunInference",
"No prompt set. Call SetPrompt() first.", __FILE__, __LINE__);
return {};
}
if (input.empty() || input.cols < 10 || input.rows < 10) {
return {};
}
}
if (!PreInferenceCheck("ANSONNXSAM3::RunInference")) return {};
try {
// Run ONNX engine inference

View File

@@ -1153,6 +1153,7 @@ namespace ANSCENTER {
}
bool ANSONNXSEG::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
_modelLoadValid = false;
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
@@ -1215,6 +1216,7 @@ namespace ANSCENTER {
}
bool ANSONNXSEG::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -1271,6 +1273,7 @@ namespace ANSCENTER {
}
bool ANSONNXSEG::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -1335,25 +1338,7 @@ namespace ANSCENTER {
}
}
std::vector<Object> ANSONNXSEG::RunInference(const cv::Mat& input, const std::string& camera_id) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
this->_logger.LogFatal("ANSONNXSEG::RunInference", "Cannot load the TensorRT model. Please check if it is exist", __FILE__, __LINE__);
std::vector<Object> result;
result.clear();
return result;
}
if (!_licenseValid) {
this->_logger.LogFatal("ANSONNXSEG::RunInference", "Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
std::vector<Object> result;
result.clear();
return result;
}
if (!_isInitialized) {
this->_logger.LogFatal("ANSONNXSEG::RunInference", "Model is not initialized", __FILE__, __LINE__);
std::vector<Object> result;
result.clear();
return result;
}
if (!PreInferenceCheck("ANSONNXSEG::RunInference")) return {};
try {
std::vector<Object> result;
if (input.empty()) return result;

View File

@@ -1734,6 +1734,7 @@ namespace ANSCENTER {
std::string& labelMap)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
_modelLoadValid = false;
bool result = ANSODBase::Initialize(licenseKey, modelConfig,
@@ -1810,6 +1811,7 @@ namespace ANSCENTER {
const std::string& modelZipPassword)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -1873,6 +1875,7 @@ namespace ANSCENTER {
std::string& labelMap)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,
modelName, className,
@@ -1948,8 +1951,10 @@ namespace ANSCENTER {
std::vector<Object> ANSONNXYOLO::RunInference(const cv::Mat& inputImgBGR,
const std::string& camera_id)
{
if (_modelLoading.load()) return {};
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
auto lock = TryLockWithTimeout("ANSONNXYOLO::RunInference");
if (!lock.owns_lock()) return {};
if (!_modelLoadValid) {
_logger.LogError("ANSONNXYOLO::RunInference", "Model not loaded", __FILE__, __LINE__);
return {};
@@ -1976,29 +1981,55 @@ namespace ANSCENTER {
const std::string& camera_id)
{
try {
ANS_DBG("ONNXYOLO", "DetectObjects: cam=%s acquiring mutex...", camera_id.c_str());
std::lock_guard<std::recursive_mutex> lock(_mutex);
ANS_DBG("ONNXYOLO", "DetectObjects: mutex acquired, cam=%s", camera_id.c_str());
if (!m_ortEngine) {
_logger.LogError("ANSONNXYOLO::DetectObjects", "ORT engine is null", __FILE__, __LINE__);
ANS_DBG("ONNXYOLO", "DetectObjects: ORT engine is null!");
// Fail-fast if a model load/init is in progress on another thread
if (_modelLoading.load()) {
ANS_DBG("ONNXYOLO", "DetectObjects: skipped — model loading in progress, cam=%s", camera_id.c_str());
return {};
}
// ── Snapshot config under a brief lock ──────────────────
// Only hold _mutex long enough to validate state and copy
// the parameters needed for inference. The actual ORT
// detect() call runs outside the lock so that concurrent
// Initialize/LoadModel calls are not blocked for the full
// duration of inference.
float probThresh, nmsThresh;
int numKps;
std::vector<std::string> classes;
bool trackerEnabled, stabilizationEnabled;
{
ANS_DBG("ONNXYOLO", "DetectObjects: cam=%s acquiring mutex...", camera_id.c_str());
auto lk = TryLockWithTimeout("ANSONNXYOLO::DetectObjects");
if (!lk.owns_lock()) return {}; // timed out
ANS_DBG("ONNXYOLO", "DetectObjects: mutex acquired, cam=%s", camera_id.c_str());
if (!m_ortEngine) {
_logger.LogError("ANSONNXYOLO::DetectObjects", "ORT engine is null", __FILE__, __LINE__);
ANS_DBG("ONNXYOLO", "DetectObjects: ORT engine is null!");
return {};
}
// Snapshot parameters while locked
probThresh = PROBABILITY_THRESHOLD;
nmsThresh = NMS_THRESHOLD;
numKps = NUM_KPS;
classes = _classes;
trackerEnabled = _trackerEnabled;
stabilizationEnabled = _stabilizationEnabled;
}
// ── _mutex released — heavy work below runs lock-free ───
// --- NV12 fast path: try to get full-res BGR from GPU NV12 frame ---
cv::Mat inferenceImage = inputImage;
float bgrScaleX = 1.0f, bgrScaleY = 1.0f;
{
auto* gpuData = tl_currentGpuFrame();
if (gpuData && gpuData->width > 0 && gpuData->height > 0) {
// Full-res NV12 available — convert to BGR on CPU for ORT
// (ORT preprocessing is CPU-based, so we need a cv::Mat)
if (gpuData->cpuYPlane && gpuData->cpuUvPlane &&
gpuData->cpuYLinesize >= gpuData->width &&
gpuData->cpuUvLinesize >= gpuData->width) {
const int fw = gpuData->width;
const int fh = gpuData->height;
// NV12 requires even dimensions
if ((fw % 2) == 0 && (fh % 2) == 0) {
try {
cv::Mat yPlane(fh, fw, CV_8UC1,
@@ -2017,10 +2048,12 @@ namespace ANSCENTER {
}
}
}
auto results = m_ortEngine->detect(inferenceImage, _classes,
PROBABILITY_THRESHOLD,
NMS_THRESHOLD,
NUM_KPS);
// Run ORT inference — no mutex held, this is the expensive call
auto results = m_ortEngine->detect(inferenceImage, classes,
probThresh,
nmsThresh,
numKps);
// --- Rescale coordinates from full-res back to display-res ---
if (bgrScaleX != 1.0f || bgrScaleY != 1.0f) {
@@ -2044,21 +2077,16 @@ namespace ANSCENTER {
for (auto& obj : results)
obj.cameraId = camera_id;
// Skip tracking for classification models
if (_trackerEnabled && !m_ortEngine->lastWasClassification) {
// Tracking/stabilization (ApplyTracking has its own lock)
if (trackerEnabled && !m_ortEngine->lastWasClassification) {
results = ApplyTracking(results, camera_id);
if (_stabilizationEnabled) results = StabilizeDetections(results, camera_id);
if (stabilizationEnabled) results = StabilizeDetections(results, camera_id);
}
return results;
}
catch (const std::exception& e) {
const std::string msg = e.what();
// ── DML device-removal detection ──────────────────────────
// HRESULT 887A0005 = DXGI_ERROR_DEVICE_REMOVED ("The GPU
// device instance has been suspended"). Once the D3D12
// device is gone the ORT session is permanently broken.
// Log once, attempt CPU fallback, suppress further flood.
if (msg.find("887A0005") != std::string::npos) {
if (!_dmlDeviceLost) {
_dmlDeviceLost = true;
@@ -2067,6 +2095,7 @@ namespace ANSCENTER {
__FILE__, __LINE__);
ANS_DBG("ONNXYOLO", "DML device lost — recreating session on CPU");
try {
std::lock_guard<std::recursive_mutex> lk(_mutex);
m_ortEngine.reset();
if (InitOrtEngine(ANSCENTER::EngineType::CPU)) {
_logger.LogInfo("ANSONNXYOLO::DetectObjects",
@@ -2084,7 +2113,6 @@ namespace ANSCENTER {
__FILE__, __LINE__);
}
}
// Suppress flood — already logged above
return {};
}
@@ -2101,8 +2129,10 @@ namespace ANSCENTER {
std::vector<std::vector<Object>> ANSONNXYOLO::RunInferencesBatch(
const std::vector<cv::Mat>& inputs, const std::string& camera_id)
{
if (_modelLoading.load()) return {};
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
auto lock = TryLockWithTimeout("ANSONNXYOLO::RunInferencesBatch");
if (!lock.owns_lock()) return {};
if (!_modelLoadValid) {
_logger.LogFatal("ANSONNXYOLO::RunInferencesBatch",
"Cannot load ONNX model", __FILE__, __LINE__);
@@ -2154,16 +2184,33 @@ namespace ANSCENTER {
const std::vector<cv::Mat>& inputImages, const std::string& camera_id)
{
try {
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!m_ortEngine) {
_logger.LogError("ANSONNXYOLO::DetectObjectsBatch",
"ORT engine is null", __FILE__, __LINE__);
return {};
if (_modelLoading.load()) return {};
// Snapshot config under brief lock
float probThresh, nmsThresh;
int numKps;
std::vector<std::string> classes;
bool trackerEnabled, stabilizationEnabled;
{
auto lk = TryLockWithTimeout("ANSONNXYOLO::DetectObjectsBatch");
if (!lk.owns_lock()) return {};
if (!m_ortEngine) {
_logger.LogError("ANSONNXYOLO::DetectObjectsBatch",
"ORT engine is null", __FILE__, __LINE__);
return {};
}
probThresh = PROBABILITY_THRESHOLD;
nmsThresh = NMS_THRESHOLD;
numKps = NUM_KPS;
classes = _classes;
trackerEnabled = _trackerEnabled;
stabilizationEnabled = _stabilizationEnabled;
}
// Heavy work outside lock
auto batchResults = m_ortEngine->detectBatch(
inputImages, _classes,
PROBABILITY_THRESHOLD, NMS_THRESHOLD, NUM_KPS);
inputImages, classes, probThresh, nmsThresh, numKps);
const bool isClassification = m_ortEngine->lastBatchWasClassification;
@@ -2171,10 +2218,9 @@ namespace ANSCENTER {
for (auto& obj : results)
obj.cameraId = camera_id;
// Skip tracking for classification models
if (_trackerEnabled && !isClassification) {
if (trackerEnabled && !isClassification) {
results = ApplyTracking(results, camera_id);
if (_stabilizationEnabled) results = StabilizeDetections(results, camera_id);
if (stabilizationEnabled) results = StabilizeDetections(results, camera_id);
}
}
@@ -2189,6 +2235,7 @@ namespace ANSCENTER {
"DirectML GPU device lost (887A0005) — attempting CPU fallback",
__FILE__, __LINE__);
try {
std::lock_guard<std::recursive_mutex> lk(_mutex);
m_ortEngine.reset();
if (!InitOrtEngine(ANSCENTER::EngineType::CPU))
_logger.LogFatal("ANSONNXYOLO::DetectObjectsBatch",

View File

@@ -31,6 +31,7 @@ namespace ANSCENTER
}
bool OPENVINOCL::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -78,6 +79,7 @@ namespace ANSCENTER
}
bool OPENVINOCL::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -173,6 +175,7 @@ namespace ANSCENTER
}
bool OPENVINOCL::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
std::string openVINOVersion = ov::get_openvino_version().buildNumber;
//this->_logger.LogDebug("OPENVINOCL::Initialize. OpenVINO version", openVINOVersion, __FILE__, __LINE__);
@@ -242,20 +245,7 @@ namespace ANSCENTER
}
std::vector<Object> OPENVINOCL::RunInference(const cv::Mat& input,const std::string& camera_id)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
// Early validation
if (!_licenseValid) {
_logger.LogError("OPENVINOCL::RunInference", "Invalid License",
__FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogError("OPENVINOCL::RunInference", "Model is not initialized",
__FILE__, __LINE__);
return {};
}
if (!PreInferenceCheck("OPENVINOCL::RunInference")) return {};
if (input.empty() || input.cols < 20 || input.rows < 20) {
_logger.LogError("OPENVINOCL::RunInference", "Input image is invalid",

View File

@@ -31,6 +31,7 @@ namespace ANSCENTER
}
bool OPENVINOOD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -79,6 +80,7 @@ namespace ANSCENTER
}
bool OPENVINOOD::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -180,6 +182,7 @@ namespace ANSCENTER
}
bool OPENVINOOD::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
if (!result) return false;
@@ -248,20 +251,7 @@ namespace ANSCENTER
}
std::vector<Object> OPENVINOOD::RunInference(const cv::Mat& input, const std::string& camera_id)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
// Early validation
if (!_licenseValid) {
_logger.LogError("OPENVINOOD::RunInference", "Invalid License",
__FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogError("OPENVINOOD::RunInference", "Model is not initialized",
__FILE__, __LINE__);
return {};
}
if (!PreInferenceCheck("OPENVINOOD::RunInference")) return {};
if (input.empty() || input.cols < 10 || input.rows < 10) {
_logger.LogError("OPENVINOOD::RunInference", "Invalid input image",

View File

@@ -29,6 +29,7 @@ namespace ANSCENTER {
}
bool ANSOVSEG::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -77,6 +78,7 @@ namespace ANSCENTER {
}
bool ANSOVSEG::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -143,6 +145,7 @@ namespace ANSCENTER {
}
bool ANSOVSEG::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
std::string openVINOVersion = ov::get_openvino_version().buildNumber;
this->_logger.LogDebug("ANSOVSEG::Initialize. OpenVINO version", openVINOVersion, __FILE__, __LINE__);
@@ -211,7 +214,7 @@ namespace ANSCENTER {
}
std::vector<Object> ANSOVSEG::RunInference(const cv::Mat& input,const std::string& camera_id)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!PreInferenceCheck("ANSOVSEG::RunInference")) return {};
try {
// Validation

View File

@@ -33,6 +33,7 @@ namespace ANSCENTER {
bool ANSPOSE::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -76,6 +77,7 @@ namespace ANSCENTER {
}
bool ANSPOSE::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -137,6 +139,7 @@ namespace ANSCENTER {
bool ANSPOSE::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
std::string openVINOVersion = ov::get_openvino_version().buildNumber;
this->_logger.LogDebug("ANSPOSE::Initialize. OpenVINO version", openVINOVersion, __FILE__, __LINE__);
@@ -199,7 +202,7 @@ namespace ANSCENTER {
std::vector<Object> ANSPOSE::RunInference(const cv::Mat& input,
const std::string& camera_id)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!PreInferenceCheck("ANSPOSE::RunInference")) return {};
try {
// Validation

View File

@@ -58,6 +58,7 @@ namespace ANSCENTER {
bool ANSRTYOLO::LoadModel(const std::string& modelZipFilePath,
const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
_isFixedBatch = false;
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
@@ -148,6 +149,7 @@ namespace ANSCENTER {
std::string modelName, std::string className,
const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
_isFixedBatch = false;
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,
@@ -250,6 +252,7 @@ namespace ANSCENTER {
const std::string& modelZipPassword,
std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
_modelLoadValid = false;
@@ -351,23 +354,7 @@ namespace ANSCENTER {
std::vector<Object> ANSRTYOLO::RunInference(const cv::Mat& inputImgBGR,
const std::string& camera_id) {
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
_logger.LogError("ANSRTYOLO::RunInference", "Cannot load TensorRT model", __FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
_logger.LogError("ANSRTYOLO::RunInference", "Invalid license", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogError("ANSRTYOLO::RunInference", "Model not initialized", __FILE__, __LINE__);
return {};
}
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10)
return {};
}
if (!PreInferenceCheck("ANSRTYOLO::RunInference")) return {};
try { return DetectObjects(inputImgBGR, camera_id); }
catch (const std::exception& e) {
_logger.LogFatal("ANSRTYOLO::RunInference", e.what(), __FILE__, __LINE__);
@@ -377,25 +364,7 @@ namespace ANSCENTER {
std::vector<std::vector<Object>> ANSRTYOLO::RunInferencesBatch(
const std::vector<cv::Mat>& inputs, const std::string& camera_id) {
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
_logger.LogFatal("ANSRTYOLO::RunInferencesBatch", "Cannot load the TensorRT model", __FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
_logger.LogFatal("ANSRTYOLO::RunInferencesBatch", "Runtime license is not valid or expired", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogFatal("ANSRTYOLO::RunInferencesBatch", "Initialisation is not valid", __FILE__, __LINE__);
return {};
}
if (inputs.empty()) {
_logger.LogFatal("ANSRTYOLO::RunInferencesBatch", "Input images vector is empty", __FILE__, __LINE__);
return {};
}
}
if (!PreInferenceCheck("ANSRTYOLO::RunInferencesBatch")) return {};
try {
if (_isFixedBatch) return ANSODBase::RunInferencesBatch(inputs, camera_id);
else return DetectObjectsBatch(inputs, camera_id);

View File

@@ -35,6 +35,7 @@ namespace ANSCENTER {
bool ANSSAM::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -67,6 +68,7 @@ namespace ANSCENTER {
}
bool ANSSAM::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -108,6 +110,7 @@ namespace ANSCENTER {
{
try {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
_modelConfig = modelConfig;
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
if (!result) return false;
@@ -146,7 +149,7 @@ namespace ANSCENTER {
}
std::vector<Object> ANSSAM::RunInference(const cv::Mat& input,const std::string& camera_id)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!PreInferenceCheck("ANSSAM::RunInference")) return {};
try {
if (!_licenseValid || !_isInitialized || input.empty() ||

View File

@@ -687,6 +687,7 @@ namespace ANSCENTER
std::string& labelMap)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
if (!result) return false;
@@ -746,6 +747,7 @@ namespace ANSCENTER
bool ANSSAM3::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -803,6 +805,7 @@ namespace ANSCENTER
const std::string& modelFolder, std::string& labelMap)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -1010,15 +1013,7 @@ namespace ANSCENTER
std::vector<Object> ANSSAM3::RunInference(const cv::Mat& input, const std::string& camera_id)
{
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid || !_isInitialized) return {};
if (!m_promptSet) {
_logger.LogError("ANSSAM3::RunInference", "No prompt set", __FILE__, __LINE__);
return {};
}
if (input.empty() || input.cols < 10 || input.rows < 10) return {};
}
if (!PreInferenceCheck("ANSSAM3::RunInference")) return {};
try {
return Detect(input, camera_id);
}

View File

@@ -58,6 +58,7 @@ namespace ANSCENTER
}
bool TENSORRTCL::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -152,6 +153,7 @@ namespace ANSCENTER
}
bool TENSORRTCL::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -257,6 +259,7 @@ namespace ANSCENTER
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
_modelLoadValid = false;
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
if (!result) return false;
@@ -360,33 +363,7 @@ namespace ANSCENTER
std::vector<Object> TENSORRTCL::RunInference(const cv::Mat& inputImgBGR,const std::string& camera_id)
{
// Validate state under brief lock
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
_logger.LogError("TENSORRTCL::RunInference",
"Cannot load the TensorRT model. Please check if it exists",
__FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
_logger.LogError("TENSORRTCL::RunInference",
"Runtime license is not valid or expired. Please contact ANSCENTER",
__FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogError("TENSORRTCL::RunInference",
"Model is not initialized",
__FILE__, __LINE__);
return {};
}
if (inputImgBGR.empty() || inputImgBGR.cols < 5 || inputImgBGR.rows < 5) {
return {};
}
}
if (!PreInferenceCheck("TENSORRTCL::RunInference")) return {};
try {
return DetectObjects(inputImgBGR, camera_id);
}
@@ -397,28 +374,7 @@ namespace ANSCENTER
}
std::vector<std::vector<Object>> TENSORRTCL::RunInferencesBatch(const std::vector<cv::Mat>& inputs, const std::string& camera_id) {
// Validate state under brief lock
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
this->_logger.LogFatal("TENSORRTCL::RunInferencesBatch",
"Cannot load the TensorRT model. Please check if it exists", __FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
this->_logger.LogFatal("TENSORRTCL::RunInferencesBatch",
"Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
this->_logger.LogFatal("TENSORRTCL::RunInferencesBatch",
"Engine not initialized", __FILE__, __LINE__);
return {};
}
if (inputs.empty()) return {};
}
if (!PreInferenceCheck("TENSORRTCL::RunInferencesBatch")) return {};
try {
return DetectObjectsBatch(inputs, camera_id);
}

View File

@@ -55,6 +55,7 @@ namespace ANSCENTER
}
bool ANSTENSORRTPOSE::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -144,6 +145,7 @@ namespace ANSCENTER
}
bool ANSTENSORRTPOSE::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try
{
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
@@ -245,6 +247,7 @@ namespace ANSCENTER
}
bool ANSTENSORRTPOSE::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
_modelLoadValid = false;
@@ -347,35 +350,7 @@ namespace ANSCENTER
}
std::vector<Object> ANSTENSORRTPOSE::RunInference(const cv::Mat& inputImgBGR,const std::string& camera_id)
{
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
// Validation checks
if (!_modelLoadValid) {
_logger.LogError("ANSTENSORRTPOSE::RunInference",
"Cannot load the TensorRT model. Please check if it exists",
__FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
_logger.LogError("ANSTENSORRTPOSE::RunInference",
"Runtime license is not valid or expired. Please contact ANSCENTER",
__FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogError("ANSTENSORRTPOSE::RunInference",
"Model is not initialized",
__FILE__, __LINE__);
return {};
}
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10) {
return {};
}
}
if (!PreInferenceCheck("ANSTENSORRTPOSE::RunInference")) return {};
try {
return DetectObjects(inputImgBGR, camera_id);
}
@@ -983,25 +958,7 @@ namespace ANSCENTER
std::vector<std::vector<Object>> ANSTENSORRTPOSE::RunInferencesBatch(
const std::vector<cv::Mat>& inputs, const std::string& camera_id)
{
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
_logger.LogError("ANSTENSORRTPOSE::RunInferencesBatch",
"Model not loaded", __FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
_logger.LogError("ANSTENSORRTPOSE::RunInferencesBatch",
"Invalid license", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogError("ANSTENSORRTPOSE::RunInferencesBatch",
"Engine not initialized", __FILE__, __LINE__);
return {};
}
if (inputs.empty()) return {};
}
if (!PreInferenceCheck("ANSTENSORRTPOSE::RunInferencesBatch")) return {};
try {
return DetectObjectsBatch(inputs, camera_id);
}

View File

@@ -55,6 +55,7 @@ namespace ANSCENTER
}
bool TENSORRTSEG::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -144,6 +145,7 @@ namespace ANSCENTER
}
bool TENSORRTSEG::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try
{
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
@@ -245,6 +247,7 @@ namespace ANSCENTER
}
bool TENSORRTSEG::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
_modelLoadValid = false;
@@ -347,27 +350,7 @@ namespace ANSCENTER
}
std::vector<Object> TENSORRTSEG::RunInference(const cv::Mat& inputImgBGR,const std::string& camera_id)
{
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
_logger.LogError("TENSORRTSEG::RunInference",
"Cannot load TensorRT model", __FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
_logger.LogError("TENSORRTSEG::RunInference",
"Invalid license", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogError("TENSORRTSEG::RunInference",
"Model not initialized", __FILE__, __LINE__);
return {};
}
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10) {
return {};
}
}
if (!PreInferenceCheck("TENSORRTSEG::RunInference")) return {};
try {
return DetectObjects(inputImgBGR, camera_id);
}
@@ -1134,25 +1117,7 @@ namespace ANSCENTER
std::vector<std::vector<Object>> TENSORRTSEG::RunInferencesBatch(
const std::vector<cv::Mat>& inputs, const std::string& camera_id)
{
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
_logger.LogError("TENSORRTSEG::RunInferencesBatch",
"Model not loaded", __FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
_logger.LogError("TENSORRTSEG::RunInferencesBatch",
"Invalid license", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogError("TENSORRTSEG::RunInferencesBatch",
"Engine not initialized", __FILE__, __LINE__);
return {};
}
if (inputs.empty()) return {};
}
if (!PreInferenceCheck("TENSORRTSEG::RunInferencesBatch")) return {};
try {
return DetectObjectsBatch(inputs, camera_id);
}

View File

@@ -58,6 +58,7 @@ namespace ANSCENTER
}
bool TENSORRTOD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
_isFixedBatch = false;
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
@@ -151,6 +152,7 @@ namespace ANSCENTER
}
bool TENSORRTOD::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try
{
_isFixedBatch = false;
@@ -256,6 +258,7 @@ namespace ANSCENTER
}
bool TENSORRTOD::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
_modelLoadValid = false;
@@ -364,31 +367,7 @@ namespace ANSCENTER
{
// Validate state under a brief lock — do NOT hold across DetectObjects so that
// the Engine pool can run concurrent inferences on different GPU slots.
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
_logger.LogError("TENSORRTOD::RunInference",
"Cannot load TensorRT model", __FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
_logger.LogError("TENSORRTOD::RunInference",
"Invalid license", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogError("TENSORRTOD::RunInference",
"Model not initialized", __FILE__, __LINE__);
return {};
}
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10) {
return {};
}
} // mutex released here — DetectObjects manages its own locking per phase
if (!PreInferenceCheck("TENSORRTOD::RunInference")) return {};
try {
return DetectObjects(inputImgBGR, camera_id);
@@ -401,34 +380,7 @@ namespace ANSCENTER
std::vector<std::vector<Object>> TENSORRTOD::RunInferencesBatch(const std::vector<cv::Mat>& inputs, const std::string& camera_id) {
// Validate state under a brief lock — do NOT hold across DetectObjectsBatch so that
// the Engine pool can serve concurrent batch requests on different GPU slots.
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
// Validate model, license, and initialization
if (!_modelLoadValid) {
this->_logger.LogFatal("TENSORRTOD::RunInferenceBatch",
"Cannot load the TensorRT model. Please check if it exists", __FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
this->_logger.LogFatal("TENSORRTOD::RunInferenceBatch",
"Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
this->_logger.LogFatal("TENSORRTOD::RunInferenceBatch",
"Initialisation is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
return {};
}
// Validate inputs
if (inputs.empty()) {
this->_logger.LogFatal("TENSORRTOD::RunInferenceBatch",
"Input images vector is empty", __FILE__, __LINE__);
return {};
}
} // mutex released here — DetectObjectsBatch manages its own GPU dispatch
if (!PreInferenceCheck("TENSORRTOD::RunInferencesBatch")) return {};
try {
if (_isFixedBatch) return ANSODBase::RunInferencesBatch(inputs, camera_id);

View File

@@ -23,6 +23,7 @@ namespace ANSCENTER {
}
bool YOLO12OD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -81,6 +82,7 @@ namespace ANSCENTER {
}
bool YOLO12OD::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName,std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className,modelFolder, labelMap);
if (!result) return false;
@@ -153,6 +155,7 @@ namespace ANSCENTER {
}
bool YOLO12OD::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
if (!result) return false;
@@ -223,7 +226,7 @@ namespace ANSCENTER {
}
std::vector<Object> YOLO12OD::RunInference(const cv::Mat& input,const std::string& camera_id)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!PreInferenceCheck("YOLO12OD::RunInference")) return {};
try {
// Validation
if (!_licenseValid) {

View File

@@ -938,6 +938,7 @@ namespace ANSCENTER
}
bool YOLOOD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -1030,6 +1031,7 @@ namespace ANSCENTER
}
bool YOLOOD::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -1152,6 +1154,7 @@ namespace ANSCENTER
}
bool YOLOOD::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
if (!result) return false;
@@ -1266,18 +1269,7 @@ namespace ANSCENTER
return RunInference(input, "CustomCam");
}
std::vector<Object> YOLOOD::RunInference(const cv::Mat& input, const std::string& camera_id) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
// Early validation - before try block
if (!_licenseValid) {
this->_logger.LogError("YOLOOD::RunInference", "Invalid License", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
this->_logger.LogError("YOLOOD::RunInference", "Model is not initialized", __FILE__, __LINE__);
return {};
}
if (!PreInferenceCheck("YOLOOD::RunInference")) return {};
if (input.empty() || input.cols < 10 || input.rows < 10) {
return {};

View File

@@ -33,6 +33,7 @@ namespace ANSCENTER
bool ANSOYOLOV10OVOD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -88,6 +89,7 @@ namespace ANSCENTER
}
bool ANSOYOLOV10OVOD::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName,std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,modelName, className,modelFolder, labelMap);
if (!result) return false;
@@ -157,6 +159,7 @@ namespace ANSCENTER
bool ANSOYOLOV10OVOD::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
std::string openVINOVersion = ov::get_openvino_version().buildNumber;
std::cout << "OpenVINO version: " << openVINOVersion << std::endl;
@@ -222,18 +225,7 @@ namespace ANSCENTER
return RunInference(input, "OpenVINO10Cam");
}
std::vector<Object> ANSOYOLOV10OVOD::RunInference(const cv::Mat& input, const std::string& camera_id) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
// Validate license and initialization status
if (!_licenseValid) {
_logger.LogError("ANSOYOLOV10OVOD::RunInference", "Invalid License", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogError("ANSOYOLOV10OVOD::RunInference", "Model is not initialized", __FILE__, __LINE__);
return {};
}
if (!PreInferenceCheck("ANSOYOLOV10OVOD::RunInference")) return {};
// Validate input
if (input.empty()) {

View File

@@ -56,6 +56,7 @@ namespace ANSCENTER
}
bool ANSYOLOV10RTOD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -154,6 +155,7 @@ namespace ANSCENTER
}
bool ANSYOLOV10RTOD::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,modelName, className, modelFolder, labelMap);
if (!result) return false;
@@ -260,6 +262,7 @@ namespace ANSCENTER
bool ANSYOLOV10RTOD::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap)
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
_modelLoadValid = false;
@@ -362,27 +365,7 @@ namespace ANSCENTER
std::vector<Object> ANSYOLOV10RTOD::RunInference(const cv::Mat& inputImgBGR, const std::string& camera_id) {
// Validate under brief lock
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
this->_logger.LogFatal("ANSYOLOV10RTOD::RunInference",
"Cannot load the TensorRT model. Please check if it is exist", __FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
this->_logger.LogFatal("ANSYOLOV10RTOD::RunInference",
"Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
this->_logger.LogFatal("ANSYOLOV10RTOD::RunInference",
"Initialisation is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
return {};
}
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10) {
return {};
}
}
if (!PreInferenceCheck("ANSYOLOV10RTOD::RunInference")) return {};
try {
return DetectObjects(inputImgBGR, camera_id);
}
@@ -1000,25 +983,7 @@ namespace ANSCENTER
std::vector<std::vector<Object>> ANSYOLOV10RTOD::RunInferencesBatch(
const std::vector<cv::Mat>& inputs, const std::string& camera_id)
{
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
_logger.LogError("ANSYOLOV10RTOD::RunInferencesBatch",
"Model not loaded", __FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
_logger.LogError("ANSYOLOV10RTOD::RunInferencesBatch",
"Invalid license", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogError("ANSYOLOV10RTOD::RunInferencesBatch",
"Engine not initialized", __FILE__, __LINE__);
return {};
}
if (inputs.empty()) return {};
}
if (!PreInferenceCheck("ANSYOLOV10RTOD::RunInferencesBatch")) return {};
try {
return DetectObjectsBatch(inputs, camera_id);
}

View File

@@ -55,6 +55,7 @@ namespace ANSCENTER
}
bool ANSYOLOV12RTOD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
if (!result) return false;
@@ -147,6 +148,7 @@ namespace ANSCENTER
}
bool ANSYOLOV12RTOD::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName,std::string className, const std::string& modelFolder, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,modelName, className,modelFolder, labelMap);
if (!result) return false;
@@ -248,6 +250,7 @@ namespace ANSCENTER
}
bool ANSYOLOV12RTOD::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
ModelLoadingGuard mlg(_modelLoading);
try {
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
_modelLoadValid = false;
@@ -343,35 +346,11 @@ namespace ANSCENTER
return RunInference(inputImgBGR, "TensorRT12Cam");
}
std::vector<Object> ANSYOLOV12RTOD::RunInference(const cv::Mat& inputImgBGR, const std::string& camera_id) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
// Validate model, license, and initialization
if (!_modelLoadValid) {
this->_logger.LogFatal("ANSYOLOV12RTOD::RunInference",
"Cannot load the TensorRT model. Please check if it is exist", __FILE__, __LINE__);
if (!PreInferenceCheck("ANSYOLOV12RTOD::RunInference")) return {};
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10)
return {};
}
if (!_licenseValid) {
this->_logger.LogFatal("ANSYOLOV12RTOD::RunInference",
"Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
this->_logger.LogFatal("ANSYOLOV12RTOD::RunInference",
"Model is not initialized", __FILE__, __LINE__);
return {};
}
// Validate input
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10) {
return {};
}
try {
return DetectObjects(inputImgBGR, camera_id);
}
catch (const std::exception& e) {
this->_logger.LogFatal("ANSYOLOV12RTOD::RunInference", e.what(), __FILE__, __LINE__);
@@ -919,22 +898,7 @@ namespace ANSCENTER
std::vector<std::vector<Object>> ANSYOLOV12RTOD::RunInferencesBatch(
const std::vector<cv::Mat>& inputs, const std::string& camera_id)
{
{
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_modelLoadValid) {
_logger.LogError("ANSYOLOV12RTOD::RunInferencesBatch", "Model not loaded", __FILE__, __LINE__);
return {};
}
if (!_licenseValid) {
_logger.LogError("ANSYOLOV12RTOD::RunInferencesBatch", "Invalid license", __FILE__, __LINE__);
return {};
}
if (!_isInitialized) {
_logger.LogError("ANSYOLOV12RTOD::RunInferencesBatch", "Engine not initialized", __FILE__, __LINE__);
return {};
}
if (inputs.empty()) return {};
}
if (!PreInferenceCheck("ANSYOLOV12RTOD::RunInferencesBatch")) return {};
try {
return DetectObjectsBatch(inputs, camera_id);
}