Merge pull request #4875 from koying/fixdroidremotekeyboard
[vuplus_xbmc] / xbmc / cores / VideoRenderers / RenderManager.cpp
index 6c8eef5..212ed27 100644 (file)
@@ -30,6 +30,7 @@
 #include "threads/SingleLock.h"
 #include "utils/log.h"
 #include "utils/TimeUtils.h"
+#include "utils/StringUtils.h"
 
 #include "Application.h"
 #include "ApplicationMessenger.h"
@@ -166,14 +167,6 @@ void CXBMCRenderManager::WaitPresentTime(double presenttime)
     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;
@@ -203,20 +196,11 @@ void CXBMCRenderManager::WaitPresentTime(double presenttime)
   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);
 }
@@ -228,11 +212,10 @@ CStdString CXBMCRenderManager::GetVSyncState()
     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;
 }
 
@@ -275,7 +258,9 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi
     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 */
@@ -393,6 +378,8 @@ void CXBMCRenderManager::FrameFinish()
   if(g_graphicsContext.IsFullScreenVideo())
     WaitPresentTime(m.timestamp);
 
+  m_clock_framefinish = GetPresentTime();
+
   { CSingleLock lock(m_presentlock);
 
     if(m_presentstep == PRESENT_FRAME)
@@ -781,7 +768,6 @@ void CXBMCRenderManager::Render(bool clear, DWORD flags, DWORD alpha)
   else
     PresentSingle(clear, flags, alpha);
 
-  g_graphicsContext.SetRenderingResolution(g_graphicsContext.GetVideoResolution(), false);
   m_overlays.Render(m_presentsource);
 }
 
@@ -1045,6 +1031,12 @@ void CXBMCRenderManager::PrepareNextRender()
 
   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;
@@ -1053,8 +1045,8 @@ void CXBMCRenderManager::PrepareNextRender()
   ++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;