Thanks JohnRKlein, that patch did seem to solve the hls stutter issue for me. I tried updating the patch for Kodi 17, not sure if it's right, but it compiles and seems to work so far.
/xbmc/cores/VideoPlayer/VideoPlayer.cpp
Code:
--- xbmc-147cec4077415c93d3d84fb82cb6b695b5a9094c/xbmc/cores/VideoPlayer/VideoPlayer.cpp 2017-05-24 15:49:32.000000000 -0500
+++ xbmc-147cec4077415c93d3d84fb82cb6b695b5a9094c-fixed/xbmc/cores/VideoPlayer/VideoPlayer.cpp 2017-06-17 00:56:33.676349590 -0500
@@ -1831,13 +1831,35 @@
level = 0.0;
offset = (double)(cached + queued) / length;
- if (currate == 0)
- return true;
+ double cache_sbp;
+ if (currate)
+ {
+ cache_sbp = 1.1 * (double)(DVD_TIME_BASE) / (double)(currate); /* underestimate by 10 % */
+ }
+ else
+ {
+ if (cache_level == 1.0)
+ {
+ cache_sbp = play_sbp;
+ }
+ else
+ {
+ cache_sbp = 0.0;
+ }
+ }
- 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 */
+
+ double cache_need;
+ if (cache_sbp)
+ {
+ cache_need = std::max(0.0, (delay) / cache_sbp); /* bytes needed until play_left == cache_left */
+ }
+ else
+ {
+ cache_need = remain - queued;
+ }
delay = cache_left - play_left;
@@ -1847,13 +1869,20 @@
* low read-rate conditions. To work around this we don't check the currate at 100%
* but between 80% and 90%
*/
- if (cache_level > 0.8 && cache_level < 0.9 && currate < maxrate)
+ if (cache_need)
+ {
+ level = cached / cache_need;
+ }
+ else
+ {
+ level = 1.0;
+ }
+
+ if (cache_level > 0.8 && cache_level < 0.9 && level < 1.0)
{
CLog::Log(LOGDEBUG, "Readrate %u is too low with %u required", currate, maxrate);
level = -1.0; /* buffer is full & our read rate is too low */
}
- else
- level = (cached + queued) / (cache_need + queued);
return true;
}
@@ -1873,16 +1902,16 @@
if (level < 0.0)
{
CGUIDialogKaiToast::QueueNotification(g_localizeStrings.Get(21454), g_localizeStrings.Get(21455));
- SetCaching(CACHESTATE_INIT);
+ SetCaching(CACHESTATE_DONE);
}
if (level >= 1.0)
- SetCaching(CACHESTATE_INIT);
+ SetCaching(CACHESTATE_DONE);
}
else
{
if ((!m_VideoPlayerAudio->AcceptsData() && m_CurrentAudio.id >= 0) ||
(!m_VideoPlayerVideo->AcceptsData() && m_CurrentVideo.id >= 0))
- SetCaching(CACHESTATE_INIT);
+ SetCaching(CACHESTATE_DONE);
}
}
@@ -1892,7 +1921,7 @@
if ((m_CurrentVideo.id >= 0 || m_CurrentAudio.id >= 0) &&
(m_CurrentVideo.id < 0 || m_CurrentVideo.syncState != IDVDStreamPlayer::SYNC_STARTING) &&
(m_CurrentAudio.id < 0 || m_CurrentAudio.syncState != IDVDStreamPlayer::SYNC_STARTING))
- SetCaching(CACHESTATE_PLAY);
+ SetCaching(CACHESTATE_FULL);
// handle exceptions
if (m_CurrentAudio.id >= 0 && m_CurrentVideo.id >= 0)
/xbmc/filesystem/FileCache.cpp
Code:
diff -ruN xbmc-147cec4077415c93d3d84fb82cb6b695b5a9094c/xbmc/filesystem/FileCache.cpp xbmc-147cec4077415c93d3d84fb82cb6b695b5a9094c-fixed/xbmc/filesystem/FileCache.cpp
--- xbmc-147cec4077415c93d3d84fb82cb6b695b5a9094c/xbmc/filesystem/FileCache.cpp 2017-05-24 15:49:32.000000000 -0500
+++ xbmc-147cec4077415c93d3d84fb82cb6b695b5a9094c-fixed/xbmc/filesystem/FileCache.cpp 2017-06-16 13:48:47.961263529 -0500
@@ -68,19 +68,37 @@
}
}
- unsigned Rate(int64_t pos, unsigned int time_bias = 0)
+ unsigned Rate(int64_t pos, unsigned int time_bias = 0, unsigned int TimeRange = 30000)
{
const unsigned ts = XbmcThreads::SystemClockMillis();
- m_size += (pos - m_pos);
+ if (m_time > TimeRange)
+ {
+ m_size *= 0.85;
+ m_time *= 0.85;
+ }
+
m_time += (ts - m_stamp);
+ m_size += (pos - m_pos);
m_pos = pos;
m_stamp = ts;
- if (m_time == 0)
+ if (m_time == 0 || m_time < TimeRange * 0.25)
+ {
+ m_size = 0;
return 0;
+ }
- return (unsigned)(1000 * (m_size / (m_time + time_bias)));
+#define StartupBuffer (TimeRange * 0.75)
+
+ if (m_time < StartupBuffer)
+ {
+ return (unsigned)(1000 * (m_size / (StartupBuffer + time_bias)));
+ }
+ else
+ {
+ return (unsigned)(1000 * (m_size / (m_time + time_bias)));
+ }
}
private:
@@ -410,7 +428,7 @@
// under estimate write rate by a second, to
// avoid uncertainty at start of caching
- m_writeRateActual = average.Rate(m_writePos, 1000);
+ m_writeRateActual = average.Rate(m_writePos);
}
}