/*************************************************************************/ /* * File name: MDigHook.c * * Synopsis: This grab example shows how to use the digitizer hook functions. * It grabs a sequence of images using hooks and plays it back. It * also uses events to signal the end of each grab and to * annotate the buffer. */ #include #include #include /* Number of buffers in the sequence. */ #define NB_GRAB_MAX 20 /* Hook functions prototypes. */ long MFTYPE GrabStart(long, MIL_ID, void MPTYPE *); long MFTYPE GrabEnd(long, MIL_ID, void MPTYPE *); /* Hook data structure. */ typedef struct { MIL_ID *MilImage; MIL_ID MilDigitizer; MIL_ID GrabEndEvent; long NbGrabStart; long NbGrabEnd; long NbFrames; double Time; } UserDataStruct; /* Main function. */ void main(void) { MIL_ID MilApplication; MIL_ID MilSystem ; MIL_ID MilDigitizer ; MIL_ID MilDisplay ; MIL_ID MilImage[NB_GRAB_MAX]; MIL_ID MilImageDisp ; MIL_TEXT_CHAR FrameIndex[10]; UserDataStruct UserStruct; double TimeWait = 0.0; long NbFrames = 0; long n; /* Allocate defaults. */ MappAllocDefault(M_SETUP, &MilApplication, &MilSystem, &MilDisplay, &MilDigitizer, &MilImageDisp); /* Allocate and clear sequence and display images. */ MappControl(M_ERROR, M_PRINT_DISABLE); for (NbFrames=0; NbFrames to record the sequence using grab hook.\n\n"); getch(); MdigHalt(MilDigitizer); /* Hook functions to grab the sequence. */ MdigHookFunction(MilDigitizer, M_GRAB_START, GrabStart, (void *)(&UserStruct)); MdigHookFunction(MilDigitizer, M_GRAB_END, GrabEnd, (void *)(&UserStruct)); /* Put digitizer in asynchronous mode. */ MdigControl(MilDigitizer, M_GRAB_MODE, M_ASYNCHRONOUS); /* Start sequence with a grab in the first buffer. */ MdigGrab(MilDigitizer, MilImage[0]); /* At this point the CPU is free to do other tasks and the sequence will be * grabbed during this time. Here, the CPU will print and draw the * index of the buffer grabbed before copying it to display. */ while (UserStruct.NbGrabEnd < NbFrames) { long GrabEndIndex; /* Wait end of grab event */ MthrWait(UserStruct.GrabEndEvent, M_EVENT_WAIT, M_NULL); /* Print the current grab index. */ GrabEndIndex = UserStruct.NbGrabEnd-1; if (GrabEndIndex >= 0) { printf("\rBuffer #%ld grabbed. ",GrabEndIndex); MOs_ltoa(GrabEndIndex, FrameIndex, 10); MgraText(M_DEFAULT, MilImage[GrabEndIndex], 32, 32, FrameIndex); MbufCopy(MilImage[GrabEndIndex],MilImageDisp); } } /* Wait for end of last grab. */ MdigGrabWait(MilDigitizer, M_GRAB_END); /* Print statistics. */ printf("\n\n%ld frames grabbed, at a frame rate of %.2f frames/sec (%.2f ms/frame).\n", UserStruct.NbGrabStart, UserStruct.NbGrabStart/UserStruct.Time, 1000.0*UserStruct.Time/UserStruct.NbGrabStart); /* Play the sequence until is pressed. */ printf("Press to end the playback.\n"); while( !kbhit() ) { /* Play the sequence. */ for (n=0; nNbGrabStart++; /* Start the timer when needed. */ if(UserPtr->NbGrabStart == 0) MappTimer(M_TIMER_RESET, (double *)&UserPtr->Time); /* Queue a new grab or stop the timer at the end. */ if (UserPtr->NbGrabStart < UserPtr->NbFrames) MdigGrab(UserPtr->MilDigitizer, UserPtr->MilImage[(UserPtr->NbGrabStart < 0) ? 0 : UserPtr->NbGrabStart]); else MappTimer(M_TIMER_READ, (double *)&UserPtr->Time); return(0); } /* Grab end hook function: * - This function is used to signal to a waiting thread (here the main()) * that a grab is completed and that the data can be processed. * * Note: Time spend in the hook function should be minimal. External * thread waiting on an event should be used to do processing. */ long MFTYPE GrabEnd(long HookType, MIL_ID EventId, void MPTYPE *UserStructPtr) { UserDataStruct *UserPtr=(UserDataStruct*)UserStructPtr; /* Increment grab count. */ UserPtr->NbGrabEnd++; /* Signal the end of grab event to the main thread waiting. */ MthrControl(UserPtr->GrabEndEvent, M_EVENT_SET, M_SIGNALED); return(0); }