[vlc-devel] [PATCH 39/48] hls: Reworking segment download synchronization.

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


---
 modules/stream_filter/httplive.c |   45 ++++++++++++++++++++++++-------------
 1 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/modules/stream_filter/httplive.c b/modules/stream_filter/httplive.c
index 14bb159..77a0b3c 100644
--- a/modules/stream_filter/httplive.c
+++ b/modules/stream_filter/httplive.c
@@ -77,6 +77,9 @@ typedef struct segment_s
 
     vlc_mutex_t lock;
     block_t     *data;      /* data */
+
+    vlc_cond_t  wait;       /* A condition to wait for segment data download
+                               This wait cond is locked by the segment mutex */
 } segment_t;
 
 typedef struct hls_stream_s
@@ -317,11 +320,13 @@ static segment_t *segment_New(hls_stream_t* hls, const int duration, const char
     segment->psz_key_path = NULL;
     if (hls->psz_current_key_path)
         segment->psz_key_path = strdup(hls->psz_current_key_path);
+    vlc_cond_init( &segment->wait );
     return segment;
 }
 
 static void segment_Free(segment_t *segment)
 {
+    vlc_cond_destroy( &segment->wait );
     vlc_mutex_destroy(&segment->lock);
 
     free(segment->uri);
@@ -1456,9 +1461,7 @@ static int hls_DownloadSegmentData(stream_t *s, hls_stream_t *hls, segment_t *se
     {
         msg_Err(s, "downloaded segment %d from stream %d failed",
                     segment->sequence, *cur_stream);
-        vlc_mutex_unlock(&segment->lock);
-        p_sys->b_reset = true;
-        return VLC_EGENERIC;
+        goto fail;
     }
     mtime_t duration = mdate() - start;
 
@@ -1470,13 +1473,14 @@ static int hls_DownloadSegmentData(stream_t *s, hls_stream_t *hls, segment_t *se
     /* If the segment is encrypted, decode it */
     if (hls_DecodeSegmentData(s, hls, segment) != VLC_SUCCESS)
     {
-        vlc_mutex_unlock(&segment->lock);
-        p_sys->b_reset = true;
-        return VLC_EGENERIC;
+        msg_Err( s, "Failed to decode segment data" );
+        goto fail;
     }
 
     duration = mdate() - start;
 
+    //Signal we just finished downloading a segment so the playback can go on.
+    vlc_cond_signal( &segment->wait );
     vlc_mutex_unlock(&segment->lock);
 
     msg_Info(s, "decode segment %d from stream %d in %dms",
@@ -1508,6 +1512,13 @@ static int hls_DownloadSegmentData(stream_t *s, hls_stream_t *hls, segment_t *se
         }
     }
     return VLC_SUCCESS;
+
+fail:
+    //Don't make the playback thread wait forever
+    vlc_cond_signal( &segment->wait );
+    vlc_mutex_unlock(&segment->lock);
+    p_sys->b_reset = true;
+    return VLC_EGENERIC;
 }
 
 static void* hls_Thread(void *p_this)
@@ -1523,7 +1534,6 @@ static void* hls_Thread(void *p_this)
         assert(hls);
 
         /* Wait to be wake up when a new segment is needed */
-        msg_Dbg(s, "Sleeping until we have a new segment to download");
         vlc_mutex_lock(&p_sys->download.lock_wait);
         vlc_cond_wait(&p_sys->download.wait, &p_sys->download.lock_wait);
         vlc_mutex_unlock(&p_sys->download.lock_wait);
@@ -2087,18 +2097,21 @@ static segment_t *GetSegment(stream_t *s)
     } while (segment == NULL);
 
     /* Is this segment ready ? */
-    while (vlc_object_alive(s) && p_sys->b_quit == false)
+    vlc_mutex_lock(&segment->lock);
+    if ( segment->data == NULL )
     {
-        vlc_mutex_lock(&segment->lock);
-        if (segment->data)
-        {
-            vlc_mutex_unlock(&segment->lock);
-            break;
-        }
-        vlc_mutex_unlock(&segment->lock);
+        //Awake the download thread:
+        vlc_mutex_lock( &p_sys->download.lock_wait );
+        vlc_cond_signal( &p_sys->download.wait );
+        vlc_mutex_unlock( &p_sys->download.lock_wait );
+    }
+    while ( segment->data == NULL && vlc_object_alive(s) && p_sys->b_quit == false )
+    {
+        //And wait for the download to be successfull...
         msg_Warn(s, "The segment (%d) is not downloaded for stream %d. Waiting a little bit....", p_sys->playback.segment, p_sys->playback.stream);
-        msleep(1000000);
+        vlc_cond_wait( &segment->wait, &segment->lock );
     }
+    vlc_mutex_unlock(&segment->lock);
 
     return segment;
 }
-- 
1.7.8.3




More information about the vlc-devel mailing list