-
Notifications
You must be signed in to change notification settings - Fork 6k
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 with the way DefaultDrmSessionManager releases its references to DrmSession-s #8576
Comments
This is definitely a bug (introduced by me in 316f8a8 - sorry!). By complete coincidence I actually spotted this on Tuesday when doing other work in However, assuming there's no other
When the manager reference count reaches zero, it releases it's underlying ExoPlayer/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java Line 467 in b100094
In the 'default' case, this ExoMediaDrm will be an ExoPlayer FrameworkMediaDrm wrapping an Android MediaDrm . This same object is used to back all the DrmSession instances acquired from the manager. FrameworkMediaDrm also has an internal reference count. If that reaches zero it also releases its underlying MediaDrm :ExoPlayer/library/core/src/main/java/com/google/android/exoplayer2/drm/FrameworkMediaDrm.java Lines 255 to 257 in b100094
When (re-)preparing and incrementing the reference count from 0 to 1, the manager reacquires the ExoPlayer/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java Line 451 in b100094
This means that after releasing & re-preparing the manager, the underlying So I don't think it's valid to keep a In your case, I think you can fix this by preparing the manager manually at the start of your code snippet, then finally releasing it when you're completely done. This means the reference count will oscillate between 1 and 2 (instead of 0 and 1). So it would be something like:
If you do this you need to be careful the
If you keep the same manager instance around (with ref-count > 0), could you leverage the keepalive support for this and avoid needing to manually acquire the session? When ExoPlayer calls There's a recent (unreleased) related DRM change that may be relevant to you. We now try and re-use |
Thank you @icbaker. As for the mechanism of re-using DefaultDrmSessionManager instances, is there any approximate date when it will be released? |
If keepalive is disabled the existing code over-eagerly releases DrmSession instances. This is arguably OK since a (Default)DrmSession should be released before its (Default)Manager is released (since the underlying MediaDrm instance might be released when the manager is released). And if all sessions are released before the manager is released then `sessions` is empty, so the loop is a no-op. Issue: #8576 #minor-release PiperOrigin-RevId: 356955308
If keepalive is disabled the existing code over-eagerly releases DrmSession instances. This is arguably OK since a (Default)DrmSession should be released before its (Default)Manager is released (since the underlying MediaDrm instance might be released when the manager is released). And if all sessions are released before the manager is released then `sessions` is empty, so the loop is a no-op. Issue: #8576 PiperOrigin-RevId: 356955308
It will be released in |
There are several situations in which it would be desirable to re-prepare ExoPlayer with a different media source while keeping the DrmSession from the previous prepare.
For example, there may be several different media sources which have the same DRM info or it is required to retry a failed playback.
In such cases not keeping the DrmSession would mean an extra license request, which takes time and consumes resources
We had a solution for this which in essence does the following:
This worked as we expected it to in ExoPlayer 2.9.4, however, we recently upgraded to ExoPlayer 2.12.2 and this mechanism does not work anymore.
Two reasons why it is no longer working are both in 2.12.2's implementation of DefaultDrmSessionManager.release():
a) when a DefaultDrmSessionManager is constructed with sessionKeepaliveMs == C.TIME_UNSET
calling DefaultDrmSessionManager.release() releases DrmSessions which it did not acquire.
b) DefaultDrmSessionManager.release() releases DrmSessions, however it does not forget them -- they are still kept in the
DefaultDrmSessionManager.sessions list.
The sequence of
always releases the DrmSession objects which are stored in the sessions list, while it does not acquire them (in the same sequence) and this eventually causes a license request (or IllegalStateException).
The text was updated successfully, but these errors were encountered: