#include <string>
#include "utils/BitstreamStats.h"
+#include "filesystem/IFile.h"
#include "FileItem.h"
+using namespace XFILE;
+
enum DVDStreamType
{
DVDSTREAM_TYPE_NONE = -1,
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;
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
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;
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;
}
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;
}