#include <mil.h>
#if M_MIL_USE_WINDOWS
#include <windows.h>
#endif
#define BUFFERING_SIZE_MAX 22
typedef struct
{
MIL_ID MilDigitizer;
MIL_ID MilDisplay;
MIL_ID MilImageDisp;
MIL_ID MilGrabBufferList[BUFFERING_SIZE_MAX];
MIL_INT MilGrabBufferListSize;
MIL_INT ProcessedImageCount;
MIL_INT CorruptImageCount;
MIL_INT FrameSizeX;
MIL_INT FrameSizeY;
MIL_INT64 FramePixelFormat;
MIL_INT FramePacketSize;
bool DataFormatChanged;
MIL_INT64 SourceDataFormat;
MIL_ID Event;
MIL_TEXT_PTR DeviceVendor;
MIL_TEXT_PTR DeviceModel;
} HookDataStruct;
void AllocateGrabBuffers(MIL_INT MilSystem, HookDataStruct* HookDataPtr);
void FreeGrabBuffers(HookDataStruct* HookDataPtr);
void AdaptToMulticastMasterStatus(MIL_INT MilSystem, HookDataStruct* HookDataPtr);
void PrintCameraInfo(HookDataStruct* HookDataPtr);
void PrintMasterStatusInfo(MIL_INT IsConnected);
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType,
MIL_ID HookId,
void* HookDataPtr);
int MosMain(void)
{
MIL_ID MilApplication;
MIL_ID MilSystem ;
MIL_INT ProcessFrameCount = 0;
MIL_INT DigProcessInProgress = M_FALSE;
MIL_INT BoardType = 0;
MIL_DOUBLE ProcessFrameRate= 0;
HookDataStruct UserHookData;
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, M_NULL, M_NULL, M_NULL);
MsysInquire(MilSystem, M_BOARD_TYPE, &BoardType);
if(((BoardType & M_BOARD_TYPE_MASK) != M_GIGE_VISION))
{
MosPrintf(MIL_TEXT("This example requires a M_GIGE_VISION system type.\n"));
MosPrintf(MIL_TEXT("Please change system type in milconfig.\n"));
MappFreeDefault(MilApplication, MilSystem, M_NULL, M_NULL, M_NULL);
return 0;
}
MdigAlloc(MilSystem, M_DEFAULT, M_NULL, M_GC_MULTICAST_SLAVE, &UserHookData.MilDigitizer);
MthrAlloc(MilSystem, M_EVENT, M_NOT_SIGNALED+M_AUTO_RESET, M_NULL, M_NULL,
&UserHookData.Event);
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, &UserHookData.MilDisplay);
AllocateGrabBuffers(MilSystem, &UserHookData);
MosPrintf(MIL_TEXT("This example demonstrates the use of IP Multicast with GigE Vision"));
MosPrintf(MIL_TEXT(" devices.\n"));
MosPrintf(MIL_TEXT("It allocates a slave digitizer that can read and grab from a GigE"));
MosPrintf(MIL_TEXT(" Vision\n"));
MosPrintf(MIL_TEXT("device provided a Multicast master digitizer is allocated on the same"));
MosPrintf(MIL_TEXT(" device.\n\n"));
MosPrintf(MIL_TEXT("This example must be used along with MulticastMaster.cpp connected to"));
MosPrintf(MIL_TEXT(" the same\n"));
MosPrintf(MIL_TEXT("GigE Vision device and running on another PC.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue."));
MosGetch();
MdispSelect(UserHookData.MilDisplay, UserHookData.MilImageDisp);
UserHookData.ProcessedImageCount = 0;
UserHookData.CorruptImageCount = 0;
UserHookData.FrameSizeX = 0;
UserHookData.FrameSizeY = 0;
UserHookData.FramePacketSize = 0;
UserHookData.FramePixelFormat = 0;
UserHookData.DataFormatChanged = false;
UserHookData.DeviceVendor = NULL;
UserHookData.DeviceModel = NULL;
PrintCameraInfo(&UserHookData);
MdigProcess(UserHookData.MilDigitizer, UserHookData.MilGrabBufferList,
UserHookData.MilGrabBufferListSize, M_START, M_DEFAULT, ProcessingFunction,
&UserHookData);
AdaptToMulticastMasterStatus(MilSystem, &UserHookData);
MdigInquire(UserHookData.MilDigitizer, M_DIG_PROCESS_IN_PROGRESS, &DigProcessInProgress);
if(DigProcessInProgress == M_TRUE)
{
MdigProcess(UserHookData.MilDigitizer, UserHookData.MilGrabBufferList,
UserHookData.MilGrabBufferListSize, M_STOP, M_DEFAULT, ProcessingFunction,
&UserHookData);
}
MdigInquire(UserHookData.MilDigitizer, M_PROCESS_FRAME_COUNT, &ProcessFrameCount);
MdigInquire(UserHookData.MilDigitizer, M_PROCESS_FRAME_RATE, &ProcessFrameRate);
MosPrintf(MIL_TEXT("\n\n%ld frames grabbed at %.1f frames/sec (%.1f ms/frame).\n"),
ProcessFrameCount, ProcessFrameRate, 1000.0/ProcessFrameRate);
MosPrintf(MIL_TEXT("Press <Enter> to end.\n\n"));
MosGetch();
FreeGrabBuffers(&UserHookData);
MdispFree(UserHookData.MilDisplay);
MdigFree(UserHookData.MilDigitizer);
MthrFree(UserHookData.Event);
if(UserHookData.DeviceVendor)
delete [] UserHookData.DeviceVendor;
if(UserHookData.DeviceModel)
delete [] UserHookData.DeviceModel;
MappFreeDefault(MilApplication, MilSystem, M_NULL, M_NULL, M_NULL);
return 0;
}
void AllocateGrabBuffers(MIL_INT MilSystem, HookDataStruct* HookDataPtr)
{
MIL_INT n = 0;
MdigInquire(HookDataPtr->MilDigitizer, M_SOURCE_DATA_FORMAT,
&HookDataPtr->SourceDataFormat);
MbufAllocColor(MilSystem,
MdigInquire(HookDataPtr->MilDigitizer, M_SIZE_BAND, M_NULL),
MdigInquire(HookDataPtr->MilDigitizer, M_SIZE_X, M_NULL),
MdigInquire(HookDataPtr->MilDigitizer, M_SIZE_Y, M_NULL),
MdigInquire(HookDataPtr->MilDigitizer, M_TYPE, M_NULL),
M_IMAGE+M_DISP+M_GRAB+M_PROC+HookDataPtr->SourceDataFormat,
&HookDataPtr->MilImageDisp);
MbufClear(HookDataPtr->MilImageDisp, M_COLOR_BLACK);
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
for(HookDataPtr->MilGrabBufferListSize = 0;
HookDataPtr->MilGrabBufferListSize<BUFFERING_SIZE_MAX;
HookDataPtr->MilGrabBufferListSize++)
{
MbufAllocColor(MilSystem,
MdigInquire(HookDataPtr->MilDigitizer, M_SIZE_BAND, M_NULL),
MdigInquire(HookDataPtr->MilDigitizer, M_SIZE_X, M_NULL),
MdigInquire(HookDataPtr->MilDigitizer, M_SIZE_Y, M_NULL),
MdigInquire(HookDataPtr->MilDigitizer, M_TYPE, M_NULL),
M_IMAGE+M_GRAB+M_PROC+HookDataPtr->SourceDataFormat,
&HookDataPtr->MilGrabBufferList[HookDataPtr->MilGrabBufferListSize]);
if (HookDataPtr->MilGrabBufferList[HookDataPtr->MilGrabBufferListSize])
{
MbufClear(HookDataPtr->MilGrabBufferList[HookDataPtr->MilGrabBufferListSize],
M_COLOR_WHITE);
}
else
break;
}
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
for (n=0; n<2 && HookDataPtr->MilGrabBufferListSize; n++)
{
HookDataPtr->MilGrabBufferListSize--;
MbufFree(HookDataPtr->MilGrabBufferList[HookDataPtr->MilGrabBufferListSize]);
}
}
void FreeGrabBuffers(HookDataStruct* HookDataPtr)
{
while(HookDataPtr->MilGrabBufferListSize > 0)
MbufFree(HookDataPtr->MilGrabBufferList[--HookDataPtr->MilGrabBufferListSize]);
MbufFree(HookDataPtr->MilImageDisp);
}
void AdaptToMulticastMasterStatus(MIL_INT MilSystem, HookDataStruct* HookDataPtr)
{
MIL_INT IsConnected = M_FALSE, IsConnectedOld = M_FALSE;
MIL_INT ProcessedImageCount = 0;
MIL_INT DigProcessInProgress = M_FALSE;
bool Done = false, GrabStopped = false;;
MdigInquire(HookDataPtr->MilDigitizer, M_GC_MULTICAST_MASTER_CONNECTED, &IsConnectedOld);
IsConnected = IsConnectedOld;
PrintMasterStatusInfo(IsConnectedOld);
do
{
ProcessedImageCount = HookDataPtr->ProcessedImageCount;
MthrWait(HookDataPtr->Event, M_EVENT_WAIT+M_EVENT_TIMEOUT(1000), M_NULL);
GrabStopped = (ProcessedImageCount == HookDataPtr->ProcessedImageCount);
if(GrabStopped && HookDataPtr->DataFormatChanged == false)
{
MdigInquire(HookDataPtr->MilDigitizer, M_GC_MULTICAST_MASTER_CONNECTED, &IsConnected);
}
if(((IsConnected == M_TRUE) && (IsConnectedOld != IsConnected)) ||
HookDataPtr->DataFormatChanged)
{
HookDataPtr->DataFormatChanged = (HookDataPtr->DataFormatChanged ? false : true);
MdigInquire(HookDataPtr->MilDigitizer, M_DIG_PROCESS_IN_PROGRESS,
&DigProcessInProgress);
if(DigProcessInProgress)
{
MdigProcess(HookDataPtr->MilDigitizer, HookDataPtr->MilGrabBufferList,
HookDataPtr->MilGrabBufferListSize, M_STOP, M_DEFAULT, ProcessingFunction,
HookDataPtr);
}
MdigControl(HookDataPtr->MilDigitizer, M_GC_UPDATE_MULTICAST_INFO, M_DEFAULT);
PrintCameraInfo(HookDataPtr);
FreeGrabBuffers(HookDataPtr);
AllocateGrabBuffers(MilSystem, HookDataPtr);
MdispSelect(HookDataPtr->MilDisplay, HookDataPtr->MilImageDisp);
MdigProcess(HookDataPtr->MilDigitizer, HookDataPtr->MilGrabBufferList,
HookDataPtr->MilGrabBufferListSize, M_START, M_DEFAULT, ProcessingFunction,
HookDataPtr);
}
IsConnectedOld = IsConnected;
PrintMasterStatusInfo(IsConnected);
if(MosKbhit())
{
MosGetch();
Done = true;
}
}
while(!Done);
}
void PrintCameraInfo(HookDataStruct* HookDataPtr)
{
MIL_TEXT_PTR PixelFormat = NULL;
MIL_TEXT_PTR MulticastAddress = NULL;
MIL_INT Len = 0;
#if M_MIL_USE_WINDOWS
system("cls");
#endif
if(HookDataPtr->DeviceVendor == NULL && HookDataPtr->DeviceModel == NULL)
{
MdigInquire(HookDataPtr->MilDigitizer, M_CAMERA_VENDOR_SIZE, &Len);
HookDataPtr->DeviceVendor = new MIL_TEXT_CHAR[Len];
MdigInquire(HookDataPtr->MilDigitizer, M_CAMERA_VENDOR, HookDataPtr->DeviceVendor);
MdigInquire(HookDataPtr->MilDigitizer, M_CAMERA_MODEL_SIZE, &Len);
HookDataPtr->DeviceModel = new MIL_TEXT_CHAR[Len];
MdigInquire(HookDataPtr->MilDigitizer, M_CAMERA_MODEL, HookDataPtr->DeviceModel);
}
if(HookDataPtr->FrameSizeX == 0 && HookDataPtr->FrameSizeY == 0)
{
MdigInquire(HookDataPtr->MilDigitizer, M_SIZE_X, &HookDataPtr->FrameSizeX);
MdigInquire(HookDataPtr->MilDigitizer, M_SIZE_Y, &HookDataPtr->FrameSizeY);
}
if(HookDataPtr->FramePixelFormat == 0)
{
MdigInquireFeature(HookDataPtr->MilDigitizer, M_FEATURE_VALUE, MIL_TEXT("PixelFormat"),
M_TYPE_ENUMERATION, &HookDataPtr->FramePixelFormat);
MdigInquireFeature(HookDataPtr->MilDigitizer, M_FEATURE_VALUE_AS_STRING+M_STRING_SIZE,
MIL_TEXT("PixelFormat"), M_DEFAULT, &Len);
PixelFormat = new MIL_TEXT_CHAR[Len];
MdigInquireFeature(HookDataPtr->MilDigitizer, M_FEATURE_VALUE_AS_STRING,
MIL_TEXT("PixelFormat"), M_DEFAULT, PixelFormat);
}
MdigInquire(HookDataPtr->MilDigitizer, M_GC_STREAM_CHANNEL_MULTICAST_ADDRESS_STRING_SIZE,
&Len);
MulticastAddress = new MIL_TEXT_CHAR[Len];
MdigInquire(HookDataPtr->MilDigitizer, M_GC_STREAM_CHANNEL_MULTICAST_ADDRESS_STRING,
MulticastAddress);
MosPrintf(MIL_TEXT("\n--------------------- Slave digitizer connection status. "));
MosPrintf(MIL_TEXT("---------------------\n\n"));
MosPrintf(MIL_TEXT("Connected to %s %s\n"), HookDataPtr->DeviceVendor,
HookDataPtr->DeviceModel);
MosPrintf(MIL_TEXT("Device pixel format: %s\n"), PixelFormat);
MosPrintf(MIL_TEXT("Device AOI: %d x %d\n"), HookDataPtr->FrameSizeX,
HookDataPtr->FrameSizeY);
MosPrintf(MIL_TEXT("Multicast address: %s\n"), MulticastAddress);
MosPrintf(MIL_TEXT("\nPress <Enter> to stop.\n\n"));
if(PixelFormat)
delete [] PixelFormat;
if(MulticastAddress)
delete [] MulticastAddress;
}
void PrintMasterStatusInfo(MIL_INT IsConnected)
{
MosPrintf(MIL_TEXT("Master digitizer status: "));
if(IsConnected)
MosPrintf(MIL_TEXT("connected\r"));
else
MosPrintf(MIL_TEXT("not connected --- waiting...\r"));
}
#define STRING_LENGTH_MAX 20
#define STRING_POS_X 20
#define STRING_POS_Y 20
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType,
MIL_ID HookId,
void* HookDataPtr)
{
HookDataStruct *UserHookDataPtr = (HookDataStruct *)HookDataPtr;
MIL_ID ModifiedBufferId;
MIL_TEXT_CHAR Text[STRING_LENGTH_MAX]= {MIL_TEXT('\0'),};
MIL_INT IsFrameCorrupt = M_FALSE;
MIL_INT FrameSizeX = 0;
MIL_INT FrameSizeY = 0;
MIL_INT FramePixelFormat = 0;
MIL_INT FramePacketSize = 0;
MdigGetHookInfo(HookId, M_MODIFIED_BUFFER+M_BUFFER_ID, &ModifiedBufferId);
MdigGetHookInfo(HookId, M_CORRUPTED_FRAME, &IsFrameCorrupt);
MdigGetHookInfo(HookId, M_GC_FRAME_SIZE_X, &FrameSizeX);
MdigGetHookInfo(HookId, M_GC_FRAME_SIZE_Y, &FrameSizeY);
MdigGetHookInfo(HookId, M_GC_FRAME_PIXEL_TYPE, &FramePixelFormat);
MdigGetHookInfo(HookId, M_GC_PACKET_SIZE, &FramePacketSize);
UserHookDataPtr->ProcessedImageCount++;
if(IsFrameCorrupt)
UserHookDataPtr->CorruptImageCount++;
if((FrameSizeX != UserHookDataPtr->FrameSizeX) ||
(FrameSizeY != UserHookDataPtr->FrameSizeY) ||
(FramePixelFormat != UserHookDataPtr->FramePixelFormat) ||
(FramePacketSize != UserHookDataPtr->FramePacketSize))
{
UserHookDataPtr->FrameSizeX = FrameSizeX;
UserHookDataPtr->FrameSizeY = FrameSizeY;
UserHookDataPtr->FramePixelFormat = FramePixelFormat;
UserHookDataPtr->FramePacketSize = FramePacketSize;
if (UserHookDataPtr->ProcessedImageCount > 1)
{
UserHookDataPtr->DataFormatChanged = M_TRUE;
MthrControl(UserHookDataPtr->Event, M_EVENT_SET, M_SIGNALED);
}
}
MosSprintf(Text, STRING_LENGTH_MAX, MIL_TEXT("%ld"),
UserHookDataPtr->ProcessedImageCount);
MgraText(M_DEFAULT, ModifiedBufferId, STRING_POS_X, STRING_POS_Y, Text);
MbufCopy(ModifiedBufferId, UserHookDataPtr->MilImageDisp);
#if M_MIL_USE_CE
if(MdigInquire(UserHookDataPtr->MilDigitizer, M_PROCESS_PENDING_GRAB_NUM, M_NULL) <= 1)
{
if ((UserHookDataPtr->ProcessedImageCount%10) == 0)
Sleep(2);
}
#endif
return 0;
}