[vlc-commits] HLS (httplive.c): fix Peek() function

F. Yhuel git at videolan.org
Mon Aug 8 14:09:54 CEST 2011


vlc | branch: master | F. Yhuel <fyhuel at viotech.net> | Thu Aug  4 16:33:43 2011 +0200| [cade3d997969c75466336c74f1a29eb4987c46d7] | committer: Jean-Paul Saman

HLS (httplive.c): fix Peek() function

The new Peek() function now allocates a block (p_sys->peeked) if the
required size (i_peek) is greater than the size of the playback
segment, and then do a copy of one (or several) segment's data block(s) in it.
In the end, p_sys->peeked might be the concatenation of several segment's data
blocks, but usually it will be NULL.

Signed-off-by: Jean-Paul Saman <jean-paul.saman at m2x.nl>

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

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

diff --git a/modules/stream_filter/httplive.c b/modules/stream_filter/httplive.c
index cc3fe48..000a911 100644
--- a/modules/stream_filter/httplive.c
+++ b/modules/stream_filter/httplive.c
@@ -92,6 +92,8 @@ struct stream_sys_t
     vlc_thread_t  reload;       /* HLS m3u8 reload thread */
     vlc_thread_t  thread;       /* HLS segment download thread */
 
+    block_t      *peeked;
+
     /* */
     vlc_array_t  *hls_stream;   /* bandwidth adaptation */
     uint64_t      bandwidth;    /* measured bandwidth (bits per second) */
@@ -1662,6 +1664,8 @@ static void Close(vlc_object_t *p_this)
 
     /* */
     vlc_UrlClean(&p_sys->m3u8);
+    if (p_sys->peeked)
+        block_Release (p_sys->peeked);
     free(p_sys);
 }
 
@@ -1850,10 +1854,9 @@ static int Read(stream_t *s, void *buffer, unsigned int i_read)
 static int Peek(stream_t *s, const uint8_t **pp_peek, unsigned int i_peek)
 {
     stream_sys_t *p_sys = s->p_sys;
-    size_t curlen = 0;
     segment_t *segment;
+    unsigned int len = i_peek;
 
-again:
     segment = GetSegment(s);
     if (segment == NULL)
     {
@@ -1864,29 +1867,77 @@ again:
 
     vlc_mutex_lock(&segment->lock);
 
-    /* remember segment to peek */
-    int peek_segment = p_sys->playback.segment;
-    do
+    size_t i_buff = segment->data->i_buffer;
+    uint8_t *p_buff = segment->data->p_buffer;
+
+    if (i_peek < i_buff)
     {
-        if (i_peek < segment->data->i_buffer)
-        {
-            *pp_peek = segment->data->p_buffer;
-            curlen += i_peek;
-        }
-        else
+        *pp_peek = p_buff;
+        vlc_mutex_unlock(&segment->lock);
+        return i_peek;
+    }
+
+    else /* This will seldom be run */
+    {
+        /* remember segment to read */
+        int peek_segment = p_sys->playback.segment;
+        size_t curlen = 0;
+        segment_t *nsegment;
+        p_sys->playback.segment++;
+        block_t *peeked = p_sys->peeked;
+
+        if (peeked == NULL)
+            peeked = block_Alloc (i_peek);
+        else if (peeked->i_buffer < i_peek)
+            peeked = block_Realloc (peeked, 0, i_peek);
+        if (peeked == NULL)
+            return 0;
+
+        memcpy(peeked->p_buffer, p_buff, i_buff);
+        curlen = i_buff;
+        len -= i_buff;
+        vlc_mutex_unlock(&segment->lock);
+
+        i_buff = peeked->i_buffer;
+        p_buff = peeked->p_buffer;
+        *pp_peek = p_buff;
+
+        while ((curlen < i_peek) && vlc_object_alive(s))
         {
-            p_sys->playback.segment++;
-            vlc_mutex_unlock(&segment->lock);
-            goto again;
-        }
-    } while ((curlen < i_peek) && vlc_object_alive(s));
+            nsegment = GetSegment(s);
+            if (nsegment == NULL)
+            {
+                msg_Err(s, "segment %d should have been available (stream %d)",
+                        p_sys->playback.segment, p_sys->playback.stream);
+                /* restore segment to read */
+                p_sys->playback.segment = peek_segment;
+                return curlen; /* eof? */
+            }
 
-    /* restore segment to read */
-    p_sys->playback.segment = peek_segment;
+            vlc_mutex_lock(&nsegment->lock);
 
-    vlc_mutex_unlock(&segment->lock);
+            if (len < nsegment->data->i_buffer)
+            {
+                memcpy(p_buff + curlen, nsegment->data->p_buffer, len);
+                curlen += len;
+            }
+            else
+            {
+                size_t i_nbuff = nsegment->data->i_buffer;
+                memcpy(p_buff + curlen, nsegment->data->p_buffer, i_nbuff);
+                curlen += i_nbuff;
+                len -= i_nbuff;
+
+                p_sys->playback.segment++;
+            }
 
-    return curlen;
+            vlc_mutex_unlock(&nsegment->lock);
+        }
+
+        /* restore segment to read */
+        p_sys->playback.segment = peek_segment;
+        return curlen;
+    }
 }
 
 static bool hls_MaySeek(stream_t *s)



More information about the vlc-commits mailing list