[vlc-devel] [PATCH 21/48] hls: Force waiting segment.

Hugo Beauzée-Luyssen beauze.h at gmail.com
Mon Jan 9 16:16:30 CET 2012


From: Luc Saillard <luc.saillard at sfr.com>

---
 modules/stream_filter/httplive.c |   66 ++++++++++++++++++++++++++-----------
 1 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/modules/stream_filter/httplive.c b/modules/stream_filter/httplive.c
index 5583393..01269b5 100644
--- a/modules/stream_filter/httplive.c
+++ b/modules/stream_filter/httplive.c
@@ -1595,7 +1595,8 @@ static void* hls_Thread(void *p_this)
                     (p_sys->download.segment >= count)) &&
                    (p_sys->download.seek == -1))
             {
-                vlc_cond_wait(&p_sys->download.wait, &p_sys->download.lock_wait);
+                mtime_t timeout = mdate() + 5000000;
+                vlc_cond_timedwait(&p_sys->download.wait, &p_sys->download.lock_wait, timeout);
                 if (!vlc_object_alive(s)) break;
                 if (p_sys->b_live) break;
                 if (p_sys->b_quit) break;
@@ -1989,11 +1990,13 @@ static int Open(vlc_object_t *p_this)
         msg_Warn(s, "less data than 3 times 'target duration' available for live playback, playback may stall");
     }
 
+#if 0
     if (Prefetch(s, &current) != VLC_SUCCESS)
     {
         msg_Err(s, "fetching first segment failed.");
         goto fail;
     }
+#endif
 
 
     p_sys->download.stream = current;
@@ -2098,12 +2101,26 @@ static segment_t *GetSegment(stream_t *s)
 {
     stream_sys_t *p_sys = s->p_sys;
     segment_t *segment = NULL;
+    hls_stream_t *hls;
+    int retry_count = 0;
 
     /* Is this segment of the current HLS stream ready? */
-    hls_stream_t *hls = hls_Get(p_sys->hls_stream, p_sys->playback.stream);
+again:
+    if (p_sys->playback.stream != p_sys->download.stream)
+    {
+        msg_Dbg(s, "Change stream playback from %d to %d", p_sys->playback.stream, p_sys->download.stream);
+        p_sys->playback.stream = p_sys->download.stream;
+    }
+    hls = hls_Get(p_sys->hls_stream, p_sys->playback.stream);
     if (hls != NULL)
     {
         vlc_mutex_lock(&hls->lock);
+        if ( p_sys->b_live == false && vlc_array_count(hls->segments) <= p_sys->playback.segment)
+        {
+            msg_Dbg(s, "End of the stream detected");
+            vlc_mutex_unlock(&hls->lock);
+            return NULL;
+        }
         segment = segment_GetSegment(hls, p_sys->playback.segment);
         vlc_mutex_unlock(&hls->lock);
         if (segment != NULL)
@@ -2117,7 +2134,31 @@ static segment_t *GetSegment(stream_t *s)
                 goto check;
             }
             vlc_mutex_unlock(&segment->lock);
-        }
+
+            /*  Perhaps nobody try to download it, so force a download after one retry */
+            if (retry_count < 3)
+            {
+                /* Force download, perhaps we are stuck into something */
+                msg_Dbg(s, "Force download segment %d of stream %d because we have already wait some time (retry_count=%d)", p_sys->playback.segment, p_sys->playback.stream, retry_count);
+                int current_stream = p_sys->playback.stream;
+                if (hls_DownloadSegmentData(s, hls, segment, &current_stream) == VLC_SUCCESS)
+                {
+                    msg_Dbg(s, "Success to download segment %d of stream %d.", p_sys->playback.segment, p_sys->playback.stream);
+                    goto again;
+                }
+                msg_Dbg(s, "Failed to force download segment %d of stream %d.", p_sys->playback.segment, p_sys->playback.stream);
+            }
+       }
+
+       mtime_t timeout = mdate() + 5000000;
+       vlc_mutex_lock(&p_sys->download.lock_wait);
+       msg_Dbg(s, "Wait until the segment %d of stream %d is downloaded (but download try to download segment %d from stream %d",
+                  p_sys->playback.segment, p_sys->playback.stream,
+                  p_sys->download.segment, p_sys->download.stream);
+       vlc_cond_timedwait(&p_sys->download.wait, &p_sys->download.lock_wait, timeout);
+       retry_count++;
+       if (vlc_object_alive(s) && !s->b_error && !p_sys->b_quit && retry_count <= 5)
+               goto again;
     }
 
     /* Was the HLS stream changed to another bitrate? */
@@ -2295,23 +2336,8 @@ again:
     segment = GetSegment(s);
     if (segment == NULL)
     {
-        msg_Err(s, "segment %d should have been available (stream %d)",
-                p_sys->playback.segment, p_sys->playback.stream);
-
-        msg_Info(s, "Waiting for segment to be downloaded");
-
-        vlc_mutex_lock(&p_sys->download.lock_wait);
-
-        /* wake up the download segment thread if blocked */
-        vlc_cond_signal(&p_sys->download.wait);
-
-        mtime_t timeout = mdate() + 5000000;
-        if( vlc_cond_timedwait( &p_sys->download.wait, &p_sys->download.lock_wait, timeout ) )
-            msg_Warn(s, "Peek() reached timeout");
-        vlc_mutex_unlock(&p_sys->download.lock_wait);
-        if (!vlc_object_alive(s) || s->b_error || p_sys->b_quit)
-            return 0; /* eof? */
-        goto again;
+        msg_Warn(s, "Peek() no segment --> end of the stream");
+        return 0; /* eof? */
     }
 
     vlc_mutex_lock(&segment->lock);
-- 
1.7.8.3




More information about the vlc-devel mailing list