#include <mil.h>
#if M_MIL_USE_WINDOWS
#include <conio.h>
#include <windows.h>
#endif
#define BUFFERING_SIZE_MAX 20
#define PRINT_DETAILS 0
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType,
MIL_ID HookId,
void* HookDataPtr);
MIL_ID MilGrabBufferList[BUFFERING_SIZE_MAX] = { 0 };
MIL_INT MilGrabBufferListSize;
typedef struct
{
MIL_DOUBLE BaseFrameRate;
MIL_DOUBLE ProcessFrameRate;
MIL_DOUBLE DelayInSeconds;
MIL_UINT64 TickFreq;
MIL_INT DelayTickVal;
MIL_INT ProcessFrameCount;
MIL_INT EqualityCounter;
bool Error;
}PacketDelayInfo;
typedef struct _PacketDelayResults
{
~_PacketDelayResults()
{
for(MIL_INT i=0; i<PixelFormatCount; i++)
delete [] PixelFormats[i];
delete [] PixelFormats;
delete [] InterPacketDelayInTicks;
delete [] InterPacketDelayInSec;
delete [] ReferenceFrameRate;
delete [] ObtainedFrameRate;
}
MIL_INT PixelFormatCount;
MIL_TEXT_PTR* PixelFormats;
MIL_INT* InterPacketDelayInTicks;
MIL_DOUBLE* InterPacketDelayInSec;
MIL_DOUBLE* ReferenceFrameRate;
MIL_DOUBLE* ObtainedFrameRate;
long Selection;
}PacketDelayResults;
void EnumeratePixelFormats(MIL_ID MilDigitizer, MIL_INT BoardType, PacketDelayResults& Results);
void ApplyPixelFormat(MIL_ID MilDigitizer, PacketDelayResults& Results);
void AllocateAcquisitionBuffers(MIL_ID MilSystem, MIL_ID MilDigitizer, MIL_INT BoardType);
void AcquireReferenceFrameRate(MIL_ID MilDigitizer, PacketDelayInfo& Info, PacketDelayResults& Results);
void FindInterPacketDelay(MIL_ID MilDigitizer, PacketDelayInfo& Info, PacketDelayResults& Results);
void PrintResults(MIL_ID MilDigitizer, PacketDelayInfo& Info, PacketDelayResults& Results);
void GetMilBufferInfoFromPixelFormat(MIL_ID MilDigitizer, MIL_INT& SizeBand,
MIL_INT& BufType, MIL_INT64& Attribute);
bool IsEqual(MIL_DOUBLE A, MIL_DOUBLE B)
{
if(((A+0.1) >= B) && ((A-0.1) <= B))
return true;
else
return false;
}
int MosMain(void)
{
MIL_ID MilApplication;
MIL_ID MilSystem ;
MIL_ID MilDigitizer ;
MIL_INT BoardType = 0;
MIL_INT NbIterations = 0, i = 0;
PacketDelayInfo PktInfo;
PacketDelayResults Results;
memset(&PktInfo, 0, sizeof(PacketDelayInfo));
memset(&Results, 0, sizeof(PacketDelayResults));
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, M_NULL,
&MilDigitizer, M_NULL);
MsysInquire(MilSystem, M_BOARD_TYPE, &BoardType);
if((BoardType != M_GIGE_VISION))
{
MosPrintf(MIL_TEXT("This example only runs on GigE Vision systems.\n"));
MappFreeDefault(MilApplication, MilSystem, M_NULL, MilDigitizer, M_NULL);
return 0;
}
MdigInquire(MilDigitizer, M_GC_COUNTER_TICK_FREQUENCY, &PktInfo.TickFreq);
if(PktInfo.TickFreq == 0)
{
MosPrintf(MIL_TEXT("Error, camera does not support inter-packet delay.\n"));
MappFreeDefault(MilApplication, MilSystem, M_NULL, MilDigitizer, M_NULL);
return 0;
}
MosPrintf(MIL_TEXT("\nThis example shows how to calculate inter-packet\n"));
MosPrintf(MIL_TEXT("delay for your GigE Vision camera.\n\n"));
MosPrintf(MIL_TEXT("Inter-packet delay is used to spread packet transmission\n"));
MosPrintf(MIL_TEXT("over the length of a frame. This is done to minimize the chance\n"));
MosPrintf(MIL_TEXT("of FIFO overruns inside your Gigabit Ethernet controller.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n\n"));
MosGetch();
EnumeratePixelFormats(MilDigitizer, BoardType, Results);
if(Results.Selection == Results.PixelFormatCount)
{
NbIterations = Results.PixelFormatCount;
Results.Selection = 0;
}
else
NbIterations = 1;
while(NbIterations--)
{
memset(&PktInfo, 0, sizeof(PacketDelayInfo));
MdigInquire(MilDigitizer, M_GC_COUNTER_TICK_FREQUENCY, &PktInfo.TickFreq);
ApplyPixelFormat(MilDigitizer, Results);
AllocateAcquisitionBuffers(MilSystem, MilDigitizer, BoardType);
MosPrintf(MIL_TEXT("\n\nCalculating inter-packet delay for %s.\n\n"), Results.PixelFormats[Results.Selection]);
AcquireReferenceFrameRate(MilDigitizer, PktInfo, Results);
FindInterPacketDelay(MilDigitizer, PktInfo, Results);
while(MilGrabBufferListSize > 0)
MbufFree(MilGrabBufferList[--MilGrabBufferListSize]);
Results.Selection++;
}
PrintResults(MilDigitizer, PktInfo, Results);
MosPrintf(MIL_TEXT("Press <Enter> to quit.\n\n\n"));
MosGetch();
MdigControl(MilDigitizer, M_GC_INTER_PACKET_DELAY, 0);
MappFreeDefault(MilApplication, MilSystem, M_NULL, MilDigitizer, M_NULL);
return 0;
}
void EnumeratePixelFormats(MIL_ID MilDigitizer, MIL_INT BoardType, PacketDelayResults& Results)
{
long SpreadFactor = 0;
MIL_INT64 PixFmt = 0;
Results.Selection = -1;
MIL_INT PixelFormats = 0;
MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_COUNT, MIL_TEXT("PixelFormat"), M_DEFAULT, &Results.PixelFormatCount);
if(Results.PixelFormatCount)
{
bool Done = false;
MIL_INT Len = 0;
Results.PixelFormats = new MIL_TEXT_PTR[Results.PixelFormatCount];
Results.InterPacketDelayInTicks = new MIL_INT[Results.PixelFormatCount];
Results.InterPacketDelayInSec = new MIL_DOUBLE[Results.PixelFormatCount];
Results.ReferenceFrameRate = new MIL_DOUBLE[Results.PixelFormatCount];
Results.ObtainedFrameRate = new MIL_DOUBLE[Results.PixelFormatCount];
MosPrintf(MIL_TEXT("Your camera supports the following pixel formats:\n"));
for(MIL_INT i=0; i<Results.PixelFormatCount; i++)
{
Results.InterPacketDelayInTicks[PixelFormats] = 0;
Results.InterPacketDelayInSec[PixelFormats] = 0;
Results.ReferenceFrameRate[PixelFormats] = 0;
Results.ObtainedFrameRate[PixelFormats] = 0;
MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_NAME+M_STRING_SIZE+i, MIL_TEXT("PixelFormat"), M_DEFAULT, &Len);
Results.PixelFormats[PixelFormats] = new MIL_TEXT_CHAR[Len];
MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_NAME+i, MIL_TEXT("PixelFormat"), M_DEFAULT, Results.PixelFormats[PixelFormats]);
MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_VALUE+i, MIL_TEXT("PixelFormat"), M_TYPE_ENUMERATION, &PixFmt);
if(PixFmt & PFNC_CUSTOM)
{
delete [] Results.PixelFormats[PixelFormats];
}
else
{
MIL_INT SizeBand = 0, BufType = 0;
MIL_INT64 Attribute = 0;
GetMilBufferInfoFromPixelFormat(MilDigitizer, SizeBand, BufType, Attribute);
if(Attribute)
{
MosPrintf(MIL_TEXT("%d %s\n"), PixelFormats, Results.PixelFormats[PixelFormats]);
PixelFormats++;
}
else
delete [] Results.PixelFormats[PixelFormats];
}
}
Results.PixelFormatCount = PixelFormats;
if(Results.PixelFormatCount > 1)
MosPrintf(MIL_TEXT("%d All\n"), Results.PixelFormatCount);
if(Results.PixelFormatCount > 1)
{
do
{
MosPrintf(MIL_TEXT("\nPlease select the pixel format that you want use for inter-packet delay\n"));
MosPrintf(MIL_TEXT("calculation (0-%d): "), Results.PixelFormatCount);
#if M_MIL_USE_WINDOWS
scanf_s("%d-", &(Results.Selection));
#else
scanf("%ld-", &(Results.Selection));
#endif
if(Results.Selection >= 0 && Results.Selection <= Results.PixelFormatCount)
Done = true;
else
MosPrintf(MIL_TEXT("Invalid selection, please try again\n."));
}
while(!Done);
MosPrintf(MIL_TEXT("\n%s selected\n\n"),
Results.Selection < Results.PixelFormatCount ? Results.PixelFormats[Results.Selection] : MIL_TEXT("All"));
}
else
Results.Selection = 0;
}
}
void ApplyPixelFormat(MIL_ID MilDigitizer, PacketDelayResults& Results)
{
MdigControlFeature(MilDigitizer, M_FEATURE_VALUE_AS_STRING, MIL_TEXT("PixelFormat"), M_DEFAULT,
Results.PixelFormats[Results.Selection]);
}
void AllocateAcquisitionBuffers(MIL_ID MilSystem, MIL_ID MilDigitizer, MIL_INT BoardType)
{
MIL_INT SizeBand = 1;
MIL_INT BufType = 8+M_UNSIGNED;
MIL_INT64 AdditionalAttributes = 0;
if(BoardType == M_GIGE_VISION)
{
MdigControl(MilDigitizer, M_GC_PIXEL_FORMAT_SWITCHING, M_DISABLE);
MdigControl(MilDigitizer, M_BAYER_CONVERSION, M_DISABLE);
GetMilBufferInfoFromPixelFormat(MilDigitizer, SizeBand, BufType, AdditionalAttributes);
}
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
for(MilGrabBufferListSize = 0;
MilGrabBufferListSize<BUFFERING_SIZE_MAX; MilGrabBufferListSize++)
{
MbufAllocColor(MilSystem,
SizeBand,
MdigInquire(MilDigitizer, M_SIZE_X, M_NULL),
MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL),
BufType,
M_IMAGE+M_GRAB+M_PROC+AdditionalAttributes,
&MilGrabBufferList[MilGrabBufferListSize]);
if (MilGrabBufferList[MilGrabBufferListSize])
{
MbufClear(MilGrabBufferList[MilGrabBufferListSize], 0xFF);
}
else
break;
}
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
}
void AcquireReferenceFrameRate(MIL_ID MilDigitizer, PacketDelayInfo& Info, PacketDelayResults& Results)
{
MdigControl(MilDigitizer, M_GC_INTER_PACKET_DELAY, 0);
MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize,
M_SEQUENCE+M_COUNT(BUFFERING_SIZE_MAX), M_DEFAULT, ProcessingFunction, M_NULL);
MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize,
M_STOP, M_DEFAULT, ProcessingFunction, M_NULL);
MdigInquire(MilDigitizer, M_PROCESS_FRAME_RATE, &Info.BaseFrameRate);
Results.ReferenceFrameRate[Results.Selection] = Info.BaseFrameRate;
MdigInquire(MilDigitizer, M_GC_THEORETICAL_INTER_PACKET_DELAY, &Info.DelayInSeconds);
Info.DelayTickVal = (MIL_UINT32)(Info.DelayInSeconds * Info.TickFreq);
}
void FindInterPacketDelay(MIL_ID MilDigitizer, PacketDelayInfo& Info, PacketDelayResults& Results)
{
bool Done = false;
#if PRINT_DETAILS
MosPrintf(MIL_TEXT("Reference frame-rate used: %.2f\n\n"), Info.BaseFrameRate);
#endif
while(!Done)
{
MdigControl(MilDigitizer, M_GC_INTER_PACKET_DELAY, Info.DelayTickVal);
MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize,
M_SEQUENCE+M_COUNT(BUFFERING_SIZE_MAX), M_DEFAULT, ProcessingFunction, M_NULL);
MdigInquire(MilDigitizer, M_PROCESS_FRAME_RATE, &Info.ProcessFrameRate);
MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize,
M_STOP, M_DEFAULT, ProcessingFunction, M_NULL);
#if PRINT_DETAILS
MosPrintf(MIL_TEXT("%Programming delay of %d ticks; frame-rate obtained: %.2f\r"),
Info.DelayTickVal, Info.ProcessFrameRate);
#else
MosPrintf(MIL_TEXT("."));
#endif
if(IsEqual(Info.BaseFrameRate, Info.ProcessFrameRate))
{
Info.EqualityCounter++;
if(Info.DelayTickVal == 0)
{
Info.DelayInSeconds = 0.0;
Info.Error = true;
Done = true;
}
else if(Info.EqualityCounter == 3)
{
Done = true;
Info.DelayInSeconds -= (Info.DelayInSeconds * 15.0 / 100.0);
if(Info.DelayInSeconds <= 0.0)
Info.DelayInSeconds = 0.0;
Info.DelayTickVal = (MIL_UINT32)(Info.DelayInSeconds * Info.TickFreq);
MdigControl(MilDigitizer, M_GC_INTER_PACKET_DELAY, Info.DelayTickVal);
}
else
{
Info.DelayInSeconds -= (Info.DelayInSeconds / 50.0);
Info.DelayTickVal = (MIL_UINT32)(Info.DelayInSeconds * Info.TickFreq);
}
}
else
{
Info.EqualityCounter = 0;
Info.DelayInSeconds -= (Info.DelayInSeconds / 10.0);
Info.DelayTickVal = (MIL_UINT32)(Info.DelayInSeconds * Info.TickFreq);
if(Info.DelayTickVal == 0)
{
Info.DelayInSeconds = 0.0;
Info.Error = true;
Done = true;
}
else if(Info.DelayInSeconds <= 0.0)
{
Info.DelayInSeconds = 0.0;
Done = true;
}
}
MosSleep(500);
}
if(Info.Error == false)
{
Results.InterPacketDelayInTicks[Results.Selection] = Info.DelayTickVal;
Results.InterPacketDelayInSec[Results.Selection] = Info.DelayInSeconds;
Results.ObtainedFrameRate[Results.Selection] = Info.ProcessFrameRate;
}
}
void PrintResults(MIL_ID MilDigitizer, PacketDelayInfo& Info, PacketDelayResults& Results)
{
MIL_TEXT_PTR lpModel, lpVendor;
MIL_INT lModelStringLength, lVendorStringLength;
MIL_INT PacketSize = 0;
MIL_TEXT_CHAR PixelFormat[255] = {'\0'};
memset(PixelFormat, 0, sizeof(MIL_TEXT_CHAR)*255);
MdigInquire(MilDigitizer, M_CAMERA_VENDOR_SIZE, &lVendorStringLength);
MdigInquire(MilDigitizer, M_CAMERA_MODEL_SIZE, &lModelStringLength);
lpVendor = new MIL_TEXT_CHAR[lVendorStringLength+1];
lpModel = new MIL_TEXT_CHAR[lModelStringLength+1];
MdigInquire(MilDigitizer, M_CAMERA_VENDOR, lpVendor);
MdigInquire(MilDigitizer, M_CAMERA_MODEL, lpModel);
MdigInquire(MilDigitizer, M_GC_PACKET_SIZE, &PacketSize);
#if M_MIL_USE_WINDOWS
system("cls");
#endif
MosPrintf(MIL_TEXT("Inter-packet delay report summary for %s %s:\n\n"), lpVendor, lpModel);
MosPrintf(MIL_TEXT("Camera parameters:\n"));
MosPrintf(MIL_TEXT("Camera SizeX: %d\n"), MdigInquire(MilDigitizer, M_SIZE_X, M_NULL));
MosPrintf(MIL_TEXT("Camera SizeY: %d\n"), MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL));
MosPrintf(MIL_TEXT("Camera Packet size: %d\n\n"), PacketSize);
for(MIL_INT i=0; i<Results.PixelFormatCount; i++)
{
MosPrintf(MIL_TEXT("Camera Pixel format: %s\n"), Results.PixelFormats[i]);
MosPrintf(MIL_TEXT("Inter-packet delay of %d ticks (%.3f usec) calculated.\n"),
Results.InterPacketDelayInTicks[i], Results.InterPacketDelayInSec[i]*1e6);
MosPrintf(MIL_TEXT("Reference frame rate: %.1f\n"), Results.ReferenceFrameRate[i]);
MosPrintf(MIL_TEXT("Obtained frame rate: %.1f\n"), Results.ObtainedFrameRate[i]);
MosPrintf(MIL_TEXT("----------------------------------------------------------\n"));
}
MosPrintf(MIL_TEXT("\nPrinted inter-packet delay results are valid only for ")
MIL_TEXT("the above parameters\n"));
delete [] lpVendor;
delete [] lpModel;
}
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType,
MIL_ID HookId,
void* HookDataPtr)
{
MIL_ID ModifiedBufferId;
MdigGetHookInfo(HookId, M_MODIFIED_BUFFER+M_BUFFER_ID, &ModifiedBufferId);
return 0;
}
void GetMilBufferInfoFromPixelFormat(MIL_ID MilDigitizer, MIL_INT& SizeBand,
MIL_INT& BufType, MIL_INT64& Attribute)
{
MdigInquire(MilDigitizer, M_SIZE_BAND, &SizeBand);
MdigInquire(MilDigitizer, M_TYPE, &BufType);
MdigInquire(MilDigitizer, M_SOURCE_DATA_FORMAT, &Attribute);
}