/
kodi-999.99-PR17081.patch
197 lines (180 loc) · 7.32 KB
/
kodi-999.99-PR17081.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
From a31feadb4ed74fadea8ea5628f2ff8775d8fe870 Mon Sep 17 00:00:00 2001
From: arnova <arnova@void.org>
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 <arnova@void.org>
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<float>(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<int64_t> m_fileSize;
From ffb01823b525b66cf7dcd22f70c8d0f3d26a166e Mon Sep 17 00:00:00 2001
From: arnova <arnova@void.org>
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<CCircularCache>(new CCircularCache(front, back)); // C++14 - Replace with std::make_unique
m_forwardCacheSize = front;
}