diff --git a/packages/mediacenter/kodi/patches/kodi-999.99-PR17081.patch b/packages/mediacenter/kodi/patches/kodi-999.99-PR17081.patch new file mode 100644 index 0000000000..6ce66b947f --- /dev/null +++ b/packages/mediacenter/kodi/patches/kodi-999.99-PR17081.patch @@ -0,0 +1,197 @@ +From a31feadb4ed74fadea8ea5628f2ff8775d8fe870 Mon Sep 17 00:00:00 2001 +From: arnova +Date: Fri, 27 Dec 2019 11:06:41 +0100 +Subject: [PATCH 1/3] fixed: Caching of small files was broken + +--- + xbmc/filesystem/FileCache.cpp | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/xbmc/filesystem/FileCache.cpp b/xbmc/filesystem/FileCache.cpp +index 8541990b5f78..2ba184cdcde5 100644 +--- a/xbmc/filesystem/FileCache.cpp ++++ b/xbmc/filesystem/FileCache.cpp +@@ -164,6 +164,10 @@ bool CFileCache::Open(const CURL& url) + cacheSize = CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_cacheMemSize; + } + ++ // Cap chunk size by cache size ++ if (m_chunkSize > cacheSize) ++ m_chunkSize = cacheSize; ++ + size_t back = cacheSize / 4; + size_t front = cacheSize - back; + +@@ -292,20 +296,25 @@ void CFileCache::Process() + } + } + +- size_t maxWrite = m_pCache->GetMaxWriteSize(m_chunkSize); ++ const int64_t maxWrite = m_pCache->GetMaxWriteSize(m_chunkSize); ++ int64_t maxSourceRead = m_chunkSize; ++ // Cap source read size by space available between current write position and EOF ++ if (m_fileSize != 0) ++ maxSourceRead = std::min(maxSourceRead, m_fileSize - m_writePos); + + /* Only read from source if there's enough write space in the cache + * else we may keep disposing data and seeking back on (slow) source + */ +- if (maxWrite < m_chunkSize && !cacheReachEOF) ++ if (maxWrite < maxSourceRead && !cacheReachEOF) + { ++ // Wait until sufficient cache write space is available + m_pCache->m_space.WaitMSec(5); + continue; + } + + ssize_t iRead = 0; + if (!cacheReachEOF) +- iRead = m_source.Read(buffer.get(), m_chunkSize); ++ iRead = m_source.Read(buffer.get(), maxSourceRead); + if (iRead == 0) + { + // Check for actual EOF and retry as long as we still have data in our cache + +From 431e10a5e4d9cf09e80adda8f66654cd83962ac4 Mon Sep 17 00:00:00 2001 +From: arnova +Date: Sat, 28 Dec 2019 10:01:34 +0100 +Subject: [PATCH 2/3] fixed: Cache forward size wasn't updated when source EOF + was hit + +--- + xbmc/filesystem/FileCache.cpp | 13 +++++-------- + xbmc/filesystem/FileCache.h | 1 - + 2 files changed, 5 insertions(+), 9 deletions(-) + +diff --git a/xbmc/filesystem/FileCache.cpp b/xbmc/filesystem/FileCache.cpp +index 2ba184cdcde5..fae41d141399 100644 +--- a/xbmc/filesystem/FileCache.cpp ++++ b/xbmc/filesystem/FileCache.cpp +@@ -90,7 +90,6 @@ CFileCache::CFileCache(const unsigned int flags) + , m_writeRate(0) + , m_writeRateActual(0) + , m_forwardCacheSize(0) +- , m_forward(0) + , m_bFilling(false) + , m_bLowSpeedDetected(false) + , m_fileSize(0) +@@ -200,7 +199,6 @@ bool CFileCache::Open(const CURL& url) + m_writePos = 0; + m_writeRate = 1024 * 1024; + m_writeRateActual = 0; +- m_forward = 0; + m_bFilling = true; + m_bLowSpeedDetected = false; + m_seekEvent.Reset(); +@@ -268,7 +266,6 @@ void CFileCache::Process() + CLog::Log(LOGDEBUG, + "CFileCache::Process - Cache completely reset for seek to position %" PRId64, + m_seekPos); +- m_forward = 0; + m_bFilling = true; + m_bLowSpeedDetected = false; + } +@@ -400,11 +397,11 @@ void CFileCache::Process() + // avoid uncertainty at start of caching + m_writeRateActual = average.Rate(m_writePos, 1000); + +- // Update forward cache size +- m_forward = m_pCache->WaitForData(0, 0); +- + // NOTE: Hysteresis (20-80%) for filling-logic +- const float level = (m_forwardCacheSize == 0) ? 0.0 : (float) m_forward / m_forwardCacheSize; ++ const int64_t forward = m_pCache->WaitForData(0, 0); ++ const float level = ++ (m_forwardCacheSize == 0) ? 0.0 : static_cast(forward / m_forwardCacheSize); ++ + if (level > 0.8f) + { + /* NOTE: We can only reliably test for low speed condition, when the cache is *really* +@@ -589,7 +586,7 @@ int CFileCache::IoControl(EIoControl request, void* param) + if (request == IOCTRL_CACHE_STATUS) + { + SCacheStatus* status = (SCacheStatus*)param; +- status->forward = m_forward; ++ status->forward = m_pCache->WaitForData(0, 0); + status->maxrate = m_writeRate; + status->currate = m_writeRateActual; + status->lowspeed = m_bLowSpeedDetected; +diff --git a/xbmc/filesystem/FileCache.h b/xbmc/filesystem/FileCache.h +index d6641fbed235..87cd92e9bc1b 100644 +--- a/xbmc/filesystem/FileCache.h ++++ b/xbmc/filesystem/FileCache.h +@@ -69,7 +69,6 @@ namespace XFILE + unsigned m_writeRate; + unsigned m_writeRateActual; + int64_t m_forwardCacheSize; +- int64_t m_forward; + bool m_bFilling; + bool m_bLowSpeedDetected; + std::atomic m_fileSize; + +From ffb01823b525b66cf7dcd22f70c8d0f3d26a166e Mon Sep 17 00:00:00 2001 +From: arnova +Date: Sun, 29 Dec 2019 11:17:56 +0100 +Subject: [PATCH 3/3] changed: Improve logic for determining memory cache size + +--- + xbmc/filesystem/FileCache.cpp | 37 +++++++++++++++++++++++------------ + 1 file changed, 25 insertions(+), 12 deletions(-) + +diff --git a/xbmc/filesystem/FileCache.cpp b/xbmc/filesystem/FileCache.cpp +index fae41d141399..1f8738568593 100644 +--- a/xbmc/filesystem/FileCache.cpp ++++ b/xbmc/filesystem/FileCache.cpp +@@ -155,27 +155,40 @@ bool CFileCache::Open(const CURL& url) + size_t cacheSize; + if (m_fileSize > 0 && m_fileSize < CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_cacheMemSize && !(m_flags & READ_AUDIO_VIDEO)) + { +- // NOTE: We don't need to take into account READ_MULTI_STREAM here as it's only used for audio/video ++ // Cap cache size by filesize, but not for audio/video files as those may grow. ++ // We don't need to take into account READ_MULTI_STREAM here as that's only used for audio/video + cacheSize = m_fileSize; ++ ++ // Cap chunk size by cache size ++ if (m_chunkSize > cacheSize) ++ m_chunkSize = cacheSize; + } + else + { + cacheSize = CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_cacheMemSize; +- } + +- // Cap chunk size by cache size +- if (m_chunkSize > cacheSize) +- m_chunkSize = cacheSize; ++ // NOTE: READ_MULTI_STREAM is only used with READ_AUDIO_VIDEO ++ if (m_flags & READ_MULTI_STREAM) ++ { ++ // READ_MULTI_STREAM requires double buffering, so use half the amount of memory for each buffer ++ cacheSize /= 2; ++ } + +- size_t back = cacheSize / 4; +- size_t front = cacheSize - back; ++ // Make sure cache can at least hold 2 chunks ++ if (cacheSize < m_chunkSize * 2) ++ cacheSize = m_chunkSize * 2; ++ } + + if (m_flags & READ_MULTI_STREAM) +- { +- // READ_MULTI_STREAM requires double buffering, so use half the amount of memory for each buffer +- front /= 2; +- back /= 2; +- } ++ CLog::Log(LOGDEBUG, "CFileCache::Open - Using double memory cache each sized %i bytes", ++ cacheSize); ++ else ++ CLog::Log(LOGDEBUG, "CFileCache::Open - Using single memory cache sized %i bytes", ++ cacheSize); ++ ++ const size_t back = cacheSize / 4; ++ const size_t front = cacheSize - back; ++ + m_pCache = std::unique_ptr(new CCircularCache(front, back)); // C++14 - Replace with std::make_unique + m_forwardCacheSize = front; + }