From 5b0b4290e36091ff75da92fe307e7744799f4411 Mon Sep 17 00:00:00 2001 From: baconz Date: Mon, 26 Jun 2023 11:58:11 -0700 Subject: [PATCH] feat: Improve performance of multi-period DASH parsing (#5350) For manifests with many streams, we saw the bulk of the manifest parse time going towards period combiner. Specifically: splitting codecs and comparing DRMs. This change cuts our manifest parse time for large manifests by nearly 30%. There are two changes: 1. Memoize the normalized codecs inside the period combiner. 2. Short circuit the DRM compatibility check if the DRMInfos arrays are the same object. We run a custom manifest parser and are therefore able to re-use the same drm infos array for functionally equivalent drms, but short circuiting also helps since in the case that the upstream period combiner is comparing a candidate stream with itself. --- lib/media/drm_engine.js | 4 ++++ lib/util/periods.js | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/media/drm_engine.js b/lib/media/drm_engine.js index b8bf2687ee..462fd4e523 100644 --- a/lib/media/drm_engine.js +++ b/lib/media/drm_engine.js @@ -2005,6 +2005,10 @@ shaka.media.DrmEngine = class { return true; } + if (drms1 === drms2) { + return true; + } + return shaka.media.DrmEngine.getCommonDrmInfos( drms1, drms2).length > 0; } diff --git a/lib/util/periods.js b/lib/util/periods.js index dd54ad0df1..3a3e6939a0 100644 --- a/lib/util/periods.js +++ b/lib/util/periods.js @@ -1067,8 +1067,13 @@ shaka.util.PeriodCombiner = class { * @private */ static areAVStreamsCompatible_(outputStream, candidate) { - const getCodec = (codecs) => - shaka.util.MimeUtils.getNormalizedCodec(codecs); + const getCodec = (codecs) => { + if (!shaka.util.PeriodCombiner.memoizedCodecs.has(codecs)) { + const normalizedCodec = shaka.util.MimeUtils.getNormalizedCodec(codecs); + shaka.util.PeriodCombiner.memoizedCodecs.set(codecs, normalizedCodec); + } + return shaka.util.PeriodCombiner.memoizedCodecs.get(codecs); + }; // Check MIME type and codecs, which should always be the same. if (candidate.mimeType != outputStream.mimeType || getCodec(candidate.codecs) != getCodec(outputStream.codecs)) { @@ -1666,3 +1671,8 @@ shaka.util.PeriodCombiner.BetterOrWorse = { EQUAL: 0, WORSE: -1, }; + +/** + * @private {Map} + */ +shaka.util.PeriodCombiner.memoizedCodecs = new Map();