w3c / encrypted-media

Encrypted Media Extensions
https://w3c.github.io/encrypted-media/
Other
180 stars 80 forks source link

Revisit the requirement to continuously run the "Monitor for CDM State Changes" algorithm #499

Open xhwang-chromium opened 2 years ago

xhwang-chromium commented 2 years ago

Currently there is a Monitor for CDM State Changes algorithm in the spec.

In MediaKeySession, it says

The User Agent shall execute the Monitor for CDM Changes algorithm continuously for each MediaKeySession object that is not closed. The Monitor for CDM Changes algorithm must be run in parallel to the main event loop but not in parallel to other procedures defined in this specification that are also defined to be run in parallel.

This requirement ensures the CDM state changes are populated to the user agent promptly. However, it's causing some implementation complexity and the benefit might not worth the cost.

To implement this feature, the CDM must keep a loop separate from the main event loop. Even worse, when the CDM is idle, i.e. no license exchange or decryption is happening, the CDM must keep running this loop to check internal of device states periodically, e.g. to check the time against the expiration time, or to check the devices' HDCP state against the output protection requirements. This not only adds more complexity, but also prevents power optimizations like put a process/thread in sleep while not playing (e.g. paused video in a background tab).

One alternative is not to execute the Monitor for CDM Changes algorithm continuously for each MediaKeySession object that is not [closed]. Instead, it only execute the algorithm when something is happening in the CDM:

This way, the CDM (and the process/thread) can idle when there's no license exchange or decryption activities happening in the CDM, providing more freedom for optimization, and can potentially reduce the complexity of the CDM. The downside is that the CDM will not be able to report key status or expiration changes at real time, but that seems to be an acceptable tradeoff. When decryption is not happening, it's less interesting to know the key statuses or expiration.

xhwang-chromium commented 2 years ago

@joeyparrish @gregwfreedman What do you feel about this from the application's (player) perspective?

xhwang-chromium commented 2 years ago

@joeyparrish @gregwfreedman Kindly ping!

Maybe we can discuss about this in the next Media Working Group meeting.

chrisn commented 2 years ago

The next Media WG meeting is Tuesday August 9 at 16:00 UTC, happy to include this in the agenda.

gregwfreedman commented 2 years ago

I think it is preferable to maintain the ability for HDCP negotiation to complete and therefore key status updates to happen independent of decryption. Our player looks at key status in order to determine what resolution to fetch and append. A player shouldn't have to wait for media to be downloaded and appended only to find that it can't be played.

xhwang-chromium commented 2 years ago

HDCP status check is indeed critical for a good user experience. We have getStatusForPolicy() API designed specifically for it to solve that issue. In general, I understand the need to monitor key statuses in various stages of the CDM's lifetime, but would like to avoid the periodic timer when the CDM is idle. If we have other cases where we need to get key statuses update even when decryption is not happening, I feel we should follow the same model as getStatusForPolicy() API to provide an explicit query API, instead of asking the CDM to maintain a periodic timer.

gregwfreedman commented 2 years ago

Before an application has a license, getStatusForPolicy can be very helpful:

Once an application has a license, the keystatuseschange event:

I am much more concerned with monitoring for CDM Changes during the initial phase of the media pipeline until it's determined that the MediaKeyStatus is 'usable' (or not). After that, I'm less concerned about when the algorithm is run, especially on background tab that's not actively decrypting.

joeyparrish commented 1 year ago

TPAC 2022:

It seems that nobody is married to a periodic update timer, so long as updates happen when they are necessary and useful to the application. Let's attempt to define here what events should trigger key status updates, and update the spec to specify those triggers, rather than a periodic updater timer.

Possible triggers discussed in TPAC:

@xhwang-chromium, @gregwfreedman, please comment if I've missed or misunderstood anything from the conversation.

Some investigation is needed to understand if display output changes are feasible as a trigger across implementations.

xhwang-chromium commented 1 year ago

I asked and on Windows OS there's no way to subscribe to HDCP changes. So the only way to "monitor" HDCP changes is by polling periodically.

So I'd like to exclude "display output changes" from the list of "possible triggers". The rest of the list looks fine:

For HDCP changes, since we already have getStatusForPolicy(), the JS application can always query it when needed.