Click here to show toolbars of the Web Online Help System: show toolbars |
/*************************************************************************************/ /* * File name: MulticastMaster.cpp * Location: See Matrox Example Launcher in the MIL Control Center * * * Synopsis: This program shows how to perform IP Multicast with GigE Vision devices. * * To do this you must have a network capable of delivering a Multicast * service over IPv4. This requires the use of routers and LAN switches * that support the Internet Group Management Protocol (IGMP). Some manual * configuration of you LAN switches might be required. More information * can be found in the IP Multicast section of Matrox GigE Vision * Assistant's help file. * * Note: This example must be used along with the MulticastSlave program * connected to the same GigE Vision device and running on another PC. */ #include <mil.h> #if M_MIL_USE_WINDOWS #include <Windows.h> #endif /* Number of images in the buffering grab queue. Generally, increasing this number gives better real-time grab. */ #define BUFFERING_SIZE_MAX 22 // Host to network byte swap long #define htonl(x) ( ( ( ( x ) & 0x000000ff ) << 24 ) | \ ( ( ( x ) & 0x0000ff00 ) << 8 ) | \ ( ( ( x ) & 0x00ff0000 ) >> 8 ) | \ ( ( ( x ) & 0xff000000 ) >> 24 ) ) // Host to network byte swap short #define htons(x) ( ( ( ( x ) & 0xff00 ) >> 8 ) | \ ( ( ( x ) & 0x00ff ) << 8 ) ) // Network to host byte swap long #define ntohl(x) htonl(x) // Network to host byte swap short #define ntohs(x) htons(x) #define IPV4_ADDRESS_SIZE 20 /* User's processing function hook data structure. */ typedef struct { MIL_ID MilImageDisp; MIL_INT ProcessedImageCount; MIL_INT CorruptImageCount; MIL_TEXT_PTR MulticastAddress; } HookDataStruct; /* Function prototypes. */ void PrintCameraInfo(MIL_ID MilDigitizer); MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID HookId, void* HookDataPtr); /* Main function. */ /* ---------------*/ int MosMain(void) { MIL_ID MilApplication; MIL_ID MilSystem ; MIL_ID MilDigitizer; MIL_ID MilDisplay; MIL_ID MilImageDisp; MIL_ID MilGrabBufferList[BUFFERING_SIZE_MAX]; MIL_INT MilGrabBufferListSize; MIL_INT ProcessFrameCount = 0; MIL_INT DigProcessInProgress = M_FALSE; MIL_INT BoardType = 0; MIL_DOUBLE ProcessFrameRate = 0; MIL_INT64 SourceDataFormat; MIL_TEXT_CHAR MulticastAddr[IPV4_ADDRESS_SIZE] = {'\0'}; HookDataStruct UserHookData; MIL_INT n = 0; /* Allocate defaults. */ MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, M_NULL, M_NULL, M_NULL); /* This example only runs on a MIL GigE Vision system type. */ 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; } /* Allocate a master Multicast digitizer. */ MdigAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_GC_MULTICAST_MASTER, &MilDigitizer); /* The default Multicast address can be changed if a conflict exists with: */ // MosSprintf(MulticastAddr, IPV4_ADDRESS_SIZE, MIL_TEXT("%s"), MIL_TEXT("239.255.16.16")); // MdigControl(MilDigitizer, M_GC_STREAM_CHANNEL_MULTICAST_ADDRESS_STRING, // M_PTR_TO_DOUBLE(MulticastAddr)); // MdigControl(MilDigitizer, M_GC_UPDATE_MULTICAST_INFO, M_DEFAULT); /* Note that the above IP address 239.255.16.16 is specified for illustrative purposes only. */ /* Allocate a display. */ MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, &MilDisplay); /* Inquire the buffer format compatible with the camera's current pixel format. */ MdigInquire(MilDigitizer, M_SOURCE_DATA_FORMAT, &SourceDataFormat); /* Allocate the display buffer clear it and associate it to the display. */ MbufAllocColor(MilSystem, MdigInquire(MilDigitizer, M_SIZE_BAND, M_NULL), MdigInquire(MilDigitizer, M_SIZE_X, M_NULL), MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL), MdigInquire(MilDigitizer, M_TYPE, M_NULL), M_IMAGE+M_DISP+M_GRAB+M_PROC+SourceDataFormat, &MilImageDisp); MbufClear(MilImageDisp, M_COLOR_BLACK); MdispSelect(MilDisplay, MilImageDisp); /* Allocate the grab buffers and clear them. */ MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE); for(MilGrabBufferListSize = 0; MilGrabBufferListSize<BUFFERING_SIZE_MAX; MilGrabBufferListSize++) { MbufAllocColor(MilSystem, MdigInquire(MilDigitizer, M_SIZE_BAND, M_NULL), MdigInquire(MilDigitizer, M_SIZE_X, M_NULL), MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL), MdigInquire(MilDigitizer, M_TYPE, M_NULL), M_IMAGE+M_GRAB+M_PROC+SourceDataFormat, &MilGrabBufferList[MilGrabBufferListSize]); if (MilGrabBufferList[MilGrabBufferListSize]) { MbufClear(MilGrabBufferList[MilGrabBufferListSize], M_COLOR_WHITE); } else break; } MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE); /* Free buffers to leave space for possible temporary buffers. */ for (n=0; n<2 && MilGrabBufferListSize; n++) { MilGrabBufferListSize--; MbufFree(MilGrabBufferList[MilGrabBufferListSize]); } 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 Multicast master digitizer that can read, write and")); MosPrintf(MIL_TEXT(" grab from\n")); MosPrintf(MIL_TEXT("a GigE Vision device.\n\n")); MosPrintf(MIL_TEXT("This example must be used along with MulticastSlave.cpp connected to")); MosPrintf(MIL_TEXT(" the same\n")); MosPrintf(MIL_TEXT("GigE Vision device and running on another PC.\n\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.")); MosGetch(); /* Print info related to the device we are connected to. */ PrintCameraInfo(MilDigitizer); /* Initialize the User's processing function data structure. */ UserHookData.MilImageDisp = MilImageDisp; UserHookData.ProcessedImageCount = 0; UserHookData.CorruptImageCount = 0; /* Start the processing. The processing function is called for every frame grabbed. */ MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, M_START, M_DEFAULT, ProcessingFunction, &UserHookData); /* NOTE: Now the main() is free to perform other tasks while the processing is executing. */ /* -------------------------------------------------------------------------------- */ MosPrintf(MIL_TEXT("If the MulticastSlave program is already running on the other PC, it")); MosPrintf(MIL_TEXT(" should\n")); MosPrintf(MIL_TEXT("have detected that this device is controlled by a multicast master")); MosPrintf(MIL_TEXT(" digitizer\n")); MosPrintf(MIL_TEXT("and have started image acquisition.\n\n")); MosPrintf(MIL_TEXT("If the MulticastSlave program is not yet started then it should be")); MosPrintf(MIL_TEXT(" started now.\n")); MosPrintf(MIL_TEXT("\nPress <Enter> to stop.\n")); MosGetch(); /* Stop the processing. */ MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, M_STOP, M_DEFAULT, ProcessingFunction, &UserHookData); /* Print statistics. */ MdigInquire(MilDigitizer, M_PROCESS_FRAME_COUNT, &ProcessFrameCount); MdigInquire(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(); while(MilGrabBufferListSize > 0) MbufFree(MilGrabBufferList[--MilGrabBufferListSize]); /* Release defaults. */ MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImageDisp); return 0; } /* Prints information regarding the device this master digitizer is connected to. */ /* ----------------------------------------------------------------------- */ void PrintCameraInfo(MIL_ID MilDigitizer) { MIL_TEXT_PTR DeviceVendor = NULL; MIL_TEXT_PTR DeviceModel = NULL; MIL_TEXT_PTR PixelFormat = NULL; MIL_INT64 Width = 0, Height = 0; MIL_INT Port = 0; MIL_INT Len = 0; MIL_TEXT_PTR MulticastAddress; #if M_MIL_USE_WINDOWS /* Clear console. */ system("cls"); #endif /* Inquire camera vendor name. */ MdigInquire(MilDigitizer, M_CAMERA_VENDOR_SIZE, &Len); DeviceVendor = new MIL_TEXT_CHAR[Len]; MdigInquire(MilDigitizer, M_CAMERA_VENDOR, DeviceVendor); /* Inquire camera model name. */ MdigInquire(MilDigitizer, M_CAMERA_MODEL_SIZE, &Len); DeviceModel = new MIL_TEXT_CHAR[Len]; MdigInquire(MilDigitizer, M_CAMERA_MODEL, DeviceModel); /* Inquire camera pixel format. */ MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE_AS_STRING+M_STRING_SIZE, MIL_TEXT("PixelFormat"), M_DEFAULT, &Len); PixelFormat = new MIL_TEXT_CHAR[Len]; MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE_AS_STRING, MIL_TEXT("PixelFormat"), M_DEFAULT, PixelFormat); /* Inquire camera width and height. */ MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE, MIL_TEXT("Width"), M_TYPE_INT64, &Width); MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE, MIL_TEXT("Height"), M_TYPE_INT64, &Height); /* Inquire the Multicast address used. */ MdigInquire(MilDigitizer, M_GC_STREAM_CHANNEL_MULTICAST_ADDRESS_STRING_SIZE, &Len); MulticastAddress = new MIL_TEXT_CHAR[Len]; MdigInquire(MilDigitizer, M_GC_STREAM_CHANNEL_MULTICAST_ADDRESS_STRING, MulticastAddress); MdigInquire(MilDigitizer, M_GC_STREAM_PORT, &Port); /* Print camera info. */ MosPrintf(MIL_TEXT("\n--------------------- Master digitizer connection status. ")); MosPrintf(MIL_TEXT("---------------------\n\n"), DeviceVendor, DeviceModel); MosPrintf(MIL_TEXT("Connected to %s %s\n"), DeviceVendor, DeviceModel); MosPrintf(MIL_TEXT("Device pixel format: %s\n"), PixelFormat); MosPrintf(MIL_TEXT("Device AOI: %d x %d\n"), Width, Height); MosPrintf(MIL_TEXT("IPv4 Multicast address: %s\n"), MulticastAddress); MosPrintf(MIL_TEXT("Stream port: %d\n\n"), Port); /* Cleanup. */ if(DeviceVendor) delete [] DeviceVendor; if(DeviceModel) delete [] DeviceModel; if(PixelFormat) delete [] PixelFormat; if(MulticastAddress) delete [] MulticastAddress; } /* User's processing function called every time a grab buffer is modified. */ /* -----------------------------------------------------------------------*/ /* Local defines. */ #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; /* Retrieve the MIL_ID of the grabbed buffer. */ MdigGetHookInfo(HookId, M_MODIFIED_BUFFER+M_BUFFER_ID, &ModifiedBufferId); MdigGetHookInfo(HookId, M_CORRUPTED_FRAME, &IsFrameCorrupt); /* Print and draw the frame count. */ UserHookDataPtr->ProcessedImageCount++; if(IsFrameCorrupt) UserHookDataPtr->CorruptImageCount++; MosSprintf(Text, STRING_LENGTH_MAX, MIL_TEXT("%ld"), UserHookDataPtr->ProcessedImageCount); MgraText(M_DEFAULT, ModifiedBufferId, STRING_POS_X, STRING_POS_Y, Text); /* Perform the processing and update the display. */ MbufCopy(ModifiedBufferId, UserHookDataPtr->MilImageDisp); #if M_MIL_USE_CE /* Give execution time to user interface when the digitizer processing queue is full. If necessary, the Sleep value can be increased to give more execution time to user interface. */ if(MdigInquire(UserHookDataPtr->MilDigitizer, M_PROCESS_PENDING_GRAB_NUM, M_NULL) <= 1) { if ((UserHookDataPtr->ProcessedImageCount%10) == 0) Sleep(2); } #endif return 0; }