#include <mil.h>
#if M_MIL_USE_WINDOWS
#include <conio.h>
#include <stdlib.h>
#include <windows.h>
#endif
#ifndef M_GC_PAYLOAD_SIZE
#define M_GC_PAYLOAD_SIZE 5197L
#endif
#define WINDOW_TITLE MIL_TEXT("Camera: ")
#define MAX_CAM 32
#define MAX_ADAPTERS 16
#define BUFFERING_SIZE_MAX 3
#define STRING_LENGTH_MAX 128
#define STRING_POS_X 20
#define STRING_POS_Y 20
#define STATS_PRINT_PERIOD 1000
#define USE_FEATURE_BROWSER 0
typedef struct
{
MIL_ID MilSystem;
MIL_ID MilDigitizer;
MIL_ID MilDisplay;
MIL_ID MilImageDisp;
MIL_ID MilGrabBufferList[BUFFERING_SIZE_MAX];
MIL_INT MilGrabBufferListSize;
MIL_INT ProcessedImageCount;
MIL_DOUBLE FrameRate;
MIL_INT ResendRequests;
MIL_INT PacketSize;
MIL_INT PacketsMissed;
MIL_INT CorruptImageCount;
MIL_INT GrabInProgress;
MIL_INT PayloadSize;
MIL_TEXT_PTR CamVendor;
MIL_TEXT_PTR CamModel;
MIL_TEXT_PTR CamUniqueId;
MIL_TEXT_PTR pAdapterName;
bool IsConnected;
MIL_INT BoardType;
} DigHookDataStruct;
#define MAX_ADAPTER_DESCRIPTION_LENGTH 512
typedef struct
{
MIL_ID MilSystem;
MIL_INT NbCameras;
DigHookDataStruct* DigHookDataStrutPtr;
bool PrintAdapterInfo;
MIL_TEXT_CHAR Adapters[MAX_ADAPTERS][MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
MIL_INT BoardType;
} SysHookDataStruct;
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType,
MIL_ID HookId,
void* HookDataPtr);
MIL_INT MFTYPE CamPresentFunction(MIL_INT HookType,
MIL_ID HookId,
void* HookDataPtr);
void DigAllocResources(MIL_ID MilSystem, MIL_INT DeviceNum,
DigHookDataStruct* UserSt,
bool PrintErrors = true);
void DigFreeResources(DigHookDataStruct* UserSt);
void DigStartAcquisition(DigHookDataStruct* UserSt);
void DigStopAcquisition(DigHookDataStruct* UserSt);
void PrintCameraInfo(SysHookDataStruct* UserSt);
void AddAdapterToList(SysHookDataStruct* UserSt, MIL_TEXT_PTR AdapterName);
int MosMain(void)
{
MIL_ID MilApplication,
MilSystem;
MIL_INT BoardType,
DevNb,
Done = M_FALSE,
ProcessFrameCount = 0,
MaxCam = MAX_CAM;
MIL_DOUBLE ProcessFrameRate = 0.0;
SysHookDataStruct SysUserHookData;
DigHookDataStruct DigUserHookData[MAX_CAM];
memset(&SysUserHookData, 0, sizeof(SysUserHookData));
memset(DigUserHookData, 0, sizeof(DigHookDataStruct)*MAX_CAM);
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, M_NULL, M_NULL, M_NULL);
MsysInquire(MilSystem, M_BOARD_TYPE, &BoardType);
SysUserHookData.MilSystem = MilSystem;
SysUserHookData.NbCameras = 0;
SysUserHookData.DigHookDataStrutPtr = DigUserHookData;
SysUserHookData.BoardType = BoardType;
if (((BoardType & M_BOARD_TYPE_MASK) != M_GIGE_VISION) &&
((BoardType & M_BOARD_TYPE_MASK) != M_USB3_VISION))
{
MosPrintf(MIL_TEXT("This example requires a M_GIGE_VISION or M_USB3_VISION system type.\n"));
MosPrintf(MIL_TEXT("Please change system type in milconfig.\n"));
MappFreeDefault(MilApplication, MilSystem, M_NULL, M_NULL, M_NULL);
MosGetch();
return -1;
}
MsysInquire(MilSystem, M_NUM_CAMERA_PRESENT, &SysUserHookData.NbCameras);
if (SysUserHookData.NbCameras > MaxCam)
SysUserHookData.NbCameras = MaxCam;
if (SysUserHookData.NbCameras)
{
MIL_INT CamerasAllocated = M_FALSE;
for (DevNb = M_DEV0; DevNb < MAX_CAM; DevNb++)
{
DigUserHookData[DevNb].BoardType = BoardType;
DigAllocResources(MilSystem, DevNb, &DigUserHookData[DevNb], false);
if (DigUserHookData[DevNb].MilDigitizer)
{
CamerasAllocated = M_TRUE;
if ((BoardType & M_BOARD_TYPE_MASK) == M_GIGE_VISION)
{
AddAdapterToList(&SysUserHookData, DigUserHookData[DevNb].pAdapterName);
}
}
}
if (CamerasAllocated == M_TRUE)
{
for (DevNb = M_DEV0; DevNb < MAX_CAM; DevNb++)
DigStartAcquisition(&DigUserHookData[DevNb]);
}
else
{
MIL_ID MilRemoteApplication = M_NULL;
MIL_INT LicenseModules = 0;
MsysInquire(MilSystem, M_OWNER_APPLICATION, &MilRemoteApplication);
MappInquire(MilRemoteApplication, M_LICENSE_MODULES, &LicenseModules);
if (!(LicenseModules & (M_LICENSE_INTERFACE)))
{
MosPrintf(MIL_TEXT("Need a GigE Vision license to run this example.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to end.\n"));
MosGetch();
MappFreeDefault(MilApplication, MilSystem, M_NULL, M_NULL, M_NULL);
return 0;
}
}
}
MsysHookFunction(MilSystem, M_CAMERA_PRESENT, CamPresentFunction, &SysUserHookData);
while (!MosKbhit())
PrintCameraInfo(&SysUserHookData);
MosGetch();
for (DevNb = M_DEV0; DevNb < MAX_CAM; DevNb++)
DigStopAcquisition(&DigUserHookData[DevNb]);
PrintCameraInfo(&SysUserHookData);
MosPrintf(MIL_TEXT("\nFreeing:\n"));
for (DevNb = M_DEV0; DevNb < MAX_CAM; DevNb++)
DigFreeResources(&DigUserHookData[DevNb]);
MsysHookFunction(MilSystem, M_CAMERA_PRESENT + M_UNHOOK, CamPresentFunction,
&SysUserHookData);
MsysFree(MilSystem);
MappFree(MilApplication);
return 0;
}
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType,
MIL_ID HookId,
void* HookDataPtr)
{
DigHookDataStruct *UserHookDataPtr = (DigHookDataStruct *)HookDataPtr;
MIL_ID ModifiedBufferId = 0;
MIL_INT ResendRequests = 0, PacketsMissed = 0, IsCorrupt = 0;
MdigGetHookInfo(HookId, M_MODIFIED_BUFFER + M_BUFFER_ID, &ModifiedBufferId);
MdigGetHookInfo(HookId, M_CORRUPTED_FRAME, &IsCorrupt);
if ((UserHookDataPtr->BoardType & M_BOARD_TYPE_MASK) == M_GIGE_VISION)
{
MdigGetHookInfo(HookId, M_GC_PACKETS_RESENDS_NUM, &ResendRequests);
MdigGetHookInfo(HookId, M_GC_PACKETS_MISSED, &PacketsMissed);
}
UserHookDataPtr->ResendRequests += ResendRequests;
UserHookDataPtr->PacketsMissed += PacketsMissed;
if (IsCorrupt)
UserHookDataPtr->CorruptImageCount++;
else
{
UserHookDataPtr->ProcessedImageCount++;
MbufCopy(ModifiedBufferId, UserHookDataPtr->MilImageDisp);
}
return 0;
}
MIL_INT MFTYPE CamPresentFunction(MIL_INT HookType,
MIL_ID HookId,
void* HookDataPtr)
{
SysHookDataStruct *UserHookDataPtr = (SysHookDataStruct *)HookDataPtr;
MIL_INT IsCamPresent, Number;
MsysGetHookInfo(UserHookDataPtr->MilSystem, HookId, M_CAMERA_PRESENT, &IsCamPresent);
MsysGetHookInfo(UserHookDataPtr->MilSystem, HookId, M_NUMBER, &Number);
MsysInquire(UserHookDataPtr->MilSystem, M_NUM_CAMERA_PRESENT,
&UserHookDataPtr->NbCameras);
if (IsCamPresent)
{
MIL_TEXT_CHAR* UniqueId = NULL;
MIL_INT Size = 0;
MsysGetHookInfo(UserHookDataPtr->MilSystem, HookId, M_GC_UNIQUE_ID_STRING_SIZE,
&Size);
UniqueId = new MIL_TEXT_CHAR[Size];
MsysGetHookInfo(UserHookDataPtr->MilSystem, HookId, M_GC_UNIQUE_ID_STRING,
UniqueId);
if (UserHookDataPtr->DigHookDataStrutPtr[Number].MilDigitizer == 0)
{
DigAllocResources(UserHookDataPtr->MilSystem, Number,
&UserHookDataPtr->DigHookDataStrutPtr[Number]);
}
else if (MosStrcmp(UserHookDataPtr->DigHookDataStrutPtr[Number].CamUniqueId,
UniqueId) != 0)
{
DigFreeResources(&UserHookDataPtr->DigHookDataStrutPtr[Number]);
for (MIL_INT i = 0; i < MAX_CAM; i++)
if ((i != Number) &&
(MosStrcmp(UserHookDataPtr->DigHookDataStrutPtr[Number].CamUniqueId,
UniqueId) == 0))
DigFreeResources(&UserHookDataPtr->DigHookDataStrutPtr[i]);
DigAllocResources(UserHookDataPtr->MilSystem, Number,
&UserHookDataPtr->DigHookDataStrutPtr[Number]);
}
if (UserHookDataPtr->DigHookDataStrutPtr[Number].MilDigitizer)
{
if ((UserHookDataPtr->BoardType & M_BOARD_TYPE_MASK) == M_GIGE_VISION)
AddAdapterToList(UserHookDataPtr,
UserHookDataPtr->DigHookDataStrutPtr[Number].pAdapterName);
}
UserHookDataPtr->DigHookDataStrutPtr[Number].IsConnected = true;
DigStartAcquisition(&UserHookDataPtr->DigHookDataStrutPtr[Number]);
delete[] UniqueId;
}
else
{
if (UserHookDataPtr->DigHookDataStrutPtr[Number].MilDigitizer)
{
DigStopAcquisition(&UserHookDataPtr->DigHookDataStrutPtr[Number]);
}
UserHookDataPtr->DigHookDataStrutPtr[Number].IsConnected = false;
}
return 0;
}
void DigAllocGigEVisionResources(DigHookDataStruct* UserSt, bool PrintErrors)
{
MIL_INT Len = 0;
MdigInquire(UserSt->MilDigitizer, M_GC_PACKET_SIZE, &UserSt->PacketSize);
MdigInquire(UserSt->MilDigitizer, M_GC_INTERFACE_NAME_SIZE, &Len);
if (Len)
{
UserSt->pAdapterName = new MIL_TEXT_CHAR[Len];
MdigInquire(UserSt->MilDigitizer, M_GC_INTERFACE_NAME, UserSt->pAdapterName);
}
}
void DigAllocResources(MIL_ID MilSystem, MIL_INT DeviceNum, DigHookDataStruct* UserSt,
bool PrintErrors)
{
MIL_INT VendorStLen, ModelStLen, UniqueIdLen;
MIL_INT SizeBand = 0, BufType = 0;
MIL_INT64 BufFormat = 0;
if (PrintErrors)
MdigAlloc(MilSystem, DeviceNum, MIL_TEXT("M_DEFAULT"), M_DEV_NUMBER,
&UserSt->MilDigitizer);
else
{
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
MdigAlloc(MilSystem, DeviceNum, MIL_TEXT("M_DEFAULT"), M_DEV_NUMBER,
&UserSt->MilDigitizer);
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
}
if (UserSt->MilDigitizer)
{
MIL_INT Len = 0;
UserSt->MilSystem = MilSystem;
UserSt->IsConnected = true;
MdigControl(UserSt->MilDigitizer, M_PROCESS_GRAB_MONITOR, M_DISABLE);
MdigControl(UserSt->MilDigitizer, M_CORRUPTED_FRAME_ERROR, M_DISABLE);
MdigInquire(UserSt->MilDigitizer, M_CAMERA_VENDOR_SIZE, &VendorStLen);
MdigInquire(UserSt->MilDigitizer, M_CAMERA_MODEL_SIZE, &ModelStLen);
UserSt->CamVendor = new MIL_TEXT_CHAR[VendorStLen];
UserSt->CamModel = new MIL_TEXT_CHAR[ModelStLen];
MdigInquire(UserSt->MilDigitizer, M_CAMERA_VENDOR, UserSt->CamVendor);
MdigInquire(UserSt->MilDigitizer, M_CAMERA_MODEL, UserSt->CamModel);
MdigInquire(UserSt->MilDigitizer, M_GC_UNIQUE_ID_STRING_SIZE, &UniqueIdLen);
UserSt->CamUniqueId = new MIL_TEXT_CHAR[UniqueIdLen];
MdigInquire(UserSt->MilDigitizer, M_GC_UNIQUE_ID_STRING, UserSt->CamUniqueId);
if ((UserSt->BoardType & M_BOARD_TYPE_MASK) == M_GIGE_VISION)
DigAllocGigEVisionResources(UserSt, PrintErrors);
#if (USE_FEATURE_BROWSER == 1)
MdigControl(UserSt->MilDigitizer, M_GC_FEATURE_BROWSER, M_OPEN + M_ASYNCHRONOUS);
#endif
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT,
&UserSt->MilDisplay);
MdispControl(UserSt->MilDisplay, M_TITLE,
M_PTR_TO_DOUBLE(UserSt->CamModel));
MdigInquire(UserSt->MilDigitizer, M_SIZE_BAND, &SizeBand);
MdigInquire(UserSt->MilDigitizer, M_TYPE, &BufType);
MdigInquire(UserSt->MilDigitizer, M_SOURCE_DATA_FORMAT, &BufFormat);
MbufAllocColor(MilSystem,
SizeBand,
MdigInquire(UserSt->MilDigitizer, M_SIZE_X, M_NULL),
MdigInquire(UserSt->MilDigitizer, M_SIZE_Y, M_NULL),
BufType,
M_IMAGE + M_GRAB + M_DISP + BufFormat,
&UserSt->MilImageDisp);
MbufClear(UserSt->MilImageDisp, M_COLOR_BLACK);
MdispSelect(UserSt->MilDisplay, UserSt->MilImageDisp);
for (MIL_INT i = 0; i < BUFFERING_SIZE_MAX; i++)
{
MbufAllocColor(MilSystem,
SizeBand,
MdigInquire(UserSt->MilDigitizer, M_SIZE_X, M_NULL),
MdigInquire(UserSt->MilDigitizer, M_SIZE_Y, M_NULL),
BufType,
M_GRAB + M_IMAGE + BufFormat,
&UserSt->MilGrabBufferList[i]);
if (UserSt->MilGrabBufferList[i])
{
UserSt->MilGrabBufferListSize++;
MbufClear(UserSt->MilGrabBufferList[i], 0);
}
}
}
}
void DigFreeResources(DigHookDataStruct* UserSt)
{
if (UserSt->MilDigitizer)
{
for (MIL_INT i = 0; i < UserSt->MilGrabBufferListSize; i++)
MbufFree(UserSt->MilGrabBufferList[i]);
MbufFree(UserSt->MilImageDisp);
MdispFree(UserSt->MilDisplay);
#if (USE_FEATURE_BROWSER == 1)
MdigControl(UserSt->MilDigitizer, M_GC_FEATURE_BROWSER, M_CLOSE);
#endif
MdigFree(UserSt->MilDigitizer);
delete[] UserSt->CamVendor;
delete[] UserSt->CamModel;
delete[] UserSt->CamUniqueId;
delete[] UserSt->pAdapterName;
memset(UserSt, 0, sizeof(DigHookDataStruct));
}
}
void DigStartAcquisition(DigHookDataStruct* UserSt)
{
if (UserSt->MilDigitizer)
{
UserSt->GrabInProgress = M_TRUE;
MdigProcess(UserSt->MilDigitizer, UserSt->MilGrabBufferList,
UserSt->MilGrabBufferListSize, M_START, M_DEFAULT,
ProcessingFunction, UserSt);
MdigInquire(UserSt->MilDigitizer, M_GC_PAYLOAD_SIZE, &UserSt->PayloadSize);
}
}
void DigStopAcquisition(DigHookDataStruct* UserSt)
{
if (UserSt->GrabInProgress)
{
MdigProcess(UserSt->MilDigitizer, UserSt->MilGrabBufferList,
UserSt->MilGrabBufferListSize, M_STOP, M_DEFAULT,
ProcessingFunction, UserSt);
UserSt->GrabInProgress = M_FALSE;
}
}
void PrintCameraInfo(SysHookDataStruct* UserSt)
{
if (UserSt->NbCameras)
{
MIL_TEXT_CHAR Str[] = MIL_TEXT(" ");
MosSleep(STATS_PRINT_PERIOD);
#if M_MIL_USE_WINDOWS
system("cls");
#endif
MosPrintf(MIL_TEXT("This example shows how to handle camera connect / ")
MIL_TEXT("disconnect events.\n\n"));
MosPrintf(MIL_TEXT("%d camera%s detected.\n"), UserSt->NbCameras,
UserSt->NbCameras > 1 ? MIL_TEXT("s") : MIL_TEXT(""));
MosPrintf(MIL_TEXT("You can proceed to add / remove cameras to your ")
MIL_TEXT("system at anytime.\n\n"));
MosPrintf(MIL_TEXT("%s----------------------------------------------------\n"), Str);
MosPrintf(MIL_TEXT("%s Camera statistics \n"), Str);
MosPrintf(MIL_TEXT("%s-------------------------------------+--------------\n"), Str);
MosPrintf(MIL_TEXT("%s Frame | Packet \n"), Str);
MosPrintf(MIL_TEXT("%s-------------------------------------+--------------\n"), Str);
MosPrintf(MIL_TEXT("%-14s%-13s%9s%8s%11s%8s%8s%8s\n"), MIL_TEXT("Model"),
MIL_TEXT("State"), MIL_TEXT("Grabbed"), MIL_TEXT("Rate"),
MIL_TEXT("Bandwidth"), MIL_TEXT("Corrupt"), MIL_TEXT("| Size"),
MIL_TEXT("Resends"));
MosPrintf(MIL_TEXT("----------------------------")
MIL_TEXT("------------------------------------+--------------\n"));
for (MIL_INT i = 0; i < MAX_CAM; i++)
{
if (UserSt->DigHookDataStrutPtr[i].MilDigitizer)
{
DigHookDataStruct* DigStPtr = &UserSt->DigHookDataStrutPtr[i];
if (DigStPtr->IsConnected)
MdigInquire(DigStPtr->MilDigitizer, M_PROCESS_FRAME_RATE, &DigStPtr->FrameRate);
else
DigStPtr->FrameRate = 0;
MosPrintf(MIL_TEXT("%-14.13s%-13.12s%9d%8.1f%11.1f%8d%8d%8d\n"),
DigStPtr->CamModel,
DigStPtr->IsConnected ? MIL_TEXT("Connected") : MIL_TEXT("Disconnected"),
DigStPtr->ProcessedImageCount,
DigStPtr->FrameRate,
(DigStPtr->PayloadSize*DigStPtr->FrameRate / 1e6),
DigStPtr->CorruptImageCount,
DigStPtr->PacketSize,
DigStPtr->ResendRequests);
}
}
MosPrintf(MIL_TEXT("----------------------------")
MIL_TEXT("---------------------------------------------------\n\n"));
if ((UserSt->BoardType & M_BOARD_TYPE_MASK) == M_GIGE_VISION)
{
MosPrintf(MIL_TEXT("Network adapter statistics\n\n"));
MIL_DOUBLE AdapterBandwidth = 0;
for (MIL_INT i = 0; i < MAX_ADAPTERS; i++)
{
AdapterBandwidth = 0;
if (UserSt->Adapters[i][0] != '\0')
{
DigHookDataStruct* DigStPtr = NULL;
for (MIL_INT j = 0; j < MAX_CAM; j++)
{
DigStPtr = &(UserSt->DigHookDataStrutPtr[j]);
if (DigStPtr->MilDigitizer &&
MosStrcmp(DigStPtr->pAdapterName, UserSt->Adapters[i]) == 0)
{
AdapterBandwidth += (DigStPtr->PayloadSize*DigStPtr->FrameRate / 1e6);
}
}
MosPrintf(MIL_TEXT("\n%-50.49s%.1f (MB/s) connected to:\n"), UserSt->Adapters[i],
AdapterBandwidth);
MosPrintf(MIL_TEXT("----------------------------")
MIL_TEXT("---------------------------------------------------\n"));
for (MIL_INT j = 0; j < MAX_CAM; j++)
{
DigStPtr = &(UserSt->DigHookDataStrutPtr[j]);
if (DigStPtr->MilDigitizer &&
MosStrcmp(DigStPtr->pAdapterName, UserSt->Adapters[i]) == 0)
MosPrintf(MIL_TEXT("%s %s\n"), DigStPtr->CamVendor, DigStPtr->CamModel);
}
}
}
}
}
else
{
#if M_MIL_USE_WINDOWS
system("cls");
#endif
MosPrintf(MIL_TEXT("This example shows how to handle camera connect / ")
MIL_TEXT("disconnect events.\n\n"));
MosPrintf(MIL_TEXT("%d camera detected.\n"), UserSt->NbCameras);
MosPrintf(MIL_TEXT("You can proceed to add / remove cameras to your system ")
MIL_TEXT("anytime.\n\n"));
MosPrintf(MIL_TEXT("\r|"));
MosSleep(STATS_PRINT_PERIOD / 4);
MosPrintf(MIL_TEXT("\r/"));
MosSleep(STATS_PRINT_PERIOD / 4);
MosPrintf(MIL_TEXT("\r-"));
MosSleep(STATS_PRINT_PERIOD / 4);
MosPrintf(MIL_TEXT("\r\\"));
MosSleep(STATS_PRINT_PERIOD / 4);
}
}
void AddAdapterToList(SysHookDataStruct* UserSt, MIL_TEXT_PTR AdapterName)
{
for (MIL_INT i = 0; i < MAX_ADAPTERS; i++)
{
if (MosStrcmp(UserSt->Adapters[i], AdapterName) == 0)
return;
}
for (MIL_INT i = 0; i < MAX_ADAPTERS; i++)
{
if (UserSt->Adapters[i][0] == '\0')
{
MosStrcpy(UserSt->Adapters[i], MAX_ADAPTER_DESCRIPTION_LENGTH + 4, AdapterName);
return;
}
}
}