shaka-player icon indicating copy to clipboard operation
shaka-player copied to clipboard

Auto-selection of hardware vs software DRM

Open wjywbs opened this issue 2 years ago • 15 comments

Have you read the FAQ and checked for duplicate open issues? Yes

Is your feature request related to a problem? Please describe. No

Describe the solution you'd like Support hardware secure CDM playback in Chrome for Windows with documentation.

Describe alternatives you've considered Whether Chrome can support PlayReady like Edge with "hardware secure CDM".

Additional context In Chrome 99, enabling "Hardware Secure Decryption" in chrome://flags will show "Google Widevine Windows CDM" in chrome://components. Does shaka player support this CDM?

flags

components

wjywbs avatar Mar 06 '22 18:03 wjywbs

👋 There are no reasons Shaka shouldn't support L1 implementation of Widevine (already does on Android w/ Chrome)

valotvince avatar Mar 07 '22 09:03 valotvince

I believe that once enabled, L1 support on Windows is triggered in software by setting robustness to HW_SECURE_ALL. @xhwang-chromium, can you confirm? To trigger the L1 implementation where possible, should this be set for both audio and video, or just video?

joeyparrish avatar Mar 07 '22 23:03 joeyparrish

We recommend to set video to be HW_SECURE_ALL and audio to be HW_SECURE_CRYPTO. But the L1 path will be selected when either is set.

xhwang-chromium avatar Mar 08 '22 17:03 xhwang-chromium

Is there an api in shaka player to detect whether the CDM supports HW or SW? Or can shaka try HW first and fallback to SW? Thanks.

wjywbs avatar Mar 09 '22 14:03 wjywbs

You could use this to detect what is the maximum level that is supported.

async function getWidevineRobustness () {
  const robustnessLevels = [
    'SW_SECURE_CRYPTO', // Widevine L3
    'SW_SECURE_DECODE', // Widevine L3
    'HW_SECURE_CRYPTO', // Widevine L2
    'HW_SECURE_DECODE', // Widevine L1
    'HW_SECURE_ALL', // Widevine L1
  ];

  const videoTestConfig = [
    {
      videoCapabilities: [
        {
          contentType: 'video/mp4; codecs="avc1.42E01E"',
          robustness: 'SW_SECURE_DECODE',
        },
      ],
    },
  ];

  const audioTestConfig = [
    {
      audioCapabilities: [
        {
          contentType: 'audio/mp4;codecs="mp4a.40.2"',
          robustness: 'SW_SECURE_DECODE',
        },
      ],
    },
  ];

  let videoRobustness;
  let audioRobustness;

  for (let i = 0; i < robustnessLevels.length; i++) {
    const level = robustnessLevels[i];
    videoTestConfig[0].videoCapabilities[0].robustness = level;
    try {
      // eslint-disable-next-line no-await-in-loop
      await navigator.requestMediaKeySystemAccess('com.widevine.alpha', videoTestConfig);
      videoRobustness = level;
    } catch (err) {}
  }

  for (let j = 0; j < robustnessLevels.length; j++) {
    const level = robustnessLevels[j];
    audioTestConfig[0].audioCapabilities[0].robustness = level;
    try {
      // eslint-disable-next-line no-await-in-loop
      await navigator.requestMediaKeySystemAccess('com.widevine.alpha', audioTestConfig);
      audioRobustness = level;
    } catch (err) {}
  }

  return {
    videoRobustness: videoRobustness,
    audioRobustness: audioRobustness,
  }
}

avelad avatar Apr 27 '22 06:04 avelad

@xhwang-chromium or if anybody else knows, can you please comment on what are the system requirements for Widevine to leverage L1 on Windows?

I assume some form of Trusted Execution Environment is required, so only selected processors are suitable. Can you confirm?

Does operating system version itself play a role in this? Is presence of Trusted Platform Module (TPM) required as well?

BucherTomas avatar Apr 28 '22 07:04 BucherTomas

As mentioned above Shaka supports hardware DRM, just through DRM configuration. There is no automatic selection of hardware vs software CDM, though. If not specified by the app, the default is up to the browser/platform.

Shaka could offer something in the future where we will automatically try HW first, then fall back to SW. I'll rename the issue to reflect this.

But before doing any work on this, we would need @xhwang-chromium to confirm is this is even necessary. If no robustness is specified, will Chrome choose the L1 CDM by default if available, and L3 otherwise? Or would L3 always be used by default?

joeyparrish avatar May 05 '22 20:05 joeyparrish

Re https://github.com/shaka-project/shaka-player/issues/4013#issuecomment-1110579710. For Chrome browser we only support 'SW_SECURE_CRYPTO' (on Android), 'SW_SECURE_DECODE' and 'HW_SECURE_ALL'. So querying for the following would be sufficient. Also, if L1 is preferred, it should be queried first, e.g.

  const robustnessLevels = [
    'HW_SECURE_ALL', // Widevine L1
    'SW_SECURE_DECODE', // Widevine L3
    'SW_SECURE_CRYPTO', // Widevine L3
  ]

Re https://github.com/shaka-project/shaka-player/issues/4013#issuecomment-1118998669. In short, for Widevine in Chrome, if no robustness is specified, we'll default to the lowest robustness, e.g. Widevine L3. This behavior is subject to change at any time so don't rely on it.

Here's our general recommendation on this topic:

Avoid Empty Robustness

What does the spec say?

http://w3c.github.io/encrypted-media/#idl-def-mediakeysystemmediacapability, emphasis added

Implementations MUST configure the CDM to support at least the robustness levels specified in the configuration of the MediaKeySystemAccess object used to create the MediaKeys object. Exact configuration of the CDM is implementation-specific, and implementations MAY configure the CDM to use the highest robustness level in the configuration even if a higher robustness level is available. If only the empty string is specified, implementations MAY be configured to use the lowest robustness level the implementation supports.

Applications SHOULD specify the robustness level(s) they require to avoid unexpected client incompatibilities.

What does Chrome do for empty robustness?

Chrome’s behavior is platform-dependent and is subject to change in the future. You may end up with the lowest level even though higher levels are available.

When an empty robustness is used, Chrome will show a warning message in the dev console.

It is recommended that a robustness level be specified. Not specifying the robustness level could result in unexpected behavior, potentially including failure to play.

What should applications do?

Always specify the robustness level(s) required (by the license server) and/or that would affect the streams selected. The application could specify multiple MediaKeySystemMediaCapability values with different robustness levels and make decisions based on which one is supported.

xhwang-chromium avatar May 06 '22 02:05 xhwang-chromium

I enabled "Google Widevine Windows CDM" in Chrome Beta 102. When video robustness is SW_SECURE_DECODE and audio robustness is SW_SECURE_CRYPTO, it seems like this L1 CDM is still selected, instead of the L3 "Widevine Content Decryption Module". Widevine proxy generates EXTERNAL_LICENSE_ERROR with message "Missing ContentId within Pssh data for ExternalLicenseRequest". When the L1 CDM is disabled, the L3 CDM can play the content. The test content uses custom encryption keys and the keys are sent to the widevine proxy. However, test content with contend id in pssh and widevine keys (https://storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd) can play when L1 CDM is enabled.

wjywbs avatar May 18 '22 12:05 wjywbs

Do you have a repro page I can look at? Thanks!

xhwang-chromium avatar May 18 '22 15:05 xhwang-chromium

Also, which codec did you query for?

xhwang-chromium avatar May 18 '22 15:05 xhwang-chromium

Please try this repro:

https://shaka-player-demo.appspot.com/demo/#audiolang=en-US;textlang=en-US;uilang=en-US;panel=CUSTOM%20CONTENT;build=compiled

Manifest url: https://personal-data-2018.s3.amazonaws.com/bbb/b5.mpd

DRM custom license server url: https://widevine-proxy.appspot.com/proxy

Shaka reports error code 6007 when L1 CDM (Hardware Secure Decryption flag) is enabled. Widevine proxy error message is EXTERNAL_LICENSE_ERROR "Challenge type cannot be Unknown"

Codec: avc1.640029,mp4a.40.2

wjywbs avatar May 18 '22 16:05 wjywbs

It's querying for HEVC w empty robustness (which will be defaulted to SW_* levels).

I think I know how this happened. I'll file a Chromium bug and fix it.

Again, it's always recommended not to have any empty robustness when querying Widevine capabilities.

xhwang-chromium avatar May 18 '22 20:05 xhwang-chromium

@xhwang-chromium can you paste the link to the Chromium bug? Thanks!

avelad avatar May 19 '22 06:05 avelad

Fix is here. The CL description has all the info. https://chromium-review.googlesource.com/c/chromium/src/+/3654750

xhwang-chromium avatar May 19 '22 07:05 xhwang-chromium

Closing due to inactivity. If this is still an issue for you or if you have further questions, the OP can ask shaka-bot to reopen it by including @shaka-bot reopen in a comment.

github-actions[bot] avatar Dec 01 '22 12:12 github-actions[bot]