Skip to content

Commit

Permalink
fix(DASH): Fix seeking on multiperiod content after variant change (#…
Browse files Browse the repository at this point in the history
…5110)

Fixes an issue where `createSegmentIndex()` creates a reference in
cached Stream and not on a new Stream. Now cached value is reused in
period flattening.

Updated assertion in Period Combiner to catch potential issues within
old approach.

Without this fix I've noticed problems around seeking on multiperiod
content after variant change.
  • Loading branch information
tykus160 authored and joeyparrish committed Apr 26, 2023
1 parent 7d8b867 commit 860b975
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 52 deletions.
97 changes: 49 additions & 48 deletions lib/dash/dash_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -1279,55 +1279,56 @@ shaka.dash.DashParser = class {
context.period.id + ',' + context.representation.id : '';

/** @type {shaka.extern.Stream} */
const stream = {
id: this.globalId_++,
originalId: context.representation.id,
createSegmentIndex: async () => {
// If we have a stream with the same context id stored in the map
// that has no segmentIndex, we should set the segmentIndex for it.
const storedInMap = contextId && context.dynamic &&
this.streamMap_[contextId];

const currentStream = storedInMap ? this.streamMap_[contextId] : stream;
if (!currentStream.segmentIndex) {
currentStream.segmentIndex = await streamInfo.generateSegmentIndex();
}
},
let stream;

closeSegmentIndex: () => {
if (stream.segmentIndex) {
stream.segmentIndex.release();
stream.segmentIndex = null;
}
},
segmentIndex: null,
mimeType: context.representation.mimeType,
codecs: context.representation.codecs,
frameRate: context.representation.frameRate,
pixelAspectRatio: context.representation.pixelAspectRatio,
bandwidth: context.bandwidth,
width: context.representation.width,
height: context.representation.height,
kind,
encrypted: contentProtection.drmInfos.length > 0,
drmInfos: contentProtection.drmInfos,
keyIds,
language,
label,
type: context.adaptationSet.contentType,
primary: isPrimary,
trickModeVideo: null,
emsgSchemeIdUris:
context.representation.emsgSchemeIdUris,
roles,
forced: forced,
channelsCount: context.representation.numChannels,
audioSamplingRate: context.representation.audioSamplingRate,
spatialAudio: spatialAudio,
closedCaptions,
hdr,
tilesLayout,
matchedStreams: [],
if (contextId && this.streamMap_[contextId]) {
stream = this.streamMap_[contextId];
} else {
stream = {
id: this.globalId_++,
originalId: context.representation.id,
createSegmentIndex: () => Promise.resolve(),
closeSegmentIndex: () => {
if (stream.segmentIndex) {
stream.segmentIndex.release();
stream.segmentIndex = null;
}
},
segmentIndex: null,
mimeType: context.representation.mimeType,
codecs: context.representation.codecs,
frameRate: context.representation.frameRate,
pixelAspectRatio: context.representation.pixelAspectRatio,
bandwidth: context.bandwidth,
width: context.representation.width,
height: context.representation.height,
kind,
encrypted: contentProtection.drmInfos.length > 0,
drmInfos: contentProtection.drmInfos,
keyIds,
language,
label,
type: context.adaptationSet.contentType,
primary: isPrimary,
trickModeVideo: null,
emsgSchemeIdUris:
context.representation.emsgSchemeIdUris,
roles,
forced,
channelsCount: context.representation.numChannels,
audioSamplingRate: context.representation.audioSamplingRate,
spatialAudio,
closedCaptions,
hdr,
tilesLayout,
matchedStreams: [],
};
}

stream.createSegmentIndex = async () => {
if (!stream.segmentIndex) {
stream.segmentIndex = await streamInfo.generateSegmentIndex();
}
};

if (contextId && context.dynamic && !this.streamMap_[contextId]) {
Expand Down
8 changes: 4 additions & 4 deletions lib/util/periods.js
Original file line number Diff line number Diff line change
Expand Up @@ -671,11 +671,11 @@ shaka.util.PeriodCombiner = class {
// Also checks if the segmentIndex is still valid after the async
// operations, to make sure we stop if the active stream has changed.
if (outputStream.segmentIndex instanceof shaka.media.MetaSegmentIndex) {
for (let i = 0; i < streams.length; i++) {
for (let i = firstNewPeriodIndex; i < streams.length; i++) {
const match = streams[i];
if (match.segmentIndex && i >= firstNewPeriodIndex) {
goog.asserts.assert(match.segmentIndex,
'stream should have a segmentIndex.');
goog.asserts.assert(match.segmentIndex,
'stream should have a segmentIndex.');
if (match.segmentIndex) {
outputStream.segmentIndex.appendSegmentIndex(match.segmentIndex);
}
}
Expand Down

0 comments on commit 860b975

Please sign in to comment.