Solved Slow Stream Stutter Question
#16
(2016-10-21, 06:06)Scott00007 Wrote: Is there anything being done about implementing this fix for a known problem? The work seems to have already been done, just needs to be copied and pasted into the right spot.

How-to: Submit a patch (wiki)

scott s.
.
Reply
#17
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);
   }
}
Reply

Logout Mark Read Team Forum Stats Members Help
Slow Stream Stutter Question0