diff --git a/karma.conf.js b/karma.conf.js index 3206cb2111..cd044c6af0 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -261,6 +261,8 @@ module.exports = (config) => { {pattern: 'test/test/assets/dash-aes-128/*', included: false}, {pattern: 'test/test/assets/dash-clearkey/*', included: false}, {pattern: 'test/test/assets/dash-vr/*', included: false}, + {pattern: 'test/test/assets/dv-p8-hevc/*', included: false}, + {pattern: 'test/test/assets/dv-p10-av1/*', included: false}, {pattern: 'test/test/assets/hls-aes-256/*', included: false}, {pattern: 'test/test/assets/hls-interstitial/*', included: false}, {pattern: 'test/test/assets/hls-raw-aac/*', included: false}, diff --git a/test/player_dolby_vision_integration.js b/test/player_dolby_vision_integration.js new file mode 100644 index 0000000000..133a5f3b9d --- /dev/null +++ b/test/player_dolby_vision_integration.js @@ -0,0 +1,135 @@ +/*! @license + * Shaka Player + * Copyright 2016 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +describe('Player Dolby Vision', () => { + const Util = shaka.test.Util; + + /** @type {!jasmine.Spy} */ + let onErrorSpy; + + /** @type {!HTMLVideoElement} */ + let video; + /** @type {shaka.Player} */ + let player; + /** @type {!shaka.util.EventManager} */ + let eventManager; + + let compiledShaka; + + /** @type {!shaka.test.Waiter} */ + let waiter; + + beforeAll(async () => { + video = shaka.test.UiUtils.createVideoElement(); + document.body.appendChild(video); + compiledShaka = + await shaka.test.Loader.loadShaka(getClientArg('uncompiled')); + }); + + beforeEach(async () => { + await shaka.test.TestScheme.createManifests(compiledShaka, '_compiled'); + player = new compiledShaka.Player(); + await player.attach(video); + + player.configure('streaming.useNativeHlsOnSafari', false); + + // Disable stall detection, which can interfere with playback tests. + player.configure('streaming.stallEnabled', false); + + // Grab event manager from the uncompiled library: + eventManager = new shaka.util.EventManager(); + waiter = new shaka.test.Waiter(eventManager); + waiter.setPlayer(player); + + onErrorSpy = jasmine.createSpy('onError'); + onErrorSpy.and.callFake((event) => fail(event.detail)); + eventManager.listen(player, 'error', Util.spyFunc(onErrorSpy)); + }); + + afterEach(async () => { + eventManager.release(); + await player.destroy(); + }); + + afterAll(() => { + document.body.removeChild(video); + }); + + /** + * @param {string} uri + * @return {!Promise} + */ + async function testPlayback(uri) { + await player.load(uri); + await video.play(); + expect(player.isLive()).toBe(false); + + // Wait for the video to start playback. If it takes longer than 10 + // seconds, fail the test. + await waiter.waitForMovementOrFailOnTimeout(video, 10); + + // Play for 2 seconds, but stop early if the video ends. If it takes + // longer than 10 seconds, fail the test. + await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 2, 10); + + await player.unload(); + } + + describe('P8 with fallback to HEVC', () => { + it('with DASH', async () => { + if (!await Util.isTypeSupported('video/mp4; codecs="hvc1.2.4.L90.90"', + /* width= */ 640, /* height= */ 360)) { + pending('Codec HEVC is not supported by the platform.'); + } + await testPlayback('/base/test/test/assets/dv-p8-hevc/manifest.mpd'); + }); + + it('with master playlist (HLS)', async () => { + if (!await Util.isTypeSupported('video/mp4; codecs="hvc1.2.4.L90.90"', + /* width= */ 640, /* height= */ 360)) { + pending('Codec HEVC is not supported by the platform.'); + } + await testPlayback('/base/test/test/assets/dv-p8-hevc/master.m3u8'); + }); + + it('with media playlist (HLS)', async () => { + if (!await Util.isTypeSupported('video/mp4; codecs="hvc1.2.4.L90.90"', + /* width= */ 640, /* height= */ 360)) { + pending('Codec HEVC is not supported by the platform.'); + } + await testPlayback('/base/test/test/assets/dv-p8-hevc/media.m3u8'); + }); + }); + + describe('P10 with fallback to AV1', () => { + it('with DASH', async () => { + if (!await Util.isTypeSupported( + 'video/mp4; codecs="av01.0.04M.10.0.111.09.16.09.0"', + /* width= */ 640, /* height= */ 360)) { + pending('Codec AV1 is not supported by the platform.'); + } + await testPlayback('/base/test/test/assets/dv-p10-av1/manifest.mpd'); + }); + + it('with master playlist (HLS)', async () => { + if (!await Util.isTypeSupported( + 'video/mp4; codecs="av01.0.04M.10.0.111.09.16.09.0"', + /* width= */ 640, /* height= */ 360)) { + pending('Codec AV1 is not supported by the platform.'); + } + await testPlayback('/base/test/test/assets/dv-p10-av1/master.m3u8'); + }); + + it('with media playlist (HLS)', async () => { + if (!await Util.isTypeSupported( + 'video/mp4; codecs="av01.0.04M.10.0.111.09.16.09.0"', + /* width= */ 640, /* height= */ 360)) { + pending('Codec AV1 is not supported by the platform.'); + } + await testPlayback('/base/test/test/assets/dv-p10-av1/media.m3u8'); + }); + }); +}); diff --git a/test/test/assets/dv-p10-av1/dovi_10-video.mp4 b/test/test/assets/dv-p10-av1/dovi_10-video.mp4 new file mode 100644 index 0000000000..b4cd29e4ab Binary files /dev/null and b/test/test/assets/dv-p10-av1/dovi_10-video.mp4 differ diff --git a/test/test/assets/dv-p10-av1/manifest.mpd b/test/test/assets/dv-p10-av1/manifest.mpd new file mode 100644 index 0000000000..af3bf4d2cf --- /dev/null +++ b/test/test/assets/dv-p10-av1/manifest.mpd @@ -0,0 +1,16 @@ + + + + + + + + + dovi_10-video.mp4 + + + + + + + diff --git a/test/test/assets/dv-p10-av1/master.m3u8 b/test/test/assets/dv-p10-av1/master.m3u8 new file mode 100644 index 0000000000..89a13b201e --- /dev/null +++ b/test/test/assets/dv-p10-av1/master.m3u8 @@ -0,0 +1,5 @@ +#EXTM3U +#EXT-X-INDEPENDENT-SEGMENTS + +#EXT-X-STREAM-INF:BANDWIDTH=550702,AVERAGE-BANDWIDTH=577484,CODECS="av01.0.04M.10.0.111.09.16.09.0",SUPPLEMENTAL-CODECS="dav1.10.01/db1p",RESOLUTION=640x360,FRAME-RATE=59.940,VIDEO-RANGE=PQ,CLOSED-CAPTIONS=NONE +media.m3u8 diff --git a/test/test/assets/dv-p10-av1/media.m3u8 b/test/test/assets/dv-p10-av1/media.m3u8 new file mode 100644 index 0000000000..41cb50aa7b --- /dev/null +++ b/test/test/assets/dv-p10-av1/media.m3u8 @@ -0,0 +1,12 @@ +#EXTM3U +#EXT-X-VERSION:6 +#EXT-X-TARGETDURATION:6 +#EXT-X-PLAYLIST-TYPE:VOD +#EXT-X-MAP:URI="dovi_10-video.mp4",BYTERANGE="871@0" +#EXTINF:5.355, +#EXT-X-BYTERANGE:368650@927 +dovi_10-video.mp4 +#EXTINF:0.667, +#EXT-X-BYTERANGE:66100 +dovi_10-video.mp4 +#EXT-X-ENDLIST diff --git a/test/test/assets/dv-p8-hevc/dovi_8-video.mp4 b/test/test/assets/dv-p8-hevc/dovi_8-video.mp4 new file mode 100644 index 0000000000..ce05290a78 Binary files /dev/null and b/test/test/assets/dv-p8-hevc/dovi_8-video.mp4 differ diff --git a/test/test/assets/dv-p8-hevc/manifest.mpd b/test/test/assets/dv-p8-hevc/manifest.mpd new file mode 100644 index 0000000000..806669a506 --- /dev/null +++ b/test/test/assets/dv-p8-hevc/manifest.mpd @@ -0,0 +1,16 @@ + + + + + + + + + dovi_8-video.mp4 + + + + + + + diff --git a/test/test/assets/dv-p8-hevc/master.m3u8 b/test/test/assets/dv-p8-hevc/master.m3u8 new file mode 100644 index 0000000000..95424cb2c2 --- /dev/null +++ b/test/test/assets/dv-p8-hevc/master.m3u8 @@ -0,0 +1,5 @@ +#EXTM3U +#EXT-X-INDEPENDENT-SEGMENTS + +#EXT-X-STREAM-INF:BANDWIDTH=807837,AVERAGE-BANDWIDTH=748074,CODECS="hvc1.2.4.L90.90",SUPPLEMENTAL-CODECS="dvh1.08.01/db2g",RESOLUTION=640x360,FRAME-RATE=59.940,VIDEO-RANGE=PQ,CLOSED-CAPTIONS=NONE +media.m3u8 diff --git a/test/test/assets/dv-p8-hevc/media.m3u8 b/test/test/assets/dv-p8-hevc/media.m3u8 new file mode 100644 index 0000000000..a38025e649 --- /dev/null +++ b/test/test/assets/dv-p8-hevc/media.m3u8 @@ -0,0 +1,18 @@ +#EXTM3U +#EXT-X-VERSION:6 +#EXT-X-TARGETDURATION:3 +#EXT-X-PLAYLIST-TYPE:VOD +#EXT-X-MAP:URI="dovi_8-video.mp4",BYTERANGE="992@0" +#EXTINF:2.002, +#EXT-X-BYTERANGE:172013@1072 +dovi_8-video.mp4 +#EXTINF:2.002, +#EXT-X-BYTERANGE:186781 +dovi_8-video.mp4 +#EXTINF:2.002, +#EXT-X-BYTERANGE:202161 +dovi_8-video.mp4 +#EXTINF:0.017, +#EXT-X-BYTERANGE:2221 +dovi_8-video.mp4 +#EXT-X-ENDLIST