Click here to show toolbars of the Web Online Help System: show toolbars |
//*************************************************************************************** // // File name: MappTrace.cs // Location: See Matrox Example Launcher in the MIL Control Center // // // Synopsis: This example shows how to explicitly control and generate a trace for // MIL functions and how to visualize it using the Matrox Profiler utility. // To generate a trace, you must open Matrox Profiler (accessible from the // MIL Control Center) and select 'Generate New Trace' from the 'File' menu // before to run your MIL application. // // Note: By default, all MIL applications are traceable without code modifications. // You can try this using Matrox Profiler with any MIL example (Ex: MappStart). // // Copyright (C) Matrox Electronic Systems Ltd., 1992-2016. // All Rights Reserved // using System; using System.Runtime.InteropServices; using Matrox.MatroxImagingLibrary; namespace MappTrace { class HookDataStruct { public MIL_ID MilImageDisp; public MIL_ID MilImageTemp1; public MIL_ID MilImageTemp2; public MIL_INT ProcessedImageCount; public MIL_ID DoneEvent; } class MappTrace { // Trace related constants private const int TRACE_TAG_HOOK_START = 1; private const int TRACE_TAG_PROCESSING = 2; private const int TRACE_TAG_PREPROCESSING = 3; // General constants. private static readonly int COLOR_BROWN = MIL.M_RGB888(100, 65, 50); private const int BUFFERING_SIZE_MAX = 3; private const int NUMBER_OF_FRAMES_TO_PROCESS = 10; static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; MIL_ID MilSystem = MIL.M_NULL; MIL_ID MilDisplay = MIL.M_NULL; MIL_ID MilDigitizer = MIL.M_NULL; MIL_ID[] MilGrabBuf = new MIL_ID[BUFFERING_SIZE_MAX]; MIL_ID MilDummyBuffer = MIL.M_NULL; MIL_INT TracesActivated = MIL.M_NO; MIL_INT NbGrabBuf = 0; MIL_INT SizeX = 0, SizeY = 0; HookDataStruct UserHookData = new HookDataStruct(); Console.Write("\nMIL PROGRAM TRACING AND PROFILING:\n"); Console.Write("----------------------------------\n\n"); Console.Write("This example shows how to generate a trace for the execution\n"); Console.Write("of the MIL functions, and to visualize it using\n"); Console.Write("the Matrox Profiler utility.\n\n"); Console.Write("ACTION REQUIRED:\n\n"); Console.Write("Open 'Matrox Profiler' from the 'MIL Control Center' and\n"); Console.Write("select 'Generate New Trace' from the 'File' menu.\n\n"); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); //************** Untraceable code section *************** // The following code will not be visible in the trace. // MIL application allocation. // At MIL Application allocation time, M_TRACE_LOG_DISABLE can be used to ensures that // an application will not be traceable regardless of Matrox Profiler or MilConfig requests // unless traces are explicitly enabled in the program using an MappControl command. // MIL.MappAlloc("M_DEFAULT", MIL.M_TRACE_LOG_DISABLE, ref MilApplication); // Dummy MIL calls that will be invisible in the trace. MIL.MsysAlloc(MIL.M_DEFAULT, MIL.M_SYSTEM_HOST, MIL.M_DEFAULT, MIL.M_DEFAULT, ref MilSystem); MIL.MbufAllocColor(MilSystem, 3, 128, 128, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE, ref MilDummyBuffer); MIL.MbufClear(MilDummyBuffer, 0L); MIL.MbufFree(MilDummyBuffer); MIL.MsysFree(MilSystem); //******************************************************* // Explicitly allow trace logging after a certain point if Matrox Profiler has // requested a trace. Note that M_TRACE = M_ENABLE can be used to force the log // of a trace even if Profiler is not opened; M_TRACE = M_DISABLE can prevent // logging of code section. // MIL.MappControl(MIL.M_DEFAULT, MIL.M_TRACE, MIL.M_DEFAULT); // Inquire if the traces are active (i.e. Profiler is open and waiting for a trace). MIL.MappInquire(MIL.M_DEFAULT, MIL.M_TRACE_ACTIVE, ref TracesActivated); if (TracesActivated == MIL.M_YES) { // Create custom trace markers: setting custom names and colors. // Initialize a custom Tag for the grab callback function with a unique color (blue). MIL.MappTrace(MIL.M_DEFAULT, MIL.M_TRACE_SET_TAG_INFORMATION, TRACE_TAG_HOOK_START, MIL.M_COLOR_BLUE, "Grab Callback Marker"); // Initialize the custom Tag for the processing section. MIL.MappTrace(MIL.M_DEFAULT, MIL.M_TRACE_SET_TAG_INFORMATION, TRACE_TAG_PROCESSING, MIL.M_DEFAULT, "Processing Section"); // Initialize the custom Tag for the preprocessing with a unique color (brown). MIL.MappTrace(MIL.M_DEFAULT, MIL.M_TRACE_SET_TAG_INFORMATION, TRACE_TAG_PREPROCESSING, COLOR_BROWN, "Preprocessing Marker"); } // Allocate MIL objects. MIL.MsysAlloc(MIL.M_DEFAULT, MIL.M_SYSTEM_HOST, MIL.M_DEFAULT, MIL.M_DEFAULT, ref MilSystem); MIL.MdigAlloc(MilSystem, MIL.M_DEFAULT, "M_DEFAULT", MIL.M_DEFAULT, ref MilDigitizer); MIL.MdispAlloc(MilSystem, MIL.M_DEFAULT, "M_DEFAULT", MIL.M_DEFAULT, ref MilDisplay); SizeX = MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X, MIL.M_NULL); SizeY = MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y, MIL.M_NULL); MIL.MbufAllocColor(MilSystem, 3, SizeX, SizeY, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP, ref UserHookData.MilImageDisp); MIL.MdispSelect(MilDisplay, UserHookData.MilImageDisp); // Allocate the processing temporary buffers. MIL.MbufAlloc2d(MilSystem, SizeX, SizeY, 8 + MIL.M_UNSIGNED, MIL.M_PROC + MIL.M_IMAGE, ref UserHookData.MilImageTemp1); MIL.MbufAlloc2d(MilSystem, SizeX, SizeY, 8 + MIL.M_UNSIGNED, MIL.M_PROC + MIL.M_IMAGE, ref UserHookData.MilImageTemp2); // Allocate the grab buffers. for (NbGrabBuf = 0; NbGrabBuf < BUFFERING_SIZE_MAX; NbGrabBuf++) { MIL.MbufAllocColor(MilSystem, 3, SizeX, SizeY, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC, ref MilGrabBuf[NbGrabBuf]); } // Initialize the user's processing function data structure. UserHookData.ProcessedImageCount = 0; MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_NOT_SIGNALED + MIL.M_AUTO_RESET, MIL.M_NULL, MIL.M_NULL, ref UserHookData.DoneEvent); GCHandle UserHookDataPtr = GCHandle.Alloc(UserHookData); MIL_DIG_HOOK_FUNCTION_PTR HookFunctionPtr = new MIL_DIG_HOOK_FUNCTION_PTR(HookFunction); // Start the processing. The processing function is called with every frame grabbed. MIL.MdigProcess(MilDigitizer, MilGrabBuf, BUFFERING_SIZE_MAX, MIL.M_START, MIL.M_DEFAULT, HookFunctionPtr, GCHandle.ToIntPtr(UserHookDataPtr)); // Stop the processing when the event is triggered. MIL.MthrWait(UserHookData.DoneEvent, MIL.M_EVENT_WAIT + MIL.M_EVENT_TIMEOUT(2000), MIL.M_NULL); // Stop the processing. MIL.MdigProcess(MilDigitizer, MilGrabBuf, BUFFERING_SIZE_MAX, MIL.M_STOP, MIL.M_DEFAULT, HookFunctionPtr, GCHandle.ToIntPtr(UserHookDataPtr)); UserHookDataPtr.Free(); // Free the grab and temporary buffers. for (NbGrabBuf = 0; NbGrabBuf < BUFFERING_SIZE_MAX; NbGrabBuf++) MIL.MbufFree(MilGrabBuf[NbGrabBuf]); MIL.MbufFree(UserHookData.MilImageTemp1); MIL.MbufFree(UserHookData.MilImageTemp2); // Free defaults. MIL.MthrFree(UserHookData.DoneEvent); MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, UserHookData.MilImageDisp); Console.Write("A dummy processing has been executed to generate "); Console.Write("operations in the trace.\n\n"); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // If Matrox Profiler activated the traces, the trace file is now ready. if (TracesActivated == MIL.M_YES) { Console.Write("A PROCESSING SEQUENCE WAS EXECUTED AND LOGGED A NEW TRACE:\n\n"); Console.Write("The trace can now be loaded in Matrox Profiler by selecting the\n"); Console.Write("corresponding file listed in the 'Trace Generation' dialog.\n\n"); Console.Write("Once loaded, Matrox Profiler's main window displays the 'Main'\n"); Console.Write("and the 'MdigProcess' threads of the application.\n\n"); Console.Write("- This main window can now be used to select a section\n"); Console.Write(" of a thread and to zoom or pan in it.\n\n"); Console.Write("- The right pane shows detailed statistics as well as a\n"); Console.Write(" 'Quick Access' list displaying all MIL function calls.\n\n"); Console.Write("- The 'User Markers' tab lists the markers and sections logged\n"); Console.Write(" during the execution. For example, selecting 'Tag:Processing'\n"); Console.Write(" allows double-clicking to refocus the display on the related\n"); Console.Write(" calls.\n\n"); Console.Write("- By clicking a particular MIL function call, either in the\n"); Console.Write(" 'main view' or in the 'Quick Access', additional details\n"); Console.Write(" are displayed, such as its parameters and execution time.\n\n"); } else { Console.Write("ERROR: No active tracing detected in MIL Profiler!\n\n"); } Console.Write("Press <Enter> to end."); Console.ReadKey(); } static MIL_INT HookFunction(MIL_INT HookType, MIL_ID HookId, IntPtr HookDataPtr) { MIL_ID CurrentImage = MIL.M_NULL; if (HookDataPtr != IntPtr.Zero) { HookDataStruct UserDataPtr = GCHandle.FromIntPtr(HookDataPtr).Target as HookDataStruct; // Add a marker to indicate the reception of a new grabbed image. MIL.MappTrace(MIL.M_DEFAULT, MIL.M_TRACE_MARKER, TRACE_TAG_HOOK_START, MIL.M_NULL, "New Image grabbed"); // Retrieve the MIL_ID of the grabbed buffer. MIL.MdigGetHookInfo(HookId, MIL.M_MODIFIED_BUFFER + MIL.M_BUFFER_ID, ref CurrentImage); // Start a Section to highlight the processing calls on the image. MIL.MappTrace(MIL.M_DEFAULT, MIL.M_TRACE_SECTION_START, TRACE_TAG_PROCESSING, UserDataPtr.ProcessedImageCount, "Processing Image"); // Add a Marker to indicate the start of the preprocessing section. MIL.MappTrace(MIL.M_DEFAULT, MIL.M_TRACE_MARKER, TRACE_TAG_PREPROCESSING, UserDataPtr.ProcessedImageCount, "Start Preprocessing"); // Do the preprocessing. MIL.MimConvert(CurrentImage, UserDataPtr.MilImageTemp1, MIL.M_RGB_TO_L); MIL.MimHistogramEqualize(UserDataPtr.MilImageTemp1, UserDataPtr.MilImageTemp1, MIL.M_UNIFORM, MIL.M_NULL, 55, 200); // Add a Marker to indicate the end of the preprocessing section. MIL.MappTrace(MIL.M_DEFAULT, MIL.M_TRACE_MARKER, TRACE_TAG_PREPROCESSING, UserDataPtr.ProcessedImageCount, "End Preprocessing"); // Do the main processing. MIL.MimBinarize(UserDataPtr.MilImageTemp1, UserDataPtr.MilImageTemp2, MIL.M_IN_RANGE, 120, 140); MIL.MimBinarize(UserDataPtr.MilImageTemp1, UserDataPtr.MilImageTemp1, MIL.M_IN_RANGE, 220, 255); MIL.MimArith(UserDataPtr.MilImageTemp1, UserDataPtr.MilImageTemp2, UserDataPtr.MilImageDisp, MIL.M_OR); // End the Section that highlights the processing. MIL.MappTrace(MIL.M_DEFAULT, MIL.M_TRACE_SECTION_END, TRACE_TAG_PROCESSING, UserDataPtr.ProcessedImageCount, "Processing Image End"); // Signal that we have done enough processing. if (++(UserDataPtr.ProcessedImageCount) >= NUMBER_OF_FRAMES_TO_PROCESS) MIL.MthrControl(UserDataPtr.DoneEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED); } return 0; } } }