private void button1_Click(object sender, EventArgs e) { // get a handle to the DigHookUserData object in the managed heap, we will use this // handle to get the object back in the callback function GCHandle UserHookDataHandle = GCHandle.Alloc(UserHookData); MIL_DIG_HOOK_FUNCTION_PTR UserHookFunctionDelegate = new MIL_DIG_HOOK_FUNCTION_PTR(ArchiveFunction); // Acquire the sequence. The processing hook function will // be called for each image grabbed to archive and display it. // If sequence is not saved to disk, stop after NbFrames. MIL.MdigProcess(MilDigitizer, MilGrabImages, NbFrames, SAVE_SEQUENCE_TO_DISK ? MIL.M_START : MIL.M_SEQUENCE, MIL.M_DEFAULT, UserHookFunctionDelegate, GCHandle.ToIntPtr(UserHookDataHandle)); // Wait for a key press. //Console.WriteLine("Press <Enter> to continue."); //Console.WriteLine(); //Console.ReadKey(true); // Stop the sequence acquisition. MIL.MdigProcess(MilDigitizer, MilGrabImages, NbFrames, MIL.M_STOP, MIL.M_DEFAULT, UserHookFunctionDelegate, GCHandle.ToIntPtr(UserHookDataHandle)); // Free the GCHandle when no longer used UserHookDataHandle.Free(); // Read and print final statistics. MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_COUNT, ref FrameCount); MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_RATE, ref FrameRate); MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_MISSED, ref FrameMissed); //Console.WriteLine(); //Console.WriteLine(); //Console.WriteLine("{0} frames archived ({1} missed), at {2:0.0} frames/sec ({3:0.0}ms/frame).", UserHookData.NbArchivedFrames, FrameMissed, FrameRate, 1000.0 / FrameRate); // Sequence file closing if required. if (SAVE_SEQUENCE_TO_DISK) { MIL.MbufExportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, FrameRate, MIL.M_CLOSE); } // Free all allocated buffers. MIL.MbufFree(MilImageDisp); for (n = 0; n < NbFrames; n++) { MIL.MbufFree(MilGrabImages[n]); } if (MilCompressedImage != MIL.M_NULL) { MIL.MbufFree(MilCompressedImage); } // Free defaults. MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MIL.M_NULL); }
private void CameraGrabStart() { try { //이미지 버퍼 배열 선언 _ImageBuffer = new MIL_ID[BufferCount]; //배열 수만큼 돎 for (int i = 0; i < _ImageBuffer.Length; i++) { //400x400 크기의 모노 이미지 버퍼 선언 (원하는대로 변경 가능) MIL.MbufAllocColor(CurrentUseCamera.SystemID, 1, 400, 400, 8, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC, ref _ImageBuffer[i]); } //그랩 콜백 등록 _GrabCallbackFunc = OnGrab; //콜백 및 그랩 비동기 시작 MIL.MdigProcess(CurrentUseCamera.DigitizerID, _ImageBuffer, _ImageBuffer.Length, MIL.M_START, MIL.M_ASYNCHRONOUS + MIL.M_TRIGGER_FOR_FIRST_GRAB, _GrabCallbackFunc, IntPtr.Zero); } catch (Exception err) { MessageBox.Show(err.Message + "\n" + err.StackTrace); } }
// Main function. static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; MIL_ID MilSystem = MIL.M_NULL; MIL_ID MilDigitizer = MIL.M_NULL; MIL_ID MilDisplay = MIL.M_NULL; MIL_ID[] MilImage = new MIL_ID[2]; MIL_ID MilImageDisp = MIL.M_NULL; MIL_ID Default = MIL.M_DEFAULT; int NbProc = 0; int n = 0; double Time = 0.0; StringBuilder Text = new StringBuilder("0", STRING_LENGTH_MAX); UserDataObject userObject = new UserDataObject(); // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, ref MilDigitizer, ref MilImageDisp); // Allocate 2 grab buffers. for (n = 0; n < 2; n++) { MIL.MbufAlloc2d(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X, MIL.M_NULL), MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y, MIL.M_NULL), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC, ref MilImage[n]); } // Hook a function to the start of each frame to print the current frame index. userObject.NbGrabStart = 0; GCHandle userObjectHandle = GCHandle.Alloc(userObject); MIL_DIG_HOOK_FUNCTION_PTR grabStartDelegate = new MIL_DIG_HOOK_FUNCTION_PTR(GrabStart); MIL.MdigHookFunction(MilDigitizer, MIL.M_GRAB_START, grabStartDelegate, GCHandle.ToIntPtr(userObjectHandle)); // Print a message. Console.WriteLine(); Console.WriteLine("DOUBLE BUFFERING ACQUISITION AND PROCESSING:"); Console.WriteLine("--------------------------------------------"); Console.WriteLine(); Console.WriteLine("Press <Enter> to stop."); Console.WriteLine(); // Put the digitizer in asynchronous mode to be able to process while grabbing. MIL.MdigControl(MilDigitizer, MIL.M_GRAB_MODE, MIL.M_ASYNCHRONOUS); // Grab the first buffer. MIL.MdigGrab(MilDigitizer, MilImage[0]); // Process one buffer while grabbing the other. n = 0; do { // Grab the other buffer while processing the previous one. MIL.MdigGrab(MilDigitizer, MilImage[1 - n]); // Synchronize and start the timer. if (NbProc == 0) { MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); } // Write the frame counter. MIL.MgraText(Default, MilImage[n], 32, 32, string.Format("{0}", NbProc + 1)); // Process the first buffer already grabbed. MIL.MimArith(MilImage[n], MIL.M_NULL, MilImageDisp, MIL.M_NOT); // Count processed buffers. NbProc++; // Toggle grab buffers. n = 1 - n; } while (!Console.KeyAvailable); // Wait until the end of the last grab and stop the timer. MIL.MdigGrabWait(MilDigitizer, MIL.M_GRAB_END); MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref Time); Console.ReadKey(); // Print statistics. Console.WriteLine("{0} frames grabbed, at a frame rate of {1:0.00} frames/sec ({2:0.00} ms/frame).", NbProc, NbProc / Time, 1000.0 * Time / NbProc); Console.WriteLine("Press <Enter> to end."); Console.WriteLine(); Console.ReadKey(); // Unhook the function at the start of each frame. MIL.MdigHookFunction(MilDigitizer, MIL.M_GRAB_START + MIL.M_UNHOOK, grabStartDelegate, GCHandle.ToIntPtr(userObjectHandle)); // Free GCHandle to allow the garbage collector to reclaim the object. userObjectHandle.Free(); // Free allocations. for (n = 0; n < 2; n++) { MIL.MbufFree(MilImage[n]); } MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImageDisp); }
// Main function. // -------------- static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; MIL_ID MilRemoteApplication = MIL.M_NULL; // Remote Application identifier if running on a remote computer MIL_ID MilSystem = MIL.M_NULL; MIL_ID MilDigitizer = MIL.M_NULL; MIL_ID MilDisplay = MIL.M_NULL; MIL_ID MilImageDisp = MIL.M_NULL; MIL_ID[] MilGrabImages = new MIL_ID[NB_GRAB_IMAGE_MAX]; MIL_ID MilCompressedImage = MIL.M_NULL; ConsoleKeyInfo Selection = new ConsoleKeyInfo('1', ConsoleKey.D1, false, false, false); int NbFrames = 0; int n = 0; int NbFramesReplayed = 0; double FrameRate = 0; double TimeWait = 0; double TotalReplay = 0; double GrabScale = GRAB_SCALE; HookDataObject UserHookData = new HookDataObject(); MIL_INT LicenseModules = 0; MIL_INT FrameCount = 0; MIL_INT FrameMissed = 0; MIL_INT CompressAttribute = 0; // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, ref MilDigitizer, MIL.M_NULL); // Allocate an image and display it. MIL.MbufAllocColor(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_BAND, MIL.M_NULL), (MIL_INT)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X) * GrabScale), (MIL_INT)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y) * GrabScale), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_DISP, ref MilImageDisp); MIL.MbufClear(MilImageDisp, 0x0); MIL.MdispSelect(MilDisplay, MilImageDisp); // Grab continuously on display at the specified scale. MIL.MdigControl(MilDigitizer, MIL.M_GRAB_SCALE, GrabScale); MIL.MdigGrabContinuous(MilDigitizer, MilImageDisp); // Print a message Console.WriteLine(); Console.WriteLine("SEQUENCE ACQUISITION:"); Console.WriteLine("--------------------"); Console.WriteLine(); // Inquire MIL licenses. MIL.MsysInquire(MilSystem, MIL.M_OWNER_APPLICATION, ref MilRemoteApplication); MIL.MappInquire(MilRemoteApplication, MIL.M_LICENSE_MODULES, ref LicenseModules); // If sequence is saved to disk, select between grabbing an // uncompressed, JPEG or JPEG2000 sequence. if (SAVE_SEQUENCE_TO_DISK && ((LicenseModules & (MIL.M_LICENSE_JPEGSTD | MIL.M_LICENSE_JPEG2000)) != 0)) { Console.WriteLine("Choose the sequence format:"); Console.WriteLine("1) Uncompressed images."); if ((LicenseModules & MIL.M_LICENSE_JPEGSTD) != 0) { Console.WriteLine("2) Compressed images with a lossy JPEG algorithm."); } if ((LicenseModules & MIL.M_LICENSE_JPEG2000) != 0) { Console.WriteLine("3) Compressed images with a lossy JPEG 2000 algorithm."); } Selection = Console.ReadKey(); } else { Console.WriteLine("Press <Enter> to record images."); Console.ReadKey(); } // Set the buffer attribute. switch (Selection.Key) { case ConsoleKey.NumPad1: case ConsoleKey.D1: case ConsoleKey.Enter: Console.WriteLine(); Console.WriteLine("Recording uncompressed images..."); Console.WriteLine(); CompressAttribute = MIL.M_NULL; break; case ConsoleKey.NumPad2: case ConsoleKey.D2: Console.WriteLine(); Console.WriteLine("Recording JPEG images..."); Console.WriteLine(); CompressAttribute = MIL.M_COMPRESS + MIL.M_JPEG_LOSSY; break; case ConsoleKey.NumPad3: case ConsoleKey.D3: Console.WriteLine(); Console.WriteLine("Recording JPEG 2000 images..."); Console.WriteLine(); CompressAttribute = MIL.M_COMPRESS + MIL.M_JPEG2000_LOSSY; break; default: Console.WriteLine(); Console.WriteLine("Invalid selection !."); Console.WriteLine(); Console.WriteLine("Using uncompressed images."); Console.WriteLine(); CompressAttribute = MIL.M_NULL; while (Console.KeyAvailable) { Console.ReadKey(); } break; } // Allocate a compressed buffer if required. if (CompressAttribute != MIL.M_NULL) { MIL.MbufAllocColor(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_BAND, MIL.M_NULL), (int)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X, MIL.M_NULL) * GrabScale), (int)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y, MIL.M_NULL) * GrabScale), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + CompressAttribute, ref MilCompressedImage); MIL.MbufControl(MilCompressedImage, MIL.M_Q_FACTOR, COMPRESSION_Q_FACTOR); } // Allocate the grab buffers to hold the sequence buffering. MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_DISABLE); for (NbFrames = 0, n = 0; n < NB_GRAB_IMAGE_MAX; n++) { MIL.MbufAllocColor(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_BAND, MIL.M_NULL), (int)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X, MIL.M_NULL) * GrabScale), (int)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y, MIL.M_NULL) * GrabScale), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB, ref MilGrabImages[n]); if (MilGrabImages[n] != MIL.M_NULL) { NbFrames++; MIL.MbufClear(MilGrabImages[n], 0xFF); } else { break; } } MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_ENABLE); // Free buffers to leave some space for possible temporary buffers. for (n = 0; n < 2 && NbFrames > 0; n++) { NbFrames--; MIL.MbufFree(MilGrabImages[NbFrames]); } // Halt continuous grab. MIL.MdigHalt(MilDigitizer); // Open the AVI file if required. if (SAVE_SEQUENCE_TO_DISK) { Console.WriteLine("Saving the sequence to an AVI file..."); Console.WriteLine(); MIL.MbufExportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_OPEN); } // Initialize User's archiving function hook data structure. UserHookData.MilSystem = MilSystem; UserHookData.MilDisplay = MilDisplay; UserHookData.MilImageDisp = MilImageDisp; UserHookData.MilCompressedImage = MilCompressedImage; UserHookData.SaveSequenceToDisk = SAVE_SEQUENCE_TO_DISK; UserHookData.NbGrabbedFrames = 0; UserHookData.NbArchivedFrames = 0; // get a handle to the DigHookUserData object in the managed heap, we will use this // handle to get the object back in the callback function GCHandle UserHookDataHandle = GCHandle.Alloc(UserHookData); MIL_DIG_HOOK_FUNCTION_PTR UserHookFunctionDelegate = new MIL_DIG_HOOK_FUNCTION_PTR(ArchiveFunction); // Acquire the sequence. The processing hook function will // be called for each image grabbed to archive and display it. // If sequence is not saved to disk, stop after NbFrames. MIL.MdigProcess(MilDigitizer, MilGrabImages, NbFrames, SAVE_SEQUENCE_TO_DISK ? MIL.M_START : MIL.M_SEQUENCE, MIL.M_DEFAULT, UserHookFunctionDelegate, GCHandle.ToIntPtr(UserHookDataHandle)); // Wait for a key press. Console.WriteLine("Press <Enter> to continue."); Console.WriteLine(); Console.ReadKey(true); // Stop the sequence acquisition. MIL.MdigProcess(MilDigitizer, MilGrabImages, NbFrames, MIL.M_STOP, MIL.M_DEFAULT, UserHookFunctionDelegate, GCHandle.ToIntPtr(UserHookDataHandle)); // Free the GCHandle when no longer used UserHookDataHandle.Free(); // Read and print final statistics. MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_COUNT, ref FrameCount); MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_RATE, ref FrameRate); MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_MISSED, ref FrameMissed); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("{0} frames archived ({1} missed), at {2:0.0} frames/sec ({3:0.0}ms/frame).", UserHookData.NbArchivedFrames, FrameMissed, FrameRate, 1000.0 / FrameRate); // Sequence file closing if required. if (SAVE_SEQUENCE_TO_DISK) { MIL.MbufExportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, FrameRate, MIL.M_CLOSE); } // Playback the sequence until a key is pressed. if (UserHookData.NbArchivedFrames > 0) { do { // If sequence must be loaded. if (SAVE_SEQUENCE_TO_DISK) { // Inquire information about the sequence. Console.WriteLine(); Console.WriteLine("Playing back sequence from the AVI file..."); Console.WriteLine(); Console.WriteLine("Press <Enter> to end."); Console.WriteLine(); Console.WriteLine(); MIL.MbufDiskInquire(SEQUENCE_FILE, MIL.M_NUMBER_OF_IMAGES, ref FrameCount); MIL.MbufDiskInquire(SEQUENCE_FILE, MIL.M_FRAME_RATE, ref FrameRate); MIL.MbufDiskInquire(SEQUENCE_FILE, MIL.M_COMPRESSION_TYPE, ref CompressAttribute); // Open the sequence file. MIL.MbufImportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_OPEN); } // Copy the images to the screen respecting the sequence frame rate. TotalReplay = 0.0; NbFramesReplayed = 0; for (n = 0; n < FrameCount; n++) { // Reset the time. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET, MIL.M_NULL); // If image was saved to disk. if (SAVE_SEQUENCE_TO_DISK) { // Load image directly to the display. MIL.MbufImportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_LOAD, MIL.M_NULL, ref MilImageDisp, n, 1, MIL.M_READ); NbFramesReplayed++; Console.Write("Frame #{0} \r", NbFramesReplayed); } else { // Copy the grabbed image to the display. MIL.MbufCopy(MilGrabImages[n], MilImageDisp); NbFramesReplayed++; Console.Write("Frame #{0} \r", NbFramesReplayed); } // Check for a pressed key to exit. if (Console.KeyAvailable && (n >= (NB_GRAB_IMAGE_MAX - 1))) { Console.ReadKey(true); break; } // Wait to have a proper frame rate. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ, ref TimeWait); TotalReplay += TimeWait; TimeWait = (1 / FrameRate) - TimeWait; MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_WAIT, ref TimeWait); TotalReplay += (TimeWait > 0) ? TimeWait : 0.0; } // Close the sequence file. if (SAVE_SEQUENCE_TO_DISK) { MIL.MbufImportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_CLOSE); } // Print statistics. Console.WriteLine(); Console.WriteLine(); Console.WriteLine("{0} frames replayed, at a frame rate of {1:0.0} frames/sec ({2:0.0} ms/frame).", NbFramesReplayed, n / TotalReplay, 1000.0 * TotalReplay / n); Console.WriteLine(); Console.WriteLine("Press <Enter> to end (or any other key to playback again)."); Console.WriteLine(); }while (Console.ReadKey(true).Key != ConsoleKey.Enter); } // Free all allocated buffers. MIL.MbufFree(MilImageDisp); for (n = 0; n < NbFrames; n++) { MIL.MbufFree(MilGrabImages[n]); } if (MilCompressedImage != MIL.M_NULL) { MIL.MbufFree(MilCompressedImage); } // Free defaults. MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MIL.M_NULL); }
// Main function. // // ---------------// static int Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; MIL_ID MilRemoteApplication = MIL.M_NULL; MIL_ID MilSystem = MIL.M_NULL; MIL_ID MilDigitizer = MIL.M_NULL; MIL_ID MilDisplay = MIL.M_NULL; MIL_ID MilImageDisp = MIL.M_NULL; MIL_ID[] MilGrabBufferList = new MIL_ID[BUFFERING_SIZE_MAX]; MIL_ID MilCompressContext = MIL.M_NULL; MIL_ID MilDecompressContext = MIL.M_NULL; MIL_INT LicenseModules = 0; MIL_INT MilSystemLocation = MIL.M_NULL; MIL_INT MilGrabBufferListSize; MIL_INT ProcessFrameCount = 0; MIL_INT NbFrames = 0; MIL_INT n = 0; double EncodingDesiredFrameRate = 0.0; double ProcessFrameRate = 0.0; MIL_INT SeqProcessFilePathSize = 0; StringBuilder SeqProcessFilePath = null; ProcessingHookDataStruct ProcessingUserHookData = new ProcessingHookDataStruct(); EncodingFrameEndHookDataStruct EncodingFrameEndUserHookData = new EncodingFrameEndHookDataStruct(); DecodingFrameEndHookDataStruct DecodingFrameEndUserHookData = new DecodingFrameEndHookDataStruct(); MIL_INT SeqSystemType = MIL.M_NULL; // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, ref MilDigitizer, ref MilImageDisp); MIL.MsysInquire(MilSystem, MIL.M_OWNER_APPLICATION, ref MilRemoteApplication); MilSystemLocation = MIL.MsysInquire(MilSystem, MIL.M_LOCATION, MIL.M_NULL); if (MIL.MappInquire(MilRemoteApplication, MIL.M_PLATFORM_OS_TYPE, MIL.M_NULL) != MIL.M_OS_WINDOWS) { if (MilSystemLocation == MIL.M_REMOTE) { Console.WriteLine("The Distributed MIL server must run on a Windows system."); } else { Console.WriteLine("This example only works with a Windows system."); } Console.WriteLine("Press <Enter> to end."); Console.ReadKey(); MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImageDisp); return(0); } // Inquire MIL licenses. MIL.MappInquire(MilRemoteApplication, MIL.M_LICENSE_MODULES, ref LicenseModules); if ((LicenseModules & MIL.M_LICENSE_JPEGSTD) != MIL.M_LICENSE_JPEGSTD) { Console.WriteLine("Need a Compression/Decompression license to run this example."); Console.WriteLine("Press <Enter> to end."); Console.ReadKey(); MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImageDisp); return(0); } // Allocate the grab buffers and clear them. MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_DISABLE); for (MilGrabBufferListSize = 0; MilGrabBufferListSize < BUFFERING_SIZE_MAX; MilGrabBufferListSize++) { MIL.MbufAllocColor(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_BAND, MIL.M_NULL), MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X, MIL.M_NULL), MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y, MIL.M_NULL), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC, ref MilGrabBufferList[MilGrabBufferListSize]); if (MilGrabBufferList[MilGrabBufferListSize] != MIL.M_NULL) { MIL.MbufClear(MilGrabBufferList[MilGrabBufferListSize], 0xFF); } else { break; } } MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_ENABLE); // Free buffers to leave space for possible temporary buffers. for (n = 0; n < 2 && MilGrabBufferListSize > 0; n++) { MilGrabBufferListSize--; MIL.MbufFree(MilGrabBufferList[MilGrabBufferListSize]); } if (MilGrabBufferListSize == 0) { Console.WriteLine("!!! No grab buffers have been allocated. Need to set more Non-Paged Memory. !!!"); MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImageDisp); Console.WriteLine("Press <Enter> to end."); Console.ReadKey(); return(1); } /* Initialize the User's processing function data structure only for Display. */ ProcessingUserHookData.MilDigitizer = MilDigitizer; ProcessingUserHookData.MilSeqContext = MIL.M_NULL; ProcessingUserHookData.MilImageDisp = MilImageDisp; ProcessingUserHookData.ProcessedImageCount = 0; ProcessingUserHookData.ProcessingOperation = ProcessingHookOperation.DISPLAY; // get a handle to the HookDataStruct object in the managed heap, we will use this // handle to get the object back in the callback function GCHandle hUserData = GCHandle.Alloc(ProcessingUserHookData); // Start the sequence acquisition. The preprocessing and encoding hook function // is called for every frame grabbed. MIL_DIG_HOOK_FUNCTION_PTR ProcessingFunctionDelegate = new MIL_DIG_HOOK_FUNCTION_PTR(ProcessingFunction); /* Start a digProcess to show the live camera output. */ MIL.MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, MIL.M_START, MIL.M_DEFAULT, ProcessingFunctionDelegate, GCHandle.ToIntPtr(hUserData)); /* Print a message. */ Console.Write("\nH.264 IMAGE SEQUENCE COMPRESSION.\n"); Console.Write("---------------------------------\n\n"); Console.Write("Press <Enter> to start compression.\r"); Console.ReadKey(); /* Stop digProcess. */ MIL.MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, MIL.M_STOP, MIL.M_DEFAULT, ProcessingFunctionDelegate, GCHandle.ToIntPtr(hUserData)); /* Inquire the dig process frame rate */ MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_RATE, ref EncodingDesiredFrameRate); Console.Write("Grabbing frames at {0:0.00} frames/sec.\n", EncodingDesiredFrameRate); // Creates a context for the H.264 compression engine. Compression will be done // using hardware or software depending on the system hardware configuration. MIL.MseqAlloc(MilSystem, MIL.M_DEFAULT, MIL.M_SEQ_COMPRESS, MIL.M_DEFAULT, MIL.M_DEFAULT, ref MilCompressContext); // Specify the destination of the compressed file and the target container type. // The last argument specifies to generate an MP4 file. MIL.MseqDefine(MilCompressContext, MIL.M_SEQ_OUTPUT(0) + MIL.M_SEQ_DEST(0), MIL.M_FILE, (MilSystemLocation != MIL.M_REMOTE ? SEQUENCE_FILE : REMOTE_SEQUENCE_FILE), MIL.M_FILE_FORMAT_MP4); // Set the compression parameters. // Sets the compression parameters valid for any resolution under 1920X1080. // Any resolution higher than that will generate an warning that can be disabled using // MseqControl with M_SETTING_AUTO_ADJUSTMENT. See documentation for more details. MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_BIT_RATE_MODE, MIL.M_VARIABLE); // MIL.M_VARIABLE or MIL.M_CONSTANT MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_BIT_RATE, 5000); // 5 Mbps bit rate MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_BIT_RATE_MAX, 5000); // 5 Mbps bit rate MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_FRAME_RATE, EncodingDesiredFrameRate); // 60Hz frame rate. MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_FRAME_RATE_MODE, MIL.M_VARIABLE); // Attempts to update the file header with the encoding frame rate // if lower than the specified frame rate. MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_QUALITY, 100); // 1=best speed, 100=best quality MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_PROFILE, MIL.M_PROFILE_HIGH); // MIL.M_PROFILE_BASELINE, MIL.M_PROFILE_MAIN, MIL.M_PROFILE_HIGH MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_LEVEL, MIL.M_LEVEL_4_2); // MIL.M_LEVEL_1, MIL.M_LEVEL_1B, MIL.M_LEVEL_1_1, MIL.M_LEVEL_1_2, MIL.M_LEVEL_1_3, // MIL.M_LEVEL_2, MIL.M_LEVEL_2_1, MIL.M_LEVEL_2_2, // MIL.M_LEVEL_3, MIL.M_LEVEL_3_1, MIL.M_LEVEL_3_2, // MIL.M_LEVEL_4, MIL.M_LEVEL_4_1, MIL.M_LEVEL_4_2, // MIL.M_LEVEL_5, MIL.M_LEVEL_5_1 MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_GROUP_OF_PICTURE_SIZE, 30); // Interval between I-Frame // Initialize the optional encoding end function data structure. EncodingFrameEndUserHookData.EncodedImageCount = 0; // get a handle to the HookDataStruct object in the managed heap, we will use this // handle to get the object back in the callback function GCHandle EncodingFrameEndUserHookDataHandle = GCHandle.Alloc(EncodingFrameEndUserHookData); // Register the encoding end function to the sequence context. MIL_SEQ_HOOK_FUNCTION_PTR FrameEncodingEndFunctionDelegate = new MIL_SEQ_HOOK_FUNCTION_PTR(FrameEncodingEndFunction); MIL.MseqHookFunction(MilCompressContext, MIL.M_FRAME_END, FrameEncodingEndFunctionDelegate, GCHandle.ToIntPtr(EncodingFrameEndUserHookDataHandle)); // Provide a sample image to initialize the encoding engine accordingly. MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_BUFFER_SAMPLE, MilGrabBufferList[0]); // Start the encoding process, waits for buffer to be fed for encoding. MIL.MseqProcess(MilCompressContext, MIL.M_START, MIL.M_ASYNCHRONOUS); // Display the type of compression used. Console.Write("Live image capture and compression to file using "); MIL.MseqInquire(MilCompressContext, MIL.M_CONTEXT, MIL.M_CODEC_TYPE, ref SeqSystemType); if (SeqSystemType == MIL.M_HARDWARE + MIL.M_QSV) { Console.WriteLine("Hardware acceleration."); } else // MIL.M_SOFTWARE + MIL.M_QSV { Console.WriteLine("Software implementation."); } // Set the sequence context id in the user hook data structure to start // feeding buffers for encoding in ProcessingFunction. // ProcessingUserHookData.MilSeqContext = MilCompressContext; ProcessingUserHookData.ProcessedImageCount = 0; ProcessingUserHookData.ProcessingOperation = ProcessingHookOperation.ENCODE; MIL.MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, MIL.M_START, MIL.M_DEFAULT, ProcessingFunctionDelegate, GCHandle.ToIntPtr(hUserData)); // NOTE: Now the main() is free to perform other tasks while the compression is executing. // --------------------------------------------------------------------------------------- // Print a message and wait for a key press after a minimum number of frames. Console.WriteLine("Press <Enter> to stop.\n"); Console.ReadKey(); // Stop the processing. MIL.MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, MIL.M_STOP + MIL.M_WAIT, MIL.M_DEFAULT, ProcessingFunctionDelegate, GCHandle.ToIntPtr(hUserData)); // Free the processing user data handle. hUserData.Free(); // Stop the encoding process MIL.MseqProcess(MilCompressContext, MIL.M_STOP, MIL.M_WAIT); // Make sure the hook handler function delegate is not prematurely garbage collected since // only MIL has a reference to it. GC.KeepAlive(FrameEncodingEndFunctionDelegate); // Free the encoding user data handle. EncodingFrameEndUserHookDataHandle.Free(); // Print statistics. MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_COUNT, ref ProcessFrameCount); MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_RATE, ref ProcessFrameRate); Console.WriteLine("{0} frames encoded at {1:0.00} frames/sec ({2:0.0} ms/frame).", ProcessFrameCount, ProcessFrameRate, 1000.0 / ProcessFrameRate); Console.WriteLine(); MIL.MseqInquire(MilCompressContext, MIL.M_SEQ_OUTPUT(0) + MIL.M_SEQ_DEST(0), MIL.M_STREAM_FILE_NAME_SIZE, ref SeqProcessFilePathSize); SeqProcessFilePath = new StringBuilder((int)SeqProcessFilePathSize); MIL.MseqInquire(MilCompressContext, MIL.M_SEQ_OUTPUT(0) + MIL.M_SEQ_DEST(0), MIL.M_STREAM_FILE_NAME, SeqProcessFilePath); Console.WriteLine("The video sequence file was written to:"); Console.WriteLine("{0}.", SeqProcessFilePath.ToString()); Console.WriteLine(); Console.WriteLine("It can be played back using any compatible video player."); // Free the grab buffers and sequence context. while (MilGrabBufferListSize > 0) { MIL.MbufFree(MilGrabBufferList[--MilGrabBufferListSize]); MilGrabBufferList[MilGrabBufferListSize] = MIL.M_NULL; } MIL.MseqFree(MilCompressContext); // Wait for a key to start the replay. Console.WriteLine("Press <Enter> to replay encoded sequence."); Console.ReadKey(); MIL.MseqAlloc(MilSystem, MIL.M_DEFAULT, MIL.M_SEQ_DECOMPRESS, MIL.M_DEFAULT, MIL.M_DEFAULT, ref MilDecompressContext); // Specify the destination of the compressed file and the target container type. // The last argument specifies to generate an MP4 file. MIL.MseqDefine(MilDecompressContext, MIL.M_SEQ_INPUT(0), MIL.M_FILE, (MilSystemLocation != MIL.M_REMOTE ? SEQUENCE_FILE : REMOTE_SEQUENCE_FILE), MIL.M_FILE_FORMAT_MP4); double outputFrameRate = 0.0; MIL.MseqInquire(MilDecompressContext, MIL.M_SEQ_INPUT(0), MIL.M_STREAM_FRAME_RATE, ref outputFrameRate); Console.WriteLine(); Console.WriteLine("Replaying file at {0:0.00} frames/second.", outputFrameRate); // Initialize the optional decoding end function data structure. DecodingFrameEndUserHookData.DecodedImageCount = 0; DecodingFrameEndUserHookData.MilImageDisp = MilImageDisp; // get a handle to the HookDataStruct object in the managed heap, we will use this // handle to get the object back in the callback function GCHandle DecodingFrameEndUserHookDataHandle = GCHandle.Alloc(DecodingFrameEndUserHookData); // Register the decoding end function to the sequence context. MIL_SEQ_HOOK_FUNCTION_PTR FrameDecodingEndFunctionDelegate = new MIL_SEQ_HOOK_FUNCTION_PTR(FrameDecodingEndFunction); MIL.MseqHookFunction(MilDecompressContext, MIL.M_FRAME_END, FrameDecodingEndFunctionDelegate, GCHandle.ToIntPtr(DecodingFrameEndUserHookDataHandle)); // Start the decoding process, waits for buffer to be fed for encoding. MIL.MseqProcess(MilDecompressContext, MIL.M_START, MIL.M_ASYNCHRONOUS); // Print a message and wait for a key press after a minimum number of frames. Console.WriteLine("Press <Enter> to stop.\n"); Console.ReadKey(); // Stop the play back. MIL.MseqProcess(MilDecompressContext, MIL.M_STOP, MIL.M_NULL); // Make sure the hook handler function delegate is not prematurely garbage collected since // only MIL has a reference to it. GC.KeepAlive(FrameDecodingEndFunctionDelegate); // Free the decoding user data handle. DecodingFrameEndUserHookDataHandle.Free(); MIL.MseqFree(MilDecompressContext); // Wait for a key to end. Console.WriteLine("Press <Enter> to end."); Console.ReadKey(); // Release defaults. MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImageDisp); return(0); }
// Main function. static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; MIL_ID MilSystem = MIL.M_NULL; MIL_ID MilDigitizer = MIL.M_NULL; MIL_ID MilDisplay = MIL.M_NULL; MIL_ID MilImageDisp = MIL.M_NULL; MIL_ID[] MilGrabBufferList = new MIL_ID[BUFFERING_SIZE_MAX]; int MilGrabBufferListSize = 0; MIL_INT ProcessFrameCount = 0; double ProcessFrameRate = 0; HookDataStruct UserHookData = new HookDataStruct(); // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, ref MilDigitizer, ref MilImageDisp); // Allocate the grab buffers and clear them. MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_DISABLE); for (MilGrabBufferListSize = 0; MilGrabBufferListSize < BUFFERING_SIZE_MAX; MilGrabBufferListSize++) { MIL.MbufAlloc2d(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X, MIL.M_NULL), MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y, MIL.M_NULL), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC, ref MilGrabBufferList[MilGrabBufferListSize]); if (MilGrabBufferList[MilGrabBufferListSize] != MIL.M_NULL) { MIL.MbufClear(MilGrabBufferList[MilGrabBufferListSize], 0xFF); } else { break; } } MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_ENABLE); // Free buffers to leave space for possible temporary buffers. for (int n = 0; n < 2 && MilGrabBufferListSize > 0; n++) { MilGrabBufferListSize--; MIL.MbufFree(MilGrabBufferList[MilGrabBufferListSize]); } // Print a message. Console.WriteLine(); Console.WriteLine("MULTIPLE BUFFERED PROCESSING."); Console.WriteLine("-----------------------------"); Console.WriteLine(); Console.Write("Press <Enter> to start processing.\r"); // Grab continuously on the display and wait for a key press. MIL.MdigGrabContinuous(MilDigitizer, MilImageDisp); Console.ReadKey(); // Halt continuous grab. MIL.MdigHalt(MilDigitizer); // Initialize the user's processing function data structure. UserHookData.MilDigitizer = MilDigitizer; UserHookData.MilImageDisp = MilImageDisp; UserHookData.ProcessedImageCount = 0; // get a handle to the HookDataStruct object in the managed heap, we will use this // handle to get the object back in the callback function GCHandle hUserData = GCHandle.Alloc(UserHookData); MIL_DIG_HOOK_FUNCTION_PTR ProcessingFunctionPtr = new MIL_DIG_HOOK_FUNCTION_PTR(ProcessingFunction); // Start the processing. The processing function is called with every frame grabbed. MIL.MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, MIL.M_START, MIL.M_DEFAULT, ProcessingFunctionPtr, GCHandle.ToIntPtr(hUserData)); // Here 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. Console.WriteLine("Press <Enter> to stop. "); Console.WriteLine(); Console.ReadKey(); // Stop the processing. MIL.MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, MIL.M_STOP, MIL.M_DEFAULT, ProcessingFunctionPtr, GCHandle.ToIntPtr(hUserData)); // Free the GCHandle when no longer used hUserData.Free(); // Print statistics. MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_COUNT, ref ProcessFrameCount); MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_RATE, ref ProcessFrameRate); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("{0} frames grabbed at {1:0.0} frames/sec ({2:0.0} ms/frame).", ProcessFrameCount, ProcessFrameRate, 1000.0 / ProcessFrameRate); Console.WriteLine("Press <Enter> to end."); Console.WriteLine(); Console.ReadKey(); // Free the grab buffers. while (MilGrabBufferListSize > 0) { MIL.MbufFree(MilGrabBufferList[--MilGrabBufferListSize]); } // Release defaults. MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImageDisp); }