Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion lib/media/preload_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
language: this.config_.preferredAudioLanguage,
role: this.config_.preferredAudioRole,
videoRole: this.config_.preferredVideoRole,
channelCount: this.config_.preferredAudioChannelCount,
channelCount: 0,
hdrLevel: this.config_.preferredVideoHdrLevel,
spatialAudio: this.config_.preferSpatialAudio,
videoLayout: this.config_.preferredVideoLayout,
Expand Down
8 changes: 8 additions & 0 deletions lib/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -5665,6 +5665,14 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
config.language = audioTrack.language;
config.role = audioTrack.roles[0] || '';
config.spatialAudio = audioTrack.spatialAudio;

const active = this.streamingEngine_.getCurrentVariant();
const activeAudio = active && active.audio;
if (activeAudio) {
config.activeAudioCodec = activeAudio.codecs || '';
config.activeAudioChannelCount = activeAudio.channelsCount || 0;
}

this.currentAdaptationSetCriteria_.configure(config);
this.chooseVariantAndSwitch_(
/* clearBuffer= */ true, /* safeMargin= */ safeMargin,
Expand Down
72 changes: 4 additions & 68 deletions lib/util/stream_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,73 +108,16 @@ shaka.util.StreamUtils = class {
// Now we have filtered variants and text tracks down by user preferences
// for formats, codecs, and decoding attributes (smooth, efficient, etc).

const audioStreamsSet = new Set();
const videoStreamsSet = new Set();
for (const variant of variants) {
if (variant.audio) {
audioStreamsSet.add(variant.audio);
}
if (variant.video) {
videoStreamsSet.add(variant.video);
}
}

// Audio streams sorted by bandwidth, lowest to highest.
const audioStreams = Array.from(audioStreamsSet).sort((v1, v2) => {
return v1.bandwidth - v2.bandwidth;
});

// Maps that are used to choose codecs when there are no preferences in
// effect above.
const validAudioIds = [];
const validAudioStreamsMap = new Map();

// A group ID composed of attributes like language, channels, role, etc to
// find redundant audio streams that only differ in terms of things like
// codec, format, and bitrate.
const getAudioGroupId = (stream) => {
const idParts = [
stream.language,
(stream.channelsCount || 0),
(stream.audioSamplingRate || 0),
stream.roles.join(','),
stream.label,
stream.groupId,
stream.fastSwitching,
];
if (stream.dependencyStream) {
idParts.push(stream.dependencyStream.baseOriginalId || '');
}
return idParts.join(';');
};

// For the first audio stream in a group (lowest bandwidth by sorting
// above), add it to the map. For subsequent audio streams in a group,
// only add it to the map if the codec matches. This could make a bad
// decision if not every audio codec is used on every quality level in the
// audio ladder. In scenarios like this, use preferredAudioCodecs. If
// preferredAudioCodecs is used, there should only be one codec left when
// we get to this stage.
for (const stream of audioStreams) {
const groupId = getAudioGroupId(stream);
const validAudioStreams = validAudioStreamsMap.get(groupId) || [];

if (!validAudioStreams.length) {
validAudioStreams.push(stream);
validAudioIds.push(stream.id);
} else {
const previousStream = validAudioStreams[validAudioStreams.length - 1];
const previousCodec =
MimeUtils.getNormalizedCodec(previousStream.codecs);
const currentCodec =
MimeUtils.getNormalizedCodec(stream.codecs);
if (previousCodec == currentCodec) {
validAudioStreams.push(stream);
validAudioIds.push(stream.id);
}
}

validAudioStreamsMap.set(groupId, validAudioStreams);
if (!videoStreamsSet.size) {
manifest.variants = variants;
return;
}

// Keys based in MimeUtils.getNormalizedCodec. Lower is better
Expand Down Expand Up @@ -270,15 +213,8 @@ shaka.util.StreamUtils = class {
// Filter out any variants that don't match, forcing AbrManager to choose
// from a single video codec and a single audio codec **per stream group**
// (resolution, etc).
manifest.variants = manifest.variants.filter((variant) => {
const audio = variant.audio;
manifest.variants = variants.filter((variant) => {
const video = variant.video;
if (audio) {
if (!validAudioIds.includes(audio.id)) {
shaka.log.debug('Dropping Variant (better codec available)', variant);
return false;
}
}
if (video) {
if (!validVideoIds.includes(video.id)) {
shaka.log.debug('Dropping Variant (better codec available)', variant);
Expand Down
50 changes: 0 additions & 50 deletions test/util/stream_utils_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -898,56 +898,6 @@ describe('StreamUtils', () => {
expect(manifest.variants.length).toBe(3);
});

it('should filter variants by the best available bandwidth' +
' for audio language', () => {
// This test is flaky in some Tizen devices, due to codec restrictions.
if (deviceDetected.getDeviceName() === 'Tizen') {
pending('Skip flaky test in Tizen');
}
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
manifest.addVariant(0, (variant) => {
variant.bandwidth = 4058558;
variant.addAudio(1, (stream) => {
stream.bandwidth = 100000;
stream.language = 'en';
stream.mime('audio/mp4', 'mp4a.40.2');
});
});
manifest.addVariant(2, (variant) => {
variant.bandwidth = 4781002;
variant.addAudio(3, (stream) => {
stream.bandwidth = 200000;
stream.language = 'en';
stream.mime('audio/mp4', 'flac');
});
});
manifest.addVariant(4, (variant) => {
variant.addAudio(5, (stream) => {
stream.bandwidth = 100000;
stream.language = 'es';
stream.mime('audio/mp4', 'mp4a.40.2');
});
});
manifest.addVariant(6, (variant) => {
variant.addAudio(7, (stream) => {
stream.bandwidth = 500000;
stream.language = 'es';
stream.mime('audio/mp4', 'flac');
});
});
});

shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
/* preferredVideoCodecs= */[],
/* preferredAudioCodecs= */[],
/* preferredDecodingAttributes= */[],
/* preferredTextFormats= */ []);

expect(manifest.variants.length).toBe(2);
expect(manifest.variants.every((v) => v.audio.bandwidth == 100000))
.toBeTruthy();
});

it('should allow multiple codecs for codec switching', async () => {
if (!await Util.isTypeSupported('video/webm; codecs="vp9"')) {
pending('Codec VP9 is not supported by the platform.');
Expand Down