Skip to content

Commit 612a36e

Browse files
authored
Feature/4415 (#4866)
* Add priority for each ABR rule to the settings * Add additional unit tests for ThroughputRule
1 parent 9b25e5d commit 612a36e

File tree

12 files changed

+145
-13
lines changed

12 files changed

+145
-13
lines changed

src/core/Settings.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import Constants from '../streaming/constants/Constants.js';
3535
import {HTTPRequest} from '../streaming/vo/metrics/HTTPRequest.js';
3636
import EventBus from './EventBus.js';
3737
import Events from './events/Events.js';
38+
import SwitchRequest from '../streaming/rules/SwitchRequest.js';
3839

3940
/** @module Settings
4041
* @description Define the configuration parameters of Dash.js MediaPlayer.
@@ -696,7 +697,7 @@ import Events from './events/Events.js';
696697
*
697698
* @property {number} [keepProtectionMediaKeysMaximumOpenSessions=-1]
698699
* Maximum number of open MediaKeySessions, when keepProtectionMediaKeys is enabled. If set, dash.js will close the oldest sessions when the limit is exceeded. -1 means unlimited.
699-
*
700+
*
700701
* @property {boolean} [ignoreEmeEncryptedEvent=false]
701702
* If set to true the player will ignore "encrypted" and "needkey" events thrown by the EME.
702703
*
@@ -1023,7 +1024,7 @@ import Events from './events/Events.js';
10231024
*
10241025
* @property {} [assumeDefaultRoleAsMain: true]
10251026
* when no Role descriptor is present, assume main per default
1026-
*
1027+
*
10271028
* @property {string} [selectionModeForInitialTrack="highestEfficiency"]
10281029
* Sets the selection mode for the initial track. This mode defines how the initial track will be selected if no initial media settings are set. If initial media settings are set this parameter will be ignored. Available options are:
10291030
*
@@ -1293,45 +1294,53 @@ function Settings() {
12931294
enableSupplementalPropertyAdaptationSetSwitching: true,
12941295
rules: {
12951296
throughputRule: {
1296-
active: true
1297+
active: true,
1298+
priority: SwitchRequest.PRIORITY.DEFAULT
12971299
},
12981300
bolaRule: {
1299-
active: true
1301+
active: true,
1302+
priority: SwitchRequest.PRIORITY.DEFAULT
13001303
},
13011304
insufficientBufferRule: {
13021305
active: true,
1306+
priority: SwitchRequest.PRIORITY.DEFAULT,
13031307
parameters: {
13041308
throughputSafetyFactor: 0.7,
13051309
segmentIgnoreCount: 2
13061310
}
13071311
},
13081312
switchHistoryRule: {
13091313
active: true,
1314+
priority: SwitchRequest.PRIORITY.DEFAULT,
13101315
parameters: {
13111316
sampleSize: 8,
13121317
switchPercentageThreshold: 0.075
13131318
}
13141319
},
13151320
droppedFramesRule: {
13161321
active: false,
1322+
priority: SwitchRequest.PRIORITY.DEFAULT,
13171323
parameters: {
13181324
minimumSampleSize: 375,
13191325
droppedFramesPercentageThreshold: 0.15
13201326
}
13211327
},
13221328
abandonRequestsRule: {
13231329
active: true,
1330+
priority: SwitchRequest.PRIORITY.DEFAULT,
13241331
parameters: {
13251332
abandonDurationMultiplier: 1.8,
13261333
minSegmentDownloadTimeThresholdInMs: 500,
13271334
minThroughputSamplesThreshold: 6
13281335
}
13291336
},
13301337
l2ARule: {
1331-
active: false
1338+
active: false,
1339+
priority: SwitchRequest.PRIORITY.DEFAULT
13321340
},
13331341
loLPRule: {
1334-
active: false
1342+
active: false,
1343+
priority: SwitchRequest.PRIORITY.DEFAULT
13351344
}
13361345
},
13371346
throughput: {

src/streaming/metrics/metrics/handlers/HttpListHandler.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,13 @@ function HttpListHandler(config) {
101101
}
102102

103103
instance = {
104-
initialize: initialize,
105-
reset: reset,
106-
handleNewMetric: handleNewMetric
104+
initialize,
105+
reset,
106+
handleNewMetric
107107
};
108108

109109
return instance;
110110
}
111111

112112
HttpListHandler.__dashjs_factory_name = 'HttpListHandler';
113-
export default FactoryMaker.getClassFactory(HttpListHandler);
113+
export default FactoryMaker.getClassFactory(HttpListHandler);

src/streaming/rules/abr/AbandonRequestsRule.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ function AbandonRequestsRule(config) {
118118

119119
if (remainingBytesToDownload > totalBytesForOptimalRepresentation) {
120120
switchRequest.representation = optimalRepresentationForBitrate;
121+
switchRequest.priority = settings.get().streaming.abr.abandonRequestsRule.priority;
121122
switchRequest.reason = {
122123
throughputInKbit,
123124
message: `[AbandonRequestRule][${mediaType} is asking to abandon and switch to quality to ${optimalRepresentationForBitrate.absoluteIndex}. The measured bandwidth was ${throughputInKbit} kbit/s`

src/streaming/rules/abr/BolaRule.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import Debug from '../../../core/Debug.js';
4141
import MediaPlayerEvents from '../../MediaPlayerEvents.js';
4242
import Constants from '../../constants/Constants.js';
4343
import AbrController from '../../controllers/AbrController.js';
44+
import Settings from '../../../core/Settings.js';
4445

4546
// BOLA_STATE_ONE_BITRATE : If there is only one bitrate (or initialization failed), always return NO_CHANGE.
4647
// BOLA_STATE_STARTUP : Set placeholder buffer such that we download fragments at most recently measured throughput.
@@ -69,10 +70,12 @@ function BolaRule(config) {
6970

7071
let instance,
7172
logger,
73+
settings,
7274
bolaStateDict;
7375

7476
function setup() {
7577
logger = Debug(context).getInstance().getLogger(instance);
78+
settings = Settings(context).getInstance();
7679
resetInitialSettings();
7780
eventBus.on(MediaPlayerEvents.BUFFER_EMPTY, _onBufferEmpty, instance);
7881
eventBus.on(MediaPlayerEvents.PLAYBACK_SEEKING, _onPlaybackSeeking, instance);
@@ -588,6 +591,7 @@ function BolaRule(config) {
588591
break;
589592
}
590593

594+
switchRequest.priority = settings.get().streaming.abr.rules.bolaRule.priority;
591595
return switchRequest;
592596
} catch (e) {
593597
logger.error(e);

src/streaming/rules/abr/DroppedFramesRule.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ function DroppedFramesRule() {
4949
}
5050
if (newRepresentation) {
5151
switchRequest.representation = newRepresentation;
52+
switchRequest.priority = settings.get().streaming.abr.rules.droppedFramesRule.priority;
5253
switchRequest.reason = {
5354
droppedFrames,
5455
message: `[DroppedFramesRule]: Switching to index ${newRepresentation.absoluteIndex}. Dropped Frames: ${droppedFrames}, Total Frames: ${totalFrames}`

src/streaming/rules/abr/InsufficientBufferRule.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ function InsufficientBufferRule(config) {
107107
}
108108

109109
switchRequest.representation = abrController.getOptimalRepresentationForBitrate(mediaInfo, bitrate, true);
110+
switchRequest.priority = settings.get().streaming.abr.rules.insufficientBufferRule.priority;
110111
switchRequest.reason = {
111112
message: '[InsufficientBufferRule]: Limiting maximum bitrate to avoid a buffer underrun.',
112113
bitrate

src/streaming/rules/abr/L2ARule.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import EventBus from '../../../core/EventBus.js';
3939
import Events from '../../../core/events/Events.js';
4040
import Debug from '../../../core/Debug.js';
4141
import Constants from '../../constants/Constants.js';
42+
import Settings from '../../../core/Settings.js';
4243

4344
const L2A_STATE_ONE_BITRATE = 'L2A_STATE_ONE_BITRATE'; // If there is only one bitrate (or initialization failed), always return NO_CHANGE.
4445
const L2A_STATE_STARTUP = 'L2A_STATE_STARTUP'; // Set placeholder buffer such that we download fragments at most recently measured throughput.
@@ -53,6 +54,7 @@ function L2ARule(config) {
5354

5455
const dashMetrics = config.dashMetrics;
5556
const eventBus = EventBus(context).getInstance();
57+
const settings = Settings(context).getInstance();
5658

5759
let instance,
5860
l2AStateDict,
@@ -461,6 +463,8 @@ function L2ARule(config) {
461463
default:
462464
_handleErrorState(rulesContext, switchRequest, l2AState)
463465
}
466+
467+
switchRequest.priority = settings.get().streaming.abr.rules.l2ARule.priority;
464468
return switchRequest;
465469
} catch (e) {
466470
logger.error(e);

src/streaming/rules/abr/SwitchHistoryRule.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ function SwitchHistoryRule() {
3434

3535
if (drops + noDrops >= settings.get().streaming.abr.rules.switchHistoryRule.parameters.sampleSize && (drops / noDrops > settings.get().streaming.abr.rules.switchHistoryRule.parameters.switchPercentageThreshold)) {
3636
switchRequest.representation = (i > 0 && switchRequests[currentPossibleRepresentation.id].drops > 0) ? representations[i - 1] : currentPossibleRepresentation;
37+
switchRequest.priority = settings.get().streaming.abr.rules.switchHistoryRule.priority;
3738
switchRequest.reason = {
3839
drops: drops,
3940
noDrops: noDrops,

src/streaming/rules/abr/ThroughputRule.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import FactoryMaker from '../../../core/FactoryMaker.js';
3232
import SwitchRequest from '../SwitchRequest.js';
3333
import MetricsConstants from '../../constants/MetricsConstants.js';
3434
import Debug from '../../../core/Debug.js';
35+
import Settings from '../../../core/Settings.js';
3536

3637
function ThroughputRule(config) {
3738

@@ -40,16 +41,19 @@ function ThroughputRule(config) {
4041
const dashMetrics = config.dashMetrics;
4142

4243
let instance,
44+
settings,
4345
logger;
4446

4547
function setup() {
4648
logger = Debug(context).getInstance().getLogger(instance);
49+
settings = Settings(context).getInstance();
4750
}
4851

4952
function getSwitchRequest(rulesContext) {
5053
try {
5154
const switchRequest = SwitchRequest(context).create();
5255
switchRequest.rule = this.getClassName();
56+
5357
const mediaInfo = rulesContext.getMediaInfo();
5458
const mediaType = rulesContext.getMediaType();
5559
const currentBufferState = dashMetrics.getCurrentBufferState(mediaType);
@@ -69,6 +73,7 @@ function ThroughputRule(config) {
6973
if (abrController.getAbandonmentStateFor(streamId, mediaType) === MetricsConstants.ALLOW_LOAD) {
7074
if (currentBufferState.state === MetricsConstants.BUFFER_LOADED || isDynamic) {
7175
switchRequest.representation = abrController.getOptimalRepresentationForBitrate(mediaInfo, throughput, true);
76+
switchRequest.priority = settings.get().streaming.abr.rules.throughputRule.priority;
7277
switchRequest.reason = {
7378
throughput,
7479
latency,

src/streaming/rules/abr/lolp/LoLpRule.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import SwitchRequest from '../../SwitchRequest.js';
4444
import MetricsConstants from '../../../constants/MetricsConstants.js';
4545
import LoLpWeightSelector from './LoLpWeightSelector.js';
4646
import Constants from '../../../constants/Constants.js';
47+
import Settings from '../../../../core/Settings.js';
4748

4849
const DWS_TARGET_LATENCY = 1.5;
4950
const DWS_BUFFER_MIN = 0.3;
@@ -56,6 +57,7 @@ function LoLPRule(config) {
5657
let context = this.context;
5758

5859
let logger,
60+
settings,
5961
instance,
6062
learningController,
6163
qoeEvaluator;
@@ -64,6 +66,7 @@ function LoLPRule(config) {
6466
logger = Debug(context).getInstance().getLogger(instance);
6567
learningController = LearningAbrController(context).create();
6668
qoeEvaluator = LoLpQoeEvaluator(context).create();
69+
settings = Settings(context).getInstance();
6770
}
6871

6972
function getSwitchRequest(rulesContext) {
@@ -142,7 +145,7 @@ function LoLPRule(config) {
142145
dynamicWeightsSelector
143146
);
144147
switchRequest.reason = { throughput: throughput, latency: latency };
145-
switchRequest.priority = SwitchRequest.PRIORITY.STRONG;
148+
switchRequest.priority = settings.get().streaming.abr.rules.loLPRule.priority;
146149

147150
scheduleController.setTimeToLoadDelay(0);
148151

0 commit comments

Comments
 (0)