#include <mil.h>
#define PROCESSING_SYSTEM_TYPE M_SYSTEM_HOST
#define PROCESSING_SYSTEM_NUMBER 2
#define USE_GRAB_SYSTEM_AS_ONE_PROCESSOR M_YES
#define PROCESS_EACH_IMAGE_ON_ALL_SYSTEMS M_YES
#define DISPLAY_EACH_IMAGE_PROCESSED M_YES
#define DISTRIBUTED_MIL_PROTOCOL MIL_TEXT("dmiltcp")
const MIL_TEXT_CHAR* SYSTEM_ADDRESSES[] = {
MIL_TEXT("localhost"), MIL_TEXT("localhost"),
MIL_TEXT("localhost"), MIL_TEXT("localhost"),
MIL_TEXT("localhost"), MIL_TEXT("localhost"),
MIL_TEXT("localhost"), MIL_TEXT("localhost"),
MIL_TEXT("localhost"), MIL_TEXT("localhost"),
MIL_TEXT("localhost"), MIL_TEXT("localhost"),
MIL_TEXT("localhost"), MIL_TEXT("localhost"),
MIL_TEXT("localhost"), MIL_TEXT("localhost")
};
#define SYSTEM_DESCRIPTOR_SIZE 512
#define BUFFER_PER_PROCESSOR 2
#define BUFFER_NUMBER (PROCESSING_SYSTEM_NUMBER * BUFFER_PER_PROCESSOR)
#define BUFFER_SCALE 1.0
#define BUFFER_MAX_STRING_LENGTH 80
#define BUFFER_DRAW_RECT_NUMBER 20
#define BUFFER_DRAW_INWARD_STEP_NUMBER 10
#define BUFFER_DRAW_RECT_STEP 10
#define GRAB_BUFFER_NUMBER (2 * PROCESSING_SYSTEM_NUMBER)
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID EventId, void* CallBackDataPtr);
typedef struct
{
MIL_ID MilDigitizer;
MIL_ID DispBuffer;
MIL_ID *SrcProcBufferListPtr;
MIL_ID *DstProcBufferListPtr;
MIL_INT SizeX, SizeY, SizeBand;
int NbSystem;
int NbProc;
double Time;
int ProcessEachImageOnAllSystems;
} ProcessingDataStruct;
int MosMain(void)
{
MIL_ID MilApplication;
MIL_ID MilSystem ;
MIL_ID MilDigitizer ;
MIL_ID MilDisplay ;
MIL_ID MilImageDisp ;
MIL_ID GrabBufferList[GRAB_BUFFER_NUMBER];
MIL_ID ProcSystemList[PROCESSING_SYSTEM_NUMBER];
MIL_ID SrcProcBufferList[BUFFER_NUMBER];
MIL_ID DstProcBufferList[BUFFER_NUMBER];
MIL_INT SizeX, SizeY, SizeBand;
MIL_TEXT_CHAR SystemDescriptor[SYSTEM_DESCRIPTOR_SIZE];
int NbSystem = 0, NbSystemToAllocate = PROCESSING_SYSTEM_NUMBER;
MIL_INT GrabFrameCount, n;
double SingleSystemProcessingRate, MultipleSystemProcessingRate;
ProcessingDataStruct ProcessingData;
MappAlloc(M_NULL, M_DEFAULT, &MilApplication);
MsysAlloc(M_DEFAULT, M_SYSTEM_DEFAULT, M_DEFAULT, M_DEFAULT, &MilSystem);
if(MsysInquire(MilSystem, M_LOCATION, M_NULL) != M_LOCAL)
{
MosPrintf(MIL_TEXT("This example requires the default system to be a local system.\n"));
MosPrintf(MIL_TEXT("Please select a local system as the default.\n"));
MsysFree(MilSystem);
MappFree(MilApplication);
MosGetch();
return -1;
}
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, &MilDisplay);
MdigAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, &MilDigitizer);
SizeX = ProcessingData.SizeX = (MIL_INT)(MdigInquire(MilDigitizer, M_SIZE_X, M_NULL)*BUFFER_SCALE);
SizeY = ProcessingData.SizeY = (MIL_INT)(MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL)*BUFFER_SCALE);
SizeBand = ProcessingData.SizeBand = (MIL_INT)(MdigInquire(MilDigitizer, M_SIZE_BAND, M_NULL));
MbufAllocColor(MilSystem, SizeBand, SizeX, SizeY, 8L+M_UNSIGNED, M_IMAGE+M_GRAB+M_DISP, &MilImageDisp);
MbufClear(MilImageDisp, 0x0);
if (DISPLAY_EACH_IMAGE_PROCESSED)
MdispSelect(MilDisplay, MilImageDisp);
for (n=0; n< GRAB_BUFFER_NUMBER; n++)
MbufAllocColor(MilSystem, SizeBand, SizeX, SizeY, 8L+M_UNSIGNED, M_IMAGE+M_GRAB, &GrabBufferList[n]);
if (USE_GRAB_SYSTEM_AS_ONE_PROCESSOR)
NbSystemToAllocate--;
for (n=0; n<NbSystemToAllocate; n++)
{
MosSprintf(SystemDescriptor, SYSTEM_DESCRIPTOR_SIZE, MIL_TEXT("%s:
DISTRIBUTED_MIL_PROTOCOL, SYSTEM_ADDRESSES[n], PROCESSING_SYSTEM_TYPE);
MsysAlloc(M_DEFAULT, SystemDescriptor, M_DEFAULT, M_DEFAULT, &ProcSystemList[n]);
if (ProcSystemList[n])
NbSystem++;
}
if (USE_GRAB_SYSTEM_AS_ONE_PROCESSOR)
{
ProcSystemList[NbSystem] = MilSystem;
NbSystem++;
}
for (n=0; n<(NbSystem*BUFFER_PER_PROCESSOR); n++)
{
MbufAllocColor(ProcSystemList[n%NbSystem], SizeBand, SizeX, SizeY, 8L+M_UNSIGNED,
M_IMAGE+M_PROC, &SrcProcBufferList[n]);
MbufAllocColor(ProcSystemList[n%NbSystem], SizeBand, SizeX, SizeY, 8L+M_UNSIGNED,
M_IMAGE+M_PROC, &DstProcBufferList[n]);
}
MdigControl(MilDigitizer, M_GRAB_SCALE, BUFFER_SCALE);
MosPrintf(MIL_TEXT("\nDISTRIBUTED MIL PROCESSING:\n"));
MosPrintf(MIL_TEXT("---------------------------\n\n"));
MosPrintf(MIL_TEXT("1 System processing:\n"));
ProcessingData.NbSystem = 1;
ProcessingData.ProcessEachImageOnAllSystems = M_NO;
ProcessingData.NbProc = 0;
ProcessingData.MilDigitizer = MilDigitizer;
ProcessingData.DispBuffer = MilImageDisp;
ProcessingData.SrcProcBufferListPtr = SrcProcBufferList;
ProcessingData.DstProcBufferListPtr = DstProcBufferList;
MdigProcess(MilDigitizer, GrabBufferList, GRAB_BUFFER_NUMBER, M_START, M_DEFAULT,
ProcessingFunction, &ProcessingData);
MosPrintf(MIL_TEXT("Press <Enter> to stop.\n\n"));
MosGetch();
MdigProcess(MilDigitizer, GrabBufferList, GRAB_BUFFER_NUMBER, M_STOP+M_WAIT, M_DEFAULT,
ProcessingFunction, &ProcessingData);
if (ProcessingData.NbProc != 0)
{
SingleSystemProcessingRate = ProcessingData.NbProc/ProcessingData.Time;
MdigInquire(MilDigitizer, M_PROCESS_FRAME_COUNT, &GrabFrameCount);
MosPrintf(MIL_TEXT("%lld Frames grabbed, %d Frames processed at %.1f frames/sec (%.1f ms/frame).\n"),
(long long)GrabFrameCount, ProcessingData.NbProc, SingleSystemProcessingRate, 1000.0/SingleSystemProcessingRate);
}
else
MosPrintf(MIL_TEXT("No frame has been grabbed.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
MosPrintf(MIL_TEXT("%d Systems processing:\n"), NbSystem);
MdigHalt(MilDigitizer);
ProcessingData.NbSystem = NbSystem;
ProcessingData.ProcessEachImageOnAllSystems = PROCESS_EACH_IMAGE_ON_ALL_SYSTEMS;
ProcessingData.NbProc = 0;
ProcessingData.DispBuffer = MilImageDisp;
ProcessingData.SrcProcBufferListPtr = SrcProcBufferList;
ProcessingData.DstProcBufferListPtr = DstProcBufferList;
MdigProcess(MilDigitizer, GrabBufferList, GRAB_BUFFER_NUMBER, M_START, M_DEFAULT,
ProcessingFunction, &ProcessingData);
MosPrintf(MIL_TEXT("Press <Enter> to stop.\n\n"));
MosGetch();
MdigProcess(MilDigitizer, GrabBufferList, GRAB_BUFFER_NUMBER, M_STOP+M_WAIT, M_DEFAULT,
ProcessingFunction, &ProcessingData);
if (ProcessingData.NbProc != 0)
{
MultipleSystemProcessingRate = ProcessingData.NbProc/ProcessingData.Time;
MdigInquire(MilDigitizer, M_PROCESS_FRAME_COUNT, &GrabFrameCount);
MosPrintf(MIL_TEXT("%lld Frames grabbed, %d Frames processed at %.1f frames/sec (%.1f ms/frame).\n\n"),
(long long)GrabFrameCount, ProcessingData.NbProc, MultipleSystemProcessingRate, 1000.0/MultipleSystemProcessingRate);
MosPrintf(MIL_TEXT("Speedup factor: %.1f.\n\n"),MultipleSystemProcessingRate/SingleSystemProcessingRate);
if (DISPLAY_EACH_IMAGE_PROCESSED && ((long)((MultipleSystemProcessingRate/SingleSystemProcessingRate)+0.1) < NbSystem))
MosPrintf(MIL_TEXT("Warning: Display might limit the processing speed. Disable it and retry.\n\n"));
}
else
MosPrintf(MIL_TEXT("No frame has been grabbed.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to end.\n\n"));
MosGetch();
for (n=0; n<GRAB_BUFFER_NUMBER; n++)
MbufFree(GrabBufferList[n]);
for (n=0; n<BUFFER_NUMBER; n++)
{
MbufFree(SrcProcBufferList[n]);
MbufFree(DstProcBufferList[n]);
}
if (USE_GRAB_SYSTEM_AS_ONE_PROCESSOR)
NbSystem--;
for (n=0; n<NbSystem; n++)
MsysFree(ProcSystemList[n]);
MbufFree(MilImageDisp);
MdispFree(MilDisplay);
MdigFree(MilDigitizer);
MsysFree(MilSystem);
MappFree(MilApplication);
return 0;
}
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID EventId, void* CallBackDataPtr)
{
ProcessingDataStruct *ProcessingDataPtr = (ProcessingDataStruct *)CallBackDataPtr;
MIL_ID CurrentProcSrcBufId, CurrentProcDstBufId;
MIL_ID GrabbedBufferId;
MIL_INT GrabbedBufferIndex;
MIL_TEXT_CHAR Text[BUFFER_MAX_STRING_LENGTH];
MIL_DOUBLE RectHalfSizeStep = 0.0;
long RectStep = 0;
long NbSystem = ProcessingDataPtr->NbSystem;
long NbProcInitial = ProcessingDataPtr->NbProc;
long NbBufferToProcess, n;
MdigGetHookInfo(EventId, M_MODIFIED_BUFFER+M_BUFFER_ID, &GrabbedBufferId);
MdigGetHookInfo(EventId, M_MODIFIED_BUFFER+M_BUFFER_INDEX, &GrabbedBufferIndex);
if (ProcessingDataPtr->NbProc == 0)
MappTimer(M_DEFAULT, M_TIMER_RESET+M_SYNCHRONOUS,&ProcessingDataPtr->Time);
if (ProcessingDataPtr->ProcessEachImageOnAllSystems)
NbBufferToProcess = NbSystem;
else
NbBufferToProcess = 1;
for(n=0; n<NbBufferToProcess; n++)
{
CurrentProcSrcBufId = ProcessingDataPtr->SrcProcBufferListPtr[(ProcessingDataPtr->NbProc)%(NbSystem*BUFFER_PER_PROCESSOR)];
CurrentProcDstBufId = ProcessingDataPtr->DstProcBufferListPtr[(ProcessingDataPtr->NbProc)%(NbSystem*BUFFER_PER_PROCESSOR)];
MbufCopy(GrabbedBufferId, CurrentProcSrcBufId);
MosSprintf(Text, BUFFER_MAX_STRING_LENGTH, MIL_TEXT("#%d."), ProcessingDataPtr->NbProc);
MgraText(M_DEFAULT, CurrentProcSrcBufId, 50, 50, Text);
#if (!M_MIL_LITE)
{
MimArith(CurrentProcSrcBufId, 0x10, CurrentProcDstBufId, M_SUB_CONST+M_SATURATION);
MimArith(CurrentProcDstBufId, M_NULL, CurrentProcSrcBufId, M_NOT);
MimRotate(CurrentProcSrcBufId, CurrentProcDstBufId,
(ProcessingDataPtr->NbProc*10)%360,
(MIL_DOUBLE) ProcessingDataPtr->SizeX/2,
(MIL_DOUBLE) ProcessingDataPtr->SizeY/2,
(MIL_DOUBLE) ProcessingDataPtr->SizeX/2,
(MIL_DOUBLE) ProcessingDataPtr->SizeY/2,
M_NEAREST_NEIGHBOR);
}
#else
{
RectStep = (ProcessingDataPtr->NbProc % BUFFER_DRAW_RECT_NUMBER);
if(RectStep < BUFFER_DRAW_INWARD_STEP_NUMBER)
RectHalfSizeStep = RectStep * BUFFER_DRAW_RECT_STEP;
else
RectHalfSizeStep = (BUFFER_DRAW_RECT_NUMBER - RectStep) * BUFFER_DRAW_RECT_STEP;
MgraColor(M_DEFAULT, 0xff);
MgraRectFill(M_DEFAULT,
CurrentProcDstBufId,
ProcessingDataPtr->SizeX/2 - RectHalfSizeStep,
ProcessingDataPtr->SizeY/2 - RectHalfSizeStep,
ProcessingDataPtr->SizeX/2 + RectHalfSizeStep,
ProcessingDataPtr->SizeY/2 + RectHalfSizeStep);
}
#endif
ProcessingDataPtr->NbProc++;
MosPrintf(MIL_TEXT("Processing #%d.\r"), ProcessingDataPtr->NbProc);
}
#if (DISPLAY_EACH_IMAGE_PROCESSED)
{
for(n=0; n<NbBufferToProcess; n++)
{
CurrentProcDstBufId = ProcessingDataPtr->DstProcBufferListPtr[(NbProcInitial+n)%(NbSystem*BUFFER_PER_PROCESSOR)];
MbufCopy(CurrentProcDstBufId, ProcessingDataPtr->DispBuffer);
}
}
#endif
MappTimer(M_DEFAULT, M_TIMER_READ+M_SYNCHRONOUS, &ProcessingDataPtr->Time);
#if M_MIL_USE_CE
if(MdigInquire(ProcessingDataPtr->MilDigitizer, M_PROCESS_PENDING_GRAB_NUM, M_NULL) <= 1)
{
if ((ProcessingDataPtr->NbProc%10) == 0)
Sleep(2);
}
#endif
return(0);
}