Skip to content

perf: Init source buffers synchronously #8646

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 26, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 7 additions & 83 deletions lib/media/media_source_engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,72 +320,6 @@ shaka.media.MediaSourceEngine = class {
p.resolve();
}

/**
* Checks if a certain type is supported.
*
* @param {shaka.extern.Stream} stream
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
* @return {!Promise<boolean>}
*/
static async isStreamSupported(stream, contentType) {
if (stream.createSegmentIndex) {
await stream.createSegmentIndex();
}
if (!stream.segmentIndex) {
return false;
}
if (stream.segmentIndex.isEmpty()) {
return true;
}
const MimeUtils = shaka.util.MimeUtils;
const TransmuxerEngine = shaka.transmuxer.TransmuxerEngine;
const ContentType = shaka.util.ManifestParserUtils.ContentType;
const StreamUtils = shaka.util.StreamUtils;
const seenCombos = new Set();
// Check each combination of mimeType and codecs within the segment index.
// Unfortunately we cannot use fullMimeTypes, as we ALSO need to check the
// getFullTypeWithAllCodecs (for the sake of the transmuxer) and we have no
// way of going from a full mimeType to a full mimeType with all codecs.
// As this function is only called in debug mode, a little inefficiency is
// acceptable.
for (const ref of stream.segmentIndex) {
const mimeType = ref.mimeType || stream.mimeType || '';
let codecs = ref.codecs || stream.codecs || '';
// Optimization for the case where the codecs and mimetype of the stream
// match the reference.
if (mimeType == stream.mimeType && codecs == stream.codecs) {
continue;
}
// Don't check the same combination of mimetype + codecs twice.
const combo = mimeType + ':' + codecs;
if (seenCombos.has(combo)) {
continue;
}
seenCombos.add(combo);
if (contentType == ContentType.TEXT) {
const fullMimeType = MimeUtils.getFullType(mimeType, codecs);
if (!shaka.text.TextEngine.isTypeSupported(fullMimeType)) {
return false;
}
} else {
if (contentType == ContentType.VIDEO) {
codecs = StreamUtils.getCorrectVideoCodecs(codecs);
} else if (contentType == ContentType.AUDIO) {
codecs = StreamUtils.getCorrectAudioCodecs(codecs, mimeType);
}
const extendedMimeType = MimeUtils.getExtendedType(
stream, mimeType, codecs);
const fullMimeType = MimeUtils.getFullTypeWithAllCodecs(
mimeType, codecs);
if (!shaka.media.Capabilities.isTypeSupported(extendedMimeType) &&
!TransmuxerEngine.isSupported(fullMimeType, stream.type)) {
return false;
}
}
}
return true;
}

/**
* Returns a map of MediaSource support for well-known types.
*
Expand Down Expand Up @@ -554,8 +488,7 @@ shaka.media.MediaSourceEngine = class {
*
* @param {!Map<shaka.util.ManifestParserUtils.ContentType,
* shaka.extern.Stream>} streamsByType
* A map of content types to streams. All streams must be supported
* according to MediaSourceEngine.isStreamSupported.
* A map of content types to streams.
* @param {boolean=} sequenceMode
* If true, the media segments are appended to the SourceBuffer in strict
* sequence.
Expand Down Expand Up @@ -602,8 +535,7 @@ shaka.media.MediaSourceEngine = class {

for (const contentType of streamsByType.keys()) {
const stream = streamsByType.get(contentType);
// eslint-disable-next-line no-await-in-loop
await this.initSourceBuffer_(contentType, stream, stream.codecs);
this.initSourceBuffer_(contentType, stream, stream.codecs);
if (this.needSplitMuxedContent_) {
this.queues_.set(ContentType.AUDIO, []);
this.queues_.set(ContentType.VIDEO, []);
Expand All @@ -623,17 +555,11 @@ shaka.media.MediaSourceEngine = class {
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
* @param {shaka.extern.Stream} stream
* @param {string} codecs
* @return {!Promise}
* @private
*/
async initSourceBuffer_(contentType, stream, codecs) {
initSourceBuffer_(contentType, stream, codecs) {
const ContentType = shaka.util.ManifestParserUtils.ContentType;

goog.asserts.assert(
await shaka.media.MediaSourceEngine.isStreamSupported(
stream, contentType),
'Type negotiation should happen before MediaSourceEngine.init!');

if (contentType == ContentType.AUDIO && codecs) {
codecs = shaka.util.StreamUtils.getCorrectAudioCodecs(
codecs, stream.mimeType);
Expand All @@ -660,8 +586,8 @@ shaka.media.MediaSourceEngine = class {
ContentType.VIDEO, (codecs || '').split(','));
if (audioCodec && videoCodec) {
this.needSplitMuxedContent_ = true;
await this.initSourceBuffer_(ContentType.AUDIO, stream, audioCodec);
await this.initSourceBuffer_(ContentType.VIDEO, stream, videoCodec);
this.initSourceBuffer_(ContentType.AUDIO, stream, audioCodec);
this.initSourceBuffer_(ContentType.VIDEO, stream, videoCodec);
return;
}
const transmuxerPlugin = shaka.transmuxer.TransmuxerEngine
Expand Down Expand Up @@ -1519,8 +1445,7 @@ shaka.media.MediaSourceEngine = class {
* @param {string} codecs
* @param {!Map<shaka.util.ManifestParserUtils.ContentType,
* shaka.extern.Stream>} streamsByType
* A map of content types to streams. All streams must be supported
* according to MediaSourceEngine.isStreamSupported.
* A map of content types to streams.
*
* @return {!Promise}
*/
Expand Down Expand Up @@ -2363,8 +2288,7 @@ shaka.media.MediaSourceEngine = class {

for (const contentType of streamsByType.keys()) {
const stream = streamsByType.get(contentType);
// eslint-disable-next-line no-await-in-loop
await this.initSourceBuffer_(contentType, stream, stream.codecs);
this.initSourceBuffer_(contentType, stream, stream.codecs);
}
const audio = streamsByType.get(ContentType.AUDIO);
if (audio && audio.isAudioMuxedInVideo) {
Expand Down
Loading