_Inside OS/2 Software Motion Video_ by Les Wilson [LISTING ONE] RC CalcNewFrameIval ( PSIB psib, PMOVIE_STR pMovie ) { LONG AudioSynchError; LONG VideoTimeError; LONG lmsTimeError; BOOL fVideoTooSlow = FALSE; BOOL fVideoBehindAudio = FALSE; BOOL fSynchPulse = psib->syncEvcb.ulSyncFlags&(SYNCPOLLING+SYNCOVERRUN); ULONG CurrentTime; MMTIME mmtimeMaster = psib->syncEvcb.mmtimeMaster; // get current time DosQuerySysInfo (QSV_MS_COUNT,QSV_MS_COUNT,&CurrentTime,sizeof(ULONG)); // Update frame time pMovie->TimeNextFrame += pMovie->FrameInterval; //********************************************* // Determine if the video is ahead or behind // the frame rate specified for this stream. //********************************************* if (CurrentTime <= pMovie->TimeNextFrame) { //***************************************************** // Video is ahead according to system clock // Compute Video Error //***************************************************** VideoTimeError = (pMovie->TimeNextFrame - CurrentTime); fVideoTooSlow = FALSE; } else { //*************************************************** // Video is behind according to system clock // Compute Video Error //*************************************************** VideoTimeError = (CurrentTime - pMovie->TimeNextFrame); fVideoTooSlow = TRUE; } /* endif - who is ahead? */ //************************************* // Is SSM reporting "Out of Tolerance" // Check for a Synch Pulse //************************************* if (psib->fSyncFlag == SYNC_ENABLED) { if (fSynchPulse && mmtimeMaster) { pMovie->ulSynchPulseCount++; /* Accumulate count of sync pulses /***********************************************************/ /* Is SSM reporting Video Behind Audio? /***********************************************************/ if (mmtimeMaster > (psib->syncEvcb.mmtimeStart + psib->syncEvcb.mmtimeSlave)) { // Video is behind audio fVideoBehindAudio = TRUE; // Compute Audio error AudioSynchError = mmtimeMaster - (psib->syncEvcb.mmtimeStart + psib->syncEvcb.mmtimeSlave); // Is Video behind according to system clock? // if (fVideoTooSlow) { if ( AudioSynchError > VideoTimeError ) { // Set the next frame time behind the current time // so that the delta to the cur time = SSM Audio Error // This will cause the video to speed up pMovie->TimeNextFrame -= ( AudioSynchError - VideoTimeError ); } else { // Set the next frame time ahead of the current time // so that the delta to the cur time = SSM Audio Error // This will cause the video to slow down pMovie->TimeNextFrame += ( VideoTimeError - AudioSynchError ); } } else { // Video OK by System Clock but SSM reports otherwise // Set the next frame time behind the current time so // that the delta to the current time = SSM Audio Error // This will cause the video to speed up pMovie->TimeNextFrame -= (AudioSynchError + VideoTimeError); } /* endif */ } else { // SSM reports Video ahead of Audio fVideoBehindAudio = FALSE; AudioSynchError = (psib->syncEvcb.mmtimeStart + psib->syncEvcb.mmtimeSlave) - mmtimeMaster; // Is video behind according to system clock? if (fVideoTooSlow) { //********************************************************* // Video is behind according to system time, but video is // running ahead of the audio (the audio must have started // late or somehow broken up, fallen behind and can't get up //********************************************************* // Set the next frame time ahead of the current time // so that the delta to the cur time = SSM Audio Error // This will cause the video to slow down pMovie->TimeNextFrame += AudioSynchError + VideoTimeError; } else { // Video ahead according to system clock and SSM //********************************************************* // Video is keeping up or is ahead according to system time // AND video is running ahead of audio. //********************************************************* if ( AudioSynchError > VideoTimeError ) { // Video is further ahead than system clock indicated // Set the next frame time ahead of the current time // so that the delta to the cur time = SSM Audio Error // This will cause the video to slow down pMovie->TimeNextFrame += AudioSynchError- VideoTimeError; } else { // Video not as far ahead as system clock indicated // Set the next frame time behind the current time // so that the delta to the cur time = SSM Audio Error // This will cause the video to speed up pMovie->TimeNextFrame -= VideoTimeError- AudioSynchError; } } /* endif */ } /* endif */ psib->syncEvcb.ulSynchFlags = 0; //************************************************************* // Recompute video time error based on updated TimeNextFrame //************************************************************* if (CurrentTime <= pMovie->TimeNextFrame) { VideoTimeError = (pMovie->TimeNextFrame - CurrentTime); fVideoTooSlow = FALSE; } else { VideoTimeError = (CurrentTime - pMovie->TimeNextFrame); fVideoTooSlow = TRUE; } /* endif - time exceeded. */ } /* endif - SSM reporting "Out of Tolerance" */ } /* endif - Listening to SSM */ /*********************************** /* Take action based on whether the /* video is running ahead or behind /*********************************** if (!fVideoTooSlow) { lmsTimeError = VideoTimeError / 3; //Convert error to milliseconds if (lmsTimeError > 32L) { // Block till next time to display a frame DosSleep(lmsTimeError); pMovie->ulLastBlockTime = CurrentTime; } else { // Too close to next frame time for system clock to be used // Be good and yield to higher priority thread if one around DosSleep(0); pMovie->ulLastBlockTime = CurrentTime; } } else { /********************************/ /* Drop some frames if behind! */ /********************************/ : : } /* endif - video too slow */ // Update Frame Count pMovie->ulFrameNumber++; return (NO_ERROR); }