[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