[vlc-devel] [PATCH] Improve HLS startup speed

Chris Smowton cs448 at cam.ac.uk
Thu May 31 01:20:30 CEST 2012


My next tweak to the HLS stream filter: this time I'm trying to get it 
to start playing a little faster when conditions are good. The attached 
patch addresses this by introducing a very simple dynamic buffering 
scheme, and by fixing a flaw which was causing more buffering than was 
intended at startup.

The existing buffering scheme was hardcoded, and inconsistent.

After an underrun due to the playback thread overtaking the download 
thread, we simply rebuffered a single segment, as a side-effect of 
trying to acquire the segment mutex in GetSegment() whilst the download 
thread was still retrieving the data for that segment (actually this was 
slightly racy; it was possible for the playback thread to beat the 
download thread to the lock, and so report a false EOF).

At startup, we fetched a hardcoded 2 segments before starting playback.

Finally, after a seek we fetched 3 segments before permitting playback 
to resume.

I've replaced these three with a variable member of hls_playback_t 
called buf_segs: the number of segments we want on hand before 
recovering from an underrun or a seek. It starts off with an optimistic 
value of 1, and is set to the most pessimistic existing value of 3 after 
we suffer our first underrun.

The rationale is that there are basically 3 situations that might happen:

1. Download is much faster than playback. In this case we might as well 
start as soon as we have enough bytes on hand; with more hacking we 
could do just that, but I settle for 1 segment since (a) I'd need to 
modify the segment locking discipline and (b) the segment might need 
2. Download is much slower than playback; then all is lost whatever we do.
3. Download is roughly the same speed as playback, with some variance 
either side. In this case a 1-segment buffer will likely cause underruns 
because the following segment will be just arriving when we finish 
playing back the current one. This is why after an underrun I switch to 
a 3-segment buffer.

So in short, the patch aims to optimistically suppose case #1, then move 
to an approach that suits case #3 after it seems there might be trouble.

Finally, I added a special case to Segment_Seek, because every startup 
was exhibiting the following behaviour:

1. Prefetch runs, fetching 2 segments before we start.
2. VLC core issues a seek to offset 0
3. Segment_Seek sets p_sys->download.seek and waits for the download 
thread to acknowledge...
4. ...but the download thread is busy fetching segment 3!
5. It finishes downloading, the seek completes, and we start playback.

The best fix here would be to permit asynchronously ordering the 
download thread to reposition without waiting if our segments are ready, 
but this would be tricky because there are lots of places where 
download.segment is assumed to have a sensible relationship with 
playback.segment. Therefore I catch a more specialised case, which 
happens to include the seek-0-at-startup case. If the download pointer 
is at segment N, and playback is being seeked to segment M, and N is 
sufficiently greater than M that we have enough segments in hand to 
satisfy p_sys->playback.buf_segs, and all segments between M and N 
(including M, excluding N) are already present, I skip waiting for the 
download thread to become available because all that would happen is 
that the download thread would immediately skip these itself and return 
to its previous position.

Finally, some results: for my simulated 128K listener pulling a 96K MP3, 
running with 10s segments, and with a 200ms RTT (representitive of 
cross-Atlantic traffic, for example), this allows him to get started in 
roughly 9 seconds (4 RTTs plus a segment download time) rather than 24 
seconds (8 RTTs plus 3 segments).

Since this is a more involved patch than the others, I guess I'll have 
done some of it wrong -- please let me know and I'll tweak it appropriately!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Improve-HLS-startup-speed.patch
Type: text/x-patch
Size: 10403 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20120531/3f7febde/attachment.bin>

More information about the vlc-devel mailing list