From e40cdd0f9d8801bc8915c0b616ed540cb316d0b3 Mon Sep 17 00:00:00 2001 From: Michelle Zhuo Date: Mon, 28 Dec 2020 16:43:04 -0800 Subject: [PATCH] fix(StreamingEngine): clear lastInitSegmentReference when clearing buffer When toggling between two text streams quickly(for example en -> fr -> en), the mediaState's lastInitSegmentReference may not get updated to 'fr' before switching back to 'en'. That way, in initSourceBuffer_(), the initSegmentReference is considered as fetched and appended, but the buffer was in fact cleared. Setting lastInitSegmentReference to null every time we clear the buffer, and fetch and append the initSegmentReference with the new update. b/168253400 Change-Id: Id6378bdadd34f93a2a2f54ac84d82cf39b89716e --- lib/media/streaming_engine.js | 1 + test/media/streaming_engine_unit.js | 38 +++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/media/streaming_engine.js b/lib/media/streaming_engine.js index ae29d86b95..78933c95d3 100644 --- a/lib/media/streaming_engine.js +++ b/lib/media/streaming_engine.js @@ -1734,6 +1734,7 @@ shaka.media.StreamingEngine = class { mediaState.clearBufferSafeMargin = 0; mediaState.clearingBuffer = true; mediaState.lastSegmentReference = null; + mediaState.lastInitSegmentReference = null; mediaState.segmentIterator = null; shaka.log.debug(logPrefix, 'clearing buffer'); diff --git a/test/media/streaming_engine_unit.js b/test/media/streaming_engine_unit.js index a0ad8adefb..192bcf886e 100644 --- a/test/media/streaming_engine_unit.js +++ b/test/media/streaming_engine_unit.js @@ -897,9 +897,11 @@ describe('StreamingEngine', () => { }); }); manifest.addTextStream(20, (stream) => { + stream.setInitSegmentReference(['text-20-init'], 0, null); stream.useSegmentTemplate('text-20-%d.mp4', 10); }); manifest.addTextStream(21, (stream) => { + stream.setInitSegmentReference(['text-21-init'], 0, null); stream.useSegmentTemplate('text-21-%d.mp4', 10); }); }); @@ -987,10 +989,9 @@ describe('StreamingEngine', () => { }); // See https://github.com/google/shaka-player/issues/2956 - it('works with fast stream switches during update', async () => { + it('works with fast variant switches during update', async () => { // Delay the appendBuffer call until later so we are waiting for this to // finish when we switch. - const Util = shaka.test.Util; const p = new shaka.util.PublicPromise(); const old = mediaSourceEngine.appendBuffer; // Replace the whole spy since we want to call the original. @@ -1013,6 +1014,39 @@ describe('StreamingEngine', () => { expect(Util.invokeSpy(mediaSourceEngine.bufferEnd, 'video')).toBe(10); }); + + it('works with fast text stream switches during update', async () => { + // Delay the appendBuffer call until later so we are waiting for this to + // finish when we switch. + const p = new shaka.util.PublicPromise(); + + const old = mediaSourceEngine.appendBuffer; + // Replace the whole spy since we want to call the original. + mediaSourceEngine.appendBuffer = + jasmine.createSpy('appendBuffer') + .and.callFake(async (type, data, start, end) => { + await p; + return Util.invokeSpy(old, type, data, start, end); + }); + + await streamingEngine.start(); + playing = true; + + await Util.fakeEventLoop(3); + netEngine.request.calls.reset(); + + streamingEngine.switchTextStream(newTextStream); + streamingEngine.switchTextStream(initialTextStream); + p.resolve(); + + await Util.fakeEventLoop(5); + + const segmentType = shaka.net.NetworkingEngine.RequestType.SEGMENT; + // Quickly switching back to text1, and text init segment should be + // fetched again. + netEngine.expectRequest('text-20-init', segmentType); + netEngine.expectNoRequest('text-21-init', segmentType); + }); }); describe('handles seeks (VOD)', () => {