From 06e520971307b41e2f2a0317a35d125bd9483263 Mon Sep 17 00:00:00 2001 From: Chris Cunningham Date: Mon, 23 Nov 2020 15:55:35 -0800 Subject: [PATCH] [WebCodecs] Actually suppress late decoder outputs Forgot to do this as part of the earlier change: https://chromium-review.googlesource.com/c/chromium/src/+/2541646 Made the test a little more interesting with hopes of catching this sort of bug. Bug: 1121340 Change-Id: Id5a23f8fe2c4e052c61f70bbed8778048adc5cee Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2556001 Reviewed-by: Eugene Zemtsov Commit-Queue: Eugene Zemtsov Commit-Queue: Chrome Cunningham Auto-Submit: Chrome Cunningham Cr-Commit-Position: refs/heads/master@{#830355} --- webcodecs/video-decoder.any.js | 47 +++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/webcodecs/video-decoder.any.js b/webcodecs/video-decoder.any.js index e667a5642e76a6..2dd85ad955b732 100644 --- a/webcodecs/video-decoder.any.js +++ b/webcodecs/video-decoder.any.js @@ -113,10 +113,18 @@ promise_test(async t => { promise_test(async t => { let buffer = await vp9.buffer(); + let outputs_before_reset = 0; + let outputs_after_reset = 0; + let decoder = new VideoDecoder({ + // Pre-reset() chunks will all have timestamp=0, while post-reset() chunks + // will all have timestamp=1. output(frame) { t.step(() => { - assert_unreached("reset() should prevent this output from arriving"); + if (frame.timestamp == 0) + outputs_before_reset++; + else + outputs_after_reset++; }); }, error(e) { @@ -126,19 +134,40 @@ promise_test(async t => { decoder.configure({codec: vp9.codec}); - decoder.decode(new EncodedVideoChunk({ - type:'key', - timestamp:0, - data: view(buffer, vp9.frames[0]) - })); + for (let i = 0; i < 100; i++) { + decoder.decode(new EncodedVideoChunk({ + type:'key', + timestamp:0, + data: view(buffer, vp9.frames[0]) + })); + } - let flushPromise = decoder.flush(); + assert_greater_than(decoder.decodeQueueSize, 0); - decoder.reset() + // Wait for the first frame to be decoded. + await t.step_wait(() => outputs_before_reset > 0, + "Decoded outputs started coming", 10000, 1); + + let saved_outputs_before_reset = outputs_before_reset; + assert_greater_than(saved_outputs_before_reset, 0); + assert_less_than(saved_outputs_before_reset, 100); + decoder.reset() assert_equals(decoder.decodeQueueSize, 0); - await promise_rejects_exactly(t, undefined, flushPromise); + decoder.configure({codec: vp9.codec}); + + for (let i = 0; i < 5; i++) { + decoder.decode(new EncodedVideoChunk({ + type:'key', + timestamp:1, + data: view(buffer, vp9.frames[0]) + })); + } + await decoder.flush(); + assert_equals(outputs_after_reset, 5); + assert_equals(saved_outputs_before_reset, outputs_before_reset); + assert_equals(decoder.decodeQueueSize, 0); endAfterEventLoopTurn(); }, 'Verify reset() suppresses output and rejects flush');