Skip to content

Commit

Permalink
Add additional logic to InsufficientBufferRule.js
Browse files Browse the repository at this point in the history
  • Loading branch information
dsilhavy committed Jul 10, 2021
1 parent 86d151f commit f3aa47a
Showing 1 changed file with 42 additions and 22 deletions.
64 changes: 42 additions & 22 deletions src/streaming/rules/abr/InsufficientBufferRule.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import MediaPlayerEvents from '../../MediaPlayerEvents';
function InsufficientBufferRule(config) {

config = config || {};
const INSUFFICIENT_BUFFER_SAFETY_FACTOR = 0.5;
const SEGMENT_IGNORE_COUNT = 2;

const context = this.context;
Expand Down Expand Up @@ -77,29 +78,48 @@ function InsufficientBufferRule(config) {
function getMaxIndex(rulesContext) {
const switchRequest = SwitchRequest(context).create();

if (!rulesContext || !rulesContext.hasOwnProperty('getMediaType')) {
return switchRequest;
}
try {

checkConfig();
if (!rulesContext || !rulesContext.hasOwnProperty('getMediaType')) {
return switchRequest;
}

const mediaType = rulesContext.getMediaType();
const currentBufferState = dashMetrics.getCurrentBufferState(mediaType);
const representationInfo = rulesContext.getRepresentationInfo();
const fragmentDuration = representationInfo.fragmentDuration;
checkConfig();

// Don't ask for a bitrate change if there is not info about buffer state or if fragmentDuration is not defined
if (shouldIgnore(mediaType) || !fragmentDuration) {
return switchRequest;
}
const mediaType = rulesContext.getMediaType();
const currentBufferState = dashMetrics.getCurrentBufferState(mediaType);
const representationInfo = rulesContext.getRepresentationInfo();
const fragmentDuration = representationInfo.fragmentDuration;
const streamInfo = rulesContext.getStreamInfo();
const streamId = streamInfo ? streamInfo.id : null;

if (currentBufferState && currentBufferState.state === MetricsConstants.BUFFER_EMPTY) {
logger.debug('[' + mediaType + '] Switch to index 0; buffer is empty.');
switchRequest.quality = 0;
switchRequest.reason = 'InsufficientBufferRule: Buffer is empty';
}
// Don't ask for a bitrate change if there is not info about buffer state or if fragmentDuration is not defined
if (shouldIgnore(mediaType) || !fragmentDuration) {
return switchRequest;
}

if (currentBufferState && currentBufferState.state === MetricsConstants.BUFFER_EMPTY) {
logger.debug('[' + mediaType + '] Switch to index 0; buffer is empty.');
switchRequest.quality = 0;
switchRequest.reason = 'InsufficientBufferRule: Buffer is empty';
} else {
const mediaInfo = rulesContext.getMediaInfo();
const abrController = rulesContext.getAbrController();
const throughputHistory = abrController.getThroughputHistory();

const bufferLevel = dashMetrics.getCurrentBufferLevel(mediaType);
const throughput = throughputHistory.getAverageThroughput(mediaType);
const latency = throughputHistory.getAverageLatency(mediaType);
const bitrate = throughput * (bufferLevel / fragmentDuration) * INSUFFICIENT_BUFFER_SAFETY_FACTOR;

switchRequest.quality = abrController.getQualityForBitrate(mediaInfo, bitrate, streamId, latency);
switchRequest.reason = 'InsufficientBufferRule: being conservative to avoid immediate rebuffering';
}

return switchRequest;
return switchRequest;
} catch (e) {
return switchRequest;
}
}

function shouldIgnore(mediaType) {
Expand All @@ -108,8 +128,8 @@ function InsufficientBufferRule(config) {

function resetInitialSettings() {
bufferStateDict = {};
bufferStateDict[Constants.VIDEO] = {ignoreCount: SEGMENT_IGNORE_COUNT};
bufferStateDict[Constants.AUDIO] = {ignoreCount: SEGMENT_IGNORE_COUNT};
bufferStateDict[Constants.VIDEO] = { ignoreCount: SEGMENT_IGNORE_COUNT };
bufferStateDict[Constants.AUDIO] = { ignoreCount: SEGMENT_IGNORE_COUNT };
}

function _onPlaybackSeeking() {
Expand All @@ -131,8 +151,8 @@ function InsufficientBufferRule(config) {
}

instance = {
getMaxIndex: getMaxIndex,
reset: reset
getMaxIndex,
reset
};

setup();
Expand Down

0 comments on commit f3aa47a

Please sign in to comment.