630 lines
20 KiB
C++
630 lines
20 KiB
C++
#include "MvsDevice.h"
|
|
#include "MvsSDKManager.h"
|
|
#include "VrError.h"
|
|
#include "VrLog.h"
|
|
#include <cstring>
|
|
#include <chrono>
|
|
#include <thread>
|
|
|
|
namespace
|
|
{
|
|
constexpr unsigned int kUsbImageNodeNum = 1;
|
|
constexpr unsigned int kUsbTransferSize = 0x40000; // 256KB, reduce per-URB DMA pressure on ARM USB2
|
|
constexpr unsigned int kUsbTransferWays = 1;
|
|
constexpr float kUsbOpenFrameRate = 2.0f;
|
|
|
|
bool IsUsbDeviceType(unsigned int type)
|
|
{
|
|
return type == MV_USB_DEVICE || type == MV_VIR_USB_DEVICE;
|
|
}
|
|
|
|
void ApplyConservativeUsbStreamConfig(void* handle, const char* stage)
|
|
{
|
|
if (!handle) return;
|
|
|
|
int frameEnableRet = MV_CC_SetBoolValue(handle, "AcquisitionFrameRateEnable", true);
|
|
int nodeRet = MV_CC_SetImageNodeNum(handle, kUsbImageNodeNum);
|
|
int sizeRet = MV_USB_SetTransferSize(handle, kUsbTransferSize);
|
|
int waysRet = MV_USB_SetTransferWays(handle, kUsbTransferWays);
|
|
|
|
MVCC_FLOATVALUE frameRateValue;
|
|
memset(&frameRateValue, 0, sizeof(frameRateValue));
|
|
int frameGetRet = MV_CC_GetFloatValue(handle, "AcquisitionFrameRate", &frameRateValue);
|
|
unsigned int readSize = 0;
|
|
unsigned int readWays = 0;
|
|
int getSizeRet = MV_USB_GetTransferSize(handle, &readSize);
|
|
int getWaysRet = MV_USB_GetTransferWays(handle, &readWays);
|
|
|
|
LOG_DEBUG("[MVS] USB stream config(%s) fps=%.1f enableRet=0x%x fpsGetRet=0x%x node=%u ret=0x%x transferSize=0x%x ret=0x%x read=0x%x readRet=0x%x transferWays=%u ret=0x%x read=%u readRet=0x%x\n",
|
|
stage ? stage : "",
|
|
frameRateValue.fCurValue, frameEnableRet, frameGetRet,
|
|
kUsbImageNodeNum, nodeRet,
|
|
kUsbTransferSize, sizeRet, readSize, getSizeRet,
|
|
kUsbTransferWays, waysRet, readWays, getWaysRet);
|
|
}
|
|
}
|
|
|
|
// 工厂
|
|
int IMvsDevice::CreateObject(IMvsDevice** ppDevice)
|
|
{
|
|
if (ppDevice == nullptr)
|
|
{
|
|
return ERR_CODE(DEV_ARG_INVAILD);
|
|
}
|
|
try
|
|
{
|
|
*ppDevice = new CMvsDevice();
|
|
return SUCCESS;
|
|
}
|
|
catch (...)
|
|
{
|
|
return ERR_CODE(DATA_ERR_MEM);
|
|
}
|
|
}
|
|
|
|
CMvsDevice::CMvsDevice() = default;
|
|
|
|
CMvsDevice::~CMvsDevice()
|
|
{
|
|
try
|
|
{
|
|
if (m_bAcquisitioning) StopAcquisition();
|
|
if (m_bDeviceOpen) CloseDevice();
|
|
if (m_bSDKInitialized) UninitSDK();
|
|
}
|
|
catch (...) {}
|
|
}
|
|
|
|
int CMvsDevice::InitSDK()
|
|
{
|
|
if (m_bSDKInitialized) return SUCCESS;
|
|
int ret = MvsSDKManager::GetInstance().InitSDK();
|
|
if (ret == SUCCESS) m_bSDKInitialized = true;
|
|
return ret;
|
|
}
|
|
|
|
int CMvsDevice::UninitSDK()
|
|
{
|
|
if (!m_bSDKInitialized) return SUCCESS;
|
|
int ret = MvsSDKManager::GetInstance().UninitSDK();
|
|
if (ret == SUCCESS) m_bSDKInitialized = false;
|
|
return ret;
|
|
}
|
|
|
|
int CMvsDevice::GetSDKVersion(std::string& version)
|
|
{
|
|
unsigned int v = MV_CC_GetSDKVersion();
|
|
char buf[64] = {0};
|
|
snprintf(buf, sizeof(buf), "MVS %u.%u.%u.%u",
|
|
(v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF);
|
|
version = buf;
|
|
return SUCCESS;
|
|
}
|
|
|
|
void CMvsDevice::FillDeviceInfo(const MV_CC_DEVICE_INFO& src, MvsDeviceInfo& dst)
|
|
{
|
|
if (src.nTLayerType == MV_GIGE_DEVICE
|
|
|| src.nTLayerType == MV_VIR_GIGE_DEVICE
|
|
|| src.nTLayerType == MV_GENTL_GIGE_DEVICE)
|
|
{
|
|
const auto& gi = src.SpecialInfo.stGigEInfo;
|
|
dst.tlType = EMvsTLType::GigE;
|
|
dst.serialNumber = reinterpret_cast<const char*>(gi.chSerialNumber);
|
|
dst.modelName = reinterpret_cast<const char*>(gi.chModelName);
|
|
dst.manufacturerName = reinterpret_cast<const char*>(gi.chManufacturerName);
|
|
dst.deviceVersion = reinterpret_cast<const char*>(gi.chDeviceVersion);
|
|
dst.userDefinedName = reinterpret_cast<const char*>(gi.chUserDefinedName);
|
|
|
|
// IP 拼接
|
|
unsigned int ip = gi.nCurrentIp;
|
|
char ipBuf[32] = {0};
|
|
snprintf(ipBuf, sizeof(ipBuf), "%u.%u.%u.%u",
|
|
(ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF);
|
|
dst.ipAddress = ipBuf;
|
|
dst.macAddress.clear();
|
|
}
|
|
else if (src.nTLayerType == MV_USB_DEVICE
|
|
|| src.nTLayerType == MV_VIR_USB_DEVICE)
|
|
{
|
|
const auto& ui = src.SpecialInfo.stUsb3VInfo;
|
|
dst.tlType = EMvsTLType::USB3;
|
|
dst.serialNumber = reinterpret_cast<const char*>(ui.chSerialNumber);
|
|
dst.modelName = reinterpret_cast<const char*>(ui.chModelName);
|
|
dst.manufacturerName = reinterpret_cast<const char*>(ui.chManufacturerName);
|
|
dst.deviceVersion = reinterpret_cast<const char*>(ui.chDeviceVersion);
|
|
dst.userDefinedName = reinterpret_cast<const char*>(ui.chUserDefinedName);
|
|
dst.ipAddress.clear();
|
|
dst.macAddress.clear();
|
|
}
|
|
else
|
|
{
|
|
dst.tlType = EMvsTLType::Other;
|
|
}
|
|
|
|
dst.displayName = dst.userDefinedName.empty()
|
|
? (dst.modelName + " (" + dst.serialNumber + ")")
|
|
: dst.userDefinedName;
|
|
}
|
|
|
|
int CMvsDevice::EnumerateDevices(std::vector<MvsDeviceInfo>& deviceList, unsigned int tLayerType)
|
|
{
|
|
if (!m_bSDKInitialized)
|
|
{
|
|
int r = InitSDK();
|
|
if (r != SUCCESS) return r;
|
|
}
|
|
|
|
deviceList.clear();
|
|
m_devInfoCache.clear();
|
|
|
|
unsigned int layer = tLayerType == 0
|
|
? (MV_GIGE_DEVICE | MV_USB_DEVICE)
|
|
: tLayerType;
|
|
|
|
MV_CC_DEVICE_INFO_LIST stDeviceList;
|
|
memset(&stDeviceList, 0, sizeof(stDeviceList));
|
|
|
|
int ret = MV_CC_EnumDevices(layer, &stDeviceList);
|
|
if (ret != MV_OK)
|
|
{
|
|
LOG_DEBUG("MV_CC_EnumDevices fail: %x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
for (unsigned int i = 0; i < stDeviceList.nDeviceNum; ++i)
|
|
{
|
|
MV_CC_DEVICE_INFO* p = stDeviceList.pDeviceInfo[i];
|
|
if (!p) continue;
|
|
|
|
m_devInfoCache.push_back(*p);
|
|
|
|
MvsDeviceInfo info;
|
|
FillDeviceInfo(*p, info);
|
|
deviceList.push_back(info);
|
|
}
|
|
|
|
LOG_DEBUG("MVS Enumerated %u devices\n", static_cast<unsigned>(deviceList.size()));
|
|
return SUCCESS;
|
|
}
|
|
|
|
int CMvsDevice::OpenDevice(const std::string& serialNumber)
|
|
{
|
|
std::lock_guard<std::mutex> lk(m_deviceMutex);
|
|
|
|
if (!m_bSDKInitialized)
|
|
{
|
|
int r = InitSDK();
|
|
if (r != SUCCESS) return r;
|
|
}
|
|
|
|
// 如果缓存为空(外部直接通过 SN 打开),先枚举一次
|
|
if (m_devInfoCache.empty())
|
|
{
|
|
std::vector<MvsDeviceInfo> tmp;
|
|
int r = EnumerateDevices(tmp);
|
|
if (r != SUCCESS) return r;
|
|
}
|
|
|
|
// 查找匹配的 SN
|
|
MV_CC_DEVICE_INFO* pTarget = nullptr;
|
|
bool targetIsUsb = false;
|
|
for (auto& dev : m_devInfoCache)
|
|
{
|
|
const char* sn = nullptr;
|
|
if (dev.nTLayerType == MV_GIGE_DEVICE
|
|
|| dev.nTLayerType == MV_VIR_GIGE_DEVICE
|
|
|| dev.nTLayerType == MV_GENTL_GIGE_DEVICE)
|
|
{
|
|
sn = reinterpret_cast<const char*>(dev.SpecialInfo.stGigEInfo.chSerialNumber);
|
|
}
|
|
else if (dev.nTLayerType == MV_USB_DEVICE
|
|
|| dev.nTLayerType == MV_VIR_USB_DEVICE)
|
|
{
|
|
sn = reinterpret_cast<const char*>(dev.SpecialInfo.stUsb3VInfo.chSerialNumber);
|
|
}
|
|
if (sn && serialNumber == sn)
|
|
{
|
|
pTarget = &dev;
|
|
targetIsUsb = IsUsbDeviceType(dev.nTLayerType);
|
|
break;
|
|
}
|
|
}
|
|
if (!pTarget) return ERR_CODE(DEV_NOT_FIND);
|
|
|
|
if (m_bDeviceOpen) CloseDevice();
|
|
|
|
int ret = MV_CC_CreateHandle(&m_handle, pTarget);
|
|
if (ret != MV_OK)
|
|
{
|
|
LOG_DEBUG("MV_CC_CreateHandle fail: %x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = MV_CC_OpenDevice(m_handle);
|
|
if (ret != MV_OK)
|
|
{
|
|
LOG_DEBUG("MV_CC_OpenDevice fail: %x\n", ret);
|
|
MV_CC_DestroyHandle(m_handle);
|
|
m_handle = nullptr;
|
|
return ret;
|
|
}
|
|
|
|
// GigE 设备建议优化包大小
|
|
if (pTarget->nTLayerType == MV_GIGE_DEVICE)
|
|
{
|
|
int nPacketSize = MV_CC_GetOptimalPacketSize(m_handle);
|
|
if (nPacketSize > 0)
|
|
{
|
|
MV_CC_SetIntValueEx(m_handle, "GevSCPSPacketSize", nPacketSize);
|
|
}
|
|
}
|
|
|
|
// USB 设备优化带宽(降低传输负载,避免资源申请失败)
|
|
if (pTarget->nTLayerType == MV_USB_DEVICE
|
|
|| pTarget->nTLayerType == MV_VIR_USB_DEVICE)
|
|
{
|
|
// 降低 USB 传输包大小,减少带宽占用
|
|
MV_CC_SetIntValueEx(m_handle, "PayloadSize", 0); // 自动计算
|
|
|
|
// 设置合理的帧率上限(避免带宽不足)
|
|
MV_CC_SetBoolValue(m_handle, "AcquisitionFrameRateEnable", true);
|
|
MV_CC_SetFloatValue(m_handle, "AcquisitionFrameRate", kUsbOpenFrameRate);
|
|
}
|
|
|
|
// 默认关闭触发模式
|
|
MV_CC_SetEnumValue(m_handle, "TriggerMode", MV_TRIGGER_MODE_OFF);
|
|
|
|
m_currentDeviceIsUsb = targetIsUsb;
|
|
if (m_currentDeviceIsUsb) ApplyConservativeUsbStreamConfig(m_handle, "open-final");
|
|
|
|
FillDeviceInfo(*pTarget, m_currentDeviceInfo);
|
|
m_bDeviceOpen = true;
|
|
return SUCCESS;
|
|
}
|
|
|
|
int CMvsDevice::OpenDeviceByIndex(unsigned int index)
|
|
{
|
|
std::vector<MvsDeviceInfo> list;
|
|
int r = EnumerateDevices(list);
|
|
if (r != SUCCESS) return r;
|
|
if (index >= list.size()) return ERR_CODE(DEV_ID_ERR);
|
|
return OpenDevice(list[index].serialNumber);
|
|
}
|
|
|
|
int CMvsDevice::CloseDevice()
|
|
{
|
|
std::lock_guard<std::mutex> lk(m_deviceMutex);
|
|
|
|
if (m_bAcquisitioning) StopAcquisition();
|
|
|
|
if (m_handle)
|
|
{
|
|
MV_CC_CloseDevice(m_handle);
|
|
MV_CC_DestroyHandle(m_handle);
|
|
m_handle = nullptr;
|
|
}
|
|
m_bDeviceOpen = false;
|
|
m_currentDeviceIsUsb = false;
|
|
return SUCCESS;
|
|
}
|
|
|
|
bool CMvsDevice::IsDeviceOpen()
|
|
{
|
|
return m_bDeviceOpen;
|
|
}
|
|
|
|
int CMvsDevice::GetDeviceInfo(MvsDeviceInfo& info)
|
|
{
|
|
if (!m_bDeviceOpen) return ERR_CODE(DEV_NO_OPEN);
|
|
info = m_currentDeviceInfo;
|
|
GetWidth(info.width);
|
|
GetHeight(info.height);
|
|
return SUCCESS;
|
|
}
|
|
|
|
int CMvsDevice::SetTriggerMode(bool enable)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
return MV_CC_SetEnumValue(m_handle, "TriggerMode",
|
|
enable ? MV_TRIGGER_MODE_ON : MV_TRIGGER_MODE_OFF);
|
|
}
|
|
|
|
int CMvsDevice::SendSoftTrigger()
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
return MV_CC_SetCommandValue(m_handle, "TriggerSoftware");
|
|
}
|
|
|
|
int CMvsDevice::StartAcquisition()
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
if (m_bAcquisitioning) return SUCCESS;
|
|
|
|
if (m_currentDeviceIsUsb) ApplyConservativeUsbStreamConfig(m_handle, "start");
|
|
|
|
int ret = MV_CC_StartGrabbing(m_handle);
|
|
if (ret == MV_OK)
|
|
{
|
|
m_bAcquisitioning = true;
|
|
}
|
|
else
|
|
{
|
|
LOG_DEBUG("MV_CC_StartGrabbing fail: %x\n", ret);
|
|
|
|
// 针对资源申请失败,输出详细诊断信息
|
|
if (ret == 0x80000006) // MV_E_RESOURCE
|
|
{
|
|
LOG_ERROR("USB resource allocation failed. Possible causes:\n");
|
|
LOG_ERROR(" 1. Insufficient USB bandwidth (try lower resolution/framerate)\n");
|
|
LOG_ERROR(" 2. USB controller overload (disconnect other USB devices)\n");
|
|
LOG_ERROR(" 3. Insufficient system memory\n");
|
|
LOG_ERROR(" 4. USB power supply insufficient\n");
|
|
|
|
// 尝试读取当前相机参数
|
|
MVCC_INTVALUE_EX stParam;
|
|
memset(&stParam, 0, sizeof(stParam));
|
|
if (MV_CC_GetIntValueEx(m_handle, "Width", &stParam) == MV_OK)
|
|
{
|
|
LOG_ERROR(" Current Width: %lld\n", stParam.nCurValue);
|
|
}
|
|
memset(&stParam, 0, sizeof(stParam));
|
|
if (MV_CC_GetIntValueEx(m_handle, "Height", &stParam) == MV_OK)
|
|
{
|
|
LOG_ERROR(" Current Height: %lld\n", stParam.nCurValue);
|
|
}
|
|
|
|
MVCC_FLOATVALUE stFloatParam;
|
|
memset(&stFloatParam, 0, sizeof(stFloatParam));
|
|
if (MV_CC_GetFloatValue(m_handle, "AcquisitionFrameRate", &stFloatParam) == MV_OK)
|
|
{
|
|
LOG_ERROR(" Current FrameRate: %.2f\n", stFloatParam.fCurValue);
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int CMvsDevice::StopAcquisition()
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
if (!m_bAcquisitioning) return SUCCESS;
|
|
int ret = MV_CC_StopGrabbing(m_handle);
|
|
if (ret == MV_OK) m_bAcquisitioning = false;
|
|
else LOG_DEBUG("MV_CC_StopGrabbing fail: %x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
bool CMvsDevice::IsAcquisitioning()
|
|
{
|
|
return m_bAcquisitioning;
|
|
}
|
|
|
|
int CMvsDevice::CaptureImage(MvsImageData& image, unsigned int timeoutMs)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
|
|
MV_FRAME_OUT stFrame;
|
|
memset(&stFrame, 0, sizeof(stFrame));
|
|
|
|
int ret = MV_CC_GetImageBuffer(m_handle, &stFrame, timeoutMs);
|
|
if (ret != MV_OK)
|
|
{
|
|
LOG_DEBUG("MV_CC_GetImageBuffer fail: %x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
image.width = stFrame.stFrameInfo.nExtendWidth
|
|
? stFrame.stFrameInfo.nExtendWidth
|
|
: stFrame.stFrameInfo.nWidth;
|
|
image.height = stFrame.stFrameInfo.nExtendHeight
|
|
? stFrame.stFrameInfo.nExtendHeight
|
|
: stFrame.stFrameInfo.nHeight;
|
|
image.dataSize = stFrame.stFrameInfo.nFrameLen;
|
|
image.pixelFormat = static_cast<int>(stFrame.stFrameInfo.enPixelType);
|
|
image.frameID = stFrame.stFrameInfo.nFrameNum;
|
|
image.timestamp = (static_cast<unsigned long long>(stFrame.stFrameInfo.nDevTimeStampHigh) << 32)
|
|
| stFrame.stFrameInfo.nDevTimeStampLow;
|
|
|
|
image.pData = new unsigned char[image.dataSize];
|
|
memcpy(image.pData, stFrame.pBufAddr, image.dataSize);
|
|
|
|
MV_CC_FreeImageBuffer(m_handle, &stFrame);
|
|
return SUCCESS;
|
|
}
|
|
|
|
int CMvsDevice::RegisterImageCallback(MvsImageCallback callback)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
{
|
|
std::lock_guard<std::mutex> lk(m_callbackMutex);
|
|
m_imageCallback = std::move(callback);
|
|
}
|
|
int ret = MV_CC_RegisterImageCallBackEx(m_handle, &CMvsDevice::OnFrameCallback, this);
|
|
LOG_DEBUG("[MVS] RegisterImageCallback handle=%p ret=0x%x\n", (void*)m_handle, ret);
|
|
return ret;
|
|
}
|
|
|
|
int CMvsDevice::UnregisterImageCallback()
|
|
{
|
|
if (!m_handle) return SUCCESS;
|
|
// MVS 没有显式反注册,使用空回调覆盖
|
|
MV_CC_RegisterImageCallBackEx(m_handle, nullptr, nullptr);
|
|
std::lock_guard<std::mutex> lk(m_callbackMutex);
|
|
m_imageCallback = nullptr;
|
|
return SUCCESS;
|
|
}
|
|
|
|
void __stdcall CMvsDevice::OnFrameCallback(unsigned char* pData,
|
|
MV_FRAME_OUT_INFO_EX* pFrameInfo,
|
|
void* pUser)
|
|
{
|
|
if (!pData || !pFrameInfo || !pUser) return;
|
|
CMvsDevice* self = static_cast<CMvsDevice*>(pUser);
|
|
|
|
MvsImageCallback cb;
|
|
{
|
|
std::lock_guard<std::mutex> lk(self->m_callbackMutex);
|
|
cb = self->m_imageCallback;
|
|
}
|
|
if (!cb) return;
|
|
|
|
MvsImageData img;
|
|
img.width = pFrameInfo->nExtendWidth ? pFrameInfo->nExtendWidth : pFrameInfo->nWidth;
|
|
img.height = pFrameInfo->nExtendHeight ? pFrameInfo->nExtendHeight : pFrameInfo->nHeight;
|
|
img.dataSize = pFrameInfo->nFrameLen;
|
|
img.pixelFormat = static_cast<int>(pFrameInfo->enPixelType);
|
|
img.frameID = pFrameInfo->nFrameNum;
|
|
img.timestamp = (static_cast<unsigned long long>(pFrameInfo->nDevTimeStampHigh) << 32)
|
|
| pFrameInfo->nDevTimeStampLow;
|
|
// 回调期间 pData 由 SDK 持有,外部不要 delete
|
|
img.pData = pData;
|
|
|
|
try { cb(img); } catch (...) {}
|
|
}
|
|
|
|
int CMvsDevice::GetWidth(unsigned int& width)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
MVCC_INTVALUE_EX v; memset(&v, 0, sizeof(v));
|
|
int ret = MV_CC_GetIntValueEx(m_handle, "Width", &v);
|
|
if (ret == MV_OK) width = static_cast<unsigned int>(v.nCurValue);
|
|
return ret;
|
|
}
|
|
|
|
int CMvsDevice::GetHeight(unsigned int& height)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
MVCC_INTVALUE_EX v; memset(&v, 0, sizeof(v));
|
|
int ret = MV_CC_GetIntValueEx(m_handle, "Height", &v);
|
|
if (ret == MV_OK) height = static_cast<unsigned int>(v.nCurValue);
|
|
return ret;
|
|
}
|
|
|
|
int CMvsDevice::SetROI(const MvsROI& roi)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
int r = 0;
|
|
r |= MV_CC_SetIntValueEx(m_handle, "OffsetX", roi.offsetX);
|
|
r |= MV_CC_SetIntValueEx(m_handle, "OffsetY", roi.offsetY);
|
|
r |= MV_CC_SetIntValueEx(m_handle, "Width", roi.width);
|
|
r |= MV_CC_SetIntValueEx(m_handle, "Height", roi.height);
|
|
return r == 0 ? SUCCESS : ERR_CODE(DEV_CTRL_ERR);
|
|
}
|
|
|
|
int CMvsDevice::GetROI(MvsROI& roi)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
MVCC_INTVALUE_EX v; memset(&v, 0, sizeof(v));
|
|
MV_CC_GetIntValueEx(m_handle, "OffsetX", &v); roi.offsetX = (int)v.nCurValue;
|
|
memset(&v, 0, sizeof(v));
|
|
MV_CC_GetIntValueEx(m_handle, "OffsetY", &v); roi.offsetY = (int)v.nCurValue;
|
|
memset(&v, 0, sizeof(v));
|
|
MV_CC_GetIntValueEx(m_handle, "Width", &v); roi.width = (int)v.nCurValue;
|
|
memset(&v, 0, sizeof(v));
|
|
MV_CC_GetIntValueEx(m_handle, "Height", &v); roi.height = (int)v.nCurValue;
|
|
return SUCCESS;
|
|
}
|
|
|
|
int CMvsDevice::SetExposureTime(double v)
|
|
{ return m_handle ? MV_CC_SetFloatValue(m_handle, "ExposureTime", (float)v) : ERR_CODE(DEV_CTRL_ERR); }
|
|
|
|
int CMvsDevice::GetExposureTime(double& v)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
MVCC_FLOATVALUE fv; memset(&fv, 0, sizeof(fv));
|
|
int r = MV_CC_GetFloatValue(m_handle, "ExposureTime", &fv);
|
|
if (r == MV_OK) v = fv.fCurValue;
|
|
return r;
|
|
}
|
|
|
|
int CMvsDevice::SetGain(double v)
|
|
{ return m_handle ? MV_CC_SetFloatValue(m_handle, "Gain", (float)v) : ERR_CODE(DEV_CTRL_ERR); }
|
|
|
|
int CMvsDevice::GetGain(double& v)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
MVCC_FLOATVALUE fv; memset(&fv, 0, sizeof(fv));
|
|
int r = MV_CC_GetFloatValue(m_handle, "Gain", &fv);
|
|
if (r == MV_OK) v = fv.fCurValue;
|
|
return r;
|
|
}
|
|
|
|
int CMvsDevice::SetFrameRate(double v)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
MV_CC_SetBoolValue(m_handle, "AcquisitionFrameRateEnable", true);
|
|
return MV_CC_SetFloatValue(m_handle, "AcquisitionFrameRate", (float)v);
|
|
}
|
|
|
|
int CMvsDevice::GetFrameRate(double& v)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
MVCC_FLOATVALUE fv; memset(&fv, 0, sizeof(fv));
|
|
int r = MV_CC_GetFloatValue(m_handle, "AcquisitionFrameRate", &fv);
|
|
if (r == MV_OK) v = fv.fCurValue;
|
|
return r;
|
|
}
|
|
|
|
int CMvsDevice::SetIntFeature(const std::string& name, int64_t v)
|
|
{ return m_handle ? MV_CC_SetIntValueEx(m_handle, name.c_str(), v) : ERR_CODE(DEV_CTRL_ERR); }
|
|
|
|
int CMvsDevice::GetIntFeature(const std::string& name, int64_t& v)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
MVCC_INTVALUE_EX iv; memset(&iv, 0, sizeof(iv));
|
|
int r = MV_CC_GetIntValueEx(m_handle, name.c_str(), &iv);
|
|
if (r == MV_OK) v = iv.nCurValue;
|
|
return r;
|
|
}
|
|
|
|
int CMvsDevice::SetFloatFeature(const std::string& name, double v)
|
|
{ return m_handle ? MV_CC_SetFloatValue(m_handle, name.c_str(), (float)v) : ERR_CODE(DEV_CTRL_ERR); }
|
|
|
|
int CMvsDevice::GetFloatFeature(const std::string& name, double& v)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
MVCC_FLOATVALUE fv; memset(&fv, 0, sizeof(fv));
|
|
int r = MV_CC_GetFloatValue(m_handle, name.c_str(), &fv);
|
|
if (r == MV_OK) v = fv.fCurValue;
|
|
return r;
|
|
}
|
|
|
|
int CMvsDevice::SetEnumFeature(const std::string& name, int64_t v)
|
|
{ return m_handle ? MV_CC_SetEnumValue(m_handle, name.c_str(), (unsigned int)v) : ERR_CODE(DEV_CTRL_ERR); }
|
|
|
|
int CMvsDevice::GetEnumFeature(const std::string& name, int64_t& v)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
MVCC_ENUMVALUE ev; memset(&ev, 0, sizeof(ev));
|
|
int r = MV_CC_GetEnumValue(m_handle, name.c_str(), &ev);
|
|
if (r == MV_OK) v = ev.nCurValue;
|
|
return r;
|
|
}
|
|
|
|
int CMvsDevice::SetBoolFeature(const std::string& name, bool v)
|
|
{ return m_handle ? MV_CC_SetBoolValue(m_handle, name.c_str(), v) : ERR_CODE(DEV_CTRL_ERR); }
|
|
|
|
int CMvsDevice::GetBoolFeature(const std::string& name, bool& v)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
bool bv = false;
|
|
int r = MV_CC_GetBoolValue(m_handle, name.c_str(), &bv);
|
|
if (r == MV_OK) v = bv;
|
|
return r;
|
|
}
|
|
|
|
int CMvsDevice::SetStringFeature(const std::string& name, const std::string& v)
|
|
{ return m_handle ? MV_CC_SetStringValue(m_handle, name.c_str(), v.c_str()) : ERR_CODE(DEV_CTRL_ERR); }
|
|
|
|
int CMvsDevice::GetStringFeature(const std::string& name, std::string& v)
|
|
{
|
|
if (!m_handle) return ERR_CODE(DEV_CTRL_ERR);
|
|
MVCC_STRINGVALUE sv; memset(&sv, 0, sizeof(sv));
|
|
int r = MV_CC_GetStringValue(m_handle, name.c_str(), &sv);
|
|
if (r == MV_OK) v = sv.chCurValue;
|
|
return r;
|
|
}
|
|
|
|
int CMvsDevice::ExecuteCommand(const std::string& name)
|
|
{ return m_handle ? MV_CC_SetCommandValue(m_handle, name.c_str()) : ERR_CODE(DEV_CTRL_ERR); }
|