示例#1
0
uint32 VDDubPreviewClock::ReadClock() const {
	uint32 ticks;
	if (mpTimer)
		ticks = mpTimer->GetPreviewTime();
	else
		ticks = VDGetAccurateTick() - mBaseTime;

	return VDRoundToInt32((double)ticks * mTicksToFrames);
}
示例#2
0
void VDDubPreviewClock::Init(IVDDubPreviewTimer *timer, IVDAsyncBlitter *blitter, double frameRate, double frameMultiplicationFactor) {
	mpTimer = timer;
	mpBlitter = blitter;
	mBaseTime = VDGetAccurateTick();
	mTicksToFrames = frameRate / 1000.0 * frameMultiplicationFactor;

	sint32 resolution;
	if (frameRate > 100.0) {
		resolution = VDRoundToInt32(10000000.0 / frameRate);
	} else {
		resolution = VDRoundToInt32(10000000.0 / 4.0 / frameRate);

		if (resolution < 10000)
			resolution = 10000;
	}

	mFrameTimer.Init3(this, resolution, resolution, false);
}
示例#3
0
void VDLoopThrottle::BeginWait() {
	if (!mWaitDepth++) {	// transitioning active -> wait
		uint32 currentTime = VDGetAccurateTick();

		if (mbLastTimeValid) {
			sint32 delta = currentTime - mLastTime;

			// Time shouldn't ever go backwards, but clocks on Windows occasionally have
			// the habit of doing so due to time adjustments, broken RDTSC, etc.
			if (delta < 0)
				delta = 0;

			mActiveTimeWindowSum -= mActiveTimeWindow[mWindowIndex];
			mActiveTimeWindow[mWindowIndex] = delta;
			mActiveTimeWindowSum += delta;
		}

		mLastTime = currentTime;
		mbLastTimeValid = true;
	}
}
示例#4
0
void VDCallbackTimer::ThreadRun() {
	uint32 timerPeriod = mTimerPeriod;
	uint32 periodHi = timerPeriod / 10000;
	uint32 periodLo = timerPeriod % 10000;
	uint32 nextTimeHi = VDGetAccurateTick() + periodHi;
	uint32 nextTimeLo = periodLo;

	uint32 maxDelay = mTimerPeriod / 2000;

	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

	HANDLE hExit = msigExit.getHandle();

	if (!mbPrecise) {
		while(!mbExit) {
			DWORD res = ::WaitForSingleObject(hExit, periodHi);

			if (res != WAIT_TIMEOUT)
				break;

			mpCB->TimerCallback();
		}
	} else {
		while(!mbExit) {
			uint32 currentTime = VDGetAccurateTick();
			sint32 delta = nextTimeHi - currentTime;

			if (delta > 0) {
				// safety guard against the clock going nuts
				DWORD res;
				if ((uint32)delta > maxDelay)
					res = ::WaitForSingleObject(hExit, maxDelay);
				else
					res = ::WaitForSingleObject(hExit, nextTimeHi - currentTime);

				if (res != WAIT_TIMEOUT)
					break;
			}

			if ((uint32)abs(delta) > maxDelay) {
				nextTimeHi = currentTime + periodHi;
				nextTimeLo = periodLo;
			} else {
				nextTimeLo += periodLo;
				nextTimeHi += periodHi;
				if (nextTimeLo >= 10000) {
					nextTimeLo -= 10000;
					++nextTimeHi;
				}
			}

			mpCB->TimerCallback();

			int adjust = mTimerPeriodAdjustment.xchg(0);
			int perdelta = mTimerPeriodDelta;

			if (adjust || perdelta) {
				timerPeriod += adjust;
				periodHi = (timerPeriod+perdelta) / 10000;
				periodLo = (timerPeriod+perdelta) % 10000;
			}
		}
	}
}