changed: Refactor CDVDInputStream to fully expose SCacheStatus + properly detect...
authorarnova <arnova@void.org>
Sat, 14 Apr 2012 09:35:11 +0000 (11:35 +0200)
committerarnova <arnova@void.org>
Sun, 15 Apr 2012 09:30:13 +0000 (11:30 +0200)
xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStream.h
xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFile.cpp
xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFile.h
xbmc/cores/dvdplayer/DVDPlayer.cpp

index d447083..1913aa1 100644 (file)
 
 #include <string>
 #include "utils/BitstreamStats.h"
+#include "filesystem/IFile.h"
 
 #include "FileItem.h"
 
+using namespace XFILE;
+
 enum DVDStreamType
 {
   DVDSTREAM_TYPE_NONE   = -1,
@@ -129,22 +132,16 @@ public:
   virtual void Abort() {}
   virtual int GetBlockSize() { return 0; }
 
-  /*! \brief Get the number of bytes currently cached/buffered ahead from
-   the current position in the input stream if applicable.
-   \return number of cached ahead data bytes (-1 if not available)
-   */
-  virtual __int64 GetCachedBytes() { return -1; }
-
   /*! \brief Indicate expected read rate in bytes per second.
    *  This could be used to throttle caching rate. Should
    *  be seen as only a hint
    */
   virtual void SetReadRate(unsigned rate) {}
 
-  /*! \briaf Current read speed from source
-   *  used to calculate caching time for startup
+  /*! \brief Get the cache status
+   \return true when cache status was succesfully obtained
    */
-  virtual unsigned GetReadRate() { return 0; }
+  virtual bool GetCacheStatus(SCacheStatus *status) { return false; }
 
   bool IsStreamType(DVDStreamType type) const { return m_streamType == type; }
   virtual bool IsEOF() = 0;
index 9c1e852..0b6d35d 100644 (file)
@@ -114,27 +114,12 @@ __int64 CDVDInputStreamFile::GetLength()
   return 0;
 }
 
-__int64 CDVDInputStreamFile::GetCachedBytes()
+bool CDVDInputStreamFile::GetCacheStatus(SCacheStatus *status)
 {
-  SCacheStatus status;
-  if(m_pFile && m_pFile->IoControl(IOCTRL_CACHE_STATUS, &status) >= 0)
-    return status.forward;
+  if(m_pFile && m_pFile->IoControl(IOCTRL_CACHE_STATUS, status) >= 0)
+    return true;
   else
-    return -1;
-}
-
-unsigned CDVDInputStreamFile::GetReadRate()
-{
-  SCacheStatus status;
-  if(m_pFile && m_pFile->IoControl(IOCTRL_CACHE_STATUS, &status) >= 0)
-  {
-    if(status.full)
-      return (unsigned)-1;
-    else
-      return status.currate;
-  }
-  else
-    return (unsigned)-1;
+    return false;
 }
 
 BitstreamStats CDVDInputStreamFile::GetBitstreamStats() const
index 2e3962f..c5fca8d 100644 (file)
@@ -37,9 +37,8 @@ public:
   virtual __int64 GetLength();
   virtual BitstreamStats GetBitstreamStats() const ;
   virtual int GetBlockSize();
-  virtual __int64 GetCachedBytes();
   virtual void SetReadRate(unsigned rate);
-  virtual unsigned GetReadRate();
+  virtual bool GetCacheStatus(SCacheStatus *status);
 
 protected:
   XFILE::CFile* m_pFile;
index 5dfb1af..8f68684 100644 (file)
@@ -1351,10 +1351,18 @@ bool CDVDPlayer::GetCachingTimes(double& level, double& delay, double& offset)
   if(!m_pInputStream || !m_pDemuxer)
     return false;
 
-  int64_t cached  = m_pInputStream->GetCachedBytes();
+  SCacheStatus status;
+  if (!m_pInputStream->GetCacheStatus(&status))
+    return false;
+
+  int64_t cached   = status.forward;
+  unsigned currate = status.currate;
+  unsigned maxrate = status.maxrate;
+  bool full        = status.full;
+
   int64_t length  = m_pInputStream->GetLength();
   int64_t remain  = length - m_pInputStream->Seek(0, SEEK_CUR);
-  unsigned rate   = m_pInputStream->GetReadRate();
+
   if(cached < 0 || length <= 0 || remain < 0)
     return false;
 
@@ -1365,22 +1373,21 @@ bool CDVDPlayer::GetCachingTimes(double& level, double& delay, double& offset)
   level  = 0.0;
   offset = (double)(cached + queued) / length;
 
-  if(rate == 0)
+  if (currate == 0)
     return true;
 
-  if(rate == (unsigned)-1) /* buffer is full */
-  {
-    level = -1.0;
-    return true;
-  }
-
-  double cache_sbp   = 1.1 * (double)DVD_TIME_BASE / rate;            /* underestimate by 10 % */
+  double cache_sbp   = 1.1 * (double)DVD_TIME_BASE / currate;         /* underestimate by 10 % */
   double play_left   = play_sbp  * (remain + queued);                 /* time to play out all remaining bytes */
   double cache_left  = cache_sbp * (remain - cached);                 /* time to cache the remaining bytes */
   double cache_need  = std::max(0.0, remain - play_left / cache_sbp); /* bytes needed until play_left == cache_left */
 
-  delay  = cache_left - play_left;
-  level  = (cached + queued) / (cache_need + queued);
+  delay = cache_left - play_left;
+
+  if (full && (currate < maxrate) )
+    level = -1.0;                          /* buffer is full & our read rate is too low  */
+  else
+    level = (cached + queued) / (cache_need + queued);
+
   return true;
 }
 
@@ -3763,9 +3770,10 @@ void CDVDPlayer::UpdatePlayState(double timeout)
     state.cache_offset = GetQueueTime() / state.time_total;
   }
 
-  if(m_pInputStream && m_pInputStream->GetCachedBytes() >= 0)
+  SCacheStatus status;
+  if(m_pInputStream && m_pInputStream->GetCacheStatus(&status) && status.forward >=0)
   {
-    state.cache_bytes = m_pInputStream->GetCachedBytes();
+    state.cache_bytes = status.forward;
     if(state.time_total)
       state.cache_bytes += m_pInputStream->GetLength() * GetQueueTime() / state.time_total;
   }