aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp20
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)