[vlc-devel] [PATCH] HttpLive stream_filter: alternative version of ChooseSegment function

Łukasz Korbel korbel85 at gmail.com
Thu Mar 8 22:20:26 CET 2012


Sorry for mistake. Here is proper version.

>From e14d53f096334f98dfc7fa2439c8cfe07111f40e Mon Sep 17 00:00:00 2001
From: Lukasz Korbel <korbel85 at gmail.com>
Date: Thu, 8 Mar 2012 21:48:17 +0100
Subject: [PATCH] Improved ChooseSegment function

Currrent version allow user to choose how m3u8 playlist will be handled.
The default behavior is to play always from first segment in playlist
(--hsl-allways-firstseg).
If hls-allways-firstseg is set to false playback will start from end
of playlist.
In that case segment is choosen using hls-delay-before-lastseg value
(seconds). If delay is set to 0
then last but two segment will be choosen, which is the latest
possible according to HLS protocol.
---
 modules/stream_filter/httplive.c |   75 +++++++++++++++++++++++---------------
 1 files changed, 46 insertions(+), 29 deletions(-)

diff --git a/modules/stream_filter/httplive.c b/modules/stream_filter/httplive.c
index ffebc0f..cd0d5f3 100644
--- a/modules/stream_filter/httplive.c
+++ b/modules/stream_filter/httplive.c
@@ -49,11 +49,25 @@
 static int  Open (vlc_object_t *);
 static void Close(vlc_object_t *);

+#define HLS_ALLWAYSFIRST_TEXT N_("Play allways from first segment in playlist")
+#define HLS_ALLWAYSFIRST_LONGTEXT N_("Start playback of live stream
from first"\
+                              " segment in the playlist. If disabled
playback "\
+                              "starting segment is choosed based on
hls-delay "\
+                              "value.")
+#define HLS_DELAY_TEXT N_("Minimal playback delay (seconds)")
+#define HLS_DELAY_LONGTEXT N_("Define minimal delay of live stream playback. "\
+                              "If this values is set to 0 vlc will
use minimal"\
+                              " delay, starting from last but two segment.")
+
 vlc_module_begin()
     set_category(CAT_INPUT)
     set_subcategory(SUBCAT_INPUT_STREAM_FILTER)
     set_description(N_("Http Live Streaming stream filter"))
     set_capability("stream_filter", 20)
+    add_bool( "hls-allways-firstseg", true, HLS_ALLWAYSFIRST_TEXT,
+              HLS_ALLWAYSFIRST_LONGTEXT, true )
+    add_integer( "hls-delay-before-lastseg", 0, HLS_DELAY_TEXT,
HLS_DELAY_LONGTEXT, true )
+               change_integer_range (0, 600)
     set_callbacks(Open, Close)
 vlc_module_end()

@@ -126,6 +140,9 @@ struct stream_sys_t
         int         stream;     /* current hls_stream  */
         int         segment;    /* current segment for playback */
     } playback;
+    /* Settings for playback */
+    bool   b_allways_firstseg; /* start always from first segment in
playlist */
+    int    delay_before_lastseg; /* delay of live stream playback (seconds)*/

     /* Playlist */
     struct hls_playlist_s
@@ -425,48 +442,44 @@ static segment_t *segment_Find(hls_stream_t
*hls, const int sequence)
     return NULL;
 }

+static int segment_Duration(hls_stream_t *hls, const int index)
+{
+    segment_t *segment = segment_GetSegment(hls, index);
+    assert(segment);
+    return segment->duration;
+}
+
 static int ChooseSegment(stream_t *s, const int current)
 {
     stream_sys_t *p_sys = (stream_sys_t *)s->p_sys;
     hls_stream_t *hls = hls_Get(p_sys->hls_stream, current);
     if (hls == NULL) return 0;

-    /* Choose a segment to start which is no closer than
-     * 3 times the target duration from the end of the playlist.
-     */
     int wanted = 0;
-    int duration = 0;
-    int sequence = 0;
     int count = vlc_array_count(hls->segments);
-    int i = p_sys->b_live ? count - 1 : 0;

-    while((i >= 0) && (i < count))
+    /* If playing live stream and hls-allways-firstseg is disabled
start playback
+    from hls-delay number of seconds before end of playlist.
Otherwise start from
+    first segment in playlist (wanted = 0) */
+    if (p_sys->b_live && !p_sys->b_allways_firstseg)
     {
-        segment_t *segment = segment_GetSegment(hls, i);
-        assert(segment);
-
-        if (segment->duration > hls->duration)
-        {
-            msg_Err(s, "EXTINF:%d duration is larger than
EXT-X-TARGETDURATION:%d",
-                    segment->duration, hls->duration);
-        }
+        /* Must start at least before last two segments.
+        http://tools.ietf.org/html/draft-pantos-http-live-streaming-00#section-6.2.2
*/
+        int duration = 0;
+        duration += segment_Duration( hls, count -1); //last seg
+        duration += segment_Duration( hls, count -2); //last but one seg

-        duration += segment->duration;
-        if (duration >= 3 * hls->duration)
-        {
-            /* Start point found */
-            wanted = p_sys->b_live ? i : 0;
-            sequence = segment->sequence;
-            break;
-        }
-
-        if (p_sys->b_live)
-            i-- ;
-        else
-            i++;
+        int i= count - 3;  //first available
+        while (duration < p_sys->delay_before_lastseg && i >= 0)
+            duration += segment_Duration( hls, i--); //uptade
duration and index
+        wanted = i;
     }

-    msg_Info(s, "Choose segment %d/%d (sequence=%d)", wanted, count, sequence);
+    //query for starting segment sequence number
+    segment_t *segment = segment_GetSegment(hls, wanted);
+    int sequence = segment->sequence;
+
+    msg_Info(s, "Choose segment %d/%d (sequence=%d)", wanted+1,
count, sequence);
     return wanted;
 }

@@ -1901,6 +1914,10 @@ static int Open(vlc_object_t *p_this)
     qsort( p_sys->hls_stream->pp_elems, p_sys->hls_stream->i_count,
            sizeof( hls_stream_t* ), &hls_CompareStreams );

+    /* Read playlist settings from config */
+    p_sys->b_allways_firstseg = var_InheritBool(s, "hls-allways-firstseg");
+    p_sys->delay_before_lastseg = var_InheritInteger(s,
"hls-delay-before-lastseg");
+
     /* Choose first HLS stream to start with */
     int current = p_sys->playback.stream = 0;
     p_sys->playback.segment = p_sys->download.segment =
ChooseSegment(s, current);
-- 
1.7.5.4



More information about the vlc-devel mailing list