[vlc-devel] [vlc-commits] commit: stream_filter/httplive.c: HLS stream size calculation ( Jean-Paul Saman )

Kurle, Brian Brian.Kurle at arrisi.com
Wed Dec 22 20:09:24 CET 2010


Jean-Paul,

I'm not completely follow what you are doing here.   The bandwidth provided in the M3U8 is only the maximum that none of the segments will exceed, not an average, or accurate summation of the collection.   However, in practice none of the segments are actually going to require this bandwidth (mostly because they are usually VBR).    This has been an issue that I've been pondering, myself when trying to fully analyze how the various Apple clients behave (and I find they, too, behave poorly when bandwidth availability changes in some situations).

brian

-----Original Message-----
From: vlc-commits-bounces at videolan.org [mailto:vlc-commits-bounces at videolan.org] On Behalf Of git at videolan.org
Sent: Wednesday, December 22, 2010 12:59 AM
To: vlc-commits at videolan.org
Subject: [vlc-commits] commit: stream_filter/httplive.c: HLS stream size calculation ( Jean-Paul Saman )

vlc | branch: master | Jean-Paul Saman <jean-paul.saman at m2x.nl> | Fri Dec 17 10:55:50 2010 +0100| [6991abef61bf44283d5312caebbc57c0b9a7eb1d] | committer: Jean-Paul Saman 

stream_filter/httplive.c: HLS stream size calculation

The function hls_GetStreamSize() calculates the HLS stream size in bytes, based
upon information found in the .m3u8 file. The sum of each segment duration
(in seconds) times bandwith in bytes (hls->bandwidth/8).

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

 modules/stream_filter/httplive.c |   49 ++++++++++++++++++++++++--------------
 1 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/modules/stream_filter/httplive.c b/modules/stream_filter/httplive.c
index 0a25b7e..374a7ab 100644
--- a/modules/stream_filter/httplive.c
+++ b/modules/stream_filter/httplive.c
@@ -77,6 +77,7 @@ typedef struct hls_stream_s
     int         sequence;   /* media sequence number */
     int         duration;   /* maximum duration per segment (ms) */
     uint64_t    bandwidth;  /* bandwidth usage of segments (bits per second)*/
+    uint64_t    size;       /* stream length (segment->duration * hls->bandwidth/8) */
 
     vlc_array_t *segments;  /* list of segments */
     vlc_url_t   url;        /* uri to m3u8 */
@@ -136,6 +137,7 @@ static int AccessDownload(stream_t *s, segment_t *segment);
 static void* hls_Thread(vlc_object_t *);
 static int get_HTTPLivePlaylist(stream_t *s, hls_stream_t *hls);
 
+static segment_t *segment_GetSegment(hls_stream_t *hls, int wanted);
 static void segment_Free(segment_t *segment);
 
 /****************************************************************************
@@ -180,6 +182,7 @@ static hls_stream_t *hls_New(vlc_array_t *hls_stream, int id, uint64_t bw, char
     hls->id = id;
     hls->bandwidth = bw;
     hls->duration = -1;/* unknown */
+    hls->size = 0;
     hls->sequence = 0; /* default is 0 */
     hls->version = 1;  /* default protocol version */
     hls->b_cache = true;
@@ -233,6 +236,25 @@ static hls_stream_t *hls_GetLast(vlc_array_t *hls_stream)
     return (hls_stream_t *) hls_Get(hls_stream, count);
 }
 
+static uint64_t hls_GetStreamSize(hls_stream_t *hls)
+{
+    /* NOTE: Stream size is calculated based on segment duration and
+     * HLS stream bandwidth from the .m3u8 file. If these are not correct
+     * then the deviation from exact byte size will be big and the seek/
+     * progressbar will not behave entirely as one expects. */
+    uint64_t size = 0UL;
+    int count = vlc_array_count(hls->segments);
+    for (int n = 0; n < count; n++)
+    {
+        segment_t *segment = segment_GetSegment(hls, n);
+        if (segment)
+        {
+            size += (segment->duration * (hls->bandwidth / 8));
+        }
+    }
+    return size;
+}
+
 /* Segment */
 static segment_t *segment_New(hls_stream_t* hls, int duration, char *uri)
 {
@@ -772,9 +794,9 @@ static int parse_HTTPLiveStreaming(stream_t *s)
             }
         }
 
+        vlc_mutex_lock(&hls->lock);
         if (p_sys->b_live)
         {
-            vlc_mutex_lock(&hls->lock);
 
             /* There should at least be 3 segments of hls->duration */
             int ok = 0;
@@ -794,12 +816,15 @@ static int parse_HTTPLiveStreaming(stream_t *s)
 
             /* Determine next time to reload playlist */
             p_sys->wakeup = p_sys->last + (hls->duration * 2 * (mtime_t)1000000);
-
-            vlc_mutex_unlock(&hls->lock);
         }
 
+        /* Stream size (approximate) */
+        hls->size = hls_GetStreamSize(hls);
+
         /* Can we cache files after playback */
         p_sys->b_cache = hls->b_cache;
+
+        vlc_mutex_unlock(&hls->lock);
     }
 
     return VLC_SUCCESS;
@@ -1474,22 +1499,10 @@ static uint64_t GetStreamSize(stream_t *s)
     if (hls == NULL) return 0;
 
     vlc_mutex_lock(&hls->lock);
-
-    /* FIXME: Stream size is not entirely exacts at this point */
-    uint64_t length = 0UL;
-    int count = vlc_array_count(hls->segments);
-    for (int n = 0; n < count; n++)
-    {
-        segment_t *segment = segment_GetSegment(hls, n);
-        if (segment)
-        {
-            length += (segment->size > 0) ? segment->size :
-                        (segment->duration * hls->bandwidth);
-        }
-    }
-
+    uint64_t size = hls->size;
     vlc_mutex_unlock(&hls->lock);
-    return length;
+
+    return size;
 }
 
 static int segment_Seek(stream_t *s, uint64_t pos)

_______________________________________________
vlc-commits mailing list
vlc-commits at videolan.org
http://mailman.videolan.org/listinfo/vlc-commits



More information about the vlc-devel mailing list