diff options
author | CrystalPT <CrystalPT@svn> | 2010-10-13 00:35:05 +0000 |
---|---|---|
committer | CrystalPT <CrystalPT@svn> | 2010-10-13 00:35:05 +0000 |
commit | 11220871d167e3455216a63fd6127c983ccca4dc (patch) | |
tree | 2146cd1525f285990d34467e3e2411054509708e | |
parent | 9bf60cda1f8f2db5cb8a12bbb190b1a08fb423c8 (diff) |
[WIN32] fixed: unreleased DXVA surfaces leak memory and prevent device reset
(cherry picked from commit 93df0052fd3098df074b6a5c4e926656d65894f7)
git-svn-id: https://xbmc.svn.sourceforge.net/svnroot/xbmc/branches/Dharma@34725 568bbfeb-2a22-0410-94d2-cc84cf5bfa90
-rw-r--r-- | xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp | 22 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h | 4 |
2 files changed, 20 insertions, 6 deletions
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp index d7c67e9211..7e2d63cb78 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp @@ -39,8 +39,8 @@ #define ALLOW_ADDING_SURFACES 0 using namespace DXVA; -using namespace boost; using namespace AUTOPTR; +using namespace std; typedef HRESULT (__stdcall *DXVA2CreateVideoServicePtr)(IDirect3DDevice9* pDD, REFIID riid, void** ppService); static DXVA2CreateVideoServicePtr g_DXVA2CreateVideoService; @@ -482,6 +482,12 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt) if(!OpenDecoder()) return false; + // The front buffer seems to be the only one required and it seems to always be m_buffer[0] on ATI and nVidia + // but how reliable is that information? + // Not adding refs causes a crash at the end of playback because the surfaces are released with the decoder, despite the >0 D3D ref count. + for(unsigned i = 0; i < m_buffer_count; i++) + m_processor->HoldSurface(m_buffer[i].surface); + avctx->get_buffer = GetBufferS; avctx->release_buffer = RelBufferS; avctx->hwaccel_context = m_context; @@ -673,10 +679,6 @@ bool CDecoder::OpenDecoder() , m_context->surface_count , &m_decoder)) - // CreateVideoDecoder will not addref the surfaces, but will release them when released - for(unsigned i = 0; i < m_buffer_count; i++) - m_buffer[i].surface->AddRef(); - m_context->decoder = m_decoder; return true; @@ -799,9 +801,10 @@ void CProcessor::Close() for(unsigned i = 0; i < m_sample.size(); i++) SAFE_RELEASE(m_sample[i].SrcSurface); m_sample.clear(); + for (vector<IDirect3DSurface9*>::iterator it = m_heldsurfaces.begin(); it != m_heldsurfaces.end(); it++) + SAFE_RELEASE(*it); } - bool CProcessor::Open(const DXVA2_VideoDesc& dsc) { if(!LoadDXVA()) @@ -860,9 +863,16 @@ bool CProcessor::Open(const DXVA2_VideoDesc& dsc) CHECK(m_service->GetProcAmpRange(m_device, &m_desc, output, DXVA2_ProcAmp_Saturation, &m_saturation)); m_time = 0; + return true; } +void CProcessor::HoldSurface(IDirect3DSurface9* surface) +{ + surface->AddRef(); + m_heldsurfaces.push_back(surface); +} + REFERENCE_TIME CProcessor::Add(IDirect3DSurface9* source) { CSingleLock lock(m_section); diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h index 5015bf85fa..00ab72414e 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h @@ -26,6 +26,8 @@ #include "Event.h" #include <dxva2api.h> #include <deque> +#include <vector> + namespace DXVA { class CProcessor; @@ -104,6 +106,7 @@ public: bool Open(const DXVA2_VideoDesc& dsc); void Close(); + void HoldSurface(IDirect3DSurface9* surface); REFERENCE_TIME Add (IDirect3DSurface9* source); bool Render(const RECT& dst, IDirect3DSurface9* target, const REFERENCE_TIME time); int Size() { return m_size; } @@ -137,6 +140,7 @@ public: long m_references; protected: + std::vector<IDirect3DSurface9*> m_heldsurfaces; }; }; |