#include <mil.h>
#include <vector>
using namespace std;
#if M_MIL_USE_WINDOWS
#include <conio.h>
#include <stdlib.h>
#include <windows.h>
#endif
#define WINDOW_TITLE MIL_TEXT("Camera: ")
#define MAX_CAM 32
#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
class DigHookDataStruct
{
public:
DigHookDataStruct()
{
Clear();
}
void Clear()
{
MilSystem = M_NULL;
MilDigitizer = M_NULL;
MilDisplay = M_NULL;
MilImageDisp = M_NULL;
memset(MilGrabBufferList, 0, sizeof(MIL_ID) * BUFFERING_SIZE_MAX);
MilGrabBufferListSize = 0;
ProcessedImageCount = 0;
FrameRate = 0;
ResendRequests = 0;
PacketSize = 0;
PacketsMissed = 0;
CorruptImageCount = 0;
GrabInProgress = 0;
PayloadSize = 0;
IsConnected = false;
SystemType = 0;
}
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_STRING CamVendor;
MIL_STRING CamModel;
MIL_STRING CamUniqueId;
MIL_STRING AdapterName;
bool IsConnected;
MIL_INT SystemType;
};
#define MAX_ADAPTER_DESCRIPTION_LENGTH 512
class SysHookDataStruct
{
public:
SysHookDataStruct()
{
MilSystem = 0;
NbCameras = 0;
DigHookDataStrutPtr = NULL;
PrintAdapterInfo = false;
SystemType = 0;
}
MIL_ID MilSystem;
MIL_INT NbCameras;
DigHookDataStruct* DigHookDataStrutPtr;
bool PrintAdapterInfo;
vector<MIL_STRING> Adapters;
MIL_INT SystemType;
};
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, const MIL_STRING& AdapterName);
int MosMain(void)
{
MIL_ID MilApplication,
MilSystem;
MIL_INT SystemType,
DevNb,
Done = M_FALSE,
ProcessFrameCount = 0,
MaxCam = MAX_CAM;
MIL_DOUBLE ProcessFrameRate = 0.0;
SysHookDataStruct SysUserHookData;
DigHookDataStruct DigUserHookData[MAX_CAM];
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, M_NULL, M_NULL, M_NULL);
MsysInquire(MilSystem, M_SYSTEM_TYPE, &SystemType);
SysUserHookData.MilSystem = MilSystem;
SysUserHookData.NbCameras = 0;
SysUserHookData.DigHookDataStrutPtr = DigUserHookData;
SysUserHookData.SystemType = SystemType;
if((SystemType != M_SYSTEM_GIGE_VISION_TYPE) &&
(SystemType != M_SYSTEM_USB3_VISION_TYPE))
{
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].SystemType = SystemType;
DigAllocResources(MilSystem, DevNb, &DigUserHookData[DevNb], false);
if (DigUserHookData[DevNb].MilDigitizer)
{
CamerasAllocated = M_TRUE;
if(SystemType == M_SYSTEM_GIGE_VISION_TYPE)
{
AddAdapterToList(&SysUserHookData, DigUserHookData[DevNb].AdapterName);
}
}
}
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->SystemType == M_SYSTEM_GIGE_VISION_TYPE)
{
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_STRING UniqueId;
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 (UserHookDataPtr->DigHookDataStrutPtr[Number].CamUniqueId != UniqueId)
{
DigFreeResources(&UserHookDataPtr->DigHookDataStrutPtr[Number]);
for (MIL_INT i = 0; i < MAX_CAM; i++)
{
if ((i != Number) && (UserHookDataPtr->DigHookDataStrutPtr[Number].CamUniqueId == UniqueId))
DigFreeResources(&UserHookDataPtr->DigHookDataStrutPtr[i]);
}
DigAllocResources(UserHookDataPtr->MilSystem, Number,
&UserHookDataPtr->DigHookDataStrutPtr[Number]);
}
if (UserHookDataPtr->DigHookDataStrutPtr[Number].MilDigitizer)
{
if(UserHookDataPtr->SystemType == M_SYSTEM_GIGE_VISION_TYPE)
AddAdapterToList(UserHookDataPtr, UserHookDataPtr->DigHookDataStrutPtr[Number].AdapterName);
}
UserHookDataPtr->DigHookDataStrutPtr[Number].IsConnected = true;
DigStartAcquisition(&UserHookDataPtr->DigHookDataStrutPtr[Number]);
}
else
{
if (UserHookDataPtr->DigHookDataStrutPtr[Number].MilDigitizer)
{
DigStopAcquisition(&UserHookDataPtr->DigHookDataStrutPtr[Number]);
}
UserHookDataPtr->DigHookDataStrutPtr[Number].IsConnected = false;
}
return 0;
}
void DigAllocGigEVisionResources(DigHookDataStruct* UserSt, bool PrintErrors)
{
MdigInquire(UserSt->MilDigitizer, M_GC_PACKET_SIZE, &UserSt->PacketSize);
MdigInquire(UserSt->MilDigitizer, M_GC_INTERFACE_NAME, UserSt->AdapterName);
}
void DigAllocResources(MIL_ID MilSystem, MIL_INT DeviceNum, DigHookDataStruct* UserSt,
bool PrintErrors)
{
MIL_INT SizeBand = 0, BufType = 0, SizeBit = 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, UserSt->CamVendor);
MdigInquire(UserSt->MilDigitizer, M_CAMERA_MODEL, UserSt->CamModel);
MdigInquire(UserSt->MilDigitizer, M_GC_UNIQUE_ID_STRING, UserSt->CamUniqueId);
if(UserSt->SystemType == M_SYSTEM_GIGE_VISION_TYPE)
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);
#if (MIL_COMPILE_VERSION >= 1030)
MdispControl(UserSt->MilDisplay, M_TITLE, UserSt->CamModel);
#else
MdispControl(UserSt->MilDisplay, M_TITLE, UserSt->CamModel.c_str());
#endif
MdigInquire(UserSt->MilDigitizer, M_SIZE_BAND, &SizeBand);
MdigInquire(UserSt->MilDigitizer, M_TYPE, &BufType);
MdigInquire(UserSt->MilDigitizer, M_SOURCE_DATA_FORMAT, &BufFormat);
MdigInquire(UserSt->MilDigitizer, M_SIZE_BIT, &SizeBit);
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);
if(SizeBit > 8)
{
MdispControl(UserSt->MilDisplay, M_VIEW_MODE, M_BIT_SHIFT);
MdispControl(UserSt->MilDisplay, M_VIEW_BIT_SHIFT, SizeBit - 8);
}
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);
UserSt->Clear();
}
}
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"), (int)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.c_str(),
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->SystemType == M_SYSTEM_GIGE_VISION_TYPE)
{
MosPrintf(MIL_TEXT("Network adapter statistics\n\n"));
MIL_DOUBLE AdapterBandwidth = 0;
for (size_t i = 0; i < UserSt->Adapters.size(); i++)
{
AdapterBandwidth = 0;
DigHookDataStruct* DigStPtr = NULL;
for (MIL_INT j = 0; j < MAX_CAM; j++)
{
DigStPtr = &(UserSt->DigHookDataStrutPtr[j]);
if (DigStPtr->MilDigitizer && DigStPtr->AdapterName == UserSt->Adapters[i])
{
AdapterBandwidth += (DigStPtr->PayloadSize*DigStPtr->FrameRate / 1e6);
}
}
MosPrintf(MIL_TEXT("\n%-50.49s%.1f (MB/s) connected to:\n"), UserSt->Adapters[i].c_str(),
AdapterBandwidth);
MosPrintf(MIL_TEXT("----------------------------")
MIL_TEXT("---------------------------------------------------\n"));
for (MIL_INT j = 0; j < MAX_CAM; j++)
{
DigStPtr = &(UserSt->DigHookDataStrutPtr[j]);
if (DigStPtr->MilDigitizer && DigStPtr->AdapterName == UserSt->Adapters[i])
MosPrintf(MIL_TEXT("%s %s\n"), DigStPtr->CamVendor.c_str(), DigStPtr->CamModel.c_str());
}
}
}
}
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"), (int)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, const MIL_STRING& AdapterName)
{
for (size_t i = 0; i < UserSt->Adapters.size(); i++)
{
if (UserSt->Adapters[i] == AdapterName)
return;
}
UserSt->Adapters.push_back(AdapterName);
}