From 5e3db78a5e545960cf135200ca415f877ff84457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Tyczy=C5=84ski?= Date: Mon, 15 Jan 2024 08:11:46 +0100 Subject: [PATCH] feat(DASH): Allow PeriodCombiner for using streams once (#6097) In our streams we have guarantee that every track will have a single match in every period. This change allows `PeriodCombiner` to take benefit of this knowledge. I was testing `PeriodCombiner.combinePeriods()` performance of mentioned changes on Tizen 2021 on 2 streams and I've got following results: | content | upstream | proposed changes | | - | -: | -: | | stream 1 | 17 ms | 12 ms | | stream 2 | 191 ms | 98 ms | Both streams are VOD. Stream 1 has 18 periods with 6 video & audio tracks in each. Stream 2 has 18 periods with 6 video tracks & 36 audio tracks in each. --- demo/config.js | 2 ++ externs/shaka/player.js | 9 ++++++++- lib/dash/dash_parser.js | 2 ++ lib/util/periods.js | 19 +++++++++++++++++++ lib/util/player_configuration.js | 1 + 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/demo/config.js b/demo/config.js index c2fa049770..034c429fc3 100644 --- a/demo/config.js +++ b/demo/config.js @@ -236,6 +236,8 @@ shakaDemo.Config = class { /* canBeUnset= */ true) .addBoolInput_('Enable DASH sequence mode', 'manifest.dash.sequenceMode') + .addBoolInput_('Use stream once in period flattening', + 'manifest.dash.useStreamOnceInPeriodFlattening') .addBoolInput_('Disable Audio', 'manifest.disableAudio') .addBoolInput_('Disable Video', 'manifest.disableVideo') .addBoolInput_('Disable Text', 'manifest.disableText') diff --git a/externs/shaka/player.js b/externs/shaka/player.js index 62000d4ab7..5615ae0112 100644 --- a/externs/shaka/player.js +++ b/externs/shaka/player.js @@ -856,7 +856,8 @@ shaka.extern.InitDataTransform; * manifestPreprocessor: function(!Element), * sequenceMode: boolean, * enableAudioGroups: boolean, - * multiTypeVariantsAllowed: boolean + * multiTypeVariantsAllowed: boolean, + * useStreamOnceInPeriodFlattening: boolean * }} * * @property {string} clockSyncUri @@ -928,6 +929,12 @@ shaka.extern.InitDataTransform; * Might result in undesirable behavior if mediaSource.codecSwitchingStrategy * is not set to SMOOTH. * Defaults to true if SMOOTH codec switching is supported, RELOAD overwise. + * @property {boolean} useStreamOnceInPeriodFlattening + * If period combiner is used, this option ensures every stream is used + * only once in period flattening. It speeds up underlying algorithm + * but may raise issues if manifest does not have stream consistency + * between periods. + * Defaults to false. * @exportDoc */ shaka.extern.DashManifestConfiguration; diff --git a/lib/dash/dash_parser.js b/lib/dash/dash_parser.js index af5063a055..8e40b253d1 100644 --- a/lib/dash/dash_parser.js +++ b/lib/dash/dash_parser.js @@ -140,6 +140,8 @@ shaka.dash.DashParser = class { this.periodCombiner_.setAllowMultiTypeVariants( this.config_.dash.multiTypeVariantsAllowed && shaka.media.Capabilities.isChangeTypeSupported()); + this.periodCombiner_.setUseStreamOnce( + this.config_.dash.useStreamOnceInPeriodFlattening); } } diff --git a/lib/util/periods.js b/lib/util/periods.js index a96bf3dfb9..80c4c6532c 100644 --- a/lib/util/periods.js +++ b/lib/util/periods.js @@ -45,6 +45,9 @@ shaka.util.PeriodCombiner = class { /** @private {boolean} */ this.multiTypeVariantsAllowed_ = false; + /** @private {boolean} */ + this.useStreamOnce_ = false; + /** * The IDs of the periods we have already used to generate streams. * This helps us identify the periods which have been added when a live @@ -1037,6 +1040,12 @@ shaka.util.PeriodCombiner = class { } } + // Remove just found stream if configured to, so possible future linear + // searches can be faster. + if (this.useStreamOnce_ && !shaka.util.PeriodCombiner.isDummy_(best)) { + streams.delete(getKey(best)); + } + return best; } @@ -1071,11 +1080,21 @@ shaka.util.PeriodCombiner = class { /** * @param {boolean} allowed If set to true, multi-mimeType or multi-codec * variants will be allowed. + * @export */ setAllowMultiTypeVariants(allowed) { this.multiTypeVariantsAllowed_ = allowed; } + /** + * @param {boolean} useOnce if true, stream will be used only once in period + * flattening algoritnm. + * @export + */ + setUseStreamOnce(useOnce) { + this.useStreamOnce_ = useOnce; + } + /** * @param {T} outputStream An audio or video output stream * @param {T} candidate A candidate stream to be combined with the output diff --git a/lib/util/player_configuration.js b/lib/util/player_configuration.js index d6bf7c788b..2c1d46d6dd 100644 --- a/lib/util/player_configuration.js +++ b/lib/util/player_configuration.js @@ -144,6 +144,7 @@ shaka.util.PlayerConfiguration = class { sequenceMode: false, enableAudioGroups: false, multiTypeVariantsAllowed, + useStreamOnceInPeriodFlattening: false, }, hls: { ignoreTextStreamFailures: false,