Skip to content

Commit

Permalink
Limit Chromecast playback to 1080p
Browse files Browse the repository at this point in the history
Original Chromecast devices can output a max of 1080p, and may have
issues digesting higher resolution content.  Since higher resolution
content would be downscaled for display anyway, limit Chromecast to
1080p to avoid both decoder issues and wasted bandwidth.

Some Cast devices may support UHD content, but the max res for
Chromecast is currently hard-coded until we have a way to detect a
device's capabilities at runtime.

Issue #261

Change-Id: I3dd093b07f9a964116f81422f3c298dfbf7e2e52
  • Loading branch information
joeyparrish committed Jul 7, 2016
1 parent 316b7fe commit 3624d8e
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 3 deletions.
5 changes: 5 additions & 0 deletions lib/cast/cast_receiver.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ shaka.cast.CastReceiver.prototype.init_ = function() {
this.player_.addEventListener(name, this.proxyEvent_.bind(this, 'player'));
}.bind(this));

// Limit streams to 1080p. In our tests, the original Chromecast seems to
// have trouble decoding above this limit. It would be a waste to select a
// higher res anyway, given that the device only outputs 1080p to begin with.
this.player_.setMaxHardwareResolution(1920, 1080);

// Start polling.
this.pollAttributes_();
};
Expand Down
3 changes: 2 additions & 1 deletion lib/offline/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,8 @@ shaka.offline.Storage.prototype.filterPeriod_ = function(period) {
}
StreamUtils.filterPeriod(this.drmEngine_, activeStreams, period);
StreamUtils.applyRestrictions(
period, this.player_.getConfiguration().restrictions);
period, this.player_.getConfiguration().restrictions,
/* maxHwRes */ { width: Infinity, height: Infinity });
};


Expand Down
20 changes: 19 additions & 1 deletion lib/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ shaka.Player = function(video, opt_dependencyInjector) {
/** @private {?shakaExtern.PlayerConfiguration} */
this.config_ = this.defaultConfig_();

/** @private {{width: number, height: number}} */
this.maxHwRes_ = { width: Infinity, height: Infinity };

/** @private {!Array.<shakaExtern.StreamChoice>} */
this.switchHistory_ = [];

Expand Down Expand Up @@ -1032,6 +1035,21 @@ shaka.Player.prototype.addTextTrack = function(
};


/**
* Set the maximum resolution that the platform's hardware can handle.
* This will be called automatically by shaka.cast.CastReceiver to enforce
* limitations of the Chromecast hardware.
*
* @param {number} width
* @param {number} height
* @export
*/
shaka.Player.prototype.setMaxHardwareResolution = function(width, height) {
this.maxHwRes_.width = width;
this.maxHwRes_.height = height;
};


/**
* Initialize the Player.
* @private
Expand Down Expand Up @@ -1230,7 +1248,7 @@ shaka.Player.prototype.filterPeriod_ = function(period) {
period.streamSets.some(shaka.util.StreamUtils.hasPlayableStreams);

var tracksChanged = shaka.util.StreamUtils.applyRestrictions(
period, this.config_.restrictions);
period, this.config_.restrictions, this.maxHwRes_);
if (tracksChanged && !this.loadChain_)
this.onTracksChanged_();

Expand Down
10 changes: 9 additions & 1 deletion lib/util/stream_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,15 @@ goog.require('shaka.util.LanguageUtils');
/**
* @param {shakaExtern.Period} period
* @param {shakaExtern.Restrictions} restrictions
* Configured restrictions from the user.
* @param {{width: number, height: number}} maxHwRes
* The maximum resolution the hardware can handle.
* This is applied separately from user restrictions because the setting
* should not be easily replaced by the user's configuration.
* @return {boolean} Whether the tracks changed.
*/
shaka.util.StreamUtils.applyRestrictions = function(period, restrictions) {
shaka.util.StreamUtils.applyRestrictions =
function(period, restrictions, maxHwRes) {
var tracksChanged = false;

period.streamSets.forEach(function(streamSet) {
Expand All @@ -40,8 +46,10 @@ shaka.util.StreamUtils.applyRestrictions = function(period, restrictions) {
if (streamSet.type == 'video') {
if (stream.width < restrictions.minWidth ||
stream.width > restrictions.maxWidth ||
stream.width > maxHwRes.width ||
stream.height < restrictions.minHeight ||
stream.height > restrictions.maxHeight ||
stream.height > maxHwRes.height ||
(stream.width * stream.height) < restrictions.minPixels ||
(stream.width * stream.height) > restrictions.maxPixels ||
stream.bandwidth < restrictions.minVideoBandwidth ||
Expand Down
7 changes: 7 additions & 0 deletions test/cast/cast_receiver_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ describe('CastReceiver', function() {
expect(Object.keys(mockPlayer.listeners).length).toBeGreaterThan(0);
});

it('limits streams to 1080p', function() {
checkChromeOrChromecast();
expect(mockPlayer.setMaxHardwareResolution).
toHaveBeenCalledWith(1920, 1080);
});

it('starts polling', function(done) {
checkChromeOrChromecast();
var fakeConfig = {key: 'value'};
Expand Down Expand Up @@ -592,6 +598,7 @@ describe('CastReceiver', function() {
seekRange: jasmine.createSpy('seekRange'),
configure: jasmine.createSpy('configure'),
setTextTrackVisibility: jasmine.createSpy('setTextTrackVisibility'),
setMaxHardwareResolution: jasmine.createSpy('setMaxHardwareResolution'),
load: jasmine.createSpy('load'),
destroy: jasmine.createSpy('destroy'),
addEventListener: function(eventName, listener) {
Expand Down

0 comments on commit 3624d8e

Please sign in to comment.