Skip to content
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

Merged
merged 12 commits into from
Oct 26, 2016

Conversation

cpearce
Copy link
Contributor

@cpearce cpearce commented Oct 17, 2016

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.

cpearce and others added 2 commits October 16, 2016 15:33
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
@wpt-pr-bot
Copy link
Collaborator

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.
@ddorwin
Copy link
Contributor

ddorwin commented Oct 17, 2016

I believe the text @cpearce is referring to is the following from https://html.spec.whatwg.org/multipage/embedded-content.html#ready-states:

If the previous ready state was HAVE_CURRENT_DATA or less, and the new ready state is HAVE_FUTURE_DATA
  The user agent must queue a task to fire a simple event named canplay at the element.
  If the element's paused attribute is false, the user agent must notify about playing for the element.

Should we also have checks for the first step (canplay)?

@@ -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");
Copy link
Contributor

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?

Copy link
Contributor Author

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");
Copy link
Contributor

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?

Copy link
Contributor Author

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.

@paulbrucecotton
Copy link

@cpearce : Can you let us know if you are okay with David's comments?

@cpearce
Copy link
Contributor Author

cpearce commented Oct 19, 2016

@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.

@ddorwin ddorwin changed the title clearkey-mp4-playback-temporary-multikey-sequential-readyState.html playing count fix [eme] clearkey-mp4-playback-temporary-multikey-sequential-readyState.html playing count fix Oct 19, 2016
Copy link
Contributor

@ddorwin ddorwin left a 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
Copy link
Contributor

@ddorwin ddorwin Oct 20, 2016

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.

Copy link
Contributor Author

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.
Copy link
Contributor

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.

Copy link
Contributor Author

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.

@cpearce
Copy link
Contributor Author

cpearce commented Oct 25, 2016

@ddorwin please re-review. Thanks!

Copy link
Contributor

@ddorwin ddorwin left a 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;
Copy link
Contributor

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");
Copy link
Contributor

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");
Copy link
Contributor

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");
Copy link
Contributor

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");
Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Contributor

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.

@cpearce
Copy link
Contributor Author

cpearce commented Oct 26, 2016

Review comments addressed.

Copy link
Contributor

@ddorwin ddorwin left a 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");
Copy link
Contributor

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.

@ddorwin
Copy link
Contributor

ddorwin commented Oct 26, 2016

@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.

@cpearce
Copy link
Contributor Author

cpearce commented Oct 26, 2016

I do not have write access, so I cannot perform a squash merge to master.

@ddorwin
Copy link
Contributor

ddorwin commented Oct 26, 2016

What do you want the commit message to be?

@cpearce
Copy link
Contributor Author

cpearce commented Oct 26, 2016

"Ensure we receivethe expected number of canplay, playing and timeupdate events, and have the correct readyState, when playback waits for a key."

@ddorwin ddorwin merged commit 7fb01a2 into web-platform-tests:master Oct 26, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants