Click here to show toolbars of the Web Online Help System: show toolbars |
/******************************************************************************/ /* * File name: FdkOffsetGainMain.cpp * Location: See Matrox Example Launcher in the MIL Control Center * * * Synopsis: This example shows how to use a custom FPGA accelerated * processing function that performs an OffsetGain operation. * * Note: This example allocates the Offset and Gain buffers in separate * memory banks of the Radient. The Gain buffer is allocated in * processing SDRAM memory. The Offset buffer is allocated in * processing SRAM memory. This helps in improving memory efficiency * by spreading bandwidth across multiple memory banks. This example * requires the GainOffsetSxxCx.firmware configuration to work properly. * You can choose this configuration using MilConfig's ProcessingFPGA * section. */ /* Headers. */ #include <mil.h> #define BUFFERING_SIZE_MAX 22 /* User's processing function prototype. */ MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID HookId, void* HookDataPtr); /* User's processing function hook data structure. */ typedef struct { MIL_ID MilImageOffset; MIL_ID MilImageGain; MIL_ID MilImageDisp; MIL_INT DivisionFactor; MIL_INT ProcessedImageCount; } HookDataStruct; /* Master MIL functions declarations. */ void FPGAOffsetGain(MIL_ID SrcImageId, MIL_ID OffsetImageId, MIL_ID GainImageId, MIL_INT Src4, MIL_ID DstImageId); /* Main function. */ int MosMain(void) { MIL_ID MilApplication; MIL_ID MilSystem ; MIL_ID MilDisplay ; MIL_ID MilDigitizer ; MIL_ID MilGrabBufferList[BUFFERING_SIZE_MAX] = { 0 }; MIL_INT MilGrabBufferListSize; MIL_ID MilImageGain ; MIL_ID MilImageOffset; MIL_ID MilImageDisp ; MIL_INT SizeX, SizeY, BoardType, n, NbFrames = 0; MIL_INT ProcessFrameCount = 0; MIL_DOUBLE ProcessFrameRate = 0; HookDataStruct UserHookData; /* Allocate defaults. */ MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, &MilDigitizer, M_NULL); /* Check if the processing FPGA is present. */ MsysInquire(MilSystem, M_BOARD_TYPE, &BoardType); if(!(BoardType & M_PF)) { MosPrintf(MIL_TEXT("Error, this example needs a processing FPGA installed on your\n")); MosPrintf(MIL_TEXT("board to continue.\n")); MosPrintf(MIL_TEXT("Exiting example.\n")); MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, M_NULL); return 0; } /* Inquire digitizer acquisition size.*/ SizeX = MdigInquire(MilDigitizer, M_SIZE_X, M_NULL); SizeY = MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL); /* Allocate buffers and initialize them. For FPGA acceleration, all source buffers must be in FPGA accessible memory. */ MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE); for(MilGrabBufferListSize = 0; MilGrabBufferListSize<BUFFERING_SIZE_MAX; MilGrabBufferListSize++) { MbufAlloc2d(MilSystem, SizeX, SizeY, 8+M_UNSIGNED, M_IMAGE+M_GRAB+M_PROC+M_FPGA_ACCESSIBLE, &MilGrabBufferList[MilGrabBufferListSize]); if (MilGrabBufferList[MilGrabBufferListSize]) MbufClear(MilGrabBufferList[MilGrabBufferListSize], 0xFF); else break; } MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE); for (n=0; n<2 && NbFrames; n++) /* Free some buffers for possible temporary buffers. */ { MilGrabBufferListSize--; MbufFree(MilGrabBufferList[MilGrabBufferListSize]); } /* Allocate Gain and Offset buffers in separate memory banks. This will help throughput because bandwidth is now spread across multiple banks. M_FAST_MEMORY indicates the buffer will be in SRAM. In the event that the board does not have an SRAM memory bank you can simply remove the M_FAST_MEMORY attribute below. This will allow the example to run on boards without SRAM memory banks. */ MbufAlloc2d(MilSystem, SizeX, SizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC+M_FPGA_ACCESSIBLE, &MilImageGain); MbufClear(MilImageGain, 16); MbufAlloc2d(MilSystem, SizeX, SizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC+M_FPGA_ACCESSIBLE+M_FAST_MEMORY, &MilImageOffset); MbufClear(MilImageOffset, 2); /* Allocate a display buffer and initialize it. For FPGA acceleration, destination buffers can be in host FPGA accessible memory or in FPGA memory. */ MbufAlloc2d(MilSystem, SizeX, SizeY, 8+M_UNSIGNED, M_IMAGE+M_GRAB+M_DISP+M_HOST_MEMORY+M_FPGA_ACCESSIBLE, &MilImageDisp); MbufClear(MilImageDisp, 0); MdispSelect(MilDisplay, MilImageDisp); /* Start a continuous grab on the display. */ MdigGrabContinuous(MilDigitizer, MilImageDisp); MosPrintf(MIL_TEXT("This example demonstrates how to use the Mfpga API to program\n")); MosPrintf(MIL_TEXT("an OffsetGain primitive and do live processing.\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetchar(); /* Start the live processing. */ MdigHalt(MilDigitizer); /* Initialize the User's processing function data structure. */ UserHookData.MilImageDisp = MilImageDisp; UserHookData.MilImageOffset = MilImageOffset; UserHookData.MilImageGain = MilImageGain; UserHookData.DivisionFactor = 8; UserHookData.ProcessedImageCount = 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. */ /* --------------------------------------------------------------------------------- */ /* Print a message and wait for a key press after a minimum number of frames. */ MosPrintf(MIL_TEXT("Press <Enter> to stop.\n\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(); /* Free the MIL objects.*/ while(MilGrabBufferListSize > 0) MbufFree(MilGrabBufferList[--MilGrabBufferListSize]); MbufFree(MilImageGain); MbufFree(MilImageOffset); MbufFree(MilImageDisp); MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, M_NULL); return 0; } /* User's call back processing function called every time a grab buffer is modified. */ /* ----------------------------------------------------------------------------------*/ MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID HookId, void* HookDataPtr) { HookDataStruct *UserHookDataPtr = (HookDataStruct *)HookDataPtr; MIL_ID ModifiedBufferId; /* Retrieve the MIL_ID of the grabbed buffer. */ MdigGetHookInfo(HookId, M_MODIFIED_BUFFER+M_BUFFER_ID, &ModifiedBufferId); /* Perform the processing and update the display. */ FPGAOffsetGain(ModifiedBufferId, UserHookDataPtr->MilImageOffset, UserHookDataPtr->MilImageGain, 4, UserHookDataPtr->MilImageDisp); /* Print and draw the frame count. */ UserHookDataPtr->ProcessedImageCount++; MosPrintf(MIL_TEXT("Processing frame #%d.\r"), UserHookDataPtr->ProcessedImageCount); return 0; }