[vlc-commits] [Git][videolan/vlc][3.0.x] playlist: temporize on EOS bursts

Rémi Denis-Courmont (@Courmisch) gitlab at videolan.org
Mon Mar 28 08:58:55 UTC 2022



Rémi Denis-Courmont pushed to branch 3.0.x at VideoLAN / VLC


Commits:
c0bb3d7b by Romain Vimont at 2022-03-26T08:49:49+00:00
playlist: temporize on EOS bursts

A mechanism was implemented to temporize on consecutive input errors, to
mitigate infinite busy loops (see commit
d06622651fcd4a608c06cb35e725fad57bf38167).

Although it avoided the most common issues, this mechanism was not
triggered for other problematic cases:
 - empty inputs;
 - inputs with unreported errors from demuxers.

Therefore, to encompass these other cases, consider the number of
consecutive stops in a small period of time instead of relying on
reported errors:
 - if a playback end occurs less than 250ms after the previous one, then
   increment the EOS burst count;
 - when more than 4 EOS burst count occur successively, start
   temporizing:
     - 100ms for the 5th
     - 200ms for the 6th
     - 400ms for the 7th
     - 800ms for the 8th
     - 1.6s for the 9th
     - 3.2s for the following

Fixes #5901
Fixes #26733
Refs vlc4/e759db90d958305afee6655e52597c4fef446c34

- - - - -


3 changed files:

- src/playlist/engine.c
- src/playlist/playlist_internal.h
- src/playlist/thread.c


Changes:

=====================================
src/playlist/engine.c
=====================================
@@ -261,7 +261,8 @@ playlist_t *playlist_Create( vlc_object_t *p_parent )
     pl_priv(p_playlist)->status.p_item = NULL;
     pl_priv(p_playlist)->status.p_node = p_playlist->p_playing;
     pl_priv(p_playlist)->request.b_request = false;
-    pl_priv(p_playlist)->i_consecutive_errors = 0;
+    pl_priv(p_playlist)->last_eos = 0;
+    pl_priv(p_playlist)->eos_burst_count = 0;
     p->request.input_dead = false;
 
     if (ml != NULL)


=====================================
src/playlist/playlist_internal.h
=====================================
@@ -87,7 +87,15 @@ typedef struct playlist_private_t
 
     int      i_last_playlist_id; /**< Last id to an item */
     bool     b_reset_currently_playing; /** Reset current item array */
-    unsigned i_consecutive_errors; /**< Number of consecutive items in error */
+
+    /**
+     * Playing a tiny stream (either empty, or with unreported errors) in a loop
+     * would cause high CPU usage. To mitigate the problem, temporize if
+     * several EOS are received too quickly.
+     */
+#define VLC_PLAYLIST_EOS_BURST_THRESHOLD (CLOCK_FREQ / 4) /* 250 ms */
+    mtime_t  last_eos;
+    unsigned eos_burst_count;
 
     bool     b_tree; /**< Display as a tree */
     bool     b_preparse; /**< Preparse items */


=====================================
src/playlist/thread.c
=====================================
@@ -498,19 +498,31 @@ static void *Thread ( void *data )
         /* Playlist in running state */
         while( !p_sys->killed && Next( p_playlist ) )
         {
-            bool ok = LoopInput( p_playlist );
-            if (ok)
-                p_sys->i_consecutive_errors = 0;
-            else
+            LoopInput( p_playlist );
+            if (p_sys->last_eos)
             {
-                if (p_sys->i_consecutive_errors < 6)
-                    p_sys->i_consecutive_errors++;
+#define MAX_EOS_BURST 4
+                mtime_t diff = mdate() - p_sys->last_eos;
+                if (diff < VLC_PLAYLIST_EOS_BURST_THRESHOLD)
+                {
+                    if (p_sys->eos_burst_count < MAX_EOS_BURST + 6)
+                        ++p_sys->eos_burst_count;
+
+                    if (p_sys->eos_burst_count > MAX_EOS_BURST)
+                    {
+                        unsigned pow = p_sys->eos_burst_count - MAX_EOS_BURST;
+                        unsigned slowdown = 1 << (pow - 1);
+                        /* 100ms, 200ms, 400ms, 800ms, 1.6s, 3.2s */
+                        mtime_t deadline = mdate() + slowdown * 100000L; /* usecs */
+                        vlc_cond_timedwait(&p_sys->signal, &p_sys->lock, deadline);
+                    }
 
-                int slowdown = 1 << (p_sys->i_consecutive_errors - 1);
-                /* 100ms, 200ms, 400ms, 800ms, 1.6s, 3.2s */
-                mtime_t deadline = mdate() + slowdown * 100000L; /* usecs */
-                vlc_cond_timedwait(&p_sys->signal, &p_sys->lock, deadline);
+                }
+                else
+                    p_sys->eos_burst_count = 0;
             }
+
+            p_sys->last_eos = mdate();
             played = true;
         }
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/c0bb3d7ba9db9b2f1a84466ee2f3acc5a78554f7

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/c0bb3d7ba9db9b2f1a84466ee2f3acc5a78554f7
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list