]> git.sesse.net Git - vlc/commitdiff
HLS: Do not assume Content-Length is set
authorRafaël Carré <funman@videolan.org>
Fri, 14 Nov 2014 10:51:16 +0000 (11:51 +0100)
committerRafaël Carré <funman@videolan.org>
Tue, 18 Nov 2014 09:23:06 +0000 (10:23 +0100)
Fixes #8078

modules/stream_filter/httplive.c

index 2a595272627e867173f668452d9131010f666bea..d66ee28dc2231a3a53a243409f3f0381040ff1e0 100644 (file)
@@ -1838,43 +1838,66 @@ static int hls_Download(stream_t *s, segment_t *segment)
         return VLC_EGENERIC;
 
     segment->size = stream_Size(p_ts);
-    assert(segment->size > 0);
 
-    segment->data = block_Alloc(segment->size);
-    if (segment->data == NULL)
-    {
+    if (segment->size == 0) {
+        int chunk_size = 65536;
+        segment->data = block_Alloc(chunk_size);
+        if (!segment->data)
+            goto nomem;
+        do {
+            if (segment->data->i_buffer - segment->size < chunk_size) {
+                chunk_size *= 2;
+                block_t *p_block = block_Realloc(segment->data, 0, segment->data->i_buffer + chunk_size);
+                if (!p_block) {
+                    block_Release(segment->data);
+                    segment->data = NULL;
+                    goto nomem;
+                }
+                segment->data = p_block;
+            }
+
+            ssize_t length = stream_Read(p_ts, segment->data->p_buffer + segment->size, chunk_size);
+            if (length <= 0) {
+                segment->data->i_buffer = segment->size;
+                break;
+            }
+            segment->size += length;
+        } while (vlc_object_alive(s));
+
         stream_Delete(p_ts);
-        return VLC_ENOMEM;
+        return VLC_SUCCESS;
     }
 
+    segment->data = block_Alloc(segment->size);
+    if (segment->data == NULL)
+        goto nomem;
+
     assert(segment->data->i_buffer == segment->size);
 
-    ssize_t length = 0, curlen = 0;
-    uint64_t size;
+    ssize_t curlen = 0;
     do
     {
         /* NOTE: Beware the size reported for a segment by the HLS server may not
          * be correct, when downloading the segment data. Therefore check the size
          * and enlarge the segment data block if necessary.
          */
-        size = stream_Size(p_ts);
+        uint64_t size = stream_Size(p_ts);
         if (size > segment->size)
         {
             msg_Dbg(s, "size changed %"PRIu64, segment->size);
             block_t *p_block = block_Realloc(segment->data, 0, size);
             if (p_block == NULL)
             {
-                stream_Delete(p_ts);
                 block_Release(segment->data);
                 segment->data = NULL;
-                return VLC_ENOMEM;
+                goto nomem;
             }
             segment->data = p_block;
             segment->size = size;
             assert(segment->data->i_buffer == segment->size);
             p_block = NULL;
         }
-        length = stream_Read(p_ts, segment->data->p_buffer + curlen, segment->size - curlen);
+        ssize_t length = stream_Read(p_ts, segment->data->p_buffer + curlen, segment->size - curlen);
         if (length <= 0)
             break;
         curlen += length;
@@ -1882,6 +1905,10 @@ static int hls_Download(stream_t *s, segment_t *segment)
 
     stream_Delete(p_ts);
     return VLC_SUCCESS;
+
+nomem:
+    stream_Delete(p_ts);
+    return VLC_ENOMEM;
 }
 
 /* Read M3U8 file */