VDPAU: improve error handling, Gotham
authorRainer Hochecker <fernetmenta@online.de>
Fri, 2 May 2014 05:37:26 +0000 (07:37 +0200)
committerRainer Hochecker <fernetmenta@online.de>
Fri, 2 May 2014 17:46:38 +0000 (19:46 +0200)
xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h

index b4d2d38..8c9437c 100644 (file)
@@ -948,6 +948,7 @@ bool CDecoder::ConfigVDPAU(AVCodecContext* avctx, int ref_frames)
 
   m_inMsgEvent.Reset();
   m_vdpauConfigured = true;
+  m_ErrorCount = 0;
   return true;
 }
 
@@ -1078,7 +1079,11 @@ void CDecoder::FFDrawSlice(struct AVCodecContext *s,
                                    (VdpPictureInfo const *)&(vdp->m_hwContext.info),
                                    vdp->m_hwContext.bitstream_buffers_used,
                                    vdp->m_hwContext.bitstream_buffers);
-  vdp->CheckStatus(vdp_st, __LINE__);
+  if (vdp->CheckStatus(vdp_st, __LINE__))
+    vdp->m_DecoderError = true;
+  else
+    vdp->m_DecoderError = false;
+
   uint64_t diff = CurrentHostCounter() - startTime;
   if (diff*1000/CurrentHostFrequency() > 30)
     CLog::Log(LOGDEBUG, "CVDPAU::DrawSlice - VdpDecoderRender long decoding: %d ms, dec: %d, proc: %d, rend: %d", (int)((diff*1000)/CurrentHostFrequency()), decoded, processed, rend);
@@ -1093,6 +1098,9 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame)
 
   CSingleLock lock(m_DecoderSection);
 
+  if (m_DecoderError && pFrame)
+    return VC_ERROR;
+
   if (!m_vdpauConfigured)
     return VC_ERROR;
 
@@ -1264,6 +1272,8 @@ bool CDecoder::CheckStatus(VdpStatus vdp_st, int line)
   {
     CLog::Log(LOGERROR, " (VDPAU) Error: %s(%d) at %s:%d\n", m_vdpauConfig.context->GetProcs().vdp_get_error_string(vdp_st), vdp_st, __FILE__, line);
 
+    m_ErrorCount++;
+
     if(m_DisplayState == VDPAU_OPEN)
     {
       if (vdp_st == VDP_STATUS_DISPLAY_PREEMPTED)
@@ -1271,12 +1281,13 @@ bool CDecoder::CheckStatus(VdpStatus vdp_st, int line)
         m_DisplayEvent.Reset();
         m_DisplayState = VDPAU_LOST;
       }
-      else
+      else if (m_ErrorCount > 2)
         m_DisplayState = VDPAU_ERROR;
     }
 
     return true;
   }
+  m_ErrorCount = 0;
   return false;
 }
 
@@ -2954,6 +2965,11 @@ bool COutput::Init()
 bool COutput::Uninit()
 {
   m_mixer.Dispose();
+  glFlush();
+  while(ProcessSyncPicture())
+  {
+    Sleep(10);
+  }
   GLUnmapSurfaces();
   ReleaseBufferPool();
   DestroyGlxContext();
index 9f58e76..28258f6 100644 (file)
@@ -610,6 +610,8 @@ protected:
   } m_DisplayState;
   CCriticalSection m_DecoderSection;
   CEvent         m_DisplayEvent;
+  int m_ErrorCount;
+  bool m_DecoderError;
 
   DllAvUtil     m_dllAvUtil;
   ThreadIdentifier m_decoderThread;