[vlc-commits] stream_filter/httplive.c: separate HLS playlist reload into another thread

Jean-Paul Saman git at videolan.org
Wed Mar 2 23:51:12 CET 2011


vlc | branch: master | Jean-Paul Saman <jean-paul.saman at m2x.nl> | Fri Feb 25 16:38:50 2011 +0100| [2723572795d30b19b8ef7790d28dbe9ccee5d304] | committer: Jean-Paul Saman

stream_filter/httplive.c: separate HLS playlist reload into another thread

Reloading HLS m3u8 file for live playback in a separate track. It used
to piggy back on the download track, which made it reload less often.
Since it would check the m3u8 file reload once after each download, which
generally takes longer then the suggested m3u8 reload algorithm.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2723572795d30b19b8ef7790d28dbe9ccee5d304
---

 modules/stream_filter/httplive.c |   98 ++++++++++++++++++++++++-------------
 1 files changed, 63 insertions(+), 35 deletions(-)

diff --git a/modules/stream_filter/httplive.c b/modules/stream_filter/httplive.c
index a165101..4a93891 100644
--- a/modules/stream_filter/httplive.c
+++ b/modules/stream_filter/httplive.c
@@ -87,7 +87,8 @@ typedef struct hls_stream_s
 struct stream_sys_t
 {
     vlc_url_t     m3u8;         /* M3U8 url */
-    vlc_thread_t  thread;       /* Thread function */
+    vlc_thread_t  reload;       /* HLS m3u8 reload thread */
+    vlc_thread_t  thread;       /* HLS segment download thread */
 
     /* */
     vlc_array_t  *hls_stream;   /* bandwidth adaptation */
@@ -140,6 +141,7 @@ static char *ReadLine(uint8_t *buffer, uint8_t **remain, size_t len);
 static int hls_Download(stream_t *s, segment_t *segment);
 
 static void* hls_Thread(void *);
+static void* hls_Reload(void *);
 
 static segment_t *segment_GetSegment(hls_stream_t *hls, int wanted);
 static void segment_Free(segment_t *segment);
@@ -1143,7 +1145,7 @@ static void* hls_Thread(void *p_this)
                     (p_sys->download.segment >= count)) &&
                    (p_sys->download.seek == -1))
             {
-                if (p_sys->b_live && (mdate() >= p_sys->playlist.wakeup))
+                if (p_sys->b_live /*&& (mdate() >= p_sys->playlist.wakeup)*/)
                     break;
                 vlc_cond_wait(&p_sys->download.wait, &p_sys->download.lock_wait);
                 if (!vlc_object_alive(s)) break;
@@ -1159,32 +1161,6 @@ static void* hls_Thread(void *p_this)
 
         if (!vlc_object_alive(s)) break;
 
-        /* reload the m3u8 index file */
-        if (p_sys->b_live)
-        {
-            double wait = 1;
-            mtime_t now = mdate();
-            if (now >= p_sys->playlist.wakeup)
-            {
-                if (hls_ReloadPlaylist(s) != VLC_SUCCESS)
-                {
-                    /* No change in playlist, then backoff */
-                    p_sys->playlist.tries++;
-                    if (p_sys->playlist.tries == 1) wait = 0.5;
-                    else if (p_sys->playlist.tries == 2) wait = 1;
-                    else if (p_sys->playlist.tries >= 3) wait = 3;
-                }
-                else p_sys->playlist.tries = 0;
-
-                /* determine next time to update playlist */
-                p_sys->playlist.last = now;
-                p_sys->playlist.wakeup = now + ((mtime_t)(hls->duration * wait)
-                                                * (mtime_t)1000000);
-            }
-
-            if (!vlc_object_alive(s)) break;
-        }
-
         vlc_mutex_lock(&hls->lock);
         segment_t *segment = segment_GetSegment(hls, p_sys->download.segment);
         vlc_mutex_unlock(&hls->lock);
@@ -1219,6 +1195,48 @@ static void* hls_Thread(void *p_this)
     return NULL;
 }
 
+static void* hls_Reload(void *p_this)
+{
+    stream_t *s = (stream_t *)p_this;
+    stream_sys_t *p_sys = s->p_sys;
+
+    assert(p_sys->b_live);
+
+    int canc = vlc_savecancel();
+
+    while (vlc_object_alive(s))
+    {
+        double wait = 1;
+        mtime_t now = mdate();
+        if (now >= p_sys->playlist.wakeup)
+        {
+            /* reload the m3u8 */
+            if (hls_ReloadPlaylist(s) != VLC_SUCCESS)
+            {
+                /* No change in playlist, then backoff */
+                p_sys->playlist.tries++;
+                if (p_sys->playlist.tries == 1) wait = 0.5;
+                else if (p_sys->playlist.tries == 2) wait = 1;
+                else if (p_sys->playlist.tries >= 3) wait = 3;
+            }
+            else p_sys->playlist.tries = 0;
+
+            hls_stream_t *hls = hls_Get(p_sys->hls_stream, p_sys->download.stream);
+            assert(hls);
+
+            /* determine next time to update playlist */
+            p_sys->playlist.last = now;
+            p_sys->playlist.wakeup = now + ((mtime_t)(hls->duration * wait)
+                                                   * (mtime_t)1000000);
+        }
+
+        mwait(p_sys->playlist.wakeup);
+    }
+
+    vlc_restorecancel(canc);
+    return NULL;
+}
+
 static int Prefetch(stream_t *s, int *current)
 {
     stream_sys_t *p_sys = s->p_sys;
@@ -1507,6 +1525,14 @@ static int Open(vlc_object_t *p_this)
         goto fail;
     }
 
+
+    p_sys->download.stream = current;
+    p_sys->playback.stream = current;
+    p_sys->download.seek = -1;
+
+    vlc_mutex_init(&p_sys->download.lock_wait);
+    vlc_cond_init(&p_sys->download.wait);
+
     /* Initialize HLS live stream */
     if (p_sys->b_live)
     {
@@ -1514,17 +1540,17 @@ static int Open(vlc_object_t *p_this)
         p_sys->playlist.last = mdate();
         p_sys->playlist.wakeup = p_sys->playlist.last +
                 ((mtime_t)hls->duration * UINT64_C(1000000));
-    }
 
-    p_sys->download.stream = current;
-    p_sys->playback.stream = current;
-    p_sys->download.seek = -1;
-
-    vlc_mutex_init(&p_sys->download.lock_wait);
-    vlc_cond_init(&p_sys->download.wait);
+        if (vlc_clone(&p_sys->reload, hls_Reload, s, VLC_THREAD_PRIORITY_LOW))
+        {
+            goto fail_thread;
+        }
+    }
 
     if (vlc_clone(&p_sys->thread, hls_Thread, s, VLC_THREAD_PRIORITY_INPUT))
     {
+        if (p_sys->b_live)
+            vlc_join(p_sys->reload, NULL);
         goto fail_thread;
     }
 
@@ -1566,6 +1592,8 @@ static void Close(vlc_object_t *p_this)
     vlc_mutex_unlock(&p_sys->download.lock_wait);
 
     /* */
+    if (p_sys->b_live)
+        vlc_join(p_sys->reload, NULL);
     vlc_join(p_sys->thread, NULL);
     vlc_mutex_destroy(&p_sys->download.lock_wait);
     vlc_cond_destroy(&p_sys->download.wait);



More information about the vlc-commits mailing list