diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp index b9c90c20aa9d6..8de616791859c 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp @@ -608,6 +608,17 @@ bool CSurfaceContext::HasFree() return !m_freeSurfaces.empty(); } +bool CSurfaceContext::HasRefs() +{ + CSingleLock lock(m_section); + for (map::iterator it = m_state.begin(); it != m_state.end(); ++it) + { + if (it->second & SURFACE_USED_FOR_REFERENCE) + return true; + } + return false; +} + //----------------------------------------------------------------------------- // DXVA RednerPictures //----------------------------------------------------------------------------- @@ -656,6 +667,16 @@ CDecoder::~CDecoder() free(m_context); } +long CDecoder::Release() +{ + // if ffmpeg holds any references, flush buffers + if (m_surface_context && m_surface_context->HasRefs()) + { + avcodec_flush_buffers(m_avctx); + } + return IHardwareDecoder::Release(); +} + void CDecoder::Close() { CSingleLock lock(m_section); @@ -902,6 +923,8 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su avctx->get_buffer2 = GetBufferS; avctx->hwaccel_context = m_context; + m_avctx = avctx; + D3DADAPTER_IDENTIFIER9 AIdentifier = g_Windowing.GetAIdentifier(); if (AIdentifier.VendorId == PCIV_Intel && m_input == DXVADDI_Intel_ModeH264_E) { @@ -1093,7 +1116,7 @@ void CDecoder::RelBuffer(uint8_t *data) } m_surface_context->ClearReference(surface); - Release(); + IHardwareDecoder::Release(); } int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h index 1b8a45d74cbb7..9d92efcebb1ff 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h @@ -60,6 +60,7 @@ class CSurfaceContext void Reset(); int Size(); bool HasFree(); + bool HasRefs(); protected: std::map m_state; @@ -122,6 +123,7 @@ class CDecoder virtual void Close(); virtual const std::string Name() { return "dxva2"; } virtual unsigned GetAllowedReferences(); + virtual long Release(); bool OpenTarget(const GUID &guid); bool OpenDecoder(); @@ -155,6 +157,7 @@ class CDecoder CSurfaceContext* m_surface_context; CDXVAContext* m_dxva_context; + AVCodecContext* m_avctx; unsigned int m_shared;