Skip to content

Commit

Permalink
fix: Pass correct adaptation value to MediaSourceEngine (#7111)
Browse files Browse the repository at this point in the history
Currently passing adaptation value via media state has 2 flaws:
- it's not passed on init segment append (thus we don't use this value
at all in CaptionParser)
- it often marks already pending update as an adaptation, instead of the
actual segment we care about
  • Loading branch information
tykus160 authored and avelad committed Aug 19, 2024
1 parent e357030 commit 1261c03
Showing 1 changed file with 26 additions and 13 deletions.
39 changes: 26 additions & 13 deletions lib/media/streaming_engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,8 @@ shaka.media.StreamingEngine = class {
return this.config_.updateIntervalSeconds / 2;
}

// Lack of segment iterator is the best indicator stream has changed.
const streamChanged = !mediaState.segmentIterator;
const reference = this.getSegmentReferenceNeeded_(
mediaState, presentationTime, bufferEnd);
if (!reference) {
Expand All @@ -1357,6 +1359,14 @@ shaka.media.StreamingEngine = class {
// a SegmentReference eventually.
return this.config_.updateIntervalSeconds;
}
// Get media state adaptation and reset this value. By guarding it during
// actual stream change we ensure it won't be cleaned by accident on regular
// append.
let adaptation = false;
if (streamChanged && mediaState.adaptation) {
adaptation = true;
mediaState.adaptation = false;
}

// Do not let any one stream get far ahead of any other.
let minTimeNeeded = Infinity;
Expand Down Expand Up @@ -1395,7 +1405,8 @@ shaka.media.StreamingEngine = class {
mediaState.segmentPrefetch.prefetchSegmentsByTime(reference.startTime);
}

const p = this.fetchAndAppend_(mediaState, presentationTime, reference);
const p = this.fetchAndAppend_(mediaState, presentationTime, reference,
adaptation);
p.catch(() => {}); // TODO(#1993): Handle asynchronous errors.
return null;
}
Expand Down Expand Up @@ -1517,9 +1528,10 @@ shaka.media.StreamingEngine = class {
* @param {!shaka.media.StreamingEngine.MediaState_} mediaState
* @param {number} presentationTime
* @param {!shaka.media.SegmentReference} reference
* @param {boolean} adaptation
* @private
*/
async fetchAndAppend_(mediaState, presentationTime, reference) {
async fetchAndAppend_(mediaState, presentationTime, reference, adaptation) {
const ContentType = shaka.util.ManifestParserUtils.ContentType;
const StreamingEngine = shaka.media.StreamingEngine;
const logPrefix = StreamingEngine.logPrefix_(mediaState);
Expand Down Expand Up @@ -1548,7 +1560,7 @@ shaka.media.StreamingEngine = class {
shaka.util.Error.Category.NETWORK,
shaka.util.Error.Code.SEGMENT_MISSING);
}
await this.initSourceBuffer_(mediaState, reference);
await this.initSourceBuffer_(mediaState, reference, adaptation);
this.destroyer_.ensureNotDestroyed();
if (this.fatalError_) {
return;
Expand Down Expand Up @@ -1605,7 +1617,7 @@ shaka.media.StreamingEngine = class {
remaining = remaining.subarray(offset);
await this.append_(
mediaState, presentationTime, stream, reference, dataToAppend,
/* isChunkedData= */ true);
/* isChunkedData= */ true, adaptation);

if (mediaState.segmentPrefetch && mediaState.segmentIterator) {
mediaState.segmentPrefetch.prefetchSegmentsByTime(
Expand Down Expand Up @@ -1644,8 +1656,8 @@ shaka.media.StreamingEngine = class {
return;
}

await this.append_(
mediaState, presentationTime, stream, reference, result);
await this.append_(mediaState, presentationTime, stream, reference,
result, /* chunkedData= */ false, adaptation);
}

if (mediaState.segmentPrefetch && mediaState.segmentIterator) {
Expand Down Expand Up @@ -1676,8 +1688,8 @@ shaka.media.StreamingEngine = class {
return;
}

await this.append_(
mediaState, presentationTime, stream, reference, result);
await this.append_(mediaState, presentationTime, stream, reference,
result, /* chunkedData= */ false, adaptation);
}

this.destroyer_.ensureNotDestroyed();
Expand Down Expand Up @@ -1876,10 +1888,11 @@ shaka.media.StreamingEngine = class {
*
* @param {shaka.media.StreamingEngine.MediaState_} mediaState
* @param {!shaka.media.SegmentReference} reference
* @param {boolean} adaptation
* @return {!Promise}
* @private
*/
async initSourceBuffer_(mediaState, reference) {
async initSourceBuffer_(mediaState, reference, adaptation) {
const ContentType = shaka.util.ManifestParserUtils.ContentType;
const MimeUtils = shaka.util.MimeUtils;
const StreamingEngine = shaka.media.StreamingEngine;
Expand Down Expand Up @@ -2039,7 +2052,8 @@ shaka.media.StreamingEngine = class {
mediaState.type, initSegment);
await this.playerInterface_.mediaSourceEngine.appendBuffer(
mediaState.type, initSegment, /* reference= */ null,
mediaState.stream, hasClosedCaptions);
mediaState.stream, hasClosedCaptions, mediaState.seeked,
adaptation);
} catch (error) {
mediaState.lastInitSegmentReference = null;
throw error;
Expand Down Expand Up @@ -2133,11 +2147,12 @@ shaka.media.StreamingEngine = class {
* @param {!shaka.media.SegmentReference} reference
* @param {BufferSource} segment
* @param {boolean=} isChunkedData
* @param {boolean=} adaptation
* @return {!Promise}
* @private
*/
async append_(mediaState, presentationTime, stream, reference, segment,
isChunkedData = false) {
isChunkedData = false, adaptation = false) {
const logPrefix = shaka.media.StreamingEngine.logPrefix_(mediaState);

const hasClosedCaptions = stream.closedCaptions &&
Expand Down Expand Up @@ -2230,8 +2245,6 @@ shaka.media.StreamingEngine = class {
// appendBuffer() call.
const seeked = mediaState.seeked;
mediaState.seeked = false;
const adaptation = mediaState.adaptation;
mediaState.adaptation = false;

await this.playerInterface_.beforeAppendSegment(mediaState.type, segment);
await this.playerInterface_.mediaSourceEngine.appendBuffer(
Expand Down

0 comments on commit 1261c03

Please sign in to comment.