[vlc-devel] [PATCH] HLS: implement pause

Rafaël Carré funman at videolan.org
Sat Aug 24 22:41:25 CEST 2013


Close #9234
---
 modules/stream_filter/httplive.c | 41 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/modules/stream_filter/httplive.c b/modules/stream_filter/httplive.c
index 0512516..699e524 100644
--- a/modules/stream_filter/httplive.c
+++ b/modules/stream_filter/httplive.c
@@ -141,6 +141,12 @@ struct stream_sys_t
     bool        b_live;     /* live stream? or vod? */
     bool        b_error;    /* parsing error */
     bool        b_aesmsg;   /* only print one time that the media is encrypted */
+    bool        can_pause;  /* can source stream be paused? */
+
+    /* Shared data */
+    vlc_cond_t   wait;
+    vlc_mutex_t  lock;
+    bool         paused;
 };
 
 /****************************************************************************
@@ -1164,6 +1170,7 @@ static int parse_M3U8(stream_t *s, vlc_array_t *streams, uint8_t *buffer, const
 
 static int hls_DownloadSegmentKey(stream_t *s, segment_t *seg)
 {
+    stream_sys_t *p_sys = s->p_sys;
     stream_t *p_m3u8 = stream_UrlNew(s, seg->psz_key_path);
     if (p_m3u8 == NULL)
     {
@@ -1767,6 +1774,7 @@ static int Prefetch(stream_t *s, int *current)
  ****************************************************************************/
 static int hls_Download(stream_t *s, segment_t *segment)
 {
+    stream_sys_t *p_sys = s->p_sys;
     assert(segment);
 
     stream_t *p_ts = stream_UrlNew(s, segment->url);
@@ -1810,7 +1818,11 @@ static int hls_Download(stream_t *s, segment_t *segment)
             assert(segment->data->i_buffer == segment->size);
             p_block = NULL;
         }
+        vlc_mutex_lock(&p_sys->lock);
+        while (p_sys->paused)
+            vlc_cond_wait(&p_sys->wait, &p_sys->lock);
         length = stream_Read(p_ts, segment->data->p_buffer + curlen, segment->size - curlen);
+        vlc_mutex_unlock(&p_sys->lock);
         if (length <= 0)
             break;
         curlen += length;
@@ -1823,6 +1835,7 @@ static int hls_Download(stream_t *s, segment_t *segment)
 /* Read M3U8 file */
 static ssize_t read_M3U8_from_stream(stream_t *s, uint8_t **buffer)
 {
+    stream_sys_t *p_sys = s->p_sys;
     int64_t total_bytes = 0;
     int64_t total_allocated = 0;
     uint8_t *p = NULL;
@@ -1975,6 +1988,12 @@ static int Open(vlc_object_t *p_this)
     s->pf_peek = Peek;
     s->pf_control = Control;
 
+    stream_Control (s->p_source, STREAM_CAN_PAUSE, &p_sys->can_pause);
+    p_sys->paused = false;
+
+    vlc_cond_init(&p_sys->wait);
+    vlc_mutex_init(&p_sys->lock);
+
     /* Parse HLS m3u8 content. */
     uint8_t *buffer = NULL;
     ssize_t len = read_M3U8_from_stream(s->p_source, &buffer);
@@ -2047,6 +2066,9 @@ fail:
     }
     vlc_array_destroy(p_sys->hls_stream);
 
+    vlc_mutex_destroy(&p_sys->lock);
+    vlc_cond_destroy(&p_sys->wait);
+
     /* */
     free(p_sys->m3u8);
     free(p_sys);
@@ -2087,6 +2109,10 @@ static void Close(vlc_object_t *p_this)
     vlc_array_destroy(p_sys->hls_stream);
 
     /* */
+
+    vlc_mutex_destroy(&p_sys->lock);
+    vlc_cond_destroy(&p_sys->wait);
+
     free(p_sys->m3u8);
     if (p_sys->peeked)
         block_Release (p_sys->peeked);
@@ -2529,13 +2555,26 @@ static int Control(stream_t *s, int i_query, va_list args)
         case STREAM_CAN_CONTROL_PACE:
             *(va_arg (args, bool *)) = true;
             break;
+        case STREAM_CAN_PAUSE:
+            *(va_arg (args, bool *)) = p_sys->can_pause;
+            break;
         case STREAM_CAN_FASTSEEK:
-        case STREAM_CAN_PAUSE: /* TODO */
             *(va_arg (args, bool *)) = false;
             break;
         case STREAM_GET_POSITION:
             *(va_arg (args, uint64_t *)) = p_sys->playback.offset;
             break;
+        case STREAM_SET_PAUSE_STATE:
+        {
+            bool paused = va_arg (args, unsigned);
+
+            vlc_mutex_lock(&p_sys->lock);
+            stream_Control(s->p_source, STREAM_SET_PAUSE_STATE, paused);
+            p_sys->paused = paused;
+            vlc_cond_signal(&p_sys->wait);
+            vlc_mutex_unlock(&p_sys->lock);
+            break;
+        }
         case STREAM_SET_POSITION:
             if (hls_MaySeek(s))
             {
-- 
1.8.1.2



More information about the vlc-devel mailing list