#include <windows.h>
#include <mil.h>
#if M_MIL_USE_CE
#define SLAVE_SYSTEM_DESCRIPTOR MIL_TEXT("dmiltcp:
#else
#define SLAVE_SYSTEM_DESCRIPTOR M_SYSTEM_DEFAULT
#endif
#define SLAVE_DLL_NAME MIL_TEXT("mbufsharedmemory")
#if M_MIL_USE_WINDOWS && !M_MIL_USE_CE
#define SLAVE_DLL_TARGET_NAME INSTALL_DIR MIL_TEXT("mil\\dll\\") SLAVE_DLL_NAME MIL_TEXT(".dll")
#elif M_MIL_USE_CE
#define SLAVE_DLL_TARGET_NAME INSTALL_DIR SLAVE_DLL_NAME MIL_TEXT(".dll")
#elif M_MIL_USE_LINUX
#define SLAVE_DLL_TARGET_NAME INSTALL_DIR MIL_TEXT("mil/lib/lib") SLAVE_DLL_NAME MIL_TEXT(".so")
#endif
#define BUFFERING_SIZE_MAX 20
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID HookId, void* HookDataPtr);
#define USE_INTERPROCESS_SHARED_MEMORY_COPY M_YES
#if USE_INTERPROCESS_SHARED_MEMORY_COPY
#define SHARED_BUFFER_NAME MIL_TEXT("Global\\SharedBuffer0")
#endif
#include "../MbufSharedMemory.h"
typedef struct
{
MIL_ID MilRemoteDigitizer;
MIL_ID MilRemoteSharedImage;
MIL_ID MilLocalImageDisp;
MIL_ID MilLocalImageProc;
MIL_ID MilLocalSharedImage;
MIL_INT ProcessedImageCount;
} HookDataStruct;
MIL_ID MFTYPE MbufAllocSharedMemory(MIL_ID MilSystem, MIL_INT SizeBand,
MIL_INT SizeX, MIL_INT SizeY, MIL_INT Type, MIL_INT DataFormat,
MIL_INT ControlFlag, MIL_INT PitchByte, MIL_CONST_TEXT_PTR SharedBufferName,
MIL_UINT64 *SharedBufferHandlePtr, MIL_ID *SharedBufferMilIdPtr);
void MFTYPE MbufFreeSharedMemory(MIL_UINT64 SharedBufferHandle, MIL_ID SharedBufferMilId);
int MosMain(void)
{
MIL_ID MilApplication;
MIL_ID MilRemoteSystem;
MIL_ID MilRemoteDigitizer;
MIL_ID MilSystemOwnerApplication;
MIL_ID MilRemoteGrabBufferList[BUFFERING_SIZE_MAX] = { 0 }, MilRemoteSharedImage = M_NULL;
MIL_INT MilRemoteGrabBufferListSize;
MIL_ID MilLocalSystem;
MIL_ID MilLocalDisplay;
MIL_ID MilLocalImageProc, MilLocalImageDisp, MilLocalSharedImage = M_NULL;
MIL_INT ProcessFrameCount = 0;
MIL_INT NbFrames = 0, n = 0;
MIL_INT BufferSize = 0;
MIL_DOUBLE ProcessFrameRate = 0, Time = 0;
HookDataStruct UserHookData;
bool CheckExistence = false;
MappAlloc(M_DEFAULT, &MilApplication);
MsysAlloc(M_DEFAULT, SLAVE_SYSTEM_DESCRIPTOR, M_DEFAULT, M_DEFAULT, &MilRemoteSystem);
if(MsysInquire(MilRemoteSystem, M_LOCATION, M_NULL) != M_REMOTE)
{
MosPrintf(MIL_TEXT("This example requires the default system to be a remote system.\n"));
MosPrintf(MIL_TEXT("Please select a remote system as the default.\n"));
MosPrintf(MIL_TEXT("If no remote systems are registered "));
MosPrintf(MIL_TEXT("please go to the DistributedMIL->Connections page, "));
MosPrintf(MIL_TEXT("register a remote system, "));
MosPrintf(MIL_TEXT("and then select it as the default system.\n"));
MsysFree(MilRemoteSystem);
MappFree(MilApplication);
MosGetch();
return -1;
}
MsysInquire(MilRemoteSystem, M_OWNER_APPLICATION, &MilSystemOwnerApplication);
if((MappInquire(M_DEFAULT, M_PLATFORM_BITNESS, M_NULL) ==
MappInquire(MilSystemOwnerApplication, M_PLATFORM_BITNESS, M_NULL)) &&
(MappInquire(M_DEFAULT, M_PLATFORM_OS_TYPE, M_NULL) ==
MappInquire(MilSystemOwnerApplication, M_PLATFORM_OS_TYPE, M_NULL)))
{
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
MappFileOperation(M_DEFAULT, SLAVE_DLL_TARGET_NAME, MilSystemOwnerApplication, M_NULL,
M_FILE_COPY_MIL_DLL, M_DEFAULT, M_NULL);
if(0 != MappGetError(M_DEFAULT, M_CURRENT, M_NULL))
{
MosPrintf(MIL_TEXT("There was an error while copying the slave library.\n"));
MosPrintf(MIL_TEXT("Checking if one is present on the remote system.\n"));
CheckExistence = true;
}
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
}
else
CheckExistence = true;
if(CheckExistence)
{
MIL_INT DllExists = M_NO;
MappFileOperation(MilSystemOwnerApplication, SLAVE_DLL_NAME, M_NULL, M_NULL,
M_FILE_EXISTS_MIL_DLL, M_DEFAULT, &DllExists);
if(DllExists != M_YES)
{
MosPrintf(MIL_TEXT("The slave library was NOT copied to the remote system.\n"));
MosPrintf(MIL_TEXT("Make sure it is present for the example to work properly.\n"));
MosPrintf(MIL_TEXT("See DistributedMILExamples.txt in the DistributedMIL examples "));
MosPrintf(MIL_TEXT("folder\nfor more information.\n"));
MsysFree(MilRemoteSystem);
MappFree(MilApplication);
MosPrintf(MIL_TEXT("Press a key to terminate.\n\n"));
MosGetch();
return -1;
}
}
MdigAlloc(MilRemoteSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, &MilRemoteDigitizer);
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
for(MilRemoteGrabBufferListSize = 0; MilRemoteGrabBufferListSize<BUFFERING_SIZE_MAX;
MilRemoteGrabBufferListSize++)
{
MbufAllocColor(MilRemoteSystem,
MdigInquire(MilRemoteDigitizer, M_SIZE_BAND, M_NULL),
MdigInquire(MilRemoteDigitizer, M_SIZE_X, M_NULL),
MdigInquire(MilRemoteDigitizer, M_SIZE_Y, M_NULL),
MdigInquire(MilRemoteDigitizer, M_TYPE, M_NULL),
M_IMAGE+M_GRAB+M_PROC,
&MilRemoteGrabBufferList[MilRemoteGrabBufferListSize]);
if (MilRemoteGrabBufferList[MilRemoteGrabBufferListSize])
MbufClear(MilRemoteGrabBufferList[MilRemoteGrabBufferListSize], 0xFF);
else
break;
}
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
for (n=0; n<2 && MilRemoteGrabBufferListSize; n++)
{
MilRemoteGrabBufferListSize--;
MbufFree(MilRemoteGrabBufferList[MilRemoteGrabBufferListSize]);
}
MsysAlloc(M_SYSTEM_HOST, M_DEFAULT, M_DEFAULT, &MilLocalSystem);
MdispAlloc(MilLocalSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, &MilLocalDisplay);
MbufAllocColor(MilLocalSystem,
MdigInquire(MilRemoteDigitizer, M_SIZE_BAND, M_NULL),
MdigInquire(MilRemoteDigitizer, M_SIZE_X, M_NULL),
MdigInquire(MilRemoteDigitizer, M_SIZE_Y, M_NULL),
MdigInquire(MilRemoteDigitizer, M_TYPE, M_NULL),
M_IMAGE+M_PROC, &MilLocalImageProc);
MbufClear(MilLocalImageProc, 0);
MbufAllocColor(MilLocalSystem,
MdigInquire(MilRemoteDigitizer, M_SIZE_BAND, M_NULL),
MdigInquire(MilRemoteDigitizer, M_SIZE_X, M_NULL),
MdigInquire(MilRemoteDigitizer, M_SIZE_Y, M_NULL),
MdigInquire(MilRemoteDigitizer, M_TYPE, M_NULL),
M_IMAGE+M_PROC+M_DISP, &MilLocalImageDisp);
MbufClear(MilLocalImageDisp, 0);
MdispSelect(MilLocalDisplay, MilLocalImageDisp);
MosPrintf(MIL_TEXT("\nDMIL REMOTE CAPTURE WITH LOCAL PROCESSING.\n"));
MosPrintf(MIL_TEXT("------------------------------------------\n\n"));
#if USE_INTERPROCESS_SHARED_MEMORY_COPY
MIL_CONST_TEXT_PTR SharedBufferName = SHARED_BUFFER_NAME;
MIL_UINT64 SharedBufferRemoteHandle, SharedBufferLocalHandle;
MbufAllocSharedMemory(MilLocalSystem,
MbufInquire(MilRemoteGrabBufferList[0], M_SIZE_BAND, M_NULL),
MbufInquire(MilRemoteGrabBufferList[0], M_SIZE_X, M_NULL),
MbufInquire(MilRemoteGrabBufferList[0], M_SIZE_Y, M_NULL),
MbufInquire(MilRemoteGrabBufferList[0], M_TYPE, M_NULL),
M_IMAGE+M_PROC+
MbufInquire(MilRemoteGrabBufferList[0], M_DATA_FORMAT, M_NULL),
SHARED_MEMORY_ALLOCATE,
MbufInquire(MilRemoteGrabBufferList[0], M_PITCH_BYTE, M_NULL),
SharedBufferName, &SharedBufferLocalHandle, &MilLocalSharedImage);
MbufClear(MilLocalSharedImage, 0x80);
MbufAllocSharedMemory(MilRemoteSystem,
MbufInquire(MilLocalSharedImage, M_SIZE_BAND, M_NULL),
MbufInquire(MilLocalSharedImage, M_SIZE_X, M_NULL),
MbufInquire(MilLocalSharedImage, M_SIZE_Y, M_NULL),
MbufInquire(MilLocalSharedImage, M_TYPE, M_NULL),
M_IMAGE+M_PROC+MbufInquire(MilLocalSharedImage, M_DATA_FORMAT, M_NULL),
SHARED_MEMORY_CREATE,
MbufInquire(MilLocalSharedImage, M_PITCH_BYTE, M_NULL),
SharedBufferName, &SharedBufferRemoteHandle, &MilRemoteSharedImage);
MbufClear(MilRemoteSharedImage, 0x80);
#endif
UserHookData.MilRemoteDigitizer = MilRemoteDigitizer;
UserHookData.MilRemoteSharedImage = MilRemoteSharedImage;
UserHookData.MilLocalImageProc = MilLocalImageProc;
UserHookData.MilLocalImageDisp = MilLocalImageDisp;
UserHookData.MilLocalSharedImage = MilLocalSharedImage;
UserHookData.ProcessedImageCount = 0;
MdigProcess(MilRemoteDigitizer, MilRemoteGrabBufferList, MilRemoteGrabBufferListSize,
M_START, M_DEFAULT, ProcessingFunction, &UserHookData);
MosPrintf(MIL_TEXT("Press <Enter> to stop.\n\n"));
MosGetch();
MdigProcess(MilRemoteDigitizer, MilRemoteGrabBufferList, MilRemoteGrabBufferListSize,
M_STOP, M_DEFAULT, ProcessingFunction, &UserHookData);
MdigInquire(MilRemoteDigitizer, M_PROCESS_FRAME_COUNT, &ProcessFrameCount);
MdigInquire(MilRemoteDigitizer, M_PROCESS_FRAME_RATE, &ProcessFrameRate);
MosPrintf(MIL_TEXT("\n\n%lld frames grabbed at %.1f frames/sec (%.1f ms/frame).\n"),
(long long)ProcessFrameCount, ProcessFrameRate, 1000.0/ProcessFrameRate);
MosPrintf(MIL_TEXT("Press <Enter> to end.\n\n"));
MosGetch();
while(MilRemoteGrabBufferListSize > 0)
MbufFree(MilRemoteGrabBufferList[--MilRemoteGrabBufferListSize]);
#if USE_INTERPROCESS_SHARED_MEMORY_COPY
MbufFreeSharedMemory(SharedBufferLocalHandle, MilLocalSharedImage);
MbufFreeSharedMemory(SharedBufferRemoteHandle, MilRemoteSharedImage);
#endif
MdigFree(MilRemoteDigitizer);
MsysFree(MilRemoteSystem);
MbufFree(MilLocalImageDisp);
MbufFree(MilLocalImageProc);
MdispFree(MilLocalDisplay);
MsysFree(MilLocalSystem);
MappFree(MilApplication);
return 0;
}
#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, BufferToProcessId;
MIL_TEXT_CHAR Text[STRING_LENGTH_MAX]= {MIL_TEXT('\0'),};
MdigGetHookInfo(HookId, M_MODIFIED_BUFFER+M_BUFFER_ID, &ModifiedBufferId);
#if (USE_INTERPROCESS_SHARED_MEMORY_COPY == M_NO)
MbufCopy(ModifiedBufferId, UserHookDataPtr->MilLocalImageProc);
BufferToProcessId = UserHookDataPtr->MilLocalImageProc;
#else
MbufCopy(ModifiedBufferId, UserHookDataPtr->MilRemoteSharedImage);
MthrWait(M_DEFAULT, M_THREAD_WAIT, M_NULL);
BufferToProcessId = UserHookDataPtr->MilLocalSharedImage;
#endif
UserHookDataPtr->ProcessedImageCount++;
MosPrintf(MIL_TEXT("Processing frame #%lld.\r"), (long long)UserHookDataPtr->ProcessedImageCount);
MosSprintf(Text, STRING_LENGTH_MAX, MIL_TEXT("%lld"),
(long long)UserHookDataPtr->ProcessedImageCount);
MgraText(M_DEFAULT, BufferToProcessId, STRING_POS_X, STRING_POS_Y, Text);
MbufCopy(BufferToProcessId, UserHookDataPtr->MilLocalImageDisp);
return 0;
}
MIL_ID MFTYPE MbufAllocSharedMemory(MIL_ID MilSystem, MIL_INT SizeBand,
MIL_INT SizeX, MIL_INT SizeY, MIL_INT Type, MIL_INT DataFormat,
MIL_INT ControlFlag, MIL_INT PitchByte,
MIL_CONST_TEXT_PTR SharedBufferName,
MIL_UINT64 *SharedBufferHandlePtr, MIL_ID *SharedBufferMilIdPtr)
{
MIL_ID Func;
MIL_INT SharedBufferNameLength = MosStrlen(SharedBufferName)+1;
MfuncAlloc(MIL_TEXT("MbufAllocSharedMemory"),
ALLOC_SHARED_MEMORY_NB_PARAM,
M_NULL,
SLAVE_DLL_NAME,
MIL_TEXT("SlaveAllocSharedMemory"),
M_USER_MODULE_1+ALLOC_SHARED_MEMORY_OPCODE,
M_SYNCHRONOUS_FUNCTION,
&Func
);
if ((ControlFlag == SHARED_MEMORY_ALLOCATE) || (ControlFlag == SHARED_MEMORY_CREATE))
{
MfuncParamMilId (Func, 1, MilSystem, M_SYSTEM, M_IN);
MfuncParamMilInt(Func, 2, SizeBand);
MfuncParamMilInt(Func, 3, SizeX);
MfuncParamMilInt(Func, 4, SizeY);
MfuncParamMilInt(Func, 5, Type);
MfuncParamMilInt(Func, 6, DataFormat);
MfuncParamMilInt(Func, 7, ControlFlag);
MfuncParamMilInt(Func, 8, PitchByte);
MfuncParamMilInt(Func, 9, SharedBufferNameLength);
MfuncParamConstMilText(Func, 10, SharedBufferName, SharedBufferNameLength, M_IN);
MfuncParamArrayMilUint64(Func, 11, SharedBufferHandlePtr, 1, M_OUT);
MfuncParamArrayMilId(Func, 12, SharedBufferMilIdPtr, 1, M_IMAGE, M_OUT+M_AS_VALUE);
MfuncCall(Func);
MfuncFree(Func);
}
else
{
MfuncErrorReport(Func,M_FUNC_ERROR+ALLOC_SHARED_MEMORY_PARAMETER_ERROR_CODE,
MIL_TEXT("Invalid parameter 7 (ControlFlag)."),
MIL_TEXT("Operation must be: SHARED_MEMORY_ALLOCATE or SHARED_MEMORY_CREATE."),
M_NULL,
M_NULL
);
}
return (*SharedBufferMilIdPtr);
}
void MFTYPE MbufFreeSharedMemory(MIL_UINT64 SharedBufferHandle, MIL_ID SharedBufferMilId)
{
MIL_ID Func;
MfuncAlloc(MIL_TEXT("MbufFreeSharedMemory"),
FREE_SHARED_MEMORY_NB_PARAM,
M_NULL,
SLAVE_DLL_NAME,
MIL_TEXT("SlaveFreeSharedMemory"),
M_USER_MODULE_1+FREE_SHARED_MEMORY_OPCODE,
M_SYNCHRONOUS_FUNCTION,
&Func
);
if (SharedBufferHandle != M_NULL)
{
MfuncParamMilUint64(Func, 1, SharedBufferHandle);
MfuncParamMilId(Func, 2, SharedBufferMilId, M_IMAGE, M_IN+M_AS_VALUE);
MfuncCall(Func);
MfuncFree(Func);
}
else
{
MfuncErrorReport(Func, M_FUNC_ERROR+FREE_SHARED_MEMORY_PARAMETER_ERROR_CODE,
MIL_TEXT("Invalid Parameter."), MIL_TEXT("Handle cannot be NULL.)"),
M_NULL, M_NULL);
}
}