[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, ¤t) != 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, ¤t_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