diff options
-rw-r--r-- | xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp index 0aac8fe53f..b03ea5c651 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp @@ -149,10 +149,10 @@ int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic) { VASurfaceID surface = GetSurfaceID(pic); CSurface* wrapper = NULL; + std::list<CSurfacePtr>::iterator it = m_surfaces_free.begin(); if(surface) { /* reget call */ - std::list<CSurfacePtr>::iterator it = m_surfaces_free.begin(); for(; it != m_surfaces_free.end(); it++) { if((*it)->m_id == surface) @@ -171,20 +171,28 @@ int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic) } else { - if(m_surfaces_free.empty()) + // To avoid stutter, we scan the free surface pool (provided by decoder) for surfaces + // that are 100% not in use by renderer. The pointers to these surfaces have a use_count of 1. + for (; it != m_surfaces_free.end() && it->use_count() > 1; it++) {} + + // If we have zero free surface from decoder OR all free surfaces are in use by renderer, we allocate a new surface + if (it == m_surfaces_free.end()) { + if (!m_surfaces_free.empty()) CLog::Log(LOGERROR, "VAAPI - renderer still using all freed up surfaces by decoder"); CLog::Log(LOGERROR, "VAAPI - unable to find free surface, trying to allocate a new one"); if(!EnsureSurfaces(avctx, m_surfaces_count+1) || m_surfaces_free.empty()) { CLog::Log(LOGERROR, "VAAPI - unable to find free surface"); return -1; } + // Set itarator position to the newly allocated surface (end-1) + it = m_surfaces_free.end(); it--; } /* getbuffer call */ - wrapper = m_surfaces_free.front().get(); + wrapper = it->get(); surface = wrapper->m_id; - m_surfaces_used.push_back(m_surfaces_free.front()); - m_surfaces_free.pop_front(); + m_surfaces_used.push_back(*it); + m_surfaces_free.erase(it); } pic->type = FF_BUFFER_TYPE_USER; @@ -349,7 +357,7 @@ bool CDecoder::EnsureContext(AVCodecContext *avctx) else m_refs = 2; } - return EnsureSurfaces(avctx, m_refs + 1 + 1); + return EnsureSurfaces(avctx, m_refs + 3); } bool CDecoder::EnsureSurfaces(AVCodecContext *avctx, unsigned n_surfaces_count) |