diff options
author | Martijn Kaijser <martijn@xbmc.org> | 2016-12-30 11:50:59 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-30 11:50:59 +0100 |
commit | 1296ce347c2d1d2eda9c86d4d0903c88e264f2c4 (patch) | |
tree | 3f7d39553598538265eece67b19267cd734a7cd0 | |
parent | 99334797e6786ca543a4c7333922cfc91fbcecab (diff) | |
parent | 58374f4e49c544fcc45f94b2577eb38485a0d0ea (diff) |
Merge pull request #11304 from MartijnKaijser/11301
VideoPlayer + win32: fix video stuttering
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp | 12 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp | 16 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/Process/ProcessInfo.h | 5 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoPlayer.cpp | 5 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoPlayer.h | 1 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.cpp | 13 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.h | 4 | ||||
-rw-r--r-- | xbmc/rendering/dx/RenderSystemDX.cpp | 24 | ||||
-rw-r--r-- | xbmc/rendering/dx/RenderSystemDX.h | 7 |
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 |