Skip to content

Commit dbc76f9

Browse files
aveladtykus160
andauthored
fix: Avoid reset or changeType in MSE when not necessary (#8744)
Fixes #8737 --------- Co-authored-by: Wojciech Tyczyński <[email protected]>
1 parent 5022f9d commit dbc76f9

File tree

2 files changed

+179
-109
lines changed

2 files changed

+179
-109
lines changed

lib/media/media_source_engine.js

Lines changed: 92 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ goog.require('goog.asserts');
1010
goog.require('shaka.log');
1111
goog.require('shaka.config.CodecSwitchingStrategy');
1212
goog.require('shaka.device.DeviceFactory');
13+
goog.require('shaka.device.IDevice');
1314
goog.require('shaka.media.Capabilities');
1415
goog.require('shaka.media.ContentWorkarounds');
1516
goog.require('shaka.media.ClosedCaptionParser');
@@ -2368,11 +2369,19 @@ shaka.media.MediaSourceEngine = class {
23682369
codec = codecs;
23692370
}
23702371
let newMimeType = shaka.util.MimeUtils.getFullType(mimeType, codec);
2372+
const currentBasicType = MimeUtils.getBasicType(
2373+
this.sourceBufferTypes_.get(contentType));
2374+
23712375
let needTransmux = this.config_.forceTransmux;
23722376
if (!shaka.media.Capabilities.isTypeSupported(newMimeType) ||
23732377
(!this.sequenceMode_ &&
23742378
shaka.util.MimeUtils.RAW_FORMATS.includes(newMimeType))) {
23752379
needTransmux = true;
2380+
} else if (!needTransmux && mimeType != currentBasicType) {
2381+
const device = shaka.device.DeviceFactory.getDevice();
2382+
needTransmux = device.getBrowserEngine() ===
2383+
shaka.device.IDevice.BrowserEngine.WEBKIT &&
2384+
shaka.util.MimeUtils.RAW_FORMATS.includes(mimeType);
23762385
}
23772386
const TransmuxerEngine = shaka.transmuxer.TransmuxerEngine;
23782387
if (needTransmux) {
@@ -2410,14 +2419,18 @@ shaka.media.MediaSourceEngine = class {
24102419
* @param {string} codecs
24112420
* @param {!Map<shaka.util.ManifestParserUtils.ContentType,
24122421
* shaka.extern.Stream>} streamsByType
2413-
* @return {!Promise<boolean>} true if there was a codec switch,
2414-
* false otherwise.
2422+
* @return {{type: string, newMimeType: string,
2423+
* transmuxer: ?shaka.extern.Transmuxer}}
24152424
* @private
24162425
*/
2417-
async codecSwitchIfNecessary_(contentType, mimeType, codecs, streamsByType) {
2426+
getInfoAboutResetOrChangeType_(contentType, mimeType, codecs, streamsByType) {
24182427
const ContentType = shaka.util.ManifestParserUtils.ContentType;
24192428
if (contentType == ContentType.TEXT) {
2420-
return false;
2429+
return {
2430+
type: shaka.media.MediaSourceEngine.ResetMode_.NONE,
2431+
newMimeType: mimeType,
2432+
transmuxer: null,
2433+
};
24212434
}
24222435
const MimeUtils = shaka.util.MimeUtils;
24232436
const currentCodec = MimeUtils.getNormalizedCodec(
@@ -2451,91 +2464,91 @@ shaka.media.MediaSourceEngine = class {
24512464
// Current/new codecs base and basic type match then no need to switch
24522465
if (currentCodec === newCodec && currentBasicType === newBasicType &&
24532466
muxedContentCheck) {
2454-
if (this.transmuxers_.has(contentType) && !transmuxer) {
2455-
this.transmuxers_.get(contentType).destroy();
2456-
this.transmuxers_.delete(contentType);
2457-
} else if (!this.transmuxers_.has(contentType) && transmuxer) {
2458-
this.transmuxers_.set(contentType, transmuxer);
2459-
} else if (transmuxer) {
2460-
// Compare if the transmuxer is different
2461-
if (this.transmuxers_.has(contentType) &&
2462-
this.transmuxers_.get(contentType).transmux !=
2463-
transmuxer.transmux) {
2464-
this.transmuxers_.get(contentType).destroy();
2465-
this.transmuxers_.delete(contentType);
2466-
this.transmuxers_.set(contentType, transmuxer);
2467-
} else {
2468-
transmuxer.destroy();
2469-
}
2470-
}
2471-
return false;
2467+
return {
2468+
type: shaka.media.MediaSourceEngine.ResetMode_.NONE,
2469+
newMimeType,
2470+
transmuxer,
2471+
};
24722472
}
24732473

24742474
let allowChangeType = true;
2475-
if (this.needSplitMuxedContent_ || (transmuxerMuxed &&
2475+
if ((this.needSplitMuxedContent_ &&
2476+
!streamsByType.has(ContentType.AUDIO)) || (transmuxerMuxed &&
24762477
transmuxer && !this.transmuxers_.has(contentType))) {
24772478
allowChangeType = false;
24782479
}
24792480

24802481
if (allowChangeType && this.config_.codecSwitchingStrategy ===
24812482
shaka.config.CodecSwitchingStrategy.SMOOTH &&
24822483
shaka.media.Capabilities.isChangeTypeSupported()) {
2483-
await this.changeType(contentType, newMimeType, transmuxer);
2484+
return {
2485+
type: shaka.media.MediaSourceEngine.ResetMode_.CHANGE_TYPE,
2486+
newMimeType,
2487+
transmuxer,
2488+
};
24842489
} else {
24852490
if (transmuxer) {
24862491
transmuxer.destroy();
24872492
}
2488-
await this.reset(streamsByType);
2493+
return {
2494+
type: shaka.media.MediaSourceEngine.ResetMode_.RESET,
2495+
newMimeType,
2496+
transmuxer: null,
2497+
};
24892498
}
2490-
return true;
24912499
}
24922500

24932501
/**
2494-
* Returns true if it's necessary codec switch to load the new stream.
2495-
*
2502+
* Codec switch if necessary, this will not resolve until the codec
2503+
* switch is over.
24962504
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
2497-
* @param {string} refMimeType
2498-
* @param {string} refCodecs
2499-
* @return {boolean}
2505+
* @param {string} mimeType
2506+
* @param {string} codecs
2507+
* @param {!Map<shaka.util.ManifestParserUtils.ContentType,
2508+
* shaka.extern.Stream>} streamsByType
2509+
* @return {!Promise<boolean>} true if there was a codec switch,
2510+
* false otherwise.
25002511
* @private
25012512
*/
2502-
isCodecSwitchNecessary_(contentType, refMimeType, refCodecs) {
2503-
if (contentType == shaka.util.ManifestParserUtils.ContentType.TEXT) {
2504-
return false;
2513+
async codecSwitchIfNecessary_(contentType, mimeType, codecs, streamsByType) {
2514+
const ContentType = shaka.util.ManifestParserUtils.ContentType;
2515+
const {type, transmuxer, newMimeType} = this.getInfoAboutResetOrChangeType_(
2516+
contentType, mimeType, codecs, streamsByType);
2517+
2518+
const newAudioStream = streamsByType.get(ContentType.AUDIO);
2519+
if (newAudioStream) {
2520+
this.needSplitMuxedContent_ = newAudioStream.isAudioMuxedInVideo;
25052521
}
2506-
const MimeUtils = shaka.util.MimeUtils;
2507-
const currentCodec = MimeUtils.getNormalizedCodec(
2508-
MimeUtils.getCodecs(this.sourceBufferTypes_.get(contentType)));
2509-
const currentBasicType = MimeUtils.getBasicType(
2510-
this.sourceBufferTypes_.get(contentType));
25112522

2512-
let newMimeType = shaka.util.MimeUtils.getFullType(refMimeType, refCodecs);
2513-
let needTransmux = this.config_.forceTransmux;
2514-
if (!shaka.media.Capabilities.isTypeSupported(newMimeType) ||
2515-
(!this.sequenceMode_ &&
2516-
shaka.util.MimeUtils.RAW_FORMATS.includes(newMimeType))) {
2517-
needTransmux = true;
2523+
if (type == shaka.media.MediaSourceEngine.ResetMode_.NONE) {
2524+
if (this.transmuxers_.has(contentType) && !transmuxer) {
2525+
this.transmuxers_.get(contentType).destroy();
2526+
this.transmuxers_.delete(contentType);
2527+
} else if (!this.transmuxers_.has(contentType) && transmuxer) {
2528+
this.transmuxers_.set(contentType, transmuxer);
2529+
} else if (transmuxer) {
2530+
// Compare if the transmuxer is different
2531+
if (this.transmuxers_.has(contentType) &&
2532+
this.transmuxers_.get(contentType).transmux !==
2533+
transmuxer.transmux) {
2534+
this.transmuxers_.get(contentType).destroy();
2535+
this.transmuxers_.set(contentType, transmuxer);
2536+
} else {
2537+
transmuxer.destroy();
2538+
}
2539+
}
2540+
return false;
25182541
}
2519-
const newMimeTypeWithAllCodecs =
2520-
shaka.util.MimeUtils.getFullTypeWithAllCodecs(
2521-
refMimeType, refCodecs);
2522-
const TransmuxerEngine = shaka.transmuxer.TransmuxerEngine;
2523-
if (needTransmux) {
2524-
const transmuxerPlugin =
2525-
TransmuxerEngine.findTransmuxer(newMimeTypeWithAllCodecs);
2526-
if (transmuxerPlugin) {
2527-
const transmuxer = transmuxerPlugin();
2528-
newMimeType =
2529-
transmuxer.convertCodecs(contentType, newMimeTypeWithAllCodecs);
2542+
2543+
if (type == shaka.media.MediaSourceEngine.ResetMode_.CHANGE_TYPE) {
2544+
await this.changeType(contentType, newMimeType, transmuxer);
2545+
} else if (type == shaka.media.MediaSourceEngine.ResetMode_.RESET) {
2546+
if (transmuxer) {
25302547
transmuxer.destroy();
25312548
}
2549+
await this.reset(streamsByType);
25322550
}
2533-
2534-
const newCodec = MimeUtils.getNormalizedCodec(
2535-
MimeUtils.getCodecs(newMimeType));
2536-
const newBasicType = MimeUtils.getBasicType(newMimeType);
2537-
2538-
return currentCodec !== newCodec || currentBasicType !== newBasicType;
2551+
return true;
25392552
}
25402553

25412554
/**
@@ -2547,15 +2560,13 @@ shaka.media.MediaSourceEngine = class {
25472560
* @param {string} codecs
25482561
* @return {boolean}
25492562
*/
2550-
isResetMediaSourceNecessary(contentType, mimeType, codecs) {
2551-
if (!this.isCodecSwitchNecessary_(contentType, mimeType, codecs)) {
2552-
return false;
2563+
isResetMediaSourceNecessary(contentType, mimeType, codecs, streamsByType) {
2564+
const info = this.getInfoAboutResetOrChangeType_(
2565+
contentType, mimeType, codecs, streamsByType);
2566+
if (info.transmuxer) {
2567+
info.transmuxer.destroy();
25532568
}
2554-
2555-
return this.config_.codecSwitchingStrategy !==
2556-
shaka.config.CodecSwitchingStrategy.SMOOTH ||
2557-
!shaka.media.Capabilities.isChangeTypeSupported() ||
2558-
this.needSplitMuxedContent_;
2569+
return info.type == shaka.media.MediaSourceEngine.ResetMode_.RESET;
25592570
}
25602571

25612572
/**
@@ -2619,6 +2630,17 @@ shaka.media.MediaSourceEngine.SourceBufferMode_ = {
26192630
};
26202631

26212632

2633+
/**
2634+
* @enum {string}
2635+
* @private
2636+
*/
2637+
shaka.media.MediaSourceEngine.ResetMode_ = {
2638+
NONE: 'none',
2639+
RESET: 'reset',
2640+
CHANGE_TYPE: 'changeType',
2641+
};
2642+
2643+
26222644
/**
26232645
* @typedef {{
26242646
* getKeySystem: function():?string,

0 commit comments

Comments
 (0)