From a2de68ac670570437b0c2f29419ecc5e69fad875 Mon Sep 17 00:00:00 2001 From: Gaetan Hervouet Date: Mon, 9 May 2022 14:42:51 -0400 Subject: [PATCH 01/11] Fix PERIOD_FLATTENING_FAILED error when periods have a compatible codec but different base sample types. --- lib/dash/dash_parser.js | 4 +-- lib/util/mime_utils.js | 21 +++++++++++++ lib/util/periods.js | 8 ++--- lib/util/stream_utils.js | 4 +-- test/util/periods_unit.js | 66 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+), 8 deletions(-) diff --git a/lib/dash/dash_parser.js b/lib/dash/dash_parser.js index 5ea78abd57..c6898e75cc 100644 --- a/lib/dash/dash_parser.js +++ b/lib/dash/dash_parser.js @@ -765,8 +765,8 @@ shaka.dash.DashParser = class { // currently support that. Just choose one. // TODO: https://github.com/shaka-project/shaka-player/issues/1528 stream.trickModeVideo = trickModeSet.streams.find((trickStream) => - shaka.util.MimeUtils.getCodecBase(stream.codecs) == - shaka.util.MimeUtils.getCodecBase(trickStream.codecs)); + shaka.util.MimeUtils.getNormalizedCodec(stream.codecs) == + shaka.util.MimeUtils.getNormalizedCodec(trickStream.codecs)); } } } diff --git a/lib/util/mime_utils.js b/lib/util/mime_utils.js index 8183e50448..8fa58a5a32 100644 --- a/lib/util/mime_utils.js +++ b/lib/util/mime_utils.js @@ -96,6 +96,27 @@ shaka.util.MimeUtils = class { return codecs.split(','); } + /** + * Get the codec from a codec string, ignoring differences in base sample types declared in the fourCC. + * + * @param {string} codecString + * @return {string} + */ + static getNormalizedCodec(codecString) { + switch (shaka.util.MimeUtils.getCodecBase(codecString)) { + case 'avc1': + case 'avc3': + return 'avc'; + case 'hvc1': + case 'hev1': + return 'hevc'; + case 'dvh1': + case 'dvhe': + return 'dovi'; + } + return codecString; + } + /** * Get the base codec from a codec string. * diff --git a/lib/util/periods.js b/lib/util/periods.js index 9f41b98162..5917fae321 100644 --- a/lib/util/periods.js +++ b/lib/util/periods.js @@ -573,8 +573,8 @@ shaka.util.PeriodCombiner = class { // TODO(#1528): Consider changing this when we support codec switching. const hasCodec = outputStreams.some((s) => { return s.mimeType == stream.mimeType && - shaka.util.MimeUtils.getCodecBase(s.codecs) == - shaka.util.MimeUtils.getCodecBase(stream.codecs); + shaka.util.MimeUtils.getNormalizedCodec(s.codecs) == + shaka.util.MimeUtils.getNormalizedCodec(stream.codecs); }); if (!hasCodec) { continue; @@ -1050,10 +1050,10 @@ shaka.util.PeriodCombiner = class { * @private */ static areAVStreamsCompatible_(outputStream, candidate) { - const getCodecBase = (codecs) => shaka.util.MimeUtils.getCodecBase(codecs); + const getNormalizedCodec = (codecs) => shaka.util.MimeUtils.getNormalizedCodec(codecs); // Check MIME type and codecs, which should always be the same. if (candidate.mimeType != outputStream.mimeType || - getCodecBase(candidate.codecs) != getCodecBase(outputStream.codecs)) { + getNormalizedCodec(candidate.codecs) != getNormalizedCodec(outputStream.codecs)) { return false; } diff --git a/lib/util/stream_utils.js b/lib/util/stream_utils.js index ed69233032..8016463951 100644 --- a/lib/util/stream_utils.js +++ b/lib/util/stream_utils.js @@ -283,12 +283,12 @@ shaka.util.StreamUtils = class { // both be considered the same codec: avc1.42c01e, avc1.4d401f let baseVideoCodec = ''; if (variant.video) { - baseVideoCodec = shaka.util.MimeUtils.getCodecBase(variant.video.codecs); + baseVideoCodec = shaka.util.MimeUtils.getNormalizedCodec(variant.video.codecs); } let baseAudioCodec = ''; if (variant.audio) { - baseAudioCodec = shaka.util.MimeUtils.getCodecBase(variant.audio.codecs); + baseAudioCodec = shaka.util.MimeUtils.getNormalizedCodec(variant.audio.codecs); } return baseVideoCodec + '-' + baseAudioCodec; diff --git a/test/util/periods_unit.js b/test/util/periods_unit.js index 87115a70e4..383dd2e53f 100644 --- a/test/util/periods_unit.js +++ b/test/util/periods_unit.js @@ -996,6 +996,72 @@ describe('PeriodCombiner', () => { expect(audio2.originalId).toBe('2,4'); }); + it('Matches streams with related codecs', async () => { + const stream1 = makeVideoStream(1080); + stream1.originalId = '1'; + stream1.bandwidth = 120000; + stream1.codecs = 'hvc1.1.4.L126.B0'; + + const stream2 = makeVideoStream(1080); + stream2.originalId = '2'; + stream2.bandwidth = 120000; + stream2.codecs = 'hev1.2.4.L123.B0'; + + const stream3 = makeVideoStream(1080); + stream3.originalId = '3'; + stream3.bandwidth = 120000; + stream3.codecs = 'dvhe.05.01'; + + const stream4 = makeVideoStream(1080); + stream4.originalId = '4'; + stream4.bandwidth = 120000; + stream4.codecs = 'dvh1.05.01'; + + const stream5 = makeVideoStream(1080); + stream5.originalId = '5'; + stream5.bandwidth = 120000; + stream5.codecs = 'avc1.42001f'; + + const stream6 = makeVideoStream(1080); + stream6.originalId = '6'; + stream6.bandwidth = 120000; + stream6.codecs = 'avc3.42001f'; + + /** @type {!Array.} */ + const periods = [ + { + id: '0', + videoStreams: [ + stream1,stream3,stream5, + ], + audioStreams: [], + textStreams: [], + imageStreams: [], + }, + { + id: '1', + videoStreams: [ + stream2,stream4,stream6, + ], + audioStreams: [], + textStreams: [], + imageStreams: [], + }, + ]; + + await combiner.combinePeriods(periods, /* isDynamic= */ true); + const variants = combiner.getVariants(); + expect(variants.length).toBe(3); + // We can use the originalId field to see what each track is composed of. + const video1 = variants[0].video; + expect(video1.originalId).toBe('1,2'); + + const video2 = variants[1].video; + expect(video2.originalId).toBe('3,4'); + + const video3 = variants[2].video; + expect(video3.originalId).toBe('5,6'); + }); it('Matches streams with most roles in common', async () => { const makeAudioStreamWithRoles = (roles) => { From a9458311110d35afb739b2b75fa7092f76b5bda4 Mon Sep 17 00:00:00 2001 From: Gaetan Hervouet Date: Mon, 9 May 2022 15:38:17 -0400 Subject: [PATCH 02/11] Fix lint issues. --- lib/util/mime_utils.js | 3 ++- lib/util/periods.js | 5 +++-- lib/util/stream_utils.js | 6 ++++-- test/util/periods_unit.js | 4 ++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/util/mime_utils.js b/lib/util/mime_utils.js index 8fa58a5a32..2acfcc0eb0 100644 --- a/lib/util/mime_utils.js +++ b/lib/util/mime_utils.js @@ -97,7 +97,8 @@ shaka.util.MimeUtils = class { } /** - * Get the codec from a codec string, ignoring differences in base sample types declared in the fourCC. + * Get the codec from a codec string, ignoring differences in base sample + * types declared in the fourCC. * * @param {string} codecString * @return {string} diff --git a/lib/util/periods.js b/lib/util/periods.js index 5917fae321..6b8e580b7b 100644 --- a/lib/util/periods.js +++ b/lib/util/periods.js @@ -1050,10 +1050,11 @@ shaka.util.PeriodCombiner = class { * @private */ static areAVStreamsCompatible_(outputStream, candidate) { - const getNormalizedCodec = (codecs) => shaka.util.MimeUtils.getNormalizedCodec(codecs); + const getCodec = (codecs) => + shaka.util.MimeUtils.getNormalizedCodec(codecs); // Check MIME type and codecs, which should always be the same. if (candidate.mimeType != outputStream.mimeType || - getNormalizedCodec(candidate.codecs) != getNormalizedCodec(outputStream.codecs)) { + getCodec(candidate.codecs) != getCodec(outputStream.codecs)) { return false; } diff --git a/lib/util/stream_utils.js b/lib/util/stream_utils.js index 8016463951..410482bb60 100644 --- a/lib/util/stream_utils.js +++ b/lib/util/stream_utils.js @@ -283,12 +283,14 @@ shaka.util.StreamUtils = class { // both be considered the same codec: avc1.42c01e, avc1.4d401f let baseVideoCodec = ''; if (variant.video) { - baseVideoCodec = shaka.util.MimeUtils.getNormalizedCodec(variant.video.codecs); + baseVideoCodec = + shaka.util.MimeUtils.getNormalizedCodec(variant.video.codecs); } let baseAudioCodec = ''; if (variant.audio) { - baseAudioCodec = shaka.util.MimeUtils.getNormalizedCodec(variant.audio.codecs); + baseAudioCodec = + shaka.util.MimeUtils.getNormalizedCodec(variant.audio.codecs); } return baseVideoCodec + '-' + baseAudioCodec; diff --git a/test/util/periods_unit.js b/test/util/periods_unit.js index 383dd2e53f..e28f11f1ed 100644 --- a/test/util/periods_unit.js +++ b/test/util/periods_unit.js @@ -1032,7 +1032,7 @@ describe('PeriodCombiner', () => { { id: '0', videoStreams: [ - stream1,stream3,stream5, + stream1, stream3, stream5, ], audioStreams: [], textStreams: [], @@ -1041,7 +1041,7 @@ describe('PeriodCombiner', () => { { id: '1', videoStreams: [ - stream2,stream4,stream6, + stream2, stream4, stream6, ], audioStreams: [], textStreams: [], From ccb2c6902a8ccff0e1330a39a84b4d1114288b49 Mon Sep 17 00:00:00 2001 From: Gaetan Hervouet Date: Mon, 9 May 2022 16:07:45 -0400 Subject: [PATCH 03/11] Add description for the returned codec names. --- lib/util/mime_utils.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/util/mime_utils.js b/lib/util/mime_utils.js index 2acfcc0eb0..3773fb3672 100644 --- a/lib/util/mime_utils.js +++ b/lib/util/mime_utils.js @@ -107,13 +107,13 @@ shaka.util.MimeUtils = class { switch (shaka.util.MimeUtils.getCodecBase(codecString)) { case 'avc1': case 'avc3': - return 'avc'; + return 'avc'; // H264 case 'hvc1': case 'hev1': - return 'hevc'; + return 'hevc'; // H265 case 'dvh1': case 'dvhe': - return 'dovi'; + return 'dovi'; // Dolby Vision } return codecString; } From 786105a21815f924447be2c5ae8caeb6906f971e Mon Sep 17 00:00:00 2001 From: Gaetan Hervouet Date: Mon, 9 May 2022 17:08:55 -0400 Subject: [PATCH 04/11] Fix default case. --- lib/util/mime_utils.js | 5 +++-- test/util/periods_unit.js | 19 ++++++++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/util/mime_utils.js b/lib/util/mime_utils.js index 3773fb3672..6caea138d8 100644 --- a/lib/util/mime_utils.js +++ b/lib/util/mime_utils.js @@ -104,7 +104,8 @@ shaka.util.MimeUtils = class { * @return {string} */ static getNormalizedCodec(codecString) { - switch (shaka.util.MimeUtils.getCodecBase(codecString)) { + const cb = shaka.util.MimeUtils.getCodecBase(codecString); + switch (cb) { case 'avc1': case 'avc3': return 'avc'; // H264 @@ -115,7 +116,7 @@ shaka.util.MimeUtils = class { case 'dvhe': return 'dovi'; // Dolby Vision } - return codecString; + return cb; } /** diff --git a/test/util/periods_unit.js b/test/util/periods_unit.js index e28f11f1ed..ad655ab941 100644 --- a/test/util/periods_unit.js +++ b/test/util/periods_unit.js @@ -1027,12 +1027,22 @@ describe('PeriodCombiner', () => { stream6.bandwidth = 120000; stream6.codecs = 'avc3.42001f'; + const stream7 = makeVideoStream(1080); + stream7.originalId = '7'; + stream7.bandwidth = 120000; + stream7.codecs = 'vp09.00.10.08'; + + const stream8 = makeVideoStream(1080); + stream8.originalId = '8'; + stream8.bandwidth = 120000; + stream8.codecs = 'vp09.01.20.08.01'; + /** @type {!Array.} */ const periods = [ { id: '0', videoStreams: [ - stream1, stream3, stream5, + stream1, stream3, stream5, stream7, ], audioStreams: [], textStreams: [], @@ -1041,7 +1051,7 @@ describe('PeriodCombiner', () => { { id: '1', videoStreams: [ - stream2, stream4, stream6, + stream2, stream4, stream6, stream8, ], audioStreams: [], textStreams: [], @@ -1051,7 +1061,7 @@ describe('PeriodCombiner', () => { await combiner.combinePeriods(periods, /* isDynamic= */ true); const variants = combiner.getVariants(); - expect(variants.length).toBe(3); + expect(variants.length).toBe(4); // We can use the originalId field to see what each track is composed of. const video1 = variants[0].video; expect(video1.originalId).toBe('1,2'); @@ -1061,6 +1071,9 @@ describe('PeriodCombiner', () => { const video3 = variants[2].video; expect(video3.originalId).toBe('5,6'); + + const video4 = variants[3].video; + expect(video4.originalId).toBe('7,8'); }); it('Matches streams with most roles in common', async () => { From 095f2f11055e6ed2f693c9b037006bbf07effa0b Mon Sep 17 00:00:00 2001 From: Joey Parrish Date: Mon, 9 May 2022 14:20:40 -0700 Subject: [PATCH 05/11] Expand variable name for readability --- lib/util/mime_utils.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/util/mime_utils.js b/lib/util/mime_utils.js index 6caea138d8..295d4199dc 100644 --- a/lib/util/mime_utils.js +++ b/lib/util/mime_utils.js @@ -104,8 +104,8 @@ shaka.util.MimeUtils = class { * @return {string} */ static getNormalizedCodec(codecString) { - const cb = shaka.util.MimeUtils.getCodecBase(codecString); - switch (cb) { + const codecBase = shaka.util.MimeUtils.getCodecBase(codecString); + switch (codecBase) { case 'avc1': case 'avc3': return 'avc'; // H264 @@ -116,7 +116,7 @@ shaka.util.MimeUtils = class { case 'dvhe': return 'dovi'; // Dolby Vision } - return cb; + return codecBase; } /** From ac6992cb5491005f2c6bdd046d169248cce6a394 Mon Sep 17 00:00:00 2001 From: Gaetan Hervouet Date: Tue, 10 May 2022 22:32:46 -0400 Subject: [PATCH 06/11] Update mime_utils to group similar codec independently of their codec string. Also fix issue in getCodecParts_. --- lib/util/mime_utils.js | 52 +++++++++++++++++++++++++--------- test/util/mime_utils_unit.js | 55 ++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 13 deletions(-) create mode 100644 test/util/mime_utils_unit.js diff --git a/lib/util/mime_utils.js b/lib/util/mime_utils.js index 6caea138d8..898b15c0fe 100644 --- a/lib/util/mime_utils.js +++ b/lib/util/mime_utils.js @@ -97,26 +97,52 @@ shaka.util.MimeUtils = class { } /** - * Get the codec from a codec string, ignoring differences in base sample - * types declared in the fourCC. + * Get the normalized codec from a codec string, + * ignoring multiple names of a same codec. * * @param {string} codecString * @return {string} */ static getNormalizedCodec(codecString) { - const cb = shaka.util.MimeUtils.getCodecBase(codecString); - switch (cb) { - case 'avc1': - case 'avc3': - return 'avc'; // H264 - case 'hvc1': - case 'hev1': + const parts = + shaka.util.MimeUtils.getCodecParts_(codecString.toLowerCase()); + const base = parts[0]; + const profile = parts[1]; + switch (true) { + case base === 'mp4a' && profile === '66': + case base === 'mp4a' && profile === '67': + case base === 'mp4a' && profile === '68': + return 'mpeg2_aac'; + case base === 'mp4a' && profile === '69': + case base === 'mp4a' && profile === '6b': + return 'mp3'; + case base === 'mp4a' && profile === '40.2': + case base === 'mp4a' && profile === '40.02': + case base === 'mp4a' && profile === '40.5': + case base === 'mp4a' && profile === '40.05': + case base === 'mp4a' && profile === '40.29': + return 'mpeg4_aac'; + case base === 'mp4a' && profile === '40.42': + return 'mpeg4_xhe_aac'; // Extended HE-AAC + case base === 'mp4a' && profile === 'a5': + return 'ac-3'; // Dolby Digital + case base === 'mp4a' && profile === 'a6': + return 'ec-3'; // Dolby Digital Plus + case base === 'mp4a' && profile === 'b2': + return 'dtsx'; // DTS:X + case base === 'mp4a' && profile === 'a9': + return 'dtsc'; // DTS Digital Surround + case base === 'avc1': + case base === 'avc3': + return 'avc'; // H264 + case base === 'hvc1': + case base === 'hev1': return 'hevc'; // H265 - case 'dvh1': - case 'dvhe': + case base === 'dvh1': + case base === 'dvhe': return 'dovi'; // Dolby Vision } - return cb; + return base; } /** @@ -175,7 +201,7 @@ shaka.util.MimeUtils = class { const base = parts[0]; - parts.pop(); + parts.shift(); const profile = parts.join('.'); // Make sure that we always return a "base" and "profile". diff --git a/test/util/mime_utils_unit.js b/test/util/mime_utils_unit.js new file mode 100644 index 0000000000..447f62b62a --- /dev/null +++ b/test/util/mime_utils_unit.js @@ -0,0 +1,55 @@ +/*! @license + * Shaka Player + * Copyright 2016 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +describe('MimeUtils', () => { + const getNormalizedCodec = (codecs) => + shaka.util.MimeUtils.getNormalizedCodec(codecs); + + it('normalizes codecs', () => { + expect(getNormalizedCodec('mp4a.66')).toBe('mpeg2_aac'); + expect(getNormalizedCodec('mp4a.67')).toBe('mpeg2_aac'); + expect(getNormalizedCodec('mp4a.68')).toBe('mpeg2_aac'); + + expect(getNormalizedCodec('mp3')).toBe('mp3'); + expect(getNormalizedCodec('mp4a.69')).toBe('mp3'); + expect(getNormalizedCodec('mp4a.6B')).toBe('mp3'); + expect(getNormalizedCodec('mp4a.6b')).toBe('mp3'); + + expect(getNormalizedCodec('mp4a.40.2')).toBe('mpeg4_aac'); + expect(getNormalizedCodec('mp4a.40.02')).toBe('mpeg4_aac'); + expect(getNormalizedCodec('mp4a.40.5')).toBe('mpeg4_aac'); + expect(getNormalizedCodec('mp4a.40.05')).toBe('mpeg4_aac'); + expect(getNormalizedCodec('mp4a.40.29')).toBe('mpeg4_aac'); + + expect(getNormalizedCodec('mp4a.40.42')).toBe('mpeg4_xhe_aac'); + + expect(getNormalizedCodec('ac-3')).toBe('ac-3'); + expect(getNormalizedCodec('mp4a.a5')).toBe('ac-3'); + expect(getNormalizedCodec('mp4a.A5')).toBe('ac-3'); + + expect(getNormalizedCodec('ec-3')).toBe('ec-3'); + expect(getNormalizedCodec('mp4a.a6')).toBe('ec-3'); + expect(getNormalizedCodec('mp4a.A6')).toBe('ec-3'); + + expect(getNormalizedCodec('vp8')).toBe('vp8'); + expect(getNormalizedCodec('vp8.0')).toBe('vp8'); + + expect(getNormalizedCodec('dtsc')).toBe('dtsc'); + expect(getNormalizedCodec('mp4a.a9')).toBe('dtsc'); + + expect(getNormalizedCodec('dtsx')).toBe('dtsx'); + expect(getNormalizedCodec('mp4a.b2')).toBe('dtsx'); + + expect(getNormalizedCodec('avc1')).toBe('avc'); + expect(getNormalizedCodec('avc3')).toBe('avc'); + + expect(getNormalizedCodec('hvc1')).toBe('hevc'); + expect(getNormalizedCodec('hev1')).toBe('hevc'); + + expect(getNormalizedCodec('dvh1.05')).toBe('dovi'); + expect(getNormalizedCodec('dvhe.05')).toBe('dovi'); + }); +}); From bc06277a5ff16fac11ed5a93dbd3e2c16b653187 Mon Sep 17 00:00:00 2001 From: Gaetan Hervouet Date: Wed, 11 May 2022 10:22:23 -0400 Subject: [PATCH 07/11] Remove grouping for ac3,ec3,dtsx and dtsc the codec string indicates a container difference which may be incompatible when switching from one to another. --- lib/util/mime_utils.js | 10 +--------- test/util/mime_utils_unit.js | 14 -------------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/lib/util/mime_utils.js b/lib/util/mime_utils.js index 898b15c0fe..f9e9dc1acc 100644 --- a/lib/util/mime_utils.js +++ b/lib/util/mime_utils.js @@ -98,7 +98,7 @@ shaka.util.MimeUtils = class { /** * Get the normalized codec from a codec string, - * ignoring multiple names of a same codec. + * grouping them as long as they are compatible. * * @param {string} codecString * @return {string} @@ -124,14 +124,6 @@ shaka.util.MimeUtils = class { return 'mpeg4_aac'; case base === 'mp4a' && profile === '40.42': return 'mpeg4_xhe_aac'; // Extended HE-AAC - case base === 'mp4a' && profile === 'a5': - return 'ac-3'; // Dolby Digital - case base === 'mp4a' && profile === 'a6': - return 'ec-3'; // Dolby Digital Plus - case base === 'mp4a' && profile === 'b2': - return 'dtsx'; // DTS:X - case base === 'mp4a' && profile === 'a9': - return 'dtsc'; // DTS Digital Surround case base === 'avc1': case base === 'avc3': return 'avc'; // H264 diff --git a/test/util/mime_utils_unit.js b/test/util/mime_utils_unit.js index 447f62b62a..67c4a81c06 100644 --- a/test/util/mime_utils_unit.js +++ b/test/util/mime_utils_unit.js @@ -26,23 +26,9 @@ describe('MimeUtils', () => { expect(getNormalizedCodec('mp4a.40.42')).toBe('mpeg4_xhe_aac'); - expect(getNormalizedCodec('ac-3')).toBe('ac-3'); - expect(getNormalizedCodec('mp4a.a5')).toBe('ac-3'); - expect(getNormalizedCodec('mp4a.A5')).toBe('ac-3'); - - expect(getNormalizedCodec('ec-3')).toBe('ec-3'); - expect(getNormalizedCodec('mp4a.a6')).toBe('ec-3'); - expect(getNormalizedCodec('mp4a.A6')).toBe('ec-3'); - expect(getNormalizedCodec('vp8')).toBe('vp8'); expect(getNormalizedCodec('vp8.0')).toBe('vp8'); - expect(getNormalizedCodec('dtsc')).toBe('dtsc'); - expect(getNormalizedCodec('mp4a.a9')).toBe('dtsc'); - - expect(getNormalizedCodec('dtsx')).toBe('dtsx'); - expect(getNormalizedCodec('mp4a.b2')).toBe('dtsx'); - expect(getNormalizedCodec('avc1')).toBe('avc'); expect(getNormalizedCodec('avc3')).toBe('avc'); From 7172b30e33657c6c52d9e503b5e48cacdb29ea08 Mon Sep 17 00:00:00 2001 From: Gaetan Hervouet Date: Wed, 11 May 2022 22:56:58 -0400 Subject: [PATCH 08/11] Remove container distinction. --- lib/util/mime_utils.js | 16 ++++++++++++---- test/util/mime_utils_unit.js | 32 +++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/lib/util/mime_utils.js b/lib/util/mime_utils.js index f9e9dc1acc..b1392f12ab 100644 --- a/lib/util/mime_utils.js +++ b/lib/util/mime_utils.js @@ -98,7 +98,7 @@ shaka.util.MimeUtils = class { /** * Get the normalized codec from a codec string, - * grouping them as long as they are compatible. + * indendently of their container. * * @param {string} codecString * @return {string} @@ -112,7 +112,7 @@ shaka.util.MimeUtils = class { case base === 'mp4a' && profile === '66': case base === 'mp4a' && profile === '67': case base === 'mp4a' && profile === '68': - return 'mpeg2_aac'; + return 'aac'; case base === 'mp4a' && profile === '69': case base === 'mp4a' && profile === '6b': return 'mp3'; @@ -121,9 +121,17 @@ shaka.util.MimeUtils = class { case base === 'mp4a' && profile === '40.5': case base === 'mp4a' && profile === '40.05': case base === 'mp4a' && profile === '40.29': - return 'mpeg4_aac'; + return 'aac'; case base === 'mp4a' && profile === '40.42': - return 'mpeg4_xhe_aac'; // Extended HE-AAC + return 'xhe_aac'; // Extended HE-AAC + case base === 'mp4a' && profile === 'a5': + return 'ac-3'; // Dolby Digital + case base === 'mp4a' && profile === 'a6': + return 'ec-3'; // Dolby Digital Plus + case base === 'mp4a' && profile === 'b2': + return 'dtsx'; // DTS:X + case base === 'mp4a' && profile === 'a9': + return 'dtsc'; // DTS Digital Surround case base === 'avc1': case base === 'avc3': return 'avc'; // H264 diff --git a/test/util/mime_utils_unit.js b/test/util/mime_utils_unit.js index 67c4a81c06..61b7941189 100644 --- a/test/util/mime_utils_unit.js +++ b/test/util/mime_utils_unit.js @@ -9,22 +9,36 @@ describe('MimeUtils', () => { shaka.util.MimeUtils.getNormalizedCodec(codecs); it('normalizes codecs', () => { - expect(getNormalizedCodec('mp4a.66')).toBe('mpeg2_aac'); - expect(getNormalizedCodec('mp4a.67')).toBe('mpeg2_aac'); - expect(getNormalizedCodec('mp4a.68')).toBe('mpeg2_aac'); + expect(getNormalizedCodec('mp4a.66')).toBe('aac'); + expect(getNormalizedCodec('mp4a.67')).toBe('aac'); + expect(getNormalizedCodec('mp4a.68')).toBe('aac'); expect(getNormalizedCodec('mp3')).toBe('mp3'); expect(getNormalizedCodec('mp4a.69')).toBe('mp3'); expect(getNormalizedCodec('mp4a.6B')).toBe('mp3'); expect(getNormalizedCodec('mp4a.6b')).toBe('mp3'); - expect(getNormalizedCodec('mp4a.40.2')).toBe('mpeg4_aac'); - expect(getNormalizedCodec('mp4a.40.02')).toBe('mpeg4_aac'); - expect(getNormalizedCodec('mp4a.40.5')).toBe('mpeg4_aac'); - expect(getNormalizedCodec('mp4a.40.05')).toBe('mpeg4_aac'); - expect(getNormalizedCodec('mp4a.40.29')).toBe('mpeg4_aac'); + expect(getNormalizedCodec('mp4a.40.2')).toBe('aac'); + expect(getNormalizedCodec('mp4a.40.02')).toBe('aac'); + expect(getNormalizedCodec('mp4a.40.5')).toBe('aac'); + expect(getNormalizedCodec('mp4a.40.05')).toBe('aac'); + expect(getNormalizedCodec('mp4a.40.29')).toBe('aac'); - expect(getNormalizedCodec('mp4a.40.42')).toBe('mpeg4_xhe_aac'); + expect(getNormalizedCodec('mp4a.40.42')).toBe('xhe_aac'); + + expect(getNormalizedCodec('ac-3')).toBe('ac-3'); + expect(getNormalizedCodec('mp4a.a5')).toBe('ac-3'); + expect(getNormalizedCodec('mp4a.A5')).toBe('ac-3'); + + expect(getNormalizedCodec('ec-3')).toBe('ec-3'); + expect(getNormalizedCodec('mp4a.a6')).toBe('ec-3'); + expect(getNormalizedCodec('mp4a.A6')).toBe('ec-3'); + + expect(getNormalizedCodec('dtsc')).toBe('dtsc'); + expect(getNormalizedCodec('mp4a.a9')).toBe('dtsc'); + + expect(getNormalizedCodec('dtsx')).toBe('dtsx'); + expect(getNormalizedCodec('mp4a.b2')).toBe('dtsx'); expect(getNormalizedCodec('vp8')).toBe('vp8'); expect(getNormalizedCodec('vp8.0')).toBe('vp8'); From 1f70352e264af7ab4fdfa05725b1d908e39615a5 Mon Sep 17 00:00:00 2001 From: Gaetan Hervouet Date: Wed, 11 May 2022 23:01:09 -0400 Subject: [PATCH 09/11] case-insensitivity tweak. --- lib/util/mime_utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/util/mime_utils.js b/lib/util/mime_utils.js index b1392f12ab..5b933e344f 100644 --- a/lib/util/mime_utils.js +++ b/lib/util/mime_utils.js @@ -105,9 +105,9 @@ shaka.util.MimeUtils = class { */ static getNormalizedCodec(codecString) { const parts = - shaka.util.MimeUtils.getCodecParts_(codecString.toLowerCase()); + shaka.util.MimeUtils.getCodecParts_(codecString); const base = parts[0]; - const profile = parts[1]; + const profile = parts[1].toLowerCase(); switch (true) { case base === 'mp4a' && profile === '66': case base === 'mp4a' && profile === '67': From 13b1e9b7783a5bfed92b946b2d2c026a82eb79a6 Mon Sep 17 00:00:00 2001 From: Gaetan Hervouet Date: Wed, 11 May 2022 23:09:28 -0400 Subject: [PATCH 10/11] Group xhe_aac and aac. --- lib/util/mime_utils.js | 11 +++++------ test/util/mime_utils_unit.js | 3 +-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/util/mime_utils.js b/lib/util/mime_utils.js index 5b933e344f..ce5b9f8949 100644 --- a/lib/util/mime_utils.js +++ b/lib/util/mime_utils.js @@ -98,7 +98,7 @@ shaka.util.MimeUtils = class { /** * Get the normalized codec from a codec string, - * indendently of their container. + * independently of their container. * * @param {string} codecString * @return {string} @@ -109,21 +109,20 @@ shaka.util.MimeUtils = class { const base = parts[0]; const profile = parts[1].toLowerCase(); switch (true) { + case base === 'mp4a' && profile === '69': + case base === 'mp4a' && profile === '6b': + return 'mp3'; case base === 'mp4a' && profile === '66': case base === 'mp4a' && profile === '67': case base === 'mp4a' && profile === '68': return 'aac'; - case base === 'mp4a' && profile === '69': - case base === 'mp4a' && profile === '6b': - return 'mp3'; case base === 'mp4a' && profile === '40.2': case base === 'mp4a' && profile === '40.02': case base === 'mp4a' && profile === '40.5': case base === 'mp4a' && profile === '40.05': case base === 'mp4a' && profile === '40.29': + case base === 'mp4a' && profile === '40.42': // Extended HE-AAC return 'aac'; - case base === 'mp4a' && profile === '40.42': - return 'xhe_aac'; // Extended HE-AAC case base === 'mp4a' && profile === 'a5': return 'ac-3'; // Dolby Digital case base === 'mp4a' && profile === 'a6': diff --git a/test/util/mime_utils_unit.js b/test/util/mime_utils_unit.js index 61b7941189..0364314ac1 100644 --- a/test/util/mime_utils_unit.js +++ b/test/util/mime_utils_unit.js @@ -23,8 +23,7 @@ describe('MimeUtils', () => { expect(getNormalizedCodec('mp4a.40.5')).toBe('aac'); expect(getNormalizedCodec('mp4a.40.05')).toBe('aac'); expect(getNormalizedCodec('mp4a.40.29')).toBe('aac'); - - expect(getNormalizedCodec('mp4a.40.42')).toBe('xhe_aac'); + expect(getNormalizedCodec('mp4a.40.42')).toBe('aac'); expect(getNormalizedCodec('ac-3')).toBe('ac-3'); expect(getNormalizedCodec('mp4a.a5')).toBe('ac-3'); From c4f412e44da1010792e14cbf711fda79846528bd Mon Sep 17 00:00:00 2001 From: Gaetan Hervouet Date: Wed, 11 May 2022 23:11:55 -0400 Subject: [PATCH 11/11] Remove unnecessary return --- lib/util/mime_utils.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/util/mime_utils.js b/lib/util/mime_utils.js index ce5b9f8949..1e0cf992d5 100644 --- a/lib/util/mime_utils.js +++ b/lib/util/mime_utils.js @@ -115,7 +115,6 @@ shaka.util.MimeUtils = class { case base === 'mp4a' && profile === '66': case base === 'mp4a' && profile === '67': case base === 'mp4a' && profile === '68': - return 'aac'; case base === 'mp4a' && profile === '40.2': case base === 'mp4a' && profile === '40.02': case base === 'mp4a' && profile === '40.5':