#include <mil.h>
#include <windows.h>
#define BUFFERING_SIZE_MAX 22
#define htonl(x) ( ( ( ( x ) & 0x000000ff ) << 24 ) | \
( ( ( x ) & 0x0000ff00 ) << 8 ) | \
( ( ( x ) & 0x00ff0000 ) >> 8 ) | \
( ( ( x ) & 0xff000000 ) >> 24 ) )
#define htons(x) ( ( ( ( x ) & 0xff00 ) >> 8 ) | \
( ( ( x ) & 0x00ff ) << 8 ) )
#define ntohl(x) htonl(x)
#define ntohs(x) htons(x)
#define IPV4_ADDRESS_SIZE 20
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_INT FramePixelFormat;
bool DataFormatChanged;
MIL_INT64 SourceDataFormat;
MIL_TEXT_CHAR MulticastAddress[IPV4_ADDRESS_SIZE];
MIL_ID Event;
MIL_TEXT_PTR DeviceVendor;
MIL_TEXT_PTR DeviceModel;
} HookDataStruct;
void AllocateGrabBuffers(MIL_INT MilSystem, HookDataStruct* HookDataPtr);
void FreeGrabBuffers(HookDataStruct* HookDataPtr);
void AdaptToDataFormatChange(MIL_INT MilSystem, HookDataStruct* HookDataPtr);
void PrintCameraInfo(HookDataStruct* HookDataPtr);
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType,
MIL_ID HookId,
void* HookDataPtr);
void GetMulticastInfo(MIL_TEXT_PTR oMulticastAddress, MIL_INT& oUdpPort);
#pragma comment(lib, "Ws2_32.lib")
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;
MIL_TEXT_CHAR MulticastAddr[IPV4_ADDRESS_SIZE] = {'\0'};
MIL_INT PortNumber = 0;
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;
}
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 monitor digitizer that can grab from a GigE Vision\n"));
MosPrintf(MIL_TEXT("device provided a Multicast master digitizer is allocated on the "));
MosPrintf(MIL_TEXT("same device.\n\n"));
MosPrintf(MIL_TEXT("This example must be used along with MulticastMaster.cpp connected "));
MosPrintf(MIL_TEXT("to the same\n"));
MosPrintf(MIL_TEXT("GigE Vision device and running on another PC.\n\n"));
MosPrintf(MIL_TEXT("A monitor Multicast digitizer does not have read acces to the GigE "));
MosPrintf(MIL_TEXT("Vision\n"));
MosPrintf(MIL_TEXT("device. Because of this some manual configuration of the digitizer "));
MosPrintf(MIL_TEXT("is required.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n"));
MosGetch();
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);
MdigAlloc(MilSystem, M_DEFAULT, MIL_TEXT("gigevision_multicast_monitor.dcf"),
M_GC_MULTICAST_MONITOR, &UserHookData.MilDigitizer);
AllocateGrabBuffers(MilSystem, &UserHookData);
MdispSelect(UserHookData.MilDisplay, UserHookData.MilImageDisp);
MdigControl(UserHookData.MilDigitizer, M_GC_PACKET_RESEND, M_ENABLE);
MdigInquire(UserHookData.MilDigitizer, M_GC_PIXEL_FORMAT, &UserHookData.FramePixelFormat);
MdigInquire(UserHookData.MilDigitizer, M_GC_STREAM_CHANNEL_MULTICAST_ADDRESS_STRING,
MulticastAddr);
MdigInquire(UserHookData.MilDigitizer, M_GC_STREAM_PORT, &PortNumber);
if(MosStrcmp(MulticastAddr, MIL_TEXT("0.0.0.0")) == 0 || PortNumber == 0)
{
GetMulticastInfo(MulticastAddr, PortNumber);
MdigControl(UserHookData.MilDigitizer, M_GC_STREAM_CHANNEL_MULTICAST_ADDRESS_STRING,
M_PTR_TO_DOUBLE(MulticastAddr));
MdigControl(UserHookData.MilDigitizer, M_GC_STREAM_PORT, PortNumber);
MdigControl(UserHookData.MilDigitizer, M_GC_UPDATE_MULTICAST_INFO, M_DEFAULT);
}
UserHookData.ProcessedImageCount = 0;
UserHookData.CorruptImageCount = 0;
UserHookData.FrameSizeX = 0;
UserHookData.FrameSizeY = 0;
UserHookData.DataFormatChanged = false;
UserHookData.DeviceVendor = NULL;
UserHookData.DeviceModel = NULL;
MdigInquire(UserHookData.MilDigitizer, M_SIZE_X, &UserHookData.FrameSizeX);
MdigInquire(UserHookData.MilDigitizer, M_SIZE_Y, &UserHookData.FrameSizeY);
PrintCameraInfo(&UserHookData);
MdigProcess(UserHookData.MilDigitizer, UserHookData.MilGrabBufferList,
UserHookData.MilGrabBufferListSize, M_START, M_DEFAULT, ProcessingFunction,
&UserHookData);
AdaptToDataFormatChange(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 GetMulticastInfo(MIL_TEXT_PTR oMulticastAddress, MIL_INT& oUdpPort)
{
MIL_INT32 lUdpPort = 0;
MosPrintf(MIL_TEXT("Enter Multicast Address to use (between 224.0.0.0 - 239.255.255.255)"));
MosPrintf(MIL_TEXT("\n\n"));
MOs_scanf_s(MIL_TEXT("%15s"), oMulticastAddress, IPV4_ADDRESS_SIZE);
MosPrintf(MIL_TEXT("Enter UDP port number to use : "));
MOs_scanf_s(MIL_TEXT("%d"), &lUdpPort, sizeof(lUdpPort));
oUdpPort = (MIL_INT)lUdpPort;
}
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_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_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 AdaptToDataFormatChange(MIL_INT MilSystem, HookDataStruct* HookDataPtr)
{
MIL_INT DigProcessInProgress = M_FALSE;
bool Done = false;
do
{
MthrWait(HookDataPtr->Event, M_EVENT_WAIT+M_EVENT_TIMEOUT(1000), M_NULL);
if(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_SOURCE_SIZE_X, HookDataPtr->FrameSizeX);
MdigControl(HookDataPtr->MilDigitizer, M_SOURCE_SIZE_Y, HookDataPtr->FrameSizeY);
MdigControl(HookDataPtr->MilDigitizer, M_GC_PIXEL_FORMAT,
HookDataPtr->FramePixelFormat);
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);
}
if(MosKbhit())
{
MosGetch();
Done = true;
}
}
while(!Done);
}
void PrintCameraInfo(HookDataStruct* HookDataPtr)
{
MIL_INT Len = 0, PortNumber = 0;
system("cls");
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);
}
MdigInquire(HookDataPtr->MilDigitizer, M_GC_STREAM_CHANNEL_MULTICAST_ADDRESS_STRING,
HookDataPtr->MulticastAddress);
MdigInquire(HookDataPtr->MilDigitizer, M_GC_STREAM_PORT, &PortNumber);
MosPrintf(MIL_TEXT("\n------------------- Monitor 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: 0x%x\n"), HookDataPtr->FramePixelFormat);
MosPrintf(MIL_TEXT("Device AOI: %d x %d\n"), HookDataPtr->FrameSizeX,
HookDataPtr->FrameSizeY);
MosPrintf(MIL_TEXT("Multicast address: %sd\n"), HookDataPtr->MulticastAddress);
MosPrintf(MIL_TEXT("UDP Port: %d\n"), PortNumber);
MosPrintf(MIL_TEXT("\nPress <Enter> to stop.\n\n"));
}
#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))
{
UserHookDataPtr->FrameSizeX = FrameSizeX;
UserHookDataPtr->FrameSizeY = FrameSizeY;
UserHookDataPtr->FramePixelFormat = FramePixelFormat;
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;
}