diff --git a/packages/mediacenter/xbmc-theme-Confluence/package.mk b/packages/mediacenter/xbmc-theme-Confluence/package.mk index 7a2c10994f..10379529c1 100644 --- a/packages/mediacenter/xbmc-theme-Confluence/package.mk +++ b/packages/mediacenter/xbmc-theme-Confluence/package.mk @@ -17,7 +17,7 @@ ################################################################################ PKG_NAME="xbmc-theme-Confluence" -PKG_VERSION="14-f6a3308" +PKG_VERSION="14-fa8281b" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/mediacenter/xbmc/package.mk b/packages/mediacenter/xbmc/package.mk index 6783c36994..2937d7fbfd 100644 --- a/packages/mediacenter/xbmc/package.mk +++ b/packages/mediacenter/xbmc/package.mk @@ -17,7 +17,7 @@ ################################################################################ PKG_NAME="xbmc" -PKG_VERSION="14-f6a3308" +PKG_VERSION="14-fa8281b" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta.patch b/packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta.patch index ac01d27b81..2c9b90eb97 100644 --- a/packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta.patch +++ b/packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta.patch @@ -1,2262 +1,3 @@ -From 0d0a987458aa8f2e4275df558f27ce061d84ed20 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 13 Sep 2014 09:03:49 +0200 -Subject: [PATCH 01/31] dxva: fix and rework video surface handling - ---- - xbmc/cores/VideoRenderers/DXVA.cpp | 79 +++--- - xbmc/cores/VideoRenderers/DXVA.h | 6 +- - xbmc/cores/VideoRenderers/DXVAHD.cpp | 60 ++--- - xbmc/cores/VideoRenderers/DXVAHD.h | 2 +- - .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 4 +- - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 1 + - xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp | 268 ++++++++++++++------- - xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h | 43 ++-- - 8 files changed, 269 insertions(+), 194 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/DXVA.cpp b/xbmc/cores/VideoRenderers/DXVA.cpp -index 8d57509..16d26c8 100644 ---- a/xbmc/cores/VideoRenderers/DXVA.cpp -+++ b/xbmc/cores/VideoRenderers/DXVA.cpp -@@ -151,7 +151,6 @@ CProcessor::CProcessor() - m_time = 0; - g_Windowing.Register(this); - -- m_surfaces = NULL; - m_context = NULL; - m_index = 0; - m_progressive = true; -@@ -174,21 +173,13 @@ void CProcessor::Close() - { - CSingleLock lock(m_section); - SAFE_RELEASE(m_process); -- for(unsigned i = 0; i < m_sample.size(); i++) -+ for(unsigned i = 0; i < m_samples.size(); i++) - { -- SAFE_RELEASE(m_sample[i].context); -- SAFE_RELEASE(m_sample[i].sample.SrcSurface); -+ SAFE_RELEASE(m_samples[i].renderPic); - } -- m_sample.clear(); -+ m_samples.clear(); - - SAFE_RELEASE(m_context); -- if (m_surfaces) -- { -- for (unsigned i = 0; i < m_size; i++) -- SAFE_RELEASE(m_surfaces[i]); -- free(m_surfaces); -- m_surfaces = NULL; -- } - } - - bool CProcessor::UpdateSize(const DXVA2_VideoDesc& dsc) -@@ -499,17 +490,23 @@ bool CProcessor::OpenProcessor() - bool CProcessor::CreateSurfaces() - { - LPDIRECT3DDEVICE9 pD3DDevice = g_Windowing.Get3DDevice(); -- m_surfaces = (LPDIRECT3DSURFACE9*)calloc(m_size, sizeof(LPDIRECT3DSURFACE9)); -+ LPDIRECT3DSURFACE9 surfaces[32]; - for (unsigned idx = 0; idx < m_size; idx++) -+ { - CHECK(pD3DDevice->CreateOffscreenPlainSurface( -- (m_desc.SampleWidth + 15) & ~15, -- (m_desc.SampleHeight + 15) & ~15, -- m_desc.Format, -- D3DPOOL_DEFAULT, -- &m_surfaces[idx], -- NULL)); -+ (m_desc.SampleWidth + 15) & ~15, -+ (m_desc.SampleHeight + 15) & ~15, -+ m_desc.Format, -+ D3DPOOL_DEFAULT, -+ &surfaces[idx], -+ NULL)); -+ } - - m_context = new CSurfaceContext(); -+ for (int i = 0; i < m_size; i++) -+ { -+ m_context->AddSurface(surfaces[i]); -+ } - - return true; - } -@@ -519,7 +516,6 @@ REFERENCE_TIME CProcessor::Add(DVDVideoPicture* picture) - CSingleLock lock(m_section); - - IDirect3DSurface9* surface = NULL; -- CSurfaceContext* context = NULL; - - if (picture->iFlags & DVP_FLAG_DROPPED) - return 0; -@@ -528,18 +524,15 @@ REFERENCE_TIME CProcessor::Add(DVDVideoPicture* picture) - { - case RENDER_FMT_DXVA: - { -- surface = (IDirect3DSurface9*)picture->data[3]; -- context = picture->context; -+ surface = picture->dxva->surface; - break; - } - - case RENDER_FMT_YUV420P: - { -- surface = m_surfaces[m_index]; -+ surface = m_context->GetAtIndex(m_index); - m_index = (m_index + 1) % m_size; - -- context = m_context; -- - D3DLOCKED_RECT rectangle; - if (FAILED(surface->LockRect(&rectangle, NULL, 0))) - return 0; -@@ -585,18 +578,18 @@ REFERENCE_TIME CProcessor::Add(DVDVideoPicture* picture) - } - } - -- if (!surface || !context) -+ if (!surface) - return 0; - - m_time += 2; - -- surface->AddRef(); -- context->Acquire(); -- - SVideoSample vs = {}; - vs.sample.Start = m_time; - vs.sample.End = 0; - vs.sample.SampleFormat = m_desc.SampleFormat; -+ vs.renderPic = NULL; -+ if (picture->format == RENDER_FMT_DXVA) -+ vs.renderPic = picture->dxva->Acquire(); - - if (picture->iFlags & DVP_FLAG_INTERLACED) - { -@@ -615,17 +608,14 @@ REFERENCE_TIME CProcessor::Add(DVDVideoPicture* picture) - vs.sample.SrcSurface = surface; - - -- vs.context = context; -- -- if(!m_sample.empty()) -- m_sample.back().sample.End = vs.sample.Start; -+ if(!m_samples.empty()) -+ m_samples.back().sample.End = vs.sample.Start; - -- m_sample.push_back(vs); -- if (m_sample.size() > m_size) -+ m_samples.push_back(vs); -+ if (m_samples.size() > m_size) - { -- SAFE_RELEASE(m_sample.front().context); -- SAFE_RELEASE(m_sample.front().sample.SrcSurface); -- m_sample.pop_front(); -+ SAFE_RELEASE(m_samples.front().renderPic); -+ m_samples.pop_front(); - } - - return m_time; -@@ -671,20 +661,19 @@ bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFEREN - REFERENCE_TIME MinTime = time - m_max_back_refs*2; - REFERENCE_TIME MaxTime = time + m_max_fwd_refs*2; - -- SSamples::iterator it = m_sample.begin(); -- while (it != m_sample.end()) -+ std::deque::iterator it = m_samples.begin(); -+ while (it != m_samples.end()) - { - if (it->sample.Start < MinTime) - { -- SAFE_RELEASE(it->context); -- SAFE_RELEASE(it->sample.SrcSurface); -- it = m_sample.erase(it); -+ SAFE_RELEASE(it->renderPic); -+ it = m_samples.erase(it); - } - else - ++it; - } - -- if(m_sample.empty()) -+ if(m_samples.empty()) - return false; - - // MinTime and MaxTime are now the first and last samples to feed the processor. -@@ -711,7 +700,7 @@ bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFEREN - for (int i = 0; i < count; i++) - samp[i].SampleFormat.SampleFormat = DXVA2_SampleUnknown; - -- for(it = m_sample.begin(); it != m_sample.end() && valid < count; ++it) -+ for(it = m_samples.begin(); it != m_samples.end() && valid < count; ++it) - { - if (it->sample.Start >= MinTime && it->sample.Start <= MaxTime) - { -diff --git a/xbmc/cores/VideoRenderers/DXVA.h b/xbmc/cores/VideoRenderers/DXVA.h -index 38da6f7..233c59b 100644 ---- a/xbmc/cores/VideoRenderers/DXVA.h -+++ b/xbmc/cores/VideoRenderers/DXVA.h -@@ -84,13 +84,11 @@ class CProcessor - struct SVideoSample - { - DXVA2_VideoSample sample; -- CSurfaceContext* context; -+ CRenderPicture* renderPic; - }; -- typedef std::deque SSamples; -- SSamples m_sample; -+ std::deque m_samples; - - CCriticalSection m_section; -- LPDIRECT3DSURFACE9* m_surfaces; - CSurfaceContext* m_context; - bool m_quirk_nodeintprocforprog; - static CCriticalSection m_dlSection; -diff --git a/xbmc/cores/VideoRenderers/DXVAHD.cpp b/xbmc/cores/VideoRenderers/DXVAHD.cpp -index e9ac51c..6788e58 100644 ---- a/xbmc/cores/VideoRenderers/DXVAHD.cpp -+++ b/xbmc/cores/VideoRenderers/DXVAHD.cpp -@@ -88,7 +88,6 @@ CProcessorHD::CProcessorHD() - m_frame = 0; - g_Windowing.Register(this); - -- m_surfaces = NULL; - m_context = NULL; - } - -@@ -112,21 +111,11 @@ void CProcessorHD::Close() - - for(unsigned i = 0; i < m_frames.size(); i++) - { -- SAFE_RELEASE(m_frames[i].context); -- SAFE_RELEASE(m_frames[i].pSurface); -+ SAFE_RELEASE(m_frames[i].pRenderPic); - } - m_frames.clear(); - - SAFE_RELEASE(m_context); -- if (m_surfaces) -- { -- for (unsigned i = 0; i < m_size; i++) -- { -- SAFE_RELEASE(m_surfaces[i]); -- } -- free(m_surfaces); -- m_surfaces = NULL; -- } - } - - bool CProcessorHD::UpdateSize(const DXVA2_VideoDesc& dsc) -@@ -330,17 +319,23 @@ bool CProcessorHD::OpenProcessor() - bool CProcessorHD::CreateSurfaces() - { - LPDIRECT3DDEVICE9 pD3DDevice = g_Windowing.Get3DDevice(); -- m_surfaces = (LPDIRECT3DSURFACE9*)calloc(m_size, sizeof(LPDIRECT3DSURFACE9)); -+ LPDIRECT3DSURFACE9 surfaces[32]; - for (unsigned idx = 0; idx < m_size; idx++) -+ { - CHECK(pD3DDevice->CreateOffscreenPlainSurface( -- (m_width + 15) & ~15, -- (m_height + 15) & ~15, -- m_format, -- m_VPDevCaps.InputPool, -- &m_surfaces[idx], -- NULL)); -+ (m_width + 15) & ~15, -+ (m_height + 15) & ~15, -+ m_format, -+ m_VPDevCaps.InputPool, -+ &surfaces[idx], -+ NULL)); -+ } - - m_context = new CSurfaceContext(); -+ for (int i = 0; i < m_size; i++) -+ { -+ m_context->AddSurface(surfaces[i]); -+ } - - return true; - } -@@ -350,7 +345,6 @@ REFERENCE_TIME CProcessorHD::Add(DVDVideoPicture* picture) - CSingleLock lock(m_section); - - IDirect3DSurface9* surface = NULL; -- CSurfaceContext* context = NULL; - - if (picture->iFlags & DVP_FLAG_DROPPED) - { -@@ -361,23 +355,20 @@ REFERENCE_TIME CProcessorHD::Add(DVDVideoPicture* picture) - { - case RENDER_FMT_DXVA: - { -- surface = (IDirect3DSurface9*)picture->data[3]; -- context = picture->context; -+ surface = picture->dxva->surface; - break; - } - - case RENDER_FMT_YUV420P: - { -- if (!m_surfaces) -+ if (!m_context) - { - CLog::Log(LOGWARNING, __FUNCTION__" - not initialized."); - return 0; - } - -- surface = m_surfaces[m_index]; -+ surface = m_context->GetAtIndex(m_index); - m_index = (m_index + 1) % m_size; -- -- context = m_context; - - D3DLOCKED_RECT rectangle; - if (FAILED(surface->LockRect(&rectangle, NULL, 0))) -@@ -430,19 +421,18 @@ REFERENCE_TIME CProcessorHD::Add(DVDVideoPicture* picture) - } - } - -- if (!surface || !context) -+ if (!surface) - { - return 0; - } - m_frame += 2; - -- surface->AddRef(); -- context->Acquire(); -- - SFrame frame = {}; - frame.index = m_frame; -- frame.pSurface = surface; -- frame.context = context; -+ frame.pSurface = surface; -+ frame.pRenderPic = NULL; -+ if (picture->format == RENDER_FMT_DXVA) -+ frame.pRenderPic = picture->dxva->Acquire(); - frame.format = DXVAHD_FRAME_FORMAT_PROGRESSIVE; - - if (picture->iFlags & DVP_FLAG_INTERLACED) -@@ -456,8 +446,7 @@ REFERENCE_TIME CProcessorHD::Add(DVDVideoPicture* picture) - - if (m_frames.size() > m_size) - { -- SAFE_RELEASE(m_frames.front().context); -- SAFE_RELEASE(m_frames.front().pSurface); -+ SAFE_RELEASE(m_frames.front().pRenderPic); - - m_frames.pop_front(); - } -@@ -526,8 +515,7 @@ bool CProcessorHD::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFER - { - if (it->index < minFrame) - { -- SAFE_RELEASE(it->context); -- SAFE_RELEASE(it->pSurface); -+ SAFE_RELEASE(it->pRenderPic); - it = m_frames.erase(it); - } - else -diff --git a/xbmc/cores/VideoRenderers/DXVAHD.h b/xbmc/cores/VideoRenderers/DXVAHD.h -index 11cb194..a6ab9f5 100644 ---- a/xbmc/cores/VideoRenderers/DXVAHD.h -+++ b/xbmc/cores/VideoRenderers/DXVAHD.h -@@ -97,7 +97,7 @@ class CProcessorHD - struct SFrame - { - IDirect3DSurface9* pSurface; -- CSurfaceContext* context; -+ CRenderPicture* pRenderPic; - unsigned int index; - unsigned format; - }; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -index 37c1c07..8333fb4 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -@@ -47,7 +47,7 @@ struct DVDCodecAvailableType - #define FRAME_TYPE_B 3 - #define FRAME_TYPE_D 4 - --namespace DXVA { class CSurfaceContext; } -+namespace DXVA { class CRenderPicture; } - namespace VAAPI { class CVaapiRenderPicture; } - namespace VDPAU { class CVdpauRenderPicture; } - class COpenMax; -@@ -72,7 +72,7 @@ struct DVDVideoPicture - int iLineSize[4]; // [4] = alpha channel, currently not used - }; - struct { -- DXVA::CSurfaceContext* context; -+ DXVA::CRenderPicture* dxva; - }; - struct { - VDPAU::CVdpauRenderPicture* vdpau; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index d06e47b..718d781 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -101,6 +101,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx - #ifdef HAS_DX - if(DXVA::CDecoder::Supports(*cur) && CSettings::Get().GetBool("videoplayer.usedxva2")) - { -+ CLog::Log(LOGNOTICE, "CDVDVideoCodecFFmpeg::GetFormat - Creating DXVA(%ix%i)", avctx->width, avctx->height); - DXVA::CDecoder* dec = new DXVA::CDecoder(); - if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount)) - { -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp -index 65959bd..ef83840 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp -@@ -218,6 +218,10 @@ static const dxva2_mode_t *dxva2_find_mode(const GUID *guid) - return NULL; - } - -+//----------------------------------------------------------------------------- -+// DXVA Context -+//----------------------------------------------------------------------------- -+ - CDXVAContext *CDXVAContext::m_context = NULL; - CCriticalSection CDXVAContext::m_section; - HMODULE CDXVAContext::m_dlHandle = NULL; -@@ -464,40 +468,165 @@ bool CDXVAContext::IsValidDecoder(CDecoder *decoder) - return false; - } - -+//----------------------------------------------------------------------------- -+// DXVA Video Surface states -+//----------------------------------------------------------------------------- -+#define SURFACE_USED_FOR_REFERENCE 0x01 -+#define SURFACE_USED_FOR_RENDER 0x02 -+ - CSurfaceContext::CSurfaceContext() - { - } - - CSurfaceContext::~CSurfaceContext() - { -- for (vector::iterator it = m_heldsurfaces.begin(); it != m_heldsurfaces.end(); ++it) -- SAFE_RELEASE(*it); -+ CLog::Log(LOGDEBUG, "%s - destructing surface context", __FUNCTION__); -+ Reset(); -+} -+ -+void CSurfaceContext::AddSurface(IDirect3DSurface9* surf) -+{ -+ CSingleLock lock(m_section); -+ surf->AddRef(); -+ m_state[surf] = 0; -+ m_freeSurfaces.push_back(surf); -+} -+ -+void CSurfaceContext::ClearReference(IDirect3DSurface9* surf) -+{ -+ CSingleLock lock(m_section); -+ if (m_state.find(surf) == m_state.end()) -+ { -+ CLog::Log(LOGWARNING, "%s - surface invalid", __FUNCTION__); -+ return; -+ } -+ m_state[surf] &= ~SURFACE_USED_FOR_REFERENCE; -+ if (m_state[surf] == 0) -+ { -+ m_freeSurfaces.push_back(surf); -+ } -+} -+ -+bool CSurfaceContext::MarkRender(IDirect3DSurface9* surf) -+{ -+ CSingleLock lock(m_section); -+ if (m_state.find(surf) == m_state.end()) -+ { -+ CLog::Log(LOGWARNING, "%s - surface invalid", __FUNCTION__); -+ return false; -+ } -+ std::list::iterator it; -+ it = std::find(m_freeSurfaces.begin(), m_freeSurfaces.end(), surf); -+ if (it != m_freeSurfaces.end()) -+ { -+ m_freeSurfaces.erase(it); -+ } -+ m_state[surf] |= SURFACE_USED_FOR_RENDER; -+ return true; -+} -+ -+void CSurfaceContext::ClearRender(IDirect3DSurface9* surf) -+{ -+ CSingleLock lock(m_section); -+ if (m_state.find(surf) == m_state.end()) -+ { -+ CLog::Log(LOGWARNING, "%s - surface invalid", __FUNCTION__); -+ return; -+ } -+ m_state[surf] &= ~SURFACE_USED_FOR_RENDER; -+ if (m_state[surf] == 0) -+ { -+ m_freeSurfaces.push_back(surf); -+ } - } - --void CSurfaceContext::HoldSurface(IDirect3DSurface9* surface) -+bool CSurfaceContext::IsValid(IDirect3DSurface9* surf) - { -- surface->AddRef(); -- m_heldsurfaces.push_back(surface); -+ CSingleLock lock(m_section); -+ if (m_state.find(surf) != m_state.end()) -+ return true; -+ else -+ return false; - } - --CDecoder::SVideoBuffer::SVideoBuffer() -+IDirect3DSurface9* CSurfaceContext::GetFree(IDirect3DSurface9* surf) - { -- surface = NULL; -- Clear(); -+ CSingleLock lock(m_section); -+ if (m_state.find(surf) != m_state.end()) -+ { -+ std::list::iterator it; -+ it = std::find(m_freeSurfaces.begin(), m_freeSurfaces.end(), surf); -+ if (it == m_freeSurfaces.end()) -+ { -+ CLog::Log(LOGWARNING, "%s - surface not free", __FUNCTION__); -+ } -+ else -+ { -+ m_freeSurfaces.erase(it); -+ m_state[surf] = SURFACE_USED_FOR_REFERENCE; -+ return surf; -+ } -+ } -+ if (!m_freeSurfaces.empty()) -+ { -+ IDirect3DSurface9* freeSurf = m_freeSurfaces.front(); -+ m_freeSurfaces.pop_front(); -+ m_state[freeSurf] = SURFACE_USED_FOR_REFERENCE; -+ return freeSurf; -+ } -+ return NULL; - } - --CDecoder::SVideoBuffer::~SVideoBuffer() -+IDirect3DSurface9* CSurfaceContext::GetAtIndex(unsigned int idx) - { -- Clear(); -+ if (idx >= m_state.size()) -+ return NULL; -+ std::map::iterator it = m_state.begin(); -+ for (unsigned int i = 0; i < idx; i++) -+ ++it; -+ return it->first; - } - --void CDecoder::SVideoBuffer::Clear() -+void CSurfaceContext::Reset() - { -- SAFE_RELEASE(surface); -- age = 0; -- used = 0; -+ CSingleLock lock(m_section); -+ for (map::iterator it = m_state.begin(); it != m_state.end(); ++it) -+ it->first->Release(); -+ m_freeSurfaces.clear(); -+ m_state.clear(); - } - -+int CSurfaceContext::Size() -+{ -+ CSingleLock lock(m_section); -+ return m_state.size(); -+} -+ -+bool CSurfaceContext::HasFree() -+{ -+ CSingleLock lock(m_section); -+ return !m_freeSurfaces.empty(); -+} -+ -+//----------------------------------------------------------------------------- -+// DXVA RednerPictures -+//----------------------------------------------------------------------------- -+ -+CRenderPicture::CRenderPicture(CSurfaceContext *context) -+{ -+ surface_context = context->Acquire(); -+} -+ -+CRenderPicture::~CRenderPicture() -+{ -+ surface_context->ClearRender(surface); -+ surface_context->Release(); -+} -+ -+//----------------------------------------------------------------------------- -+// DXVA Decoder -+//----------------------------------------------------------------------------- -+ - CDecoder::CDecoder() - : m_event(true) - { -@@ -505,21 +634,21 @@ CDecoder::CDecoder() - m_state = DXVA_OPEN; - m_device = NULL; - m_decoder = NULL; -- m_buffer_count = 0; -- m_buffer_age = 0; - m_refs = 0; - m_shared = 0; - m_surface_context = NULL; -+ m_presentPicture = NULL; - m_dxva_context = NULL; - memset(&m_format, 0, sizeof(m_format)); - m_context = (dxva_context*)calloc(1, sizeof(dxva_context)); - m_context->cfg = (DXVA2_ConfigPictureDecode*)calloc(1, sizeof(DXVA2_ConfigPictureDecode)); -- m_context->surface = (IDirect3DSurface9**)calloc(m_buffer_max, sizeof(IDirect3DSurface9*)); -+ m_context->surface = (IDirect3DSurface9**)calloc(32, sizeof(IDirect3DSurface9*)); - g_Windowing.Register(this); - } - - CDecoder::~CDecoder() - { -+ CLog::Log(LOGDEBUG, "%s - destructing decoder, %ld", __FUNCTION__, this); - g_Windowing.Unregister(this); - Close(); - free(m_context->surface); -@@ -532,13 +661,14 @@ void CDecoder::Close() - CSingleLock lock(m_section); - SAFE_RELEASE(m_decoder); - SAFE_RELEASE(m_surface_context); -- for(unsigned i = 0; i < m_buffer_count; i++) -- m_buffer[i].Clear(); -- m_buffer_count = 0; -+ SAFE_RELEASE(m_presentPicture); - memset(&m_format, 0, sizeof(m_format)); - - if (m_dxva_context) -+ { -+ CLog::Log(LOGNOTICE, "%s - closing decoder", __FUNCTION__); - m_dxva_context->Release(this); -+ } - m_dxva_context = NULL; - } - -@@ -769,7 +899,7 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su - if(!OpenDecoder()) - return false; - -- avctx->get_buffer2 = GetBufferS; -+ avctx->get_buffer2 = GetBufferS; - avctx->hwaccel_context = m_context; - - D3DADAPTER_IDENTIFIER9 AIdentifier = g_Windowing.GetAIdentifier(); -@@ -801,12 +931,16 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame) - if(result) - return result; - -+ SAFE_RELEASE(m_presentPicture); -+ - if(frame) - { -- for(unsigned i = 0; i < m_buffer_count; i++) -+ if (m_surface_context->IsValid((IDirect3DSurface9*)frame->data[3])) - { -- if(m_buffer[i].surface == (IDirect3DSurface9*)frame->data[3]) -- return VC_BUFFER | VC_PICTURE; -+ m_presentPicture = new CRenderPicture(m_surface_context); -+ m_presentPicture->surface = (IDirect3DSurface9*)frame->data[3]; -+ m_surface_context->MarkRender(m_presentPicture->surface); -+ return VC_BUFFER | VC_PICTURE; - } - CLog::Log(LOGWARNING, "DXVA - ignoring invalid surface"); - return VC_BUFFER; -@@ -819,10 +953,10 @@ bool CDecoder::GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture - { - ((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetPictureCommon(picture); - CSingleLock lock(m_section); -+ -+ picture->dxva = m_presentPicture; - picture->format = RENDER_FMT_DXVA; - picture->extended_format = (unsigned int)m_format.Format; -- picture->context = m_surface_context; -- picture->data[3]= frame->data[3]; - return true; - } - -@@ -922,21 +1056,15 @@ bool CDecoder::OpenDecoder() - - m_context->surface_count = m_refs + 1 + 1 + m_shared; // refs + 1 decode + 1 libavcodec safety + processor buffer - -- if(m_context->surface_count > m_buffer_count) -- { -- CLog::Log(LOGDEBUG, "DXVA - allocating %d surfaces", m_context->surface_count - m_buffer_count); -+ CLog::Log(LOGDEBUG, "DXVA - allocating %d surfaces", m_context->surface_count); - -- if (!m_dxva_context->CreateSurfaces(m_format.SampleWidth, m_format.SampleHeight, m_format.Format, -- m_context->surface_count - 1 - m_buffer_count, m_context->surface + m_buffer_count)) -- return false; -- -- for(unsigned i = m_buffer_count; i < m_context->surface_count; i++) -- { -- m_buffer[i].surface = m_context->surface[i]; -- m_surface_context->HoldSurface(m_context->surface[i]); -- } -+ if (!m_dxva_context->CreateSurfaces(m_format.SampleWidth, m_format.SampleHeight, m_format.Format, -+ m_context->surface_count - 1, m_context->surface)) -+ return false; - -- m_buffer_count = m_context->surface_count; -+ for(unsigned i = 0; i < m_context->surface_count; i++) -+ { -+ m_surface_context->AddSurface(m_context->surface[i]); - } - - if (!m_dxva_context->CreateDecoder(m_input, &m_format, m_context->cfg, m_context->surface, m_context->surface_count, &m_decoder)) -@@ -957,18 +1085,15 @@ bool CDecoder::Supports(enum PixelFormat fmt) - void CDecoder::RelBuffer(uint8_t *data) - { - CSingleLock lock(m_section); -- IDirect3DSurface9* surface = (IDirect3DSurface9*)data; -+ IDirect3DSurface9* surface = (IDirect3DSurface9*)(uintptr_t)data; - -- for(unsigned i = 0; i < m_buffer_count; i++) -+ if (!m_surface_context->IsValid(surface)) - { -- if(m_buffer[i].surface == surface) -- { -- m_buffer[i].used = false; -- m_buffer[i].age = ++m_buffer_age; -- break; -- } -+ CLog::Log(LOGWARNING, "%s - return of invalid surface", __FUNCTION__); - } - -+ m_surface_context->ClearReference(surface); -+ - Release(); - } - -@@ -979,46 +1104,12 @@ int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags) - if (!m_decoder) - return -1; - -- if(avctx->coded_width != m_format.SampleWidth -- || avctx->coded_height != m_format.SampleHeight) -- { -- Close(); -- if(!Open(avctx, avctx->pix_fmt, m_shared)) -- { -- Close(); -- return -1; -- } -- } -- -- int count = 0; -- SVideoBuffer* buf = NULL; -- for(unsigned i = 0; i < m_buffer_count; i++) -- { -- if(m_buffer[i].used) -- count++; -- else -- { -- if(!buf || buf->age > m_buffer[i].age) -- buf = m_buffer+i; -- } -- } -- -- if(count >= m_refs+2) -- { -- m_refs++; --#if ALLOW_ADDING_SURFACES -- if(!OpenDecoder()) -- return -1; -- return GetBuffer(avctx, pic); --#else -- Close(); -- return -1; --#endif -- } -- -- if(!buf) -+ IDirect3DSurface9* surf = (IDirect3DSurface9*)(uintptr_t)pic->data[3]; -+ surf = m_surface_context->GetFree(surf != 0 ? surf : NULL); -+ if (surf == NULL) - { -- CLog::Log(LOGERROR, "DXVA - unable to find new unused buffer"); -+ CLog::Log(LOGERROR, "%s - no surface available - dec: %d, render: %d", __FUNCTION__); -+ m_state = DXVA_LOST; - return -1; - } - -@@ -1030,8 +1121,8 @@ int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags) - pic->linesize[i] = 0; - } - -- pic->data[0] = (uint8_t*)buf->surface; -- pic->data[3] = (uint8_t*)buf->surface; -+ pic->data[0] = (uint8_t*)surf; -+ pic->data[3] = (uint8_t*)surf; - AVBufferRef *buffer = av_buffer_create(pic->data[3], 0, RelBufferS, this, 0); - if (!buffer) - { -@@ -1039,7 +1130,6 @@ int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags) - return -1; - } - pic->buf[0] = buffer; -- buf->used = true; - - Acquire(); - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h -index fa24556..1b8a45d 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #include "settings/VideoSettings.h" - #include "guilib/Geometry.h" - -@@ -49,10 +50,32 @@ class CSurfaceContext - CSurfaceContext(); - ~CSurfaceContext(); - -- void HoldSurface(IDirect3DSurface9* surface); -+ void AddSurface(IDirect3DSurface9* surf); -+ void ClearReference(IDirect3DSurface9* surf); -+ bool MarkRender(IDirect3DSurface9* surf); -+ void ClearRender(IDirect3DSurface9* surf); -+ bool IsValid(IDirect3DSurface9* surf); -+ IDirect3DSurface9* GetFree(IDirect3DSurface9* surf); -+ IDirect3DSurface9* GetAtIndex(unsigned int idx); -+ void Reset(); -+ int Size(); -+ bool HasFree(); - - protected: -- std::vector m_heldsurfaces; -+ std::map m_state; -+ std::list m_freeSurfaces; -+ CCriticalSection m_section; -+}; -+ -+class CRenderPicture -+ : public IDVDResourceCounted -+{ -+public: -+ CRenderPicture(CSurfaceContext *context); -+ ~CRenderPicture(); -+ IDirect3DSurface9* surface; -+protected: -+ CSurfaceContext *surface_context; - }; - - typedef HRESULT(__stdcall *DXVA2CreateVideoServicePtr)(IDirect3DDevice9* pDD, REFIID riid, void** ppService); -@@ -121,26 +144,12 @@ class CDecoder - virtual void OnLostDevice() { CSingleLock lock(m_section); m_state = DXVA_LOST; m_event.Reset(); } - virtual void OnResetDevice() { CSingleLock lock(m_section); m_state = DXVA_RESET; m_event.Set(); } - -- struct SVideoBuffer -- { -- SVideoBuffer(); -- ~SVideoBuffer(); -- void Clear(); -- -- IDirect3DSurface9* surface; -- bool used; -- int age; -- }; -- - IDirectXVideoDecoder* m_decoder; - HANDLE m_device; - GUID m_input; - DXVA2_VideoDesc m_format; -- static const unsigned m_buffer_max = 32; -- SVideoBuffer m_buffer[m_buffer_max]; -- unsigned m_buffer_count; -- unsigned m_buffer_age; - int m_refs; -+ CRenderPicture *m_presentPicture; - - struct dxva_context* m_context; - - -From f1ea9298555e290c05de91e08d73fd2b89f20350 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 14 Sep 2014 11:20:18 +0200 -Subject: [PATCH 02/31] dxva: let renderer control the render buffers - ---- - xbmc/cores/VideoRenderers/BaseRenderer.h | 3 +- - xbmc/cores/VideoRenderers/DXVA.cpp | 277 +++++++++++--------------- - xbmc/cores/VideoRenderers/DXVA.h | 14 +- - xbmc/cores/VideoRenderers/DXVAHD.cpp | 235 +++++----------------- - xbmc/cores/VideoRenderers/DXVAHD.h | 14 +- - xbmc/cores/VideoRenderers/RenderManager.cpp | 23 +-- - xbmc/cores/VideoRenderers/WinRenderer.cpp | 110 ++++++++-- - xbmc/cores/VideoRenderers/WinRenderer.h | 13 +- - xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp | 1 - - 9 files changed, 281 insertions(+), 409 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h -index fb41ccf..d303598 100644 ---- a/xbmc/cores/VideoRenderers/BaseRenderer.h -+++ b/xbmc/cores/VideoRenderers/BaseRenderer.h -@@ -29,7 +29,7 @@ - - #define MAX_PLANES 3 - #define MAX_FIELDS 3 --#define NUM_BUFFERS 3 -+#define NUM_BUFFERS 6 - - class CSetting; - -@@ -93,6 +93,7 @@ class CBaseRenderer - virtual unsigned int GetMaxBufferSize() { return 0; } - virtual void SetBufferSize(int numBuffers) { } - virtual void ReleaseBuffer(int idx) { } -+ virtual bool NeedBufferForRef(int idx) { return false; } - - virtual bool Supports(ERENDERFEATURE feature) { return false; } - -diff --git a/xbmc/cores/VideoRenderers/DXVA.cpp b/xbmc/cores/VideoRenderers/DXVA.cpp -index 16d26c8..e38a9f0 100644 ---- a/xbmc/cores/VideoRenderers/DXVA.cpp -+++ b/xbmc/cores/VideoRenderers/DXVA.cpp -@@ -148,11 +148,9 @@ CProcessor::CProcessor() - { - m_service = NULL; - m_process = NULL; -- m_time = 0; - g_Windowing.Register(this); - - m_context = NULL; -- m_index = 0; - m_progressive = true; - } - -@@ -173,12 +171,6 @@ void CProcessor::Close() - { - CSingleLock lock(m_section); - SAFE_RELEASE(m_process); -- for(unsigned i = 0; i < m_samples.size(); i++) -- { -- SAFE_RELEASE(m_samples[i].renderPic); -- } -- m_samples.clear(); -- - SAFE_RELEASE(m_context); - } - -@@ -362,8 +354,6 @@ bool CProcessor::Open(UINT width, UINT height, unsigned int flags, unsigned int - if (!OpenProcessor()) - return false; - -- m_time = 0; -- - return true; - } - -@@ -511,114 +501,71 @@ bool CProcessor::CreateSurfaces() - return true; - } - --REFERENCE_TIME CProcessor::Add(DVDVideoPicture* picture) -+CRenderPicture *CProcessor::Convert(DVDVideoPicture* picture) - { -- CSingleLock lock(m_section); -- -- IDirect3DSurface9* surface = NULL; -- -- if (picture->iFlags & DVP_FLAG_DROPPED) -- return 0; -- -- switch (picture->format) -+ if (picture->format != RENDER_FMT_YUV420P) - { -- case RENDER_FMT_DXVA: -- { -- surface = picture->dxva->surface; -- break; -- } -- -- case RENDER_FMT_YUV420P: -- { -- surface = m_context->GetAtIndex(m_index); -- m_index = (m_index + 1) % m_size; -- -- D3DLOCKED_RECT rectangle; -- if (FAILED(surface->LockRect(&rectangle, NULL, 0))) -- return 0; -- -- // Convert to NV12 - Luma -- // TODO: Optimize this later using shaders/swscale/etc. -- uint8_t *s = picture->data[0]; -- uint8_t* bits = (uint8_t*)(rectangle.pBits); -- for (unsigned y = 0; y < picture->iHeight; y++) -- { -- memcpy(bits, s, picture->iWidth); -- s += picture->iLineSize[0]; -- bits += rectangle.Pitch; -- } -- -- D3DSURFACE_DESC desc; -- if (FAILED(surface->GetDesc(&desc))) -- return 0; -- -- // Convert to NV12 - Chroma -- for (unsigned y = 0; y < picture->iHeight/2; y++) -- { -- uint8_t *s_u = picture->data[1] + (y * picture->iLineSize[1]); -- uint8_t *s_v = picture->data[2] + (y * picture->iLineSize[2]); -- uint8_t *d_uv = ((uint8_t*)(rectangle.pBits)) + (desc.Height + y) * rectangle.Pitch; -- for (unsigned x = 0; x < picture->iWidth/2; x++) -- { -- *d_uv++ = *s_u++; -- *d_uv++ = *s_v++; -- } -- } -- -- if (FAILED(surface->UnlockRect())) -- return 0; -- -- break; -- } -- -- default: -- { -- CLog::Log(LOGWARNING, "DXVA - colorspace not supported by processor, skipping frame"); -- return 0; -- } -+ CLog::Log(LOGERROR, "%s - colorspace not supported by processor, skipping frame.", __FUNCTION__); -+ return NULL; - } - -+ IDirect3DSurface9* surface = m_context->GetFree(NULL); - if (!surface) -- return 0; -- -- m_time += 2; -+ { -+ CLog::Log(LOGERROR, "%s - no free video surface", __FUNCTION__); -+ return NULL; -+ } - -- SVideoSample vs = {}; -- vs.sample.Start = m_time; -- vs.sample.End = 0; -- vs.sample.SampleFormat = m_desc.SampleFormat; -- vs.renderPic = NULL; -- if (picture->format == RENDER_FMT_DXVA) -- vs.renderPic = picture->dxva->Acquire(); -+ D3DLOCKED_RECT rectangle; -+ if (FAILED(surface->LockRect(&rectangle, NULL, 0))) -+ { -+ CLog::Log(LOGERROR, "%s - could not lock rect", __FUNCTION__); -+ m_context->ClearReference(surface); -+ return NULL; -+ } - -- if (picture->iFlags & DVP_FLAG_INTERLACED) -+ // Convert to NV12 - Luma -+ // TODO: Optimize this later using shaders/swscale/etc. -+ uint8_t *s = picture->data[0]; -+ uint8_t* bits = (uint8_t*)(rectangle.pBits); -+ for (unsigned y = 0; y < picture->iHeight; y++) - { -- if (picture->iFlags & DVP_FLAG_TOP_FIELD_FIRST) -- vs.sample.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedEvenFirst; -- else -- vs.sample.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedOddFirst; -+ memcpy(bits, s, picture->iWidth); -+ s += picture->iLineSize[0]; -+ bits += rectangle.Pitch; - } -- else -+ D3DSURFACE_DESC desc; -+ if (FAILED(surface->GetDesc(&desc))) - { -- vs.sample.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame; -+ CLog::Log(LOGERROR, "%s - could not get surface descriptor", __FUNCTION__); -+ m_context->ClearReference(surface); -+ return NULL; - } -- -- vs.sample.PlanarAlpha = DXVA2_Fixed32OpaqueAlpha(); -- vs.sample.SampleData = 0; -- vs.sample.SrcSurface = surface; -- -- -- if(!m_samples.empty()) -- m_samples.back().sample.End = vs.sample.Start; -- -- m_samples.push_back(vs); -- if (m_samples.size() > m_size) -+ // Convert to NV12 - Chroma -+ uint8_t *s_u, *s_v, *d_uv; -+ for (unsigned y = 0; y < picture->iHeight / 2; y++) - { -- SAFE_RELEASE(m_samples.front().renderPic); -- m_samples.pop_front(); -+ s_u = picture->data[1] + (y * picture->iLineSize[1]); -+ s_v = picture->data[2] + (y * picture->iLineSize[2]); -+ d_uv = ((uint8_t*)(rectangle.pBits)) + (desc.Height + y) * rectangle.Pitch; -+ for (unsigned x = 0; x < picture->iWidth / 2; x++) -+ { -+ *d_uv++ = *s_u++; -+ *d_uv++ = *s_v++; -+ } -+ } -+ if (FAILED(surface->UnlockRect())) -+ { -+ CLog::Log(LOGERROR, "%s - failed to unlock surface", __FUNCTION__); -+ m_context->ClearReference(surface); -+ return NULL; - } - -- return m_time; -+ m_context->ClearReference(surface); -+ m_context->MarkRender(surface); -+ CRenderPicture *pic = new CRenderPicture(m_context); -+ pic->surface = surface; -+ return pic; - } - - static DXVA2_Fixed32 ConvertRange(const DXVA2_ValueRange& range, int value, int min, int max, int def) -@@ -635,10 +582,13 @@ static DXVA2_Fixed32 ConvertRange(const DXVA2_ValueRange& range, int value, int - return range.DefaultValue; - } - --bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFERENCE_TIME time, DWORD flags) -+bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, IDirect3DSurface9** source, DWORD flags, UINT frameIdx) - { - CSingleLock lock(m_section); - -+ if (!source[2]) -+ return false; -+ - // With auto deinterlacing, the Ion Gen. 1 drops some frames with deinterlacing processor + progressive flags for progressive material. - // For that GPU (or when specified by an advanced setting), use the progressive processor. - // This is at the expense of the switch speed when video interlacing flags change and a deinterlacing processor is actually required. -@@ -657,29 +607,6 @@ bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFEREN - return false; - } - -- // MinTime and MaxTime are the first and last samples to keep. Delete the rest. -- REFERENCE_TIME MinTime = time - m_max_back_refs*2; -- REFERENCE_TIME MaxTime = time + m_max_fwd_refs*2; -- -- std::deque::iterator it = m_samples.begin(); -- while (it != m_samples.end()) -- { -- if (it->sample.Start < MinTime) -- { -- SAFE_RELEASE(it->renderPic); -- it = m_samples.erase(it); -- } -- else -- ++it; -- } -- -- if(m_samples.empty()) -- return false; -- -- // MinTime and MaxTime are now the first and last samples to feed the processor. -- MinTime = time - m_caps.NumBackwardRefSamples*2; -- MaxTime = time + m_caps.NumForwardRefSamples*2; -- - D3DSURFACE_DESC desc; - CHECK(target->GetDesc(&desc)); - CRect rectTarget(0, 0, desc.Width, desc.Height); -@@ -687,12 +614,37 @@ bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFEREN - RECT sourceRECT = { src.x1, src.y1, src.x2, src.y2 }; - RECT dstRECT = { dst.x1, dst.y1, dst.x2, dst.y2 }; - -+ // set sample format for progressive and interlaced -+ UINT sampleFormat = DXVA2_SampleProgressiveFrame; -+ if (flags & RENDER_FLAG_FIELD0 && flags & RENDER_FLAG_TOP) -+ sampleFormat = DXVA2_SampleFieldInterleavedEvenFirst; -+ else if (flags & RENDER_FLAG_FIELD1 && flags & RENDER_FLAG_BOT) -+ sampleFormat = DXVA2_SampleFieldInterleavedEvenFirst; -+ if (flags & RENDER_FLAG_FIELD0 && flags & RENDER_FLAG_BOT) -+ sampleFormat = DXVA2_SampleFieldInterleavedOddFirst; -+ if (flags & RENDER_FLAG_FIELD1 && flags & RENDER_FLAG_TOP) -+ sampleFormat = DXVA2_SampleFieldInterleavedOddFirst; - - // How to prepare the samples array for VideoProcessBlt - // - always provide current picture + the number of forward and backward references required by the current processor. - // - provide the surfaces in the array in increasing temporal order - // - at the start of playback, there may not be enough samples available. Use SampleFormat.SampleFormat = DXVA2_SampleUnknown for the missing samples. - -+ unsigned int providedPast = 0; -+ for (int i = 3; i < 8; i++) -+ { -+ if (source[i]) -+ providedPast++; -+ } -+ unsigned int providedFuture = 0; -+ for (int i = 1; i >= 0; i--) -+ { -+ if (source[i]) -+ providedFuture++; -+ } -+ int futureFrames = std::min(providedFuture, m_caps.NumForwardRefSamples); -+ int pastFrames = std::min(providedPast, m_caps.NumBackwardRefSamples); -+ - int count = 1 + m_caps.NumBackwardRefSamples + m_caps.NumForwardRefSamples; - int valid = 0; - auto_aptr samp(new DXVA2_VideoSample[count]); -@@ -700,50 +652,49 @@ bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFEREN - for (int i = 0; i < count; i++) - samp[i].SampleFormat.SampleFormat = DXVA2_SampleUnknown; - -- for(it = m_samples.begin(); it != m_samples.end() && valid < count; ++it) -+ int start = 2 - futureFrames; -+ int end = 2 + pastFrames; -+ int sampIdx = 0; -+ for (int i = start; i <= end; i++) - { -- if (it->sample.Start >= MinTime && it->sample.Start <= MaxTime) -+ if (!source[i]) -+ continue; -+ -+ if (i < 2) - { -- DXVA2_VideoSample& vs = samp[(it->sample.Start - MinTime) / 2]; -- vs = it->sample; -- vs.SrcRect = sourceRECT; -- vs.DstRect = dstRECT; -- if(vs.End == 0) -- vs.End = vs.Start + 2; -- -- // Override the sample format when the processor doesn't need to deinterlace or when deinterlacing is forced and flags are missing. -- if (m_progressive) -- vs.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame; -- else if (m_deinterlace_mode == VS_DEINTERLACEMODE_FORCE && vs.SampleFormat.SampleFormat == DXVA2_SampleProgressiveFrame) -- vs.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedEvenFirst; -- -- valid++; -+ // furture frames -+ sampIdx = 2 - i + m_caps.NumBackwardRefSamples; - } -- } -- -- // MS' guidelines above don't work. The blit fails when the processor is given DXVA2_SampleUnknown samples (with ATI at least). -- // The ATI driver works with a reduced number of samples though, support that for now. -- // Problem is an ambiguity if there are future refs requested by the processor. There are no such implementations at the moment. -- int offset = 0; -- if(valid < count) -- { -- CLog::Log(LOGWARNING, __FUNCTION__" - did not find all required samples, adjusting the sample array."); -- -- for (int i = 0; i < count; i++) -+ else if (i == 2) - { -- if (samp[i].SampleFormat.SampleFormat == DXVA2_SampleUnknown) -- offset = i+1; -+ // current frame -+ sampIdx = m_caps.NumBackwardRefSamples; - } -- count -= offset; -- if (count == 0) -+ else - { -- CLog::Log(LOGWARNING, __FUNCTION__" - no usable samples."); -- return false; -+ // past frames -+ sampIdx = m_caps.NumBackwardRefSamples - (i-2); - } -+ DXVA2_VideoSample& vs = samp[sampIdx]; -+ vs.SrcSurface = source[i]; -+ vs.SrcRect = sourceRECT; -+ vs.DstRect = dstRECT; -+ vs.SampleData = 0; -+ vs.Start = frameIdx + sampIdx - m_caps.NumBackwardRefSamples; -+ vs.End = vs.Start + 2; -+ vs.PlanarAlpha = DXVA2_Fixed32OpaqueAlpha(); -+ vs.SampleFormat.SampleFormat = sampleFormat; -+ -+ // Override the sample format when the processor doesn't need to deinterlace or when deinterlacing is forced and flags are missing. -+ if (m_progressive) -+ vs.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame; -+ else if (m_deinterlace_mode == VS_DEINTERLACEMODE_FORCE && vs.SampleFormat.SampleFormat == DXVA2_SampleProgressiveFrame) -+ vs.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedEvenFirst; - } - -+ - DXVA2_VideoProcessBltParams blt = {}; -- blt.TargetFrame = time; -+ blt.TargetFrame = frameIdx; - if (flags & RENDER_FLAG_FIELD1) - blt.TargetFrame += 1; - blt.TargetRect = dstRECT; -@@ -776,7 +727,7 @@ bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFEREN - float verts[2][3]= {}; - g_Windowing.Get3DDevice()->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 1, verts, 3*sizeof(float)); - -- CHECK(m_process->VideoProcessBlt(target, &blt, &samp[offset], count, NULL)); -+ CHECK(m_process->VideoProcessBlt(target, &blt, &samp[0], count, NULL)); - return true; - } - -diff --git a/xbmc/cores/VideoRenderers/DXVA.h b/xbmc/cores/VideoRenderers/DXVA.h -index 233c59b..460e665 100644 ---- a/xbmc/cores/VideoRenderers/DXVA.h -+++ b/xbmc/cores/VideoRenderers/DXVA.h -@@ -44,9 +44,10 @@ class CProcessor - virtual void UnInit(); - virtual bool Open(UINT width, UINT height, unsigned int flags, unsigned int format, unsigned int extended_format); - virtual void Close(); -- virtual REFERENCE_TIME Add(DVDVideoPicture* picture); -- virtual bool Render(CRect src, CRect dst, IDirect3DSurface9* target, const REFERENCE_TIME time, DWORD flags); -+ virtual CRenderPicture *Convert(DVDVideoPicture* picture); -+ virtual bool Render(CRect src, CRect dst, IDirect3DSurface9* target, IDirect3DSurface9** source, DWORD flags, UINT frameIdx); - virtual unsigned Size() { if (m_service) return m_size; return 0; } -+ virtual unsigned PastRefs() { return m_max_back_refs; } - - virtual void OnCreateDevice() {} - virtual void OnDestroyDevice() { CSingleLock lock(m_section); Close(); } -@@ -72,21 +73,12 @@ class CProcessor - DXVA2_ValueRange m_contrast; - DXVA2_ValueRange m_hue; - DXVA2_ValueRange m_saturation; -- REFERENCE_TIME m_time; - unsigned m_size; - unsigned m_max_back_refs; - unsigned m_max_fwd_refs; - EDEINTERLACEMODE m_deinterlace_mode; - EINTERLACEMETHOD m_interlace_method; - bool m_progressive; // true for progressive source or to force ignoring interlacing flags. -- unsigned m_index; -- -- struct SVideoSample -- { -- DXVA2_VideoSample sample; -- CRenderPicture* renderPic; -- }; -- std::deque m_samples; - - CCriticalSection m_section; - CSurfaceContext* m_context; -diff --git a/xbmc/cores/VideoRenderers/DXVAHD.cpp b/xbmc/cores/VideoRenderers/DXVAHD.cpp -index 6788e58..8834aa5 100644 ---- a/xbmc/cores/VideoRenderers/DXVAHD.cpp -+++ b/xbmc/cores/VideoRenderers/DXVAHD.cpp -@@ -84,8 +84,6 @@ CProcessorHD::CProcessorHD() - { - m_pDXVAHD = NULL; - m_pDXVAVP = NULL; -- m_index = 0; -- m_frame = 0; - g_Windowing.Register(this); - - m_context = NULL; -@@ -108,13 +106,6 @@ void CProcessorHD::Close() - { - CSingleLock lock(m_section); - SAFE_RELEASE(m_pDXVAVP); -- -- for(unsigned i = 0; i < m_frames.size(); i++) -- { -- SAFE_RELEASE(m_frames[i].pRenderPic); -- } -- m_frames.clear(); -- - SAFE_RELEASE(m_context); - } - -@@ -264,8 +255,6 @@ bool CProcessorHD::Open(UINT width, UINT height, unsigned int flags, unsigned in - return false; - } - -- m_frame = 0; -- - return true; - } - -@@ -340,120 +329,6 @@ bool CProcessorHD::CreateSurfaces() - return true; - } - --REFERENCE_TIME CProcessorHD::Add(DVDVideoPicture* picture) --{ -- CSingleLock lock(m_section); -- -- IDirect3DSurface9* surface = NULL; -- -- if (picture->iFlags & DVP_FLAG_DROPPED) -- { -- return 0; -- } -- -- switch (picture->format) -- { -- case RENDER_FMT_DXVA: -- { -- surface = picture->dxva->surface; -- break; -- } -- -- case RENDER_FMT_YUV420P: -- { -- if (!m_context) -- { -- CLog::Log(LOGWARNING, __FUNCTION__" - not initialized."); -- return 0; -- } -- -- surface = m_context->GetAtIndex(m_index); -- m_index = (m_index + 1) % m_size; -- -- D3DLOCKED_RECT rectangle; -- if (FAILED(surface->LockRect(&rectangle, NULL, 0))) -- { -- return 0; -- } -- -- // Convert to NV12 - Luma -- // TODO: Optimize this later using shaders/swscale/etc. -- uint8_t *s = picture->data[0]; -- uint8_t* bits = (uint8_t*)(rectangle.pBits); -- for (unsigned y = 0; y < picture->iHeight; y++) -- { -- memcpy(bits, s, picture->iWidth); -- s += picture->iLineSize[0]; -- bits += rectangle.Pitch; -- } -- -- D3DSURFACE_DESC desc; -- if (FAILED(surface->GetDesc(&desc))) -- { -- return 0; -- } -- -- // Convert to NV12 - Chroma -- uint8_t *s_u, *s_v, *d_uv; -- for (unsigned y = 0; y < picture->iHeight/2; y++) -- { -- s_u = picture->data[1] + (y * picture->iLineSize[1]); -- s_v = picture->data[2] + (y * picture->iLineSize[2]); -- d_uv = ((uint8_t*)(rectangle.pBits)) + (desc.Height + y) * rectangle.Pitch; -- for (unsigned x = 0; x < picture->iWidth/2; x++) -- { -- *d_uv++ = *s_u++; -- *d_uv++ = *s_v++; -- } -- } -- -- if (FAILED(surface->UnlockRect())) -- { -- return 0; -- } -- break; -- } -- -- default: -- { -- CLog::Log(LOGWARNING, __FUNCTION__" - colorspace not supported by processor, skipping frame."); -- return 0; -- } -- } -- -- if (!surface) -- { -- return 0; -- } -- m_frame += 2; -- -- SFrame frame = {}; -- frame.index = m_frame; -- frame.pSurface = surface; -- frame.pRenderPic = NULL; -- if (picture->format == RENDER_FMT_DXVA) -- frame.pRenderPic = picture->dxva->Acquire(); -- frame.format = DXVAHD_FRAME_FORMAT_PROGRESSIVE; -- -- if (picture->iFlags & DVP_FLAG_INTERLACED) -- { -- frame.format = picture->iFlags & DVP_FLAG_TOP_FIELD_FIRST -- ? DXVAHD_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST -- : DXVAHD_FRAME_FORMAT_INTERLACED_BOTTOM_FIELD_FIRST; -- } -- -- m_frames.push_back(frame); -- -- if (m_frames.size() > m_size) -- { -- SAFE_RELEASE(m_frames.front().pRenderPic); -- -- m_frames.pop_front(); -- } -- -- return m_frame; --} -- - bool CProcessorHD::ApplyFilter(DXVAHD_FILTER filter, int value, int min, int max, int def) - { - if (filter > NUM_FILTERS) -@@ -488,7 +363,7 @@ bool CProcessorHD::ApplyFilter(DXVAHD_FILTER filter, int value, int min, int max - return !FAILED( m_pDXVAVP->SetVideoProcessStreamState( 0, state, sizeof(data), &data ) ); - } - --bool CProcessorHD::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFERENCE_TIME frame, DWORD flags) -+bool CProcessorHD::Render(CRect src, CRect dst, IDirect3DSurface9* target, IDirect3DSurface9** source, DWORD flags, UINT frameIdx) - { - CSingleLock lock(m_section); - -@@ -498,6 +373,9 @@ bool CProcessorHD::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFER - return false; - } - -+ if (!source[2]) -+ return false; -+ - EDEINTERLACEMODE deinterlace_mode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; - if (g_advancedSettings.m_DXVANoDeintProcForProgressive) - deinterlace_mode = (flags & RENDER_FLAG_FIELD0 || flags & RENDER_FLAG_FIELD1) ? VS_DEINTERLACEMODE_FORCE : VS_DEINTERLACEMODE_OFF; -@@ -507,26 +385,6 @@ bool CProcessorHD::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFER - || ( interlace_method != VS_INTERLACEMETHOD_DXVA_BOB - && interlace_method != VS_INTERLACEMETHOD_DXVA_BEST); - -- // minFrame is the first samples to keep. Delete the rest. -- REFERENCE_TIME minFrame = frame - m_max_back_refs * 2; -- -- SFrames::iterator it = m_frames.begin(); -- while (it != m_frames.end()) -- { -- if (it->index < minFrame) -- { -- SAFE_RELEASE(it->pRenderPic); -- it = m_frames.erase(it); -- } -- else -- ++it; -- } -- -- if(m_frames.empty()) -- { -- return false; -- } -- - D3DSURFACE_DESC desc; - CHECK(target->GetDesc(&desc)); - CRect rectTarget(0, 0, desc.Width, desc.Height); -@@ -534,51 +392,62 @@ bool CProcessorHD::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFER - RECT sourceRECT = { src.x1, src.y1, src.x2, src.y2 }; - RECT dstRECT = { dst.x1, dst.y1, dst.x2, dst.y2 }; - -- // MinTime and MaxTime are now the first and last samples to feed the processor. -- minFrame = frame - m_VPCaps.PastFrames * 2; -- REFERENCE_TIME maxFrame = frame + m_VPCaps.FutureFrames * 2; -- -- bool isValid(false); - DXVAHD_FRAME_FORMAT dxvaFrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE; - -+ unsigned int providedPast = 0; -+ for (int i = 3; i < 8; i++) -+ { -+ if (source[i]) -+ providedPast++; -+ } -+ unsigned int providedFuture = 0; -+ for (int i = 1; i >= 0; i--) -+ { -+ if (source[i]) -+ providedFuture++; -+ } -+ int futureFrames = std::min(providedFuture, m_VPCaps.FutureFrames); -+ int pastFrames = std::min(providedPast, m_VPCaps.PastFrames); -+ - DXVAHD_STREAM_DATA stream_data = { 0 }; - stream_data.Enable = TRUE; -- stream_data.PastFrames = 0; -- stream_data.FutureFrames = 0; -- stream_data.ppPastSurfaces = new IDirect3DSurface9*[m_VPCaps.PastFrames]; -- stream_data.ppFutureSurfaces = new IDirect3DSurface9*[m_VPCaps.FutureFrames]; -+ stream_data.PastFrames = pastFrames; -+ stream_data.FutureFrames = futureFrames; -+ stream_data.ppPastSurfaces = new IDirect3DSurface9*[pastFrames]; -+ stream_data.ppFutureSurfaces = new IDirect3DSurface9*[futureFrames]; -+ -+ int start = 2 - futureFrames; -+ int end = 2 + pastFrames; - -- for(it = m_frames.begin(); it != m_frames.end(); ++it) -+ for (int i = start; i <= end; i++) - { -- if (it->index >= minFrame && it->index <= maxFrame) -+ if (!source[i]) -+ continue; -+ -+ if (i > 2) - { -- if (it->index < frame) -- { -- // frames order should be { .., T-1, T-2, T-3 } -- stream_data.ppPastSurfaces[(frame - it->index)/2 - 1] = it->pSurface; -- stream_data.PastFrames++; -- } -- else if (it->index == frame) -- { -- stream_data.pInputSurface = it->pSurface; -- dxvaFrameFormat = (DXVAHD_FRAME_FORMAT) it->format; -- isValid = true; -- } -- else if (it->index > frame) -- { -- // frames order should be { T+1, T+2, T+3, .. } -- stream_data.ppFutureSurfaces[(it->index - frame)/2 - 1] = it->pSurface; -- stream_data.FutureFrames++; -- } -+ // frames order should be { ?, T-3, T-2, T-1 } -+ stream_data.ppPastSurfaces[2+pastFrames-i] = source[i]; -+ } -+ else if (i == 2) -+ { -+ stream_data.pInputSurface = source[2]; -+ } -+ else if (i < 2) -+ { -+ // frames order should be { T+1, T+2, T+3, .. } -+ stream_data.ppFutureSurfaces[1-i] = source[i]; - } - } - -- // no present frame, skip -- if (!isValid) -- { -- CLog::Log(LOGWARNING, __FUNCTION__" - uncomplete stream data, skipping frame."); -- return false; -- } -+ if (flags & RENDER_FLAG_FIELD0 && flags & RENDER_FLAG_TOP) -+ dxvaFrameFormat = DXVAHD_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST; -+ else if (flags & RENDER_FLAG_FIELD1 && flags & RENDER_FLAG_BOT) -+ dxvaFrameFormat = DXVAHD_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST; -+ if (flags & RENDER_FLAG_FIELD0 && flags & RENDER_FLAG_BOT) -+ dxvaFrameFormat = DXVAHD_FRAME_FORMAT_INTERLACED_BOTTOM_FIELD_FIRST; -+ if (flags & RENDER_FLAG_FIELD1 && flags & RENDER_FLAG_TOP) -+ dxvaFrameFormat = DXVAHD_FRAME_FORMAT_INTERLACED_BOTTOM_FIELD_FIRST; - - // Override the sample format when the processor doesn't need to deinterlace or when deinterlacing is forced and flags are missing. - if (progressive) -@@ -594,7 +463,7 @@ bool CProcessorHD::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFER - bool frameProgressive = dxvaFrameFormat == DXVAHD_FRAME_FORMAT_PROGRESSIVE; - - // Progressive or Interlaced video at normal rate. -- stream_data.InputFrameOrField = frame + (flags & RENDER_FLAG_FIELD1 ? 1 : 0); -+ stream_data.InputFrameOrField = frameIdx; - stream_data.OutputIndex = flags & RENDER_FLAG_FIELD1 && !frameProgressive ? 1 : 0; - - DXVAHD_STREAM_STATE_FRAME_FORMAT_DATA frame_format = { dxvaFrameFormat }; -@@ -630,7 +499,7 @@ bool CProcessorHD::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFER - LOGIFERROR( m_pDXVAVP->SetVideoProcessBltState( DXVAHD_BLT_STATE_TARGET_RECT - , sizeof(targetRect), &targetRect ) ); - -- HRESULT hr = m_pDXVAVP->VideoProcessBltHD(target, frame, 1, &stream_data); -+ HRESULT hr = m_pDXVAVP->VideoProcessBltHD(target, frameIdx, 1, &stream_data); - if(FAILED(hr)) - { - CLog::Log(LOGERROR, __FUNCTION__" - failed executing VideoProcessBltHD with error %x", hr); -diff --git a/xbmc/cores/VideoRenderers/DXVAHD.h b/xbmc/cores/VideoRenderers/DXVAHD.h -index a6ab9f5..00b6948 100644 ---- a/xbmc/cores/VideoRenderers/DXVAHD.h -+++ b/xbmc/cores/VideoRenderers/DXVAHD.h -@@ -59,9 +59,9 @@ class CProcessorHD - virtual void UnInit(); - virtual bool Open(UINT width, UINT height, unsigned int flags, unsigned int format, unsigned int extended_format); - virtual void Close(); -- virtual REFERENCE_TIME Add(DVDVideoPicture* picture); -- virtual bool Render(CRect src, CRect dst, IDirect3DSurface9* target, const REFERENCE_TIME time, DWORD flags); -+ virtual bool Render(CRect src, CRect dst, IDirect3DSurface9* target, IDirect3DSurface9 **source, DWORD flags, UINT frameIdx); - virtual unsigned Size() { if (m_pDXVAHD) return m_size; return 0; } -+ virtual unsigned PastRefs() { return m_max_back_refs; } - - virtual void OnCreateDevice() {} - virtual void OnDestroyDevice() { CSingleLock lock(m_section); UnInit(); } -@@ -83,7 +83,6 @@ class CProcessorHD - unsigned int m_width; - unsigned int m_height; - D3DFORMAT m_format; -- REFERENCE_TIME m_frame; - unsigned int m_flags; - unsigned int m_renderFormat; - -@@ -94,15 +93,6 @@ class CProcessorHD - }; - ProcAmpInfo m_Filters[NUM_FILTERS]; - -- struct SFrame -- { -- IDirect3DSurface9* pSurface; -- CRenderPicture* pRenderPic; -- unsigned int index; -- unsigned format; -- }; -- typedef std::deque SFrames; -- SFrames m_frames; - static DXVAHDCreateVideoServicePtr m_DXVAHDCreateVideoService; - }; - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index b2f2d1f..7300896 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -262,13 +262,7 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi - m_format = format; - - int processor = m_pRenderer->GetProcessorSize(); -- 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 */ -- -+ m_QueueSize = std::min(buffers, processor); - m_QueueSize = std::min(m_QueueSize, (int)m_pRenderer->GetMaxBufferSize()); - m_QueueSize = std::min(m_QueueSize, NUM_BUFFERS); - if(m_QueueSize < 2) -@@ -365,11 +359,16 @@ void CXBMCRenderManager::FrameMove() - /* release all previous */ - for(std::deque::iterator it = m_discard.begin(); it != m_discard.end(); ) - { -- // TODO check for fence -- m_pRenderer->ReleaseBuffer(*it); -- m_overlays.Release(*it); -- m_free.push_back(*it); -- it = m_discard.erase(it); -+ // renderer may want to keep the frame for postprocessing -+ if (!m_pRenderer->NeedBufferForRef(*it)) -+ { -+ m_pRenderer->ReleaseBuffer(*it); -+ m_overlays.Release(*it); -+ m_free.push_back(*it); -+ it = m_discard.erase(it); -+ } -+ else -+ ++it; - } - } - } -diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp -index d76c6b0..a5e515f 100644 ---- a/xbmc/cores/VideoRenderers/WinRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/WinRenderer.cpp -@@ -198,6 +198,7 @@ void CWinRenderer::SelectRenderMethod() - - RenderMethodDetail *rmdet = FindRenderMethod(m_renderMethod); - CLog::Log(LOGDEBUG, __FUNCTION__": Selected render method %d: %s", m_renderMethod, rmdet != NULL ? rmdet->name : "unknown"); -+ m_frameIdx = 0; - } - - bool CWinRenderer::UpdateRenderMethod() -@@ -270,6 +271,11 @@ int CWinRenderer::NextYV12Texture() - - bool CWinRenderer::AddVideoPicture(DVDVideoPicture* picture, int index) - { -+ if (!m_NumYV12Buffers) -+ { -+ return false; -+ } -+ - if (m_renderMethod == RENDER_DXVA) - { - int source = index; -@@ -277,7 +283,17 @@ bool CWinRenderer::AddVideoPicture(DVDVideoPicture* picture, int index) - return false; - - DXVABuffer *buf = (DXVABuffer*)m_VideoBuffers[source]; -- buf->id = m_processor->Add(picture); -+ SAFE_RELEASE(buf->pic); -+ if (picture->format == RENDER_FMT_DXVA) -+ { -+ buf->pic = picture->dxva->Acquire(); -+ } -+ else -+ { -+ buf->pic = m_processor->Convert(picture); -+ } -+ buf->frameIdx = m_frameIdx; -+ m_frameIdx += 2; - return true; - } - return false; -@@ -341,7 +357,9 @@ void CWinRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - else - pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); - -- if (!m_bConfigured) return; -+ if (!m_bConfigured) -+ return; -+ - ManageTextures(); - - CSingleLock lock(g_graphicsContext); -@@ -998,6 +1016,9 @@ void CWinRenderer::RenderProcessor(DWORD flags) - - DXVABuffer *image = (DXVABuffer*)m_VideoBuffers[m_iYV12RenderBuffer]; - -+ if (!image->pic) -+ return; -+ - IDirect3DSurface9* target; - if ( m_bUseHQScaler - || g_graphicsContext.GetStereoMode() == RENDER_STEREO_MODE_ANAGLYPH_RED_CYAN -@@ -1014,7 +1035,50 @@ void CWinRenderer::RenderProcessor(DWORD flags) - } - } - -- m_processor->Render(m_sourceRect, destRect, target, image->id, flags); -+ IDirect3DSurface9 *source[8]; -+ memset(source, 0, 8 * sizeof(IDirect3DSurface9*)); -+ source[2] = image->pic->surface; -+ -+ int past = 0; -+ int future = 0; -+ DXVABuffer **buffers = (DXVABuffer**)m_VideoBuffers; -+ -+ // set future frames -+ while (future < 2) -+ { -+ bool found = false; -+ for (int i = 0; i < m_NumYV12Buffers; i++) -+ { -+ if (buffers[i] && buffers[i]->pic && buffers[i]->frameIdx == image->frameIdx + (future + 2)) -+ { -+ source[1 - future++] = buffers[i]->pic->surface; -+ found = true; -+ break; -+ } -+ } -+ if (!found) -+ break; -+ } -+ -+ // set past frames -+ while (past < 4) -+ { -+ bool found = false; -+ for (int i = 0; i < m_NumYV12Buffers; i++) -+ { -+ if (buffers[i] && buffers[i]->pic && buffers[i]->frameIdx == image->frameIdx - (past + 2)) -+ { -+ source[3 + past++] = buffers[i]->pic->surface; -+ found = true; -+ break; -+ } -+ } -+ if (!found) -+ break; -+ } -+ -+ -+ m_processor->Render(m_sourceRect, destRect, target, source, flags, image->frameIdx); - - target->Release(); - -@@ -1255,6 +1319,29 @@ unsigned int CWinRenderer::GetProcessorSize() - return 0; - } - -+void CWinRenderer::ReleaseBuffer(int idx) -+{ -+ if (m_renderMethod == RENDER_DXVA && m_VideoBuffers[idx]) -+ SAFE_RELEASE(((DXVABuffer*)m_VideoBuffers[idx])->pic); -+} -+ -+bool CWinRenderer::NeedBufferForRef(int idx) -+{ -+ // check if processor wants to keep past frames -+ if (m_format == RENDER_FMT_DXVA && m_processor) -+ { -+ DXVABuffer** buffers = (DXVABuffer**)m_VideoBuffers; -+ -+ int numPast = m_processor->PastRefs(); -+ if (buffers[idx] && buffers[idx]->pic) -+ { -+ if (buffers[idx]->frameIdx + numPast*2 >= buffers[m_iYV12RenderBuffer]->frameIdx) -+ return true; -+ } -+ } -+ return false; -+} -+ - //============================================ - - YUVBuffer::~YUVBuffer() -@@ -1405,21 +1492,4 @@ void YUVBuffer::Clear() - } - } - -- --//================================== -- --DXVABuffer::~DXVABuffer() --{ -- Release(); --} -- --void DXVABuffer::Release() --{ -- id = 0; --} -- --void DXVABuffer::StartDecode() --{ -- Release(); --} - #endif -diff --git a/xbmc/cores/VideoRenderers/WinRenderer.h b/xbmc/cores/VideoRenderers/WinRenderer.h -index 10d7613..6d081a3 100644 ---- a/xbmc/cores/VideoRenderers/WinRenderer.h -+++ b/xbmc/cores/VideoRenderers/WinRenderer.h -@@ -128,13 +128,11 @@ struct DXVABuffer : SVideoBuffer - { - DXVABuffer() - { -- id = 0; -+ pic = NULL; - } -- ~DXVABuffer(); -- virtual void Release(); -- virtual void StartDecode(); -- -- int64_t id; -+ ~DXVABuffer() { SAFE_RELEASE(pic); } -+ DXVA::CRenderPicture *pic; -+ unsigned int frameIdx; - }; - - class CWinRenderer : public CBaseRenderer -@@ -173,6 +171,8 @@ class CWinRenderer : public CBaseRenderer - virtual unsigned int GetProcessorSize(); - virtual void SetBufferSize(int numBuffers) { m_neededBuffers = numBuffers; } - virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } -+ virtual void ReleaseBuffer(int idx); -+ virtual bool NeedBufferForRef(int idx); - - protected: - virtual void Render(DWORD flags); -@@ -240,6 +240,7 @@ class CWinRenderer : public CBaseRenderer - unsigned int m_destHeight; - - int m_neededBuffers; -+ unsigned int m_frameIdx; - }; - - #else -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp -index ef83840..b9c90c2 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp -@@ -1091,7 +1091,6 @@ void CDecoder::RelBuffer(uint8_t *data) - { - CLog::Log(LOGWARNING, "%s - return of invalid surface", __FUNCTION__); - } -- - m_surface_context->ClearReference(surface); - - Release(); - -From d838433713638503a74a6be70a351c06ca1c7747 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 14 Sep 2014 12:24:31 +0200 -Subject: [PATCH 03/31] dxva: flush ffmpeg buffers if it holds any refs on - close - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp | 25 ++++++++++++++++++++++++- - xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h | 3 +++ - 2 files changed, 27 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp -index b9c90c2..8de6167 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 1b8a45d..9d92efc 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; - - -From 2cf7f1b4e7bde22067c5c4f18d8db02573bc098e Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 16 Sep 2014 11:50:11 +0200 -Subject: [PATCH 04/31] renderer: rename/correct GetProcessorSize, processor is - not exposed anymore - ---- - xbmc/cores/VideoRenderers/BaseRenderer.h | 2 +- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 14 +++++--------- - xbmc/cores/VideoRenderers/LinuxRendererGL.h | 2 +- - xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 10 ++-------- - xbmc/cores/VideoRenderers/LinuxRendererGLES.h | 2 +- - xbmc/cores/VideoRenderers/RenderManager.cpp | 6 +++--- - xbmc/cores/VideoRenderers/WinRenderer.cpp | 4 ++-- - xbmc/cores/VideoRenderers/WinRenderer.h | 2 +- - 8 files changed, 16 insertions(+), 26 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h -index d303598..7c2bc01 100644 ---- a/xbmc/cores/VideoRenderers/BaseRenderer.h -+++ b/xbmc/cores/VideoRenderers/BaseRenderer.h -@@ -89,7 +89,7 @@ class CBaseRenderer - /** - * Returns number of references a single buffer can retain when rendering a single frame - */ -- virtual unsigned int GetProcessorSize() { return 0; } -+ virtual unsigned int GetBufferSize() { return 0; } - virtual unsigned int GetMaxBufferSize() { return 0; } - virtual void SetBufferSize(int numBuffers) { } - virtual void ReleaseBuffer(int idx) { } -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index 417577d..e5dbc2e 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -3496,16 +3496,12 @@ void CLinuxRendererGL::UnBindPbo(YUVBUFFER& buff) - glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); - } - --unsigned int CLinuxRendererGL::GetProcessorSize() --{ -- if(m_format == RENDER_FMT_VDPAU -- || m_format == RENDER_FMT_VDPAU_420 -- || m_format == RENDER_FMT_VAAPI -- || m_format == RENDER_FMT_VAAPINV12 -- || m_format == RENDER_FMT_CVBREF) -- return 1; -+unsigned int CLinuxRendererGL::GetBufferSize() -+{ -+ if(m_format == RENDER_FMT_CVBREF) -+ return 2; - else -- return 0; -+ return 3; - } - - #ifdef HAVE_LIBVDPAU -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index 1e46940..275ef29 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -136,7 +136,7 @@ class CLinuxRendererGL : public CBaseRenderer - virtual void ReleaseBuffer(int idx); - virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; } - virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } -- virtual unsigned int GetProcessorSize(); -+ virtual unsigned int GetBufferSize(); - - #ifdef HAVE_LIBVDPAU - virtual void AddProcessor(VDPAU::CVdpauRenderPicture* vdpau, int index); -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -index 8db4ea1..24669e6 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -@@ -2893,15 +2893,9 @@ EINTERLACEMETHOD CLinuxRendererGLES::AutoInterlaceMethod() - #endif - } - --unsigned int CLinuxRendererGLES::GetProcessorSize() -+unsigned int CLinuxRendererGLES::GetBufferSize() - { -- if(m_format == RENDER_FMT_OMXEGL -- || m_format == RENDER_FMT_CVBREF -- || m_format == RENDER_FMT_EGLIMG -- || m_format == RENDER_FMT_MEDIACODEC) -- return 1; -- else -- return 0; -+ return 2; - } - - #ifdef HAVE_LIBOPENMAX -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -index 1e89ecf..058d76c 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -@@ -143,7 +143,7 @@ class CLinuxRendererGLES : public CBaseRenderer - virtual void ReleaseBuffer(int idx); - virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; } - virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } -- virtual unsigned int GetProcessorSize(); -+ virtual unsigned int GetBufferSize(); - - virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index 7300896..cc72781 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -261,14 +261,14 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi - lock2.Enter(); - m_format = format; - -- int processor = m_pRenderer->GetProcessorSize(); -- m_QueueSize = std::min(buffers, processor); -+ int renderbuffers = m_pRenderer->GetBufferSize(); -+ m_QueueSize = std::min(buffers, renderbuffers); - m_QueueSize = std::min(m_QueueSize, (int)m_pRenderer->GetMaxBufferSize()); - m_QueueSize = std::min(m_QueueSize, NUM_BUFFERS); - if(m_QueueSize < 2) - { - m_QueueSize = 2; -- CLog::Log(LOGWARNING, "CXBMCRenderManager::Configure - queue size too small (%d, %d, %d)", m_QueueSize, processor, buffers); -+ CLog::Log(LOGWARNING, "CXBMCRenderManager::Configure - queue size too small (%d, %d, %d)", m_QueueSize, renderbuffers, buffers); - } - - m_pRenderer->SetBufferSize(m_QueueSize); -diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp -index a5e515f..d995d77 100644 ---- a/xbmc/cores/VideoRenderers/WinRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/WinRenderer.cpp -@@ -1311,12 +1311,12 @@ EINTERLACEMETHOD CWinRenderer::AutoInterlaceMethod() - return VS_INTERLACEMETHOD_DEINTERLACE_HALF; - } - --unsigned int CWinRenderer::GetProcessorSize() -+unsigned int CWinRenderer::GetBufferSize() - { - if (m_format == RENDER_FMT_DXVA && m_processor) - return m_processor->Size(); - else -- return 0; -+ return 2; - } - - void CWinRenderer::ReleaseBuffer(int idx) -diff --git a/xbmc/cores/VideoRenderers/WinRenderer.h b/xbmc/cores/VideoRenderers/WinRenderer.h -index 6d081a3..f8b0d6f 100644 ---- a/xbmc/cores/VideoRenderers/WinRenderer.h -+++ b/xbmc/cores/VideoRenderers/WinRenderer.h -@@ -168,7 +168,7 @@ class CWinRenderer : public CBaseRenderer - - void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); - -- virtual unsigned int GetProcessorSize(); -+ virtual unsigned int GetBufferSize(); - virtual void SetBufferSize(int numBuffers) { m_neededBuffers = numBuffers; } - virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } - virtual void ReleaseBuffer(int idx); - -From 2abf53e056b70991f8610e62dc496962dca088aa Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Wed, 17 Sep 2014 11:14:43 +0200 -Subject: [PATCH 05/31] squash render - ---- - xbmc/cores/VideoRenderers/DXVA.cpp | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/DXVA.cpp b/xbmc/cores/VideoRenderers/DXVA.cpp -index e38a9f0..b3de758 100644 ---- a/xbmc/cores/VideoRenderers/DXVA.cpp -+++ b/xbmc/cores/VideoRenderers/DXVA.cpp -@@ -645,13 +645,9 @@ bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, IDirect - int futureFrames = std::min(providedFuture, m_caps.NumForwardRefSamples); - int pastFrames = std::min(providedPast, m_caps.NumBackwardRefSamples); - -- int count = 1 + m_caps.NumBackwardRefSamples + m_caps.NumForwardRefSamples; -- int valid = 0; -+ int count = 1 + pastFrames + futureFrames; - auto_aptr samp(new DXVA2_VideoSample[count]); - -- for (int i = 0; i < count; i++) -- samp[i].SampleFormat.SampleFormat = DXVA2_SampleUnknown; -- - int start = 2 - futureFrames; - int end = 2 + pastFrames; - int sampIdx = 0; -@@ -680,7 +676,7 @@ bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, IDirect - vs.SrcRect = sourceRECT; - vs.DstRect = dstRECT; - vs.SampleData = 0; -- vs.Start = frameIdx + sampIdx - m_caps.NumBackwardRefSamples; -+ vs.Start = frameIdx + (sampIdx - pastFrames) * 2; - vs.End = vs.Start + 2; - vs.PlanarAlpha = DXVA2_Fixed32OpaqueAlpha(); - vs.SampleFormat.SampleFormat = sampleFormat; - From 223f17f5921aa453053a56e1ee0fa7d2293e107d Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 28 May 2012 10:34:39 +0200 @@ -4667,148 +2408,3 @@ index f5f4654..5de26a4 100644 Sleep(10); continue; } - -From 7a56b2d58c00948282e65f8f532caaccd2f785e6 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Wed, 17 Sep 2014 12:27:49 +0200 -Subject: [PATCH 29/31] vaapi: flush ffmpeg buffers if it holds any refs on - close - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 20 ++++++++++++++++++++ - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 2 ++ - 2 files changed, 22 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index 0edb0eb..cb70740 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -417,6 +417,17 @@ bool CVideoSurfaces::HasFree() - return !m_freeSurfaces.empty(); - } - -+bool CVideoSurfaces::HasRefs() -+{ -+ CSingleLock lock(m_section); -+ for (std::map::iterator it = m_state.begin(); it != m_state.end(); ++it) -+ { -+ if (it->second & SURFACE_USED_FOR_REFERENCE) -+ return true; -+ } -+ return false; -+} -+ - //----------------------------------------------------------------------------- - // VAAPI - //----------------------------------------------------------------------------- -@@ -440,6 +451,7 @@ CDecoder::CDecoder() : m_vaapiOutput(&m_inMsgEvent) - m_vaapiConfig.context = 0; - m_vaapiConfig.contextId = VA_INVALID_ID; - m_vaapiConfig.configId = VA_INVALID_ID; -+ m_avctx = NULL; - } - - CDecoder::~CDecoder() -@@ -568,6 +580,8 @@ bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat fmt, unsigned - avctx->hwaccel_context = &m_hwContext; - avctx->get_buffer2 = CDecoder::FFGetBuffer; - avctx->slice_flags = SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD; -+ -+ m_avctx = avctx; - return true; - } - -@@ -586,6 +600,12 @@ void CDecoder::Close() - - long CDecoder::Release() - { -+ // if ffmpeg holds any references, flush buffers -+ if (m_avctx && m_videoSurfaces.HasRefs()) -+ { -+ avcodec_flush_buffers(m_avctx); -+ } -+ - // check if we should do some pre-cleanup here - // a second decoder might need resources - if (m_vaapiConfigured == true) -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -index d937eea..63fdb69 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -@@ -331,6 +331,7 @@ class CVideoSurfaces - void Reset(); - int Size(); - bool HasFree(); -+ bool HasRefs(); - protected: - std::map m_state; - std::list m_freeSurfaces; -@@ -427,6 +428,7 @@ class CDecoder - CVaapiConfig m_vaapiConfig; - CVideoSurfaces m_videoSurfaces; - vaapi_context m_hwContext; -+ AVCodecContext* m_avctx; - - COutput m_vaapiOutput; - CVaapiBufferStats m_bufferStats; - -From 499284507842eb82a0497d03539bac576ec888f8 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Wed, 17 Sep 2014 12:30:09 +0200 -Subject: [PATCH 30/31] vaapi: drop unused member - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 1 - - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 1 - - 2 files changed, 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index cb70740..3ecd540 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -495,7 +495,6 @@ bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat fmt, unsigned - m_vaapiConfig.surfaceWidth = avctx->width; - m_vaapiConfig.surfaceHeight = avctx->height; - m_vaapiConfig.aspect = avctx->sample_aspect_ratio; -- m_vaapiConfig.numRenderBuffers = surfaces; - m_decoderThread = CThread::GetCurrentThreadId(); - m_DisplayState = VAAPI_OPEN; - m_vaapiConfigured = false; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -index 63fdb69..c5a0071 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -@@ -116,7 +116,6 @@ struct CVaapiConfig - CDecoder *vaapi; - int upscale; - CVideoSurfaces *videoSurfaces; -- int numRenderBuffers; - uint32_t maxReferences; - bool useInteropYuv; - CVAAPIContext *context; - -From be5471189e521da1b23ae78bd0b276b981cbf737 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Wed, 17 Sep 2014 12:50:47 +0200 -Subject: [PATCH 31/31] renderer: bump number of buffers for vdpau and vaapi - ---- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index e5dbc2e..72bcbfa 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -3500,6 +3500,11 @@ unsigned int CLinuxRendererGL::GetBufferSize() - { - if(m_format == RENDER_FMT_CVBREF) - return 2; -+ else if (m_format == RENDER_FMT_VAAPI || -+ m_format == RENDER_FMT_VAAPINV12 || -+ m_format == RENDER_FMT_VDPAU || -+ m_format == RENDER_FMT_VDPAU_420) -+ return 5; - else - return 3; - }