#include "threads/SingleLock.h"
#include "utils/log.h"
#include "utils/TimeUtils.h"
+#include "utils/StringUtils.h"
#include "Application.h"
#include "ApplicationMessenger.h"
return;
}
- bool ismaster = CDVDClock::IsMasterClock();
-
- //the videoreferenceclock updates its clock on every vertical blank
- //we want every frame's presenttime to end up in the middle of two vblanks
- //if CDVDPlayerAudio is the master clock, we add a correction to the presenttime
- if (ismaster)
- presenttime += m_presentcorr * frametime;
-
double clock = CDVDClock::WaitAbsoluteClock(presenttime * DVD_TIME_BASE) / DVD_TIME_BASE;
double target = 0.5;
double error = ( clock - presenttime ) / frametime - target;
avgerror /= ERRORBUFFSIZE;
- //if CDVDPlayerAudio is not the master clock, we change the clock speed slightly
+ //we change the clock speed slightly
//to make every frame's presenttime end up in the middle of two vblanks
- if (!ismaster)
- {
- //integral correction, clamp to -0.5:0.5 range
- m_presentcorr = std::max(std::min(m_presentcorr + avgerror * 0.01, 0.1), -0.1);
- g_VideoReferenceClock.SetFineAdjust(1.0 - avgerror * 0.01 - m_presentcorr * 0.01);
- }
- else
- {
- //integral correction, wrap to -0.5:0.5 range
- m_presentcorr = wrap(m_presentcorr + avgerror * 0.01, target - 1.0, target);
- g_VideoReferenceClock.SetFineAdjust(1.0);
- }
+ //integral correction, clamp to -0.5:0.5 range
+ m_presentcorr = std::max(std::min(m_presentcorr + avgerror * 0.01, 0.1), -0.1);
+ g_VideoReferenceClock.SetFineAdjust(1.0 - avgerror * 0.01 - m_presentcorr * 0.01);
//printf("%f %f % 2.0f%% % f % f\n", presenttime, clock, m_presentcorr * 100, error, error_org);
}
avgerror += m_errorbuff[i];
avgerror /= ERRORBUFFSIZE;
- CStdString state;
- state.Format("sync:%+3d%% avg:%3d%% error:%2d%%"
- , MathUtils::round_int(m_presentcorr * 100)
- , MathUtils::round_int(avgerror * 100)
- , abs(MathUtils::round_int(m_presenterr * 100)));
+ CStdString state = StringUtils::Format("sync:%+3d%% avg:%3d%% error:%2d%%"
+ , MathUtils::round_int(m_presentcorr * 100)
+ , MathUtils::round_int(avgerror * 100)
+ , abs(MathUtils::round_int(m_presenterr * 100)));
return state;
}
m_format = format;
int processor = m_pRenderer->GetProcessorSize();
- if(processor)
+ if(processor > buffers) /* DXVA-HD returns processor size 6 */
+ m_QueueSize = 3; /* we need queue size of 3 to get future frames in the processor */
+ else if(processor)
m_QueueSize = buffers - processor + 1; /* respect maximum refs */
else
m_QueueSize = m_pRenderer->GetMaxBufferSize(); /* no refs to data */
if(g_graphicsContext.IsFullScreenVideo())
WaitPresentTime(m.timestamp);
+ m_clock_framefinish = GetPresentTime();
+
{ CSingleLock lock(m_presentlock);
if(m_presentstep == PRESENT_FRAME)
else
PresentSingle(clear, flags, alpha);
- g_graphicsContext.SetRenderingResolution(g_graphicsContext.GetVideoResolution(), false);
m_overlays.Render(m_presentsource);
}
double clocktime = GetPresentTime();
double frametime = 1.0 / GetMaximumFPS();
+ double correction = 0.0;
+ int fps = g_VideoReferenceClock.GetRefreshRate();
+ if((fps > 0) && g_graphicsContext.IsFullScreenVideo() && (clocktime != m_clock_framefinish))
+ {
+ correction = frametime;
+ }
/* see if any future queued frames are already due */
std::deque<int>::reverse_iterator curr, prev;
++prev;
while (prev != m_queued.rend())
{
- if(clocktime > m_Queue[*prev].timestamp /* previous frame is late */
- && clocktime > m_Queue[*curr].timestamp - frametime) /* selected frame is close to it's display time */
+ if(clocktime > m_Queue[*prev].timestamp + correction /* previous frame is late */
+ && clocktime > m_Queue[*curr].timestamp - frametime + correction) /* selected frame is close to it's display time */
break;
++curr;
++prev;