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

Problem adapting between SD and HD Widevine content #968

Closed
baseballbrad3 opened this issue Nov 18, 2015 · 5 comments
Closed

Problem adapting between SD and HD Widevine content #968

baseballbrad3 opened this issue Nov 18, 2015 · 5 comments
Labels

Comments

@baseballbrad3
Copy link

baseballbrad3 commented Nov 18, 2015

I have some DASH content that is Widevine protected. It's throwing an exception (android.media.MediaCodec$CryptoException with a full stack trace below) on adaption to a track that is protected with an HD key from a track that is protected with an SD key. Adaption between bitrates of the same resolution work fine. The same MPD behaves fine when using Shaka on Chrome browsers (both desktop and Android) which leads me to believe that this is an ExoPlayer issue (or how I'm using ExoPlayer).

From what I can tell, on adaption from SD -> HD, Shaka is making a new license request for the HD track as soon as the first chunk of the HD track is done downloading. Then it's good to go and doesn't need to make a new license request when going from HD -> SD as it had the SD license from initial playback. Unless I'm missing it, it doesn't look like the provided ExoPlayer implementations handle this behavior.

I tested a sample MPD from the ExoPlayer demo app (titled "WV: HDCP not specified") in my own implementation and it worked fine. It adapted back and forth from SD resolutions to HD resolutions. But it only made two license requests: one for the audio and one for the initial video (which I confirmed by removing the audioRenderer and it only made the one license request for video). Is this likely to have worked because the tracks contained in the sample MPD were only protected with an SD or an HD key?

Just some notes about my environment, all the content is on demand (not live), we're not using key rotation, and we've tested on Nexus Player (Android 6.0), Nexus 5X (Android 6.0), Galaxy Tab A (Android 5.0.2), all of which I believe are Widevine level 1.

Stack trace for exception

Internal track renderer error.
com.google.android.exoplayer.ExoPlaybackException: android.media.MediaCodec$CryptoException: Error decrypting data: requested key has not been loaded
    at com.google.android.exoplayer.MediaCodecTrackRenderer.feedInputBuffer(MediaCodecTrackRenderer.java:653)
    at com.google.android.exoplayer.MediaCodecTrackRenderer.doSomeWork(MediaCodecTrackRenderer.java:460)
    at com.google.android.exoplayer.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:431)
    at com.google.android.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:213)
    at android.os.Handler.dispatchMessage(Handler.java:98)
    at android.os.Looper.loop(Looper.java:148)
    at android.os.HandlerThread.run(HandlerThread.java:61)
    at com.google.android.exoplayer.util.PriorityHandlerThread.run(PriorityHandlerThread.java:40)
 Caused by: android.media.MediaCodec$CryptoException: Error decrypting data: requested key has not been loaded
    at android.media.MediaCodec.native_queueSecureInputBuffer(Native Method)
    at android.media.MediaCodec.queueSecureInputBuffer(MediaCodec.java:2292)
    at com.google.android.exoplayer.MediaCodecTrackRenderer.feedInputBuffer(MediaCodecTrackRenderer.java:644)
    at com.google.android.exoplayer.MediaCodecTrackRenderer.doSomeWork(MediaCodecTrackRenderer.java:460) 
    at com.google.android.exoplayer.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:431) 
    at com.google.android.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:213) 
    at android.os.Handler.dispatchMessage(Handler.java:98) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.os.HandlerThread.run(HandlerThread.java:61) 
    at com.google.android.exoplayer.util.PriorityHandlerThread.run(PriorityHandlerThread.java:40) 
onCryptoError
android.media.MediaCodec$CryptoException: Error decrypting data: requested key has not been loaded
    at android.media.MediaCodec.native_queueSecureInputBuffer(Native Method)
    at android.media.MediaCodec.queueSecureInputBuffer(MediaCodec.java:2292)
    at com.google.android.exoplayer.MediaCodecTrackRenderer.feedInputBuffer(MediaCodecTrackRenderer.java:644)
    at com.google.android.exoplayer.MediaCodecTrackRenderer.doSomeWork(MediaCodecTrackRenderer.java:460)
    at com.google.android.exoplayer.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:431)
    at com.google.android.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:213)
    at android.os.Handler.dispatchMessage(Handler.java:98)
    at android.os.Looper.loop(Looper.java:148)
    at android.os.HandlerThread.run(HandlerThread.java:61)
    at com.google.android.exoplayer.util.PriorityHandlerThread.run(PriorityHandlerThread.java:40)
@ojw28
Copy link
Contributor

ojw28 commented Nov 18, 2015

Widevine license requests include a content id (which is independent to the stream from which the data used to generate the request was obtained). The license server is expected to return all keys to which the user is entitled for the content id.

So regardless of which stream is used to make the initial license request, the license response should contain both HD and SD keys (assuming the user is is entitled to play both). Hence subsequent requests are unnecessary to allow adaptation between HD and SD. This is obviously a more efficient way of doing things than requiring additional license requests when quality switches occur.

It sounds a bit like an issue with the license server?

@ojw28 ojw28 added the question label Nov 18, 2015
@baseballbrad3
Copy link
Author

Thinking back the our proxy implementation, it's entirely possible we're not returning all keys. Thanks for the info. I'll report back when I figure out what's going on with the license response.

@baseballbrad3
Copy link
Author

Our strategy has changed a bit and I'm unfortunately not going to be exploring this anymore. Hopefully anyone else that has the same issue got something from this question.

@baseballbrad3
Copy link
Author

I would like to provide an update. We ended up making a change to our Widevine proxy so that it returns all the keys and the crash was resolved. I hope this helps anyone in a similar situation.

@ojw28
Copy link
Contributor

ojw28 commented Dec 2, 2015

Glad you fixed the issue; and thanks for sharing!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants