c0045796 by David LaPalomento

Scale the initial bandwidth estimate

Multiply the bandwidth measurement from the master playlist by five to account for the higher ratio of latency to throughput for this request relative to segments. Using the bandwidth number directly was almost always resulting in very low initial bandwidth estimates and poorer quality startup than necessary. The scaling factor was obtained by testing a number of videos from a high throughput/low latency connection as an upper bound and the same connection throttled to "DSL" levels with Network Link Conditioner for the lower bound. Update the playlist switching simulator to apply initial bandwidth estimates and reduce the simulation duration a bit so that the early behavior is more visible.
1 parent bc2d1c4d
......@@ -138,7 +138,14 @@ videojs.Hls.prototype.handleSourceOpen = function() {
};
oldMediaPlaylist = this.playlists.media();
this.setBandwidth(this.playlists);
// the bandwidth estimate for the first segment is based on round trip
// time for the master playlist. the master playlist is almost always
// tiny so the round trip time is dominated by latency and so the
// computed bandwidth is much lower than steady-state. to account for
// this, we scale the bandwidth estimate from the master playlist.
this.setBandwidth({
bandwidth: this.playlists.bandwidth * 5
});
selectedPlaylist = this.selectPlaylist();
oldBitrate = oldMediaPlaylist.attributes &&
......
......@@ -94,11 +94,11 @@
</p>
The video is available at
<ul>
<li><input class=bitrate type=number min=1 value=65536> bits per second</li>
<li><input class=bitrate type=number min=1 value=153600> bits per second</li>
<li><input class=bitrate type=number min=1 value=450560> bits per second</li>
<li><input class=bitrate type=number min=1 value=921600> bits per second</li>
<li><input class=bitrate type=number min=1 value=1536000> bits per second</li>
<li><input class=bitrate type=number min=1 value=312000> bits per second</li>
<li><input class=bitrate type=number min=1 value=524000> bits per second</li>
<li><input class=bitrate type=number min=1 value=1296000> bits per second</li>
<li><input class=bitrate type=number min=1 value=2125000> bits per second</li>
<li><input class=bitrate type=number min=1 value=3125000> bits per second</li>
</ul>
</form>
</section>
......
(function(window, document) {
'use strict';
var segmentDuration = 9, // seconds
segmentCount = 100,
segmentCount = 10,
duration = segmentDuration * segmentCount,
propagationDelay = 0.5,
......@@ -171,13 +171,21 @@
return currentTime;
};
bandwidths.sort(function(left, right) {
return left.time - right.time;
});
// respond to the playlist requests
requests[0].bandwidth = bandwidths[0].bandwidth;
requests.shift().respond(200, null, master);
requests[0].bandwidth = bandwidths[0].bandwidth;
requests[0].respond(200, null, playlistResponse(+requests[0].url.match(/\d+$/)));
requests.shift();
bandwidths.sort(function(left, right) {
return left.time - right.time;
// record the measured bandwidth for the playlist requests
results.effectiveBandwidth.push({
time: 0,
bandwidth: player.hls.bandwidth
});
// pre-calculate the bandwidth at each second
......
......@@ -618,6 +618,21 @@ test('selects a playlist below the current bandwidth', function() {
'the low bitrate stream is selected');
});
test('scales the bandwidth estimate for the first segment', function() {
player.src({
src: 'manifest/master.m3u8',
type: 'application/vnd.apple.mpegurl'
});
openMediaSource(player);
requests[0].bandwidth = 500;
requests.shift().respond(200, null,
'#EXTM3U\n' +
'#EXT-X-PLAYLIST-TYPE:VOD\n' +
'#EXT-X-TARGETDURATION:10\n');
equal(player.hls.bandwidth, 500 * 5, 'scaled the bandwidth estimate by 5');
});
test('raises the minimum bitrate for a stream proportionially', function() {
var playlist;
player.src({
......