-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[eme] clearkey-mp4-playback-temporary-multikey-sequential-readyState.html playing count fix #3985
[eme] clearkey-mp4-playback-temporary-multikey-sequential-readyState.html playing count fix #3985
Conversation
Update from master
We should get two "playing" events in this test; one when we first play the media encrypted with the first key, and then once we hit waiting for the second key we should drop back to readyState HAVE_METADATA, and once we receive the second key and play the second segment again, the readyState will raise above HAVE_FUTURE_DATA or more and we should fire another "playing" event. See: https://dev.w3.org/html5/spec-preview/media-elements.html#ready-states
Reviewers for this pull request are: @ddorwin. |
key, or if we are waiting for a key but the readyState is HAVE_METADATA. The "Waiting for key" algorithm says to change the readyState to HAVE_METADATA. The HTMLMediaElement.readyState spec says "If the previous ready state was HAVE_FUTURE_DATA or more, and the new ready state is HAVE_CURRENT_DATA or less" we should dispatch a "timeupdate" event. So this test can't assert that we don't get a timeupdate event while we're waiting for a key, as we're supposed to. So just assert that we should only get a timeupdate while waiting for a key if we're already in HAVE_METADATA, so that we test that we've transitioned.
I believe the text @cpearce is referring to is the following from https://html.spec.whatwg.org/multipage/embedded-content.html#ready-states:
Should we also have checks for the first step ( |
@@ -62,11 +63,12 @@ function runTest(config,qualifier) { | |||
} | |||
|
|||
function onPlaying(event) { | |||
assert_equals(_mediaKeySessions.length, 1, "Playback should start with a single key / session"); | |||
_playingCount++; | |||
assert_equals(_mediaKeySessions.length, _playingCount, "Should get one 'playing' event per key / session played"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also check that _playingCount is <= 2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Done.
} | ||
|
||
function onTimeupdate(event) { | ||
assert_false(_waitingForKey, "Should not continue playing whilst waiting for a key"); | ||
assert_true(!_waitingForKey || _video.readyState == _video.HAVE_METADATA, "Should not continue playing whilst waiting for a key"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe explain why we should get a timeupdate
when _video.readyState == _video.HAVE_METADATA
. Is this at the beginning or on the transition due to waiting for a key?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we're required to fire 'timeupdate' when we transition from readyState HAVE_FUTURE_DATA or more to HAVE_CURRENT_DATA or less. I've added a comment.
@cpearce : Can you let us know if you are okay with David's comments? |
@paulbrucecotton In principle, yes I agree with those comments, but I'm not sure what readyState behaviour we're targeting until w3c/encrypted-media#336, w3c/encrypted-media#338, and w3c/encrypted-media#339 are resolved. And this test is testing readyState behaviour. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Looks good except I have questions about one of the asserts.
assert_false(_waitingForKey, "Should not continue playing whilst waiting for a key"); | ||
// We should not receive 'timeupdate' events due to playing while waiting for a key, except | ||
// when we first start waiting for key we should change the readyState to HAVE_METADATA | ||
// which will trigger the "If the previous ready state was HAVE_FUTURE_DATA or more, and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to update this once w3c/encrypted-media#338 is fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
// when we first start waiting for key we should change the readyState to HAVE_METADATA | ||
// which will trigger the "If the previous ready state was HAVE_FUTURE_DATA or more, and | ||
// the new ready state is HAVE_CURRENT_DATA or less" case of the readyState change | ||
// algorithm which requires a "timeupdate" event be fired. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you only want to see timeupdate once in that case?
It seems that the current logic is likely to always be true even if we get many timeupdate events while waiting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the test to count the number of timeupdates we get while waiting, and assert that we only get one. I've not been able to get the test to pass in Firefox yet.
@ddorwin please re-review. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works, but I'd like to see the comments addressed. Feel free to get someone else to merge once you are satisfied.
_waitingForKey = false, | ||
_playingCount = 0, | ||
_canplayCount = 0, | ||
_timeupdateWhileWaiting = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...Count
?
@@ -66,11 +69,27 @@ function runTest(config,qualifier) { | |||
} | |||
|
|||
function onPlaying(event) { | |||
assert_equals(_mediaKeySessions.length, 1, "Playback should start with a single key / session"); | |||
_playingCount++; | |||
assert_equals(_mediaKeySessions.length, _playingCount, "Should get one 'playing' event per key / session played"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/played/added/ ?
|
||
function onCanPlay(event) { | ||
_canplayCount++; | ||
assert_equals(_mediaKeySessions.length, _canplayCount, "Should get one 'canplay' event per key / session played"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto: s/played/added/ ?
// the new ready state is HAVE_CURRENT_DATA or less" case of the readyState change | ||
// algorithm which requires a "timeupdate" event be fired. | ||
if (_waitingForKey) { | ||
assert_equals(++_timeupdateWhileWaiting, 1, "Should only receive one timeupdate while waiting for key"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before calling test.done(), we should assert_equals(_timeupdateWhileWaiting, 1) to ensure we did get that one instance. Currently, it's possible to get 0 and pass.
// algorithm which requires a "timeupdate" event be fired. | ||
if (_waitingForKey) { | ||
assert_equals(++_timeupdateWhileWaiting, 1, "Should only receive one timeupdate while waiting for key"); | ||
assert_equals(_video.readyState, _video.HAVE_CURRENT_DATA, "Should not continue playing whilst waiting for a key"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this assert really have the meaning in the string? It seems that the logic above and expecting no more than one accomplishes that now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be clear, are you suggesting I remove the assert or change the string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change the string. This is a little duplication of the other similar assert, but checking that it hasn't changed is not a bad thing.
Review comments addressed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. LGTM. One string could be clearer.
} | ||
|
||
if (_video.currentTime > config.duration) { | ||
assert_equals(_mediaKeySessions.length, config.initData.length, "It should require all keys to reach end of content"); | ||
assert_equals(_timeupdateWhileWaitingCount, 1, "Should have only received one timeupdate while waiting for key"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: ... received exactly one...
The check on line 90 checks no more than one. This checks that we did get that one.
@cpearce, are you able to squash and merge? I was going to, but it's not clear what the commit message should be since there are many commits and it's not clear that the main ones are still accurate. If you have permission to merge, please do so with the commit message you want. Otherwise, post it here and I'll merge. |
I do not have write access, so I cannot perform a squash merge to master. |
What do you want the commit message to be? |
"Ensure we receivethe expected number of canplay, playing and timeupdate events, and have the correct readyState, when playback waits for a key." |
Fix clearkey-mp4-playback-temporary-multikey-sequential-readyState.html so that it expects two "playing" events, as the specification calls for firing "playing" every time the readyState was HAVE_CURRENT_DATA or less and the new ready state is HAVE_FUTURE_DATA. The waiting for key algorithm requires us to drop the readyState to HAVE_METADATA, so we should expect to fire two "playing" events.
I have patches for Firefox in the works to make us pass this test with this fix.