diff --git a/lib/util/stream_utils.js b/lib/util/stream_utils.js index 908e48b6df..b3fb4c0a92 100644 --- a/lib/util/stream_utils.js +++ b/lib/util/stream_utils.js @@ -499,6 +499,33 @@ shaka.util.StreamUtils = class { } + /** + * Queries mediaCapabilities for the decoding info for that decoding config, + * and assigns it to the given variant. + * If that query has been done before, instead return a cached result. + * @param {!shaka.extern.Variant} variant + * @param {!MediaDecodingConfiguration} decodingConfig + * @private + */ + static async getDecodingInfosForVariant_(variant, decodingConfig) { + try { + const cacheKey = JSON.stringify(decodingConfig); + const cache = shaka.util.StreamUtils.decodingConfigCache; + if (cache[cacheKey]) { + variant.decodingInfos.push(cache[cacheKey]); + } else { + const result = + await navigator.mediaCapabilities.decodingInfo(decodingConfig); + cache[cacheKey] = result; + variant.decodingInfos.push(result); + } + } catch (e) { + shaka.log.info('MediaCapabilities.decodingInfo() failed.', + JSON.stringify(decodingConfig), e); + } + } + + /** * Get the decodingInfo results of the variants via MediaCapabilities. * This should be called after the DrmEngine is created and configured, and @@ -518,18 +545,6 @@ shaka.util.StreamUtils = class { return; } - const mediaCapabilities = navigator.mediaCapabilities; - - const getVariantDecodingInfos = (async (variant, decodingConfig) => { - try { - const result = await mediaCapabilities.decodingInfo(decodingConfig); - variant.decodingInfos.push(result); - } catch (e) { - shaka.log.info('MediaCapabilities.decodingInfo() failed.', - JSON.stringify(decodingConfig), e); - } - }); - for (const variant of variants) { /** @type {!Array.} */ const decodingConfigs = shaka.util.StreamUtils.getDecodingConfigs_( @@ -540,7 +555,8 @@ shaka.util.StreamUtils = class { // https://github.com/shaka-project/shaka-player/pull/4708#discussion_r1022581178 for (const config of decodingConfigs) { // eslint-disable-next-line no-await-in-loop - await getVariantDecodingInfos(variant, config); + await shaka.util.StreamUtils.getDecodingInfosForVariant_( + variant, config); } } } @@ -1578,6 +1594,16 @@ shaka.util.StreamUtils = class { }; +/** + * A cache of results from mediaCapabilities.decodingInfo, indexed by the + * (stringified) decodingConfig. + * + * @type {Object.<(!string), (!MediaCapabilitiesDecodingInfo)>} + * @export + */ +shaka.util.StreamUtils.decodingConfigCache = {}; + + /** @private {number} */ shaka.util.StreamUtils.nextTrackId_ = 0; diff --git a/test/test/boot.js b/test/test/boot.js index 99e7d70259..6df7f23fce 100644 --- a/test/test/boot.js +++ b/test/test/boot.js @@ -331,6 +331,11 @@ function configureJasmineEnvironment() { }); } + // Reset decoding config cache after each test. + afterEach(() => { + shaka.util.StreamUtils.decodingConfigCache = {}; + }); + // Code in karma-jasmine's adapter will malform test failures when the // expectation message contains a stack trace, losing the failure message and // mixing up the stack trace of the failure. To avoid this, we modify