Network Cache Redux #1388

Closed
wants to merge 1 commit into
from
@@ -23,6 +23,7 @@
#include "filesystem/IFile.h"
#include "utils/log.h"
#include "utils/URIUtils.h"
+#include "settings/AdvancedSettings.h"
using namespace XFILE;
@@ -51,8 +52,13 @@ bool CDVDInputStreamFile::Open(const char* strFile, const std::string& content)
if (!m_pFile)
return false;
+ unsigned int flags = READ_TRUNCATED | READ_BITRATE | READ_CHUNKED;
+
+ if (!URIUtils::IsOnDVD(strFile) && !URIUtils::IsBluray(strFile) && g_advancedSettings.m_alwaysForceBuffer)
+ flags |= READ_CACHED;
+
// open file in binary mode
- if (!m_pFile->Open(strFile, READ_TRUNCATED | READ_BITRATE | READ_CHUNKED))
+ if (!m_pFile->Open(strFile, flags))
{
delete m_pFile;
m_pFile = NULL;
@@ -144,6 +150,7 @@ int CDVDInputStreamFile::GetBlockSize()
void CDVDInputStreamFile::SetReadRate(unsigned rate)
{
unsigned maxrate = rate + 1024 * 1024 / 8;
+ CLog::Log(LOGDEBUG, "CDVDInputStreamFile::SetReadRate - Read rate set to %u bytes per second", maxrate);
if(m_pFile->IoControl(IOCTRL_CACHE_SETRATE, &maxrate) >= 0)
CLog::Log(LOGDEBUG, "CDVDInputStreamFile::SetReadRate - set cache throttle rate to %u bytes per second", maxrate);
}
@@ -420,6 +420,7 @@ CDVDPlayer::CDVDPlayer(IPlayerCallback& callback)
m_offset_pts = 0.0;
m_playSpeed = DVD_PLAYSPEED_NORMAL;
m_caching = CACHESTATE_DONE;
+ m_readrate = 0;
memset(&m_SpeedState, 0, sizeof(m_SpeedState));
@@ -677,7 +678,11 @@ bool CDVDPlayer::OpenDemuxStream()
int64_t len = m_pInputStream->GetLength();
int64_t tim = m_pDemuxer->GetStreamLength();
if(len > 0 && tim > 0)
- m_pInputStream->SetReadRate(len * 1000 / tim);
+ {
+ //cap to intital read rate to 40 megabits/second if less than average bitrate * 1.25
+ m_readrate = std::min((unsigned int)((len * 1000 / tim) * 1.25), (unsigned int) (40000000 / 8));
+ m_pInputStream->SetReadRate(m_readrate);
+ }
return true;
}
@@ -1081,7 +1086,10 @@ void CDVDPlayer::Process()
// update application with our state
UpdateApplication(1000);
-
+
+ //update readrate based on peak bitrate
+ UpdateReadRate();
+
if (CheckDelayedChannelEntry())
continue;
@@ -4020,6 +4028,20 @@ void CDVDPlayer::UpdateApplication(double timeout)
m_UpdateApplication = CDVDClock::GetAbsoluteClock();
}
+void CDVDPlayer::UpdateReadRate()
+{
+ unsigned int bytespersecond = (GetVideoBitrate() + GetAudioBitrate()) / 8;
+
+ if (bytespersecond > m_readrate)
+ {
+ //if current bitrate * 1.25 is over 40 Mbs then cap at at max of actual bitrate or 40 Mb/s whichever is greater
+ //otherwise set read rate to current bitrate * 1.25
+ m_readrate = std::min((unsigned int)(bytespersecond * 1.25), std::max((unsigned int) bytespersecond, (unsigned int) (40000000 / 8)));
+
+ m_pInputStream->SetReadRate(m_readrate);
+ }
+}
+
bool CDVDPlayer::CanRecord()
{
CSingleLock lock(m_StateSection);
@@ -340,6 +340,7 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer
void UpdateApplication(double timeout);
void UpdatePlayState(double timeout);
+ void UpdateReadRate();
double m_UpdateApplication;
bool m_bAbortRequest;
@@ -349,7 +350,7 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer
ECacheState m_caching;
CFileItem m_item;
unsigned int m_iChannelEntryTimeOut;
-
+ unsigned int m_readrate;
CCurrentStream m_CurrentAudio;
CCurrentStream m_CurrentVideo;
@@ -18,6 +18,7 @@
*
*/
+#include <limits.h>
#include "threads/SystemClock.h"
#include "utils/AutoPtrHandle.h"
#include "FileCache.h"
@@ -85,11 +86,27 @@ CFileCache::CFileCache() : CThread("CFileCache")
m_seekPos = 0;
m_readPos = 0;
m_writePos = 0;
- if (g_advancedSettings.m_cacheMemBufferSize == 0)
+ if (g_advancedSettings.m_freeMemCachePercent == 0)
m_pCache = new CSimpleFileCache();
else
- m_pCache = new CCircularCache(g_advancedSettings.m_cacheMemBufferSize
- , std::max<unsigned int>( g_advancedSettings.m_cacheMemBufferSize / 4, 1024 * 1024));
+ {
+ //set cache size of m_freeMemCachePercent of free ram, with hardcoded 1 GB upper limit
+ MEMORYSTATUSEX stat;
+ stat.dwLength = sizeof(MEMORYSTATUSEX);
+ GlobalMemoryStatusEx(&stat);
+
+ //limit max cache to 1 GB
+ unsigned int maxcache = (1024 * 1024 * 1000);
+ double ramamount = (stat.ullAvailPhys * (g_advancedSettings.m_freeMemCachePercent / 100.00));
+
+ unsigned int cacheRam = std::min(static_cast<unsigned int>(ramamount), maxcache);
+
+ unsigned int frontCache = static_cast<unsigned int>(cacheRam * 0.75);
+ unsigned int backCache = cacheRam - frontCache;
+
+ m_pCache = new CCircularCache(frontCache, std::max<unsigned int>(backCache, 1024 * 1024));
+ }
+
m_seekPossible = 0;
m_cacheFull = false;
}
@@ -38,9 +38,9 @@ MemBufferCache::MemBufferCache()
: CCacheStrategy()
{
m_nStartPosition = 0;
- m_buffer.Create(g_advancedSettings.m_cacheMemBufferSize + 1);
- m_HistoryBuffer.Create(g_advancedSettings.m_cacheMemBufferSize + 1);
- m_forwardBuffer.Create(g_advancedSettings.m_cacheMemBufferSize + 1);
+ m_buffer.Create((1024 * 1024 * 10) + 1);
+ m_HistoryBuffer.Create((1024 * 1024 * 10) + 1);
+ m_forwardBuffer.Create((1024 * 1024 * 10) + 1);
}
@@ -297,7 +297,8 @@ void CAdvancedSettings::Initialize()
m_measureRefreshrate = false;
- m_cacheMemBufferSize = 1024 * 1024 * 20;
+ m_alwaysForceBuffer = false;
+ m_freeMemCachePercent = 50;
m_addonPackageFolderSize = 200;
m_jsonOutputCompact = true;
@@ -676,11 +677,12 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
pElement = pRootElement->FirstChildElement("network");
if (pElement)
{
+ XMLUtils::GetBoolean(pElement, "alwaysforcebuffer", m_alwaysForceBuffer);
XMLUtils::GetInt(pElement, "curlclienttimeout", m_curlconnecttimeout, 1, 1000);
XMLUtils::GetInt(pElement, "curllowspeedtime", m_curllowspeedtime, 1, 1000);
XMLUtils::GetInt(pElement, "curlretries", m_curlretries, 0, 10);
XMLUtils::GetBoolean(pElement,"disableipv6", m_curlDisableIPV6);
- XMLUtils::GetUInt(pElement, "cachemembuffersize", m_cacheMemBufferSize);
+ XMLUtils::GetInt(pElement, "freememorycachepercent", m_freeMemCachePercent, 0, 80);
}
pElement = pRootElement->FirstChildElement("jsonrpc");
@@ -348,7 +348,8 @@ class CAdvancedSettings
int m_guiDirtyRegionNoFlipTimeout;
unsigned int m_addonPackageFolderSize;
- unsigned int m_cacheMemBufferSize;
+ bool m_alwaysForceBuffer;
+ int m_freeMemCachePercent;
bool m_jsonOutputCompact;
unsigned int m_jsonTcpPort;