|
|
@@ -3,6 +3,12 @@
|
|
|
// 模块名称
|
|
|
static const char MODULE_NAME[] = "TakePhoto";
|
|
|
|
|
|
+// 相机类型
|
|
|
+static unsigned int device_type = MV_GIGE_DEVICE | MV_USB_DEVICE;
|
|
|
+
|
|
|
+// 制造厂商
|
|
|
+static const char *manufacturer = "Hikrobot";
|
|
|
+
|
|
|
// 保存照片
|
|
|
static int SavePhoto(HANDLE hCam, MV_FRAME_OUT *pFrame, EImgType imgType, const char *imgFile);
|
|
|
|
|
|
@@ -86,7 +92,7 @@ getp:
|
|
|
int TakePhoto(EImgType imgType, const char *saveImgPath, int timeout, SImgMark *pImgMark)
|
|
|
{
|
|
|
int fd; char runDir[MAX_PATH_CHARS] = { 0 }, lockFile[MAX_PATH_CHARS+32] = { 0 };
|
|
|
- int ret; SImgMark imgMark = { 0 }; HANDLE hCam = NULL; PthotoProcCtx ctx = { 0 };
|
|
|
+ int ret; SImgMark imgMark = { 0 }; HANDLE hCam = NULL; PthotoProcCtx ctx = { 0 }; int index = 0;
|
|
|
MV_CC_DEVICE_INFO_LIST devList = { 0 }; MV_CC_DEVICE_INFO *pDevInfo = NULL; MVCC_ENUMVALUE exposureMode = { 0 };
|
|
|
|
|
|
// 1, 占用锁定, 避免同时间拍照
|
|
|
@@ -94,7 +100,7 @@ int TakePhoto(EImgType imgType, const char *saveImgPath, int timeout, SImgMark *
|
|
|
if(runDir[strlen(runDir)-1] == '/') sprintf(lockFile, "%s%s", runDir, "status/");
|
|
|
else sprintf(lockFile, "%s/%s", runDir, "status/");
|
|
|
if(!sw_dir_exists(lockFile)) sw_dir_create(lockFile);
|
|
|
- strcat(lockFile, "takephoto.lock");
|
|
|
+ strcat(lockFile, "hk_takephoto.lock");
|
|
|
|
|
|
fd = open(lockFile, O_CREAT | O_RDWR | __O_CLOEXEC, 0666);
|
|
|
if(-1 == fd) { return -1; }
|
|
|
@@ -109,36 +115,66 @@ int TakePhoto(EImgType imgType, const char *saveImgPath, int timeout, SImgMark *
|
|
|
goto end_p;
|
|
|
}
|
|
|
|
|
|
- ret = MV_CC_EnumDevices(MV_USB_DEVICE, &devList);
|
|
|
+ ret = MV_CC_EnumDevices(device_type, &devList);
|
|
|
if(MV_OK != ret)
|
|
|
{
|
|
|
- sw_log_error("[%s] USB口枚举相机失败, errCode=0x%x!!", MODULE_NAME, ret);
|
|
|
+ sw_log_error("[%s] 枚举相机,执行错误, errCode=0x%x!!", MODULE_NAME, ret);
|
|
|
goto end_p;
|
|
|
}
|
|
|
- if(devList.nDeviceNum != 1)
|
|
|
+ if(devList.nDeviceNum < 1)
|
|
|
{
|
|
|
ret = -3;
|
|
|
- sw_log_error("[%s] USB口相机数量错误, deviceNum=%u!!", MODULE_NAME, devList.nDeviceNum);
|
|
|
+ sw_log_error("[%s] 没有相机,数量=%u!!", MODULE_NAME, devList.nDeviceNum);
|
|
|
goto end_p;
|
|
|
}
|
|
|
|
|
|
- pDevInfo = devList.pDeviceInfo[0];
|
|
|
+findp:
|
|
|
+ pDevInfo = devList.pDeviceInfo[index++];
|
|
|
if(!pDevInfo)
|
|
|
{
|
|
|
ret = -4;
|
|
|
sw_log_error("[%s] unexpected internal error, unable to obtain detailed information about the industrial camera!!", MODULE_NAME);
|
|
|
goto end_p;
|
|
|
}
|
|
|
- strcpy(imgMark.camModelName, (const char *)pDevInfo->SpecialInfo.stUsb3VInfo.chModelName);
|
|
|
- strcpy(imgMark.camSerialNum, (const char *)pDevInfo->SpecialInfo.stUsb3VInfo.chSerialNumber);
|
|
|
+
|
|
|
+ char name[MAX_LINE_CHARS] = { 0 }; if(0) ;
|
|
|
+ else if(pDevInfo->nTLayerType == MV_USB_DEVICE /*U口相机*/)
|
|
|
+ {
|
|
|
+ strcpy(name, (const char *)pDevInfo->SpecialInfo.stUsb3VInfo.chManufacturerName);
|
|
|
+ strcpy(imgMark.camModelName, (const char *)pDevInfo->SpecialInfo.stUsb3VInfo.chModelName);
|
|
|
+ strcpy(imgMark.camSerialNum, (const char *)pDevInfo->SpecialInfo.stUsb3VInfo.chSerialNumber);
|
|
|
+ }
|
|
|
+ else if(pDevInfo->nTLayerType == MV_GIGE_DEVICE/*G口相机*/)
|
|
|
+ {
|
|
|
+ strcpy(name, (const char *)pDevInfo->SpecialInfo.stGigEInfo.chManufacturerName);
|
|
|
+ strcpy(imgMark.camModelName, (const char *)pDevInfo->SpecialInfo.stGigEInfo.chModelName);
|
|
|
+ strcpy(imgMark.camSerialNum, (const char *)pDevInfo->SpecialInfo.stGigEInfo.chSerialNumber);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(xstrcasecmp(name, manufacturer) != 0)
|
|
|
+ {
|
|
|
+ if(index < devList.nDeviceNum) goto findp;
|
|
|
+ ret = -5;
|
|
|
+ sw_log_error("[%s] 没有找到 \"%s\" 的相机!!", MODULE_NAME, manufacturer);
|
|
|
+ goto end_p;
|
|
|
+ }
|
|
|
|
|
|
// 3, 打开相机, 设置其触发模式
|
|
|
ret = MV_CC_CreateHandleWithoutLog(&hCam, pDevInfo);
|
|
|
if(MV_OK == ret) ret = MV_CC_OpenDevice(hCam, MV_ACCESS_Exclusive, 0);
|
|
|
- if(MV_OK == ret) ret = MV_USB_SetTransferWays(hCam, 1); // 设置传输通道个数(RTU硬件资源有限, 需要降低通道数)
|
|
|
+ if(MV_OK == ret && pDevInfo->nTLayerType == MV_USB_DEVICE /*U口相机*/)
|
|
|
+ {
|
|
|
+ ret = MV_USB_SetTransferWays(hCam, 1); // 设置传输通道个数(RTU硬件资源有限, 需要降低通道数)
|
|
|
+ }
|
|
|
+ if(MV_OK == ret && pDevInfo->nTLayerType == MV_GIGE_DEVICE/*G口相机*/)
|
|
|
+ { // 探测网络最佳包大小(只对GigE相机有效)
|
|
|
+ int size = MV_CC_GetOptimalPacketSize(hCam);
|
|
|
+ if(size > 0) ret = MV_CC_SetIntValueEx(hCam, "GevSCPSPacketSize", size);
|
|
|
+ else ret = -6;
|
|
|
+ }
|
|
|
if(MV_OK != ret)
|
|
|
{
|
|
|
- sw_log_error("[%s] USB口相机打开失败, errCode=0x%x!!", MODULE_NAME, ret);
|
|
|
+ sw_log_error("[%s] 打开相机时发生错误, errCode=0x%x!!", MODULE_NAME, ret);
|
|
|
goto end_p;
|
|
|
}
|
|
|
|
|
|
@@ -146,7 +182,7 @@ int TakePhoto(EImgType imgType, const char *saveImgPath, int timeout, SImgMark *
|
|
|
if(MV_OK == ret) ret = MV_CC_SetEnumValue(hCam, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE); // 设置软件触发
|
|
|
if(MV_OK != ret)
|
|
|
{
|
|
|
- sw_log_error("[%s] USB口相机设置失败, errCode=0x%x!!", MODULE_NAME, ret);
|
|
|
+ sw_log_error("[%s] 设置相机时发生错误, errCode=0x%x!!", MODULE_NAME, ret);
|
|
|
goto end_p;
|
|
|
}
|
|
|
|
|
|
@@ -154,7 +190,7 @@ int TakePhoto(EImgType imgType, const char *saveImgPath, int timeout, SImgMark *
|
|
|
ret = MV_CC_GetExposureAutoMode(hCam, &exposureMode);
|
|
|
if(MV_OK != ret)
|
|
|
{
|
|
|
- sw_log_error("[%s] 获取-曝光模式失败, errCode=0x%x!!", MODULE_NAME, ret);
|
|
|
+ sw_log_error("[%s] 获取曝光模式时出错, errCode=0x%x!!", MODULE_NAME, ret);
|
|
|
goto end_p;
|
|
|
}
|
|
|
if(exposureMode.nCurValue != MV_EXPOSURE_AUTO_MODE_OFF) { ctx.isExposureAuto = true; clock_gettime(CLOCK_MONOTONIC, &ctx.expTime0); }
|
|
|
@@ -163,7 +199,7 @@ int TakePhoto(EImgType imgType, const char *saveImgPath, int timeout, SImgMark *
|
|
|
ret = MV_CC_StartGrabbing(hCam);
|
|
|
if(MV_OK != ret)
|
|
|
{
|
|
|
- sw_log_error("[%s] USB口相机取流失败, errCode=0x%x!!", MODULE_NAME, ret);
|
|
|
+ sw_log_error("[%s] 相机取流时发生错误, errCode=0x%x!!", MODULE_NAME, ret);
|
|
|
goto end_p;
|
|
|
}
|
|
|
|
|
|
@@ -173,7 +209,7 @@ int TakePhoto(EImgType imgType, const char *saveImgPath, int timeout, SImgMark *
|
|
|
ctx.hESig = sw_signal_create();
|
|
|
if(!ctx.hESig)
|
|
|
{
|
|
|
- ret = -5;
|
|
|
+ ret = -7;
|
|
|
sw_log_error("[%s] SIG信号量创建失败!!", MODULE_NAME);
|
|
|
goto end_p;
|
|
|
}
|
|
|
@@ -182,7 +218,7 @@ int TakePhoto(EImgType imgType, const char *saveImgPath, int timeout, SImgMark *
|
|
|
HANDLE hThrd = sw_thrd_create("PhotoProc", THREAD_DEFAULT_PRIORITY, THREAD_DEFAULT_STACK_SIZE, PhotoProc, (unsigned long)&ctx, 0);
|
|
|
if(!hThrd)
|
|
|
{
|
|
|
- ret = -6;
|
|
|
+ ret = -8;
|
|
|
sw_signal_destroy(ctx.hESig);
|
|
|
sw_log_error("[%s] 拍照线程-创建失败!!", MODULE_NAME);
|
|
|
goto end_p;
|
|
|
@@ -193,7 +229,7 @@ int TakePhoto(EImgType imgType, const char *saveImgPath, int timeout, SImgMark *
|
|
|
if(0 == ret) ret = ctx.rCode;
|
|
|
else
|
|
|
{
|
|
|
- ret = -7;
|
|
|
+ ret = -9;
|
|
|
sw_log_error("[%s] 拍照过程-等待超时!!", MODULE_NAME);
|
|
|
}
|
|
|
|
|
|
@@ -232,7 +268,7 @@ static int SavePhoto(HANDLE hCam, MV_FRAME_OUT *pFrame, EImgType imgType, const
|
|
|
MV_SAVE_IMAGE_PARAM_EX3 saveParams = { 0 }; MVCC_INTVALUE_EX iv;
|
|
|
char *filename1 = (char *)imgFile, *filename2 = NULL; int ret; char ext[5];
|
|
|
|
|
|
- if(!hCam || !pFrame || !filename1 || strlen(filename1) <= 0) return -8;
|
|
|
+ if(!hCam || !pFrame || !filename1 || strlen(filename1) <= 0) return -15;
|
|
|
|
|
|
switch(imgType)
|
|
|
{
|
|
|
@@ -244,7 +280,7 @@ static int SavePhoto(HANDLE hCam, MV_FRAME_OUT *pFrame, EImgType imgType, const
|
|
|
imgType = MV_Image_Jpeg;
|
|
|
strcpy(ext, ".jpg");
|
|
|
break;
|
|
|
- default: return -9;
|
|
|
+ default: return -16;
|
|
|
}
|
|
|
|
|
|
ret = MV_CC_GetIntValueEx(hCam, "PayloadSize", &iv);
|
|
|
@@ -263,7 +299,7 @@ static int SavePhoto(HANDLE hCam, MV_FRAME_OUT *pFrame, EImgType imgType, const
|
|
|
if(imgType == IMG_TYPE_JPG) saveParams.nBufferSize = (unsigned int)(iv.nCurValue * 1);
|
|
|
else saveParams.nBufferSize = (unsigned int)(iv.nCurValue * 4);
|
|
|
saveParams.pImageBuffer = (unsigned char *)sw_heap_malloc(saveParams.nBufferSize);
|
|
|
- if(!saveParams.pImageBuffer) return -10;
|
|
|
+ if(!saveParams.pImageBuffer) return -17;
|
|
|
|
|
|
ret = MV_CC_SaveImageEx3(hCam, &saveParams);
|
|
|
if(MV_OK != ret) goto end_p;
|
|
|
@@ -272,7 +308,7 @@ static int SavePhoto(HANDLE hCam, MV_FRAME_OUT *pFrame, EImgType imgType, const
|
|
|
{
|
|
|
filename2 = (char *)sw_heap_malloc(strlen(filename1) +sizeof(ext));
|
|
|
if(filename2) sprintf(filename2, "%s%s", filename1, ext);
|
|
|
- else { ret = -11; goto end_p; }
|
|
|
+ else { ret = -18; goto end_p; }
|
|
|
ret = sw_file_update(filename2, "wb", (const char *)saveParams.pImageBuffer, saveParams.nImageLen);
|
|
|
sw_heap_free(filename2);
|
|
|
}
|
|
|
@@ -282,14 +318,14 @@ static int SavePhoto(HANDLE hCam, MV_FRAME_OUT *pFrame, EImgType imgType, const
|
|
|
}
|
|
|
|
|
|
if(ret == saveParams.nImageLen) ret = MV_OK;
|
|
|
- else ret = -12;
|
|
|
+ else ret = -19;
|
|
|
|
|
|
end_p:
|
|
|
sw_heap_free(saveParams.pImageBuffer);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-// 获取系统当前USBFS内存大小(MB), 成功返回: >=0, 失败返回: -1值
|
|
|
+// 获取系统当前USBFS内存大小(MB), 成功返回: >=0, 失败返回: <0值
|
|
|
int GetSysUsbfsMemCurrentSize()
|
|
|
{
|
|
|
const char *usbfsFile = "/sys/module/usbcore/parameters/usbfs_memory_mb";
|
|
|
@@ -303,7 +339,7 @@ int GetSysUsbfsMemCurrentSize()
|
|
|
return val;
|
|
|
}
|
|
|
|
|
|
-// 设置系统新的USBFS内存大小(MB), 成功返回: 0值, 失败返回: -1值
|
|
|
+// 设置系统新的USBFS内存大小(MB), 成功返回: 0值, 失败返回: <0值
|
|
|
int SetSysUsbfsMemSize(int val)
|
|
|
{
|
|
|
const char *usbfsFile = "/sys/module/usbcore/parameters/usbfs_memory_mb";
|
|
|
@@ -312,8 +348,8 @@ int SetSysUsbfsMemSize(int val)
|
|
|
else return -1;
|
|
|
}
|
|
|
|
|
|
-// 获取当前连接在USB口上的相机数, 失败返回: <0值, 成功返回: >=0
|
|
|
-int GetUsbCameraCount()
|
|
|
+// 获取当前已连接的海康相机的数量, 成功返回: >=0, 失败返回: <0值
|
|
|
+int GetHKCameraCount()
|
|
|
{
|
|
|
MV_CC_DEVICE_INFO_LIST devList = { 0 };
|
|
|
int ret;
|
|
|
@@ -325,15 +361,30 @@ int GetUsbCameraCount()
|
|
|
goto end_p;
|
|
|
}
|
|
|
|
|
|
- ret = MV_CC_EnumDevices(MV_USB_DEVICE, &devList);
|
|
|
+ ret = MV_CC_EnumDevices(device_type, &devList);
|
|
|
if(MV_OK != ret)
|
|
|
{
|
|
|
- sw_log_error("[%s] USB口枚举相机失败, errCode=0x%x!!", MODULE_NAME, ret);
|
|
|
- goto end_p;
|
|
|
+ sw_log_error("[%s] 枚举相机,执行错误, errCode=0x%x!!", MODULE_NAME, ret);
|
|
|
+ ret = -1; goto end_p;
|
|
|
}
|
|
|
|
|
|
ret = devList.nDeviceNum;
|
|
|
|
|
|
+ if(ret > 0)
|
|
|
+ {
|
|
|
+ int index = 0, cnt = 0; MV_CC_DEVICE_INFO *pDevInfo = NULL; char name[MAX_LINE_CHARS] = { 0 };
|
|
|
+findp:
|
|
|
+ pDevInfo = devList.pDeviceInfo[index++];
|
|
|
+
|
|
|
+ if(0) ;
|
|
|
+ else if(pDevInfo && pDevInfo->nTLayerType == MV_USB_DEVICE /*U口相机*/) strcpy(name, (const char *)pDevInfo->SpecialInfo.stUsb3VInfo.chManufacturerName);
|
|
|
+ else if(pDevInfo && pDevInfo->nTLayerType == MV_GIGE_DEVICE/*G口相机*/) strcpy(name, (const char *)pDevInfo->SpecialInfo.stGigEInfo.chManufacturerName);
|
|
|
+
|
|
|
+ if(xstrcasecmp(name, manufacturer) == 0) cnt++;
|
|
|
+ if(index < devList.nDeviceNum) goto findp;
|
|
|
+ else ret = cnt;
|
|
|
+ }
|
|
|
+
|
|
|
end_p:
|
|
|
MV_CC_Finalize();
|
|
|
|