Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Network Cache Redux #1388

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "filesystem/IFile.h"
#include "utils/log.h"
#include "utils/URIUtils.h"
#include "settings/AdvancedSettings.h"

using namespace XFILE;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
26 changes: 24 additions & 2 deletions xbmc/cores/dvdplayer/DVDPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -1081,7 +1086,10 @@ void CDVDPlayer::Process()

// update application with our state
UpdateApplication(1000);


//update readrate based on peak bitrate
UpdateReadRate();

if (CheckDelayedChannelEntry())
continue;

Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion xbmc/cores/dvdplayer/DVDPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
23 changes: 20 additions & 3 deletions xbmc/filesystem/FileCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*
*/

#include <limits.h>
#include "threads/SystemClock.h"
#include "utils/AutoPtrHandle.h"
#include "FileCache.h"
Expand Down Expand Up @@ -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;
}
Expand Down
6 changes: 3 additions & 3 deletions xbmc/filesystem/MemBufferCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}


Expand Down
6 changes: 4 additions & 2 deletions xbmc/settings/AdvancedSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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");
Expand Down
3 changes: 2 additions & 1 deletion xbmc/settings/AdvancedSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down