aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartijn Kaijser <martijn@xbmc.org>2016-12-30 11:50:59 +0100
committerGitHub <noreply@github.com>2016-12-30 11:50:59 +0100
commit1296ce347c2d1d2eda9c86d4d0903c88e264f2c4 (patch)
tree3f7d39553598538265eece67b19267cd734a7cd0
parent99334797e6786ca543a4c7333922cfc91fbcecab (diff)
parent58374f4e49c544fcc45f94b2577eb38485a0d0ea (diff)
Merge pull request #11304 from MartijnKaijser/11301
VideoPlayer + win32: fix video stuttering
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp12
-rw-r--r--xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp16
-rw-r--r--xbmc/cores/VideoPlayer/Process/ProcessInfo.h5
-rw-r--r--xbmc/cores/VideoPlayer/VideoPlayer.cpp5
-rw-r--r--xbmc/cores/VideoPlayer/VideoPlayer.h1
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.cpp13
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.h4
-rw-r--r--xbmc/rendering/dx/RenderSystemDX.cpp24
-rw-r--r--xbmc/rendering/dx/RenderSystemDX.h7
9 files changed, 82 insertions, 5 deletions
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp
index c32e58b433..4ea37ac7c9 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp
@@ -981,6 +981,18 @@ bool CDecoder::GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture
picture->dxva = m_presentPicture;
picture->format = RENDER_FMT_DXVA;
picture->extended_format = (unsigned int)m_format.OutputFormat;
+
+ int queued, discard, free;
+ m_processInfo.GetRenderBuffers(queued, discard, free);
+ if (free > 1)
+ {
+ g_Windowing.RequestDecodingTime();
+ }
+ else
+ {
+ g_Windowing.ReleaseDecodingTime();
+ }
+
return true;
}
diff --git a/xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp b/xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp
index ea1c5caa51..971b590c29 100644
--- a/xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp
+++ b/xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp
@@ -349,6 +349,22 @@ void CProcessInfo::UpdateRenderInfo(CRenderInfo &info)
}
}
+void CProcessInfo::UpdateRenderBuffers(int queued, int discard, int free)
+{
+ CSingleLock lock(m_renderSection);
+ m_renderBufQueued = queued;
+ m_renderBufDiscard = discard;
+ m_renderBufFree = free;
+}
+
+void CProcessInfo::GetRenderBuffers(int &queued, int &discard, int &free)
+{
+ CSingleLock lock(m_renderSection);
+ queued = m_renderBufQueued;
+ discard = m_renderBufDiscard;
+ free = m_renderBufFree;
+}
+
// player states
void CProcessInfo::SetStateSeeking(bool active)
{
diff --git a/xbmc/cores/VideoPlayer/Process/ProcessInfo.h b/xbmc/cores/VideoPlayer/Process/ProcessInfo.h
index f91765ca73..14267c4de0 100644
--- a/xbmc/cores/VideoPlayer/Process/ProcessInfo.h
+++ b/xbmc/cores/VideoPlayer/Process/ProcessInfo.h
@@ -69,6 +69,8 @@ public:
void SetRenderClockSync(bool enabled);
bool IsRenderClockSync();
void UpdateRenderInfo(CRenderInfo &info);
+ void UpdateRenderBuffers(int queued, int discard, int free);
+ void GetRenderBuffers(int &queued, int &discard, int &free);
// player states
void SetStateSeeking(bool active);
@@ -101,6 +103,9 @@ protected:
CCriticalSection m_renderSection;
bool m_isClockSync;
CRenderInfo m_renderInfo;
+ int m_renderBufQueued = 0;
+ int m_renderBufFree = 0;
+ int m_renderBufDiscard = 0;
// player states
CCriticalSection m_stateSection;
diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.cpp b/xbmc/cores/VideoPlayer/VideoPlayer.cpp
index 6d373e6af7..dded334532 100644
--- a/xbmc/cores/VideoPlayer/VideoPlayer.cpp
+++ b/xbmc/cores/VideoPlayer/VideoPlayer.cpp
@@ -5326,6 +5326,11 @@ void CVideoPlayer::UpdateRenderInfo(CRenderInfo &info)
m_processInfo->UpdateRenderInfo(info);
}
+void CVideoPlayer::UpdateRenderBuffers(int queued, int discard, int free)
+{
+ m_processInfo->UpdateRenderBuffers(queued, discard, free);
+}
+
// IDispResource interface
void CVideoPlayer::OnLostDisplay()
{
diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.h b/xbmc/cores/VideoPlayer/VideoPlayer.h
index c82afb7e4c..41ff6b4c86 100644
--- a/xbmc/cores/VideoPlayer/VideoPlayer.h
+++ b/xbmc/cores/VideoPlayer/VideoPlayer.h
@@ -409,6 +409,7 @@ protected:
virtual void GetDebugInfo(std::string &audio, std::string &video, std::string &general) override;
virtual void UpdateClockSync(bool enabled) override;
virtual void UpdateRenderInfo(CRenderInfo &info) override;
+ virtual void UpdateRenderBuffers(int queued, int discard, int free) override;
void CreatePlayers();
void DestroyPlayers();
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.cpp
index 412bcdccae..17c428cb28 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.cpp
@@ -349,14 +349,13 @@ void CRenderManager::FrameWait(int ms)
m_presentevent.wait(lock, timeout.MillisLeft());
}
-bool CRenderManager::HasFrame()
+bool CRenderManager::IsPresenting()
{
if (!IsConfigured())
return false;
CSingleLock lock(m_presentlock);
- if (m_presentstep == PRESENT_READY ||
- m_presentstep == PRESENT_FRAME || m_presentstep == PRESENT_FRAME2)
+ if (!m_presentTimer.IsTimePast())
return true;
else
return false;
@@ -401,6 +400,7 @@ void CRenderManager::FrameMove()
m_pRenderer->FlipPage(m_presentsource);
m_presentstep = PRESENT_FRAME;
m_presentevent.notifyAll();
+ m_presentTimer.Set(1000);
}
// release all previous
@@ -416,6 +416,8 @@ void CRenderManager::FrameMove()
}
else
++it;
+
+ m_playerPort->UpdateRenderBuffers(m_queued.size(), m_discard.size(), m_free.size());
}
m_bRenderGUI = true;
@@ -842,6 +844,7 @@ void CRenderManager::FlipPage(volatile std::atomic_bool& bStop, double pts,
m.presentmethod = presentmethod;
m.pts = pts;
requeue(m_queued, m_free);
+ m_playerPort->UpdateRenderBuffers(m_queued.size(), m_discard.size(), m_free.size());
// signal to any waiters to check state
if (m_presentstep == PRESENT_IDLE)
@@ -979,7 +982,7 @@ bool CRenderManager::IsGuiLayer()
if (!m_pRenderer)
return false;
- if ((m_pRenderer->IsGuiLayer() && HasFrame()) ||
+ if ((m_pRenderer->IsGuiLayer() && IsPresenting()) ||
m_renderedOverlay || m_overlays.HasOverlay(m_presentsource))
return true;
@@ -1338,6 +1341,8 @@ void CRenderManager::PrepareNextRender()
m_queued.pop_front();
m_presentpts = m_Queue[idx].pts - totalLatency;
m_presentevent.notifyAll();
+
+ m_playerPort->UpdateRenderBuffers(m_queued.size(), m_discard.size(), m_free.size());
}
}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.h b/xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.h
index 9bb9011b69..d5340877bc 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.h
@@ -59,6 +59,7 @@ protected:
virtual void GetDebugInfo(std::string &audio, std::string &video, std::string &general) = 0;
virtual void UpdateClockSync(bool enabled) = 0;
virtual void UpdateRenderInfo(CRenderInfo &info) = 0;
+ virtual void UpdateRenderBuffers(int queued, int discard, int free) = 0;
};
class CRenderManager
@@ -72,7 +73,6 @@ public:
float GetAspectRatio();
void FrameMove();
void FrameWait(int ms);
- bool HasFrame();
void Render(bool clear, DWORD flags = 0, DWORD alpha = 255, bool gui = true);
bool IsGuiLayer();
bool IsVideoLayer();
@@ -163,6 +163,7 @@ protected:
void PresentBlend(bool clear, DWORD flags, DWORD alpha);
void PrepareNextRender();
+ bool IsPresenting();
bool Configure();
void CreateRenderer();
@@ -241,6 +242,7 @@ protected:
int m_lateframes;
double m_presentpts;
EPRESENTSTEP m_presentstep;
+ XbmcThreads::EndTime m_presentTimer;
bool m_forceNext;
int m_presentsource;
XbmcThreads::ConditionVariable m_presentevent;
diff --git a/xbmc/rendering/dx/RenderSystemDX.cpp b/xbmc/rendering/dx/RenderSystemDX.cpp
index fa9e8bdd92..21c571db1d 100644
--- a/xbmc/rendering/dx/RenderSystemDX.cpp
+++ b/xbmc/rendering/dx/RenderSystemDX.cpp
@@ -1189,6 +1189,17 @@ void CRenderSystemDX::PresentRenderImpl(bool rendered)
CD3DHelper::PSClearShaderResources(m_pContext);
}
+ // time for decoder that may require the context
+ {
+ CSingleLock lock(m_decoderSection);
+ XbmcThreads::EndTime timer;
+ timer.Set(5);
+ while (!m_decodingTimer.IsTimePast() && !timer.IsTimePast())
+ {
+ m_decodingEvent.wait(lock, 1);
+ }
+ }
+
FinishCommandList();
m_pImdContext->Flush();
@@ -1218,6 +1229,19 @@ void CRenderSystemDX::PresentRenderImpl(bool rendered)
m_pContext->OMSetRenderTargets(1, &m_pRenderTargetView, m_depthStencilView);
}
+void CRenderSystemDX::RequestDecodingTime()
+{
+ CSingleLock lock(m_decoderSection);
+ m_decodingTimer.Set(3);
+}
+
+void CRenderSystemDX::ReleaseDecodingTime()
+{
+ CSingleLock lock(m_decoderSection);
+ m_decodingTimer.SetExpired();
+ m_decodingEvent.notify();
+}
+
bool CRenderSystemDX::BeginRender()
{
if (!m_bRenderCreated)
diff --git a/xbmc/rendering/dx/RenderSystemDX.h b/xbmc/rendering/dx/RenderSystemDX.h
index bde90e407d..f0bf875616 100644
--- a/xbmc/rendering/dx/RenderSystemDX.h
+++ b/xbmc/rendering/dx/RenderSystemDX.h
@@ -28,6 +28,7 @@
#include <vector>
#include "rendering/RenderSystem.h"
#include "guilib/GUIShaderDX.h"
+#include "threads/Condition.h"
#include "threads/CriticalSection.h"
#include "easyhook/easyhook.h"
@@ -79,6 +80,8 @@ public:
void GetDisplayMode(DXGI_MODE_DESC *mode, bool useCached = false);
void FinishCommandList(bool bExecute = true) const;
void FlushGPU() const;
+ void RequestDecodingTime();
+ void ReleaseDecodingTime();
ID3D11Device* Get3D11Device() const { return m_pD3DDev; }
ID3D11DeviceContext* Get3D11Context() const { return m_pContext; }
@@ -187,6 +190,10 @@ protected:
bool m_bStereoEnabled{false};
TRACED_HOOK_HANDLE m_hHook{nullptr};
HMODULE m_hDriverModule{nullptr};
+
+ CCriticalSection m_decoderSection;
+ XbmcThreads::EndTime m_decodingTimer;
+ XbmcThreads::ConditionVariable m_decodingEvent;
};
#endif