diff --git a/demo/src/main/assets/sample_media.exolist.json b/demo/src/main/assets/sample_media.exolist.json index 6ea5069a91..8798cba036 100644 --- a/demo/src/main/assets/sample_media.exolist.json +++ b/demo/src/main/assets/sample_media.exolist.json @@ -30,42 +30,50 @@ { "name": "WV: HDCP not specified", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "drm": "widevine:d286538032258a1c:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=d286538032258a1c&provider=widevine_test" }, { "name": "WV: HDCP not required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "drm": "widevine:48fcc369939ac96c:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=48fcc369939ac96c&provider=widevine_test" }, { "name": "WV: HDCP required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "drm": "widevine:e06c39f1151da3df:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=e06c39f1151da3df&provider=widevine_test" }, { "name": "WV: Secure video path required (MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "drm": "widevine:0894c7c8719b28a0:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=0894c7c8719b28a0&provider=widevine_test" }, { "name": "WV: Secure video path required (WebM,VP9)", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears.mpd", - "drm": "widevine:0894c7c8719b28a0:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=0894c7c8719b28a0&provider=widevine_test" }, { "name": "WV: Secure video path required (MP4,H265)", "uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears.mpd", - "drm": "widevine:0894c7c8719b28a0:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=0894c7c8719b28a0&provider=widevine_test" }, { "name": "WV: HDCP + secure video path required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "drm": "widevine:efd045b1eb61888a:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=efd045b1eb61888a&provider=widevine_test" }, { "name": "WV: 30s license duration (fails at ~30s)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "drm": "widevine:f9a34cab7b05881a:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=f9a34cab7b05881a&provider=widevine_test" } ] }, @@ -75,32 +83,38 @@ { "name": "WV: HDCP: None (not required)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "drm": "widevine:HDCP_None:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=HDCP_None&provider=widevine_test" }, { "name": "WV: HDCP: 1.0 required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "drm": "widevine:HDCP_V1:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=HDCP_V1&provider=widevine_test" }, { "name": "WV: HDCP: 2.0 required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "drm": "widevine:HDCP_V2:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=HDCP_V2&provider=widevine_test" }, { "name": "WV: HDCP: 2.1 required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "drm": "widevine:HDCP_V2_1:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=HDCP_V2_1&provider=widevine_test" }, { "name": "WV: HDCP: 2.2 required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "drm": "widevine:HDCP_V2_2:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=HDCP_V2_2&provider=widevine_test" }, { "name": "WV: HDCP: No digital output", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "drm": "widevine:HDCP_NO_DIGTAL_OUTPUT:widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=HDCP_NO_DIGTAL_OUTPUT&provider=widevine_test" } ] }, @@ -126,22 +140,26 @@ { "name": "WV: Secure SD & HD (MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "drm": "widevine::widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" }, { "name": "WV: Secure SD (MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd", - "drm": "widevine::widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" }, { "name": "WV: Secure HD (MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_hd.mpd", - "drm": "widevine::widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" }, { "name": "WV: Secure UHD (MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_uhd.mpd", - "drm": "widevine::widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" } ] }, @@ -167,22 +185,26 @@ { "name": "WV: Secure SD & HD (WebM,VP9)", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears.mpd", - "drm": "widevine::widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" }, { "name": "WV: Secure SD (WebM,VP9)", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_sd.mpd", - "drm": "widevine::widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" }, { "name": "WV: Secure HD (WebM,VP9)", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_hd.mpd", - "drm": "widevine::widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" }, { "name": "WV: Secure UHD (WebM,VP9)", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_uhd.mpd", - "drm": "widevine::widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" } ] }, @@ -208,22 +230,26 @@ { "name": "WV: Secure SD & HD (MP4,H265)", "uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears.mpd", - "drm": "widevine::widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" }, { "name": "WV: Secure SD (MP4,H265)", "uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears_sd.mpd", - "drm": "widevine::widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" }, { "name": "WV: Secure HD (MP4,H265)", "uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears_hd.mpd", - "drm": "widevine::widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" }, { "name": "WV: Secure UHD (MP4,H265)", "uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears_uhd.mpd", - "drm": "widevine::widevine_test" + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" } ] }, @@ -237,7 +263,8 @@ { "name": "Super speed (PlayReady)", "uri": "http://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism", - "drm": "playready::" + "drm_scheme": "playready", + "drm_license_url": "http://playready.directtaps.net/pr/svc/rightsmanager.asmx" } ] }, @@ -335,7 +362,7 @@ "name": "Playlists", "samples": [ { - "name": "Cats and dogs", + "name": "Cats -> Dogs", "playlist": [ { "uri": "http://html5demos.com/assets/dizzy.mp4" @@ -346,7 +373,7 @@ ] }, { - "name": "Audio then Video", + "name": "Audio -> Video", "playlist": [ { "uri": "https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/audio-141.mp4" @@ -355,6 +382,28 @@ "uri": "http://storage.googleapis.com/exoplayer-test-media-1/mkv/android-screens-lavf-56.36.100-aac-avc-main-1280x720.mkv" } ] + }, + { + "name": "Clear -> Enc -> Clear -> Enc -> Enc", + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test", + "playlist": [ + { + "uri": "http://html5demos.com/assets/dizzy.mp4" + }, + { + "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd" + }, + { + "uri": "http://html5demos.com/assets/dizzy.mp4" + }, + { + "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd" + }, + { + "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd" + } + ] } ] } diff --git a/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java b/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java index 067da8bd5f..36e189de9f 100644 --- a/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java +++ b/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java @@ -99,8 +99,7 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback, SimpleExoPlayer.Id3MetadataListener, MappingTrackSelector.EventListener { public static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid"; - public static final String DRM_CONTENT_ID_EXTRA = "drm_content_id"; - public static final String DRM_PROVIDER_EXTRA = "drm_provider"; + public static final String DRM_LICENSE_URL = "drm_license_url"; public static final String PREFER_EXTENSION_DECODERS = "prefer_extension_decoders"; public static final String ACTION_VIEW = "com.google.android.exoplayer.demo.action.VIEW"; @@ -267,13 +266,13 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback, Intent intent = getIntent(); if (player == null) { boolean preferExtensionDecoders = intent.getBooleanExtra(PREFER_EXTENSION_DECODERS, false); - UUID drmSchemeUuid = (UUID) intent.getSerializableExtra(DRM_SCHEME_UUID_EXTRA); + UUID drmSchemeUuid = intent.hasExtra(DRM_SCHEME_UUID_EXTRA) + ? UUID.fromString(intent.getStringExtra(DRM_SCHEME_UUID_EXTRA)) : null; DrmSessionManager drmSessionManager = null; if (drmSchemeUuid != null) { - String drmContentId = intent.getStringExtra(DRM_CONTENT_ID_EXTRA); - String drmProvider = intent.getStringExtra(DRM_PROVIDER_EXTRA); + String drmLicenseUrl = intent.getStringExtra(DRM_LICENSE_URL); try { - drmSessionManager = buildDrmSessionManager(drmSchemeUuid, drmContentId, drmProvider); + drmSessionManager = buildDrmSessionManager(drmSchemeUuid, drmLicenseUrl); } catch (UnsupportedDrmException e) { onUnsupportedDrmError(e); return; @@ -367,17 +366,17 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback, } } - private DrmSessionManager buildDrmSessionManager(UUID uuid, String id, String provider) + private DrmSessionManager buildDrmSessionManager(UUID uuid, String licenseUrl) throws UnsupportedDrmException { if (Util.SDK_INT < 18) { return null; } if (C.PLAYREADY_UUID.equals(uuid)) { return StreamingDrmSessionManager.newPlayReadyInstance( - TestMediaDrmCallback.newPlayReadyInstance(), null, mainHandler, eventLogger); + TestMediaDrmCallback.newPlayReadyInstance(licenseUrl), null, mainHandler, eventLogger); } else if (C.WIDEVINE_UUID.equals(uuid)) { return StreamingDrmSessionManager.newWidevineInstance( - TestMediaDrmCallback.newWidevineInstance(id, provider), null, mainHandler, eventLogger); + TestMediaDrmCallback.newWidevineInstance(licenseUrl), null, mainHandler, eventLogger); } else { throw new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME); } diff --git a/demo/src/main/java/com/google/android/exoplayer2/demo/SampleChooserActivity.java b/demo/src/main/java/com/google/android/exoplayer2/demo/SampleChooserActivity.java index 0ba9c299ce..3fe4359227 100644 --- a/demo/src/main/java/com/google/android/exoplayer2/demo/SampleChooserActivity.java +++ b/demo/src/main/java/com/google/android/exoplayer2/demo/SampleChooserActivity.java @@ -162,8 +162,7 @@ public class SampleChooserActivity extends Activity { String uri = null; String extension = null; UUID drmUuid = null; - String drmContentId = null; - String drmProvider = null; + String drmLicenseUrl = null; boolean preferExtensionDecoders = false; ArrayList playlistSamples = null; @@ -180,17 +179,22 @@ public class SampleChooserActivity extends Activity { case "extension": extension = reader.nextString(); break; - case "drm": - String[] drmComponents = reader.nextString().split(":", -1); - drmUuid = getDrmUuid(drmComponents[0]); - drmContentId = drmComponents[1]; - drmProvider = drmComponents[2]; + case "drm_scheme": + Assertions.checkState(!insidePlaylist, "Invalid attribute on nested item: drm_scheme"); + drmUuid = getDrmUuid(reader.nextString()); + break; + case "drm_license_url": + Assertions.checkState(!insidePlaylist, + "Invalid attribute on nested item: drm_license_url"); + drmLicenseUrl = reader.nextString(); break; case "prefer_extension_decoders": + Assertions.checkState(!insidePlaylist, + "Invalid attribute on nested item: prefer_extension_decoders"); preferExtensionDecoders = reader.nextBoolean(); break; case "playlist": - Assertions.checkState(!insidePlaylist, "Nested playlists are invalid"); + Assertions.checkState(!insidePlaylist, "Invalid nesting of playlists"); playlistSamples = new ArrayList<>(); reader.beginArray(); while (reader.hasNext()) { @@ -207,11 +211,11 @@ public class SampleChooserActivity extends Activity { if (playlistSamples != null) { UriSample[] playlistSamplesArray = playlistSamples.toArray( new UriSample[playlistSamples.size()]); - return new PlaylistSample(sampleName, drmUuid, drmContentId, drmProvider, - preferExtensionDecoders, playlistSamplesArray); + return new PlaylistSample(sampleName, drmUuid, drmLicenseUrl, preferExtensionDecoders, + playlistSamplesArray); } else { - return new UriSample(sampleName, drmUuid, drmContentId, drmProvider, - preferExtensionDecoders, uri, extension); + return new UriSample(sampleName, drmUuid, drmLicenseUrl, preferExtensionDecoders, uri, + extension); } } @@ -233,7 +237,11 @@ public class SampleChooserActivity extends Activity { case "playready": return C.PLAYREADY_UUID; default: - throw new ParserException("Unsupported drm type: " + typeString); + try { + return UUID.fromString(typeString); + } catch (RuntimeException e) { + throw new ParserException("Unsupported drm type: " + typeString); + } } } @@ -331,24 +339,26 @@ public class SampleChooserActivity extends Activity { public final String name; public final boolean preferExtensionDecoders; - - // TODO: DRM properties should be specified on UriSample only. This requires changes to - // PlayerActivity and beyond to be able to handle playlists containing multiple DRM protected - // items that have different DRM properties. public final UUID drmSchemeUuid; - public final String drmContentId; - public final String drmProvider; + public final String drmLicenseUrl; - public Sample(String name, UUID drmSchemeUuid, String drmContentId, String drmProvider, + public Sample(String name, UUID drmSchemeUuid, String drmLicenseUrl, boolean preferExtensionDecoders) { this.name = name; this.drmSchemeUuid = drmSchemeUuid; - this.drmContentId = drmContentId; - this.drmProvider = drmProvider; + this.drmLicenseUrl = drmLicenseUrl; this.preferExtensionDecoders = preferExtensionDecoders; } - public abstract Intent buildIntent(Context context); + public Intent buildIntent(Context context) { + Intent intent = new Intent(context, PlayerActivity.class); + intent.putExtra(PlayerActivity.PREFER_EXTENSION_DECODERS, preferExtensionDecoders); + if (drmSchemeUuid != null) { + intent.putExtra(PlayerActivity.DRM_SCHEME_UUID_EXTRA, drmSchemeUuid.toString()); + intent.putExtra(PlayerActivity.DRM_LICENSE_URL, drmLicenseUrl); + } + return intent; + } } @@ -357,21 +367,16 @@ public class SampleChooserActivity extends Activity { public final String uri; public final String extension; - public UriSample(String name, UUID drmSchemeUuid, String drmContentId, String drmProvider, + public UriSample(String name, UUID drmSchemeUuid, String drmLicenseUrl, boolean preferExtensionDecoders, String uri, String extension) { - super(name, drmSchemeUuid, drmContentId, drmProvider, preferExtensionDecoders); + super(name, drmSchemeUuid, drmLicenseUrl, preferExtensionDecoders); this.uri = uri; this.extension = extension; } @Override public Intent buildIntent(Context context) { - return new Intent(context, PlayerActivity.class) - .setAction(PlayerActivity.ACTION_VIEW) - .putExtra(PlayerActivity.DRM_SCHEME_UUID_EXTRA, drmSchemeUuid) - .putExtra(PlayerActivity.DRM_CONTENT_ID_EXTRA, drmContentId) - .putExtra(PlayerActivity.DRM_PROVIDER_EXTRA, drmProvider) - .putExtra(PlayerActivity.PREFER_EXTENSION_DECODERS, preferExtensionDecoders) + return super.buildIntent(context) .setData(Uri.parse(uri)) .putExtra(PlayerActivity.EXTENSION_EXTRA, extension) .setAction(PlayerActivity.ACTION_VIEW); @@ -383,9 +388,9 @@ public class SampleChooserActivity extends Activity { public final UriSample[] children; - public PlaylistSample(String name, UUID drmSchemeUuid, String drmContentId, String drmProvider, + public PlaylistSample(String name, UUID drmSchemeUuid, String drmLicenseUrl, boolean preferExtensionDecoders, UriSample... children) { - super(name, drmSchemeUuid, drmContentId, drmProvider, preferExtensionDecoders); + super(name, drmSchemeUuid, drmLicenseUrl, preferExtensionDecoders); this.children = children; } @@ -397,12 +402,7 @@ public class SampleChooserActivity extends Activity { uris[i] = children[i].uri; extensions[i] = children[i].extension; } - return new Intent(context, PlayerActivity.class) - .setAction(PlayerActivity.ACTION_VIEW) - .putExtra(PlayerActivity.DRM_SCHEME_UUID_EXTRA, drmSchemeUuid) - .putExtra(PlayerActivity.DRM_CONTENT_ID_EXTRA, drmContentId) - .putExtra(PlayerActivity.DRM_PROVIDER_EXTRA, drmProvider) - .putExtra(PlayerActivity.PREFER_EXTENSION_DECODERS, preferExtensionDecoders) + return super.buildIntent(context) .putExtra(PlayerActivity.URI_LIST_EXTRA, uris) .putExtra(PlayerActivity.EXTENSION_LIST_EXTRA, extensions) .setAction(PlayerActivity.ACTION_VIEW_LIST); diff --git a/demo/src/main/java/com/google/android/exoplayer2/demo/TestMediaDrmCallback.java b/demo/src/main/java/com/google/android/exoplayer2/demo/TestMediaDrmCallback.java index f009319762..dff33c9958 100644 --- a/demo/src/main/java/com/google/android/exoplayer2/demo/TestMediaDrmCallback.java +++ b/demo/src/main/java/com/google/android/exoplayer2/demo/TestMediaDrmCallback.java @@ -38,9 +38,6 @@ import java.util.UUID; @TargetApi(18) /* package */ final class TestMediaDrmCallback implements MediaDrmCallback { - private static final String WIDEVINE_BASE_URL = "https://proxy.uat.widevine.com/proxy"; - private static final String PLAYREADY_BASE_URL = - "http://playready.directtaps.net/pr/svc/rightsmanager.asmx"; private static final Map PLAYREADY_KEY_REQUEST_PROPERTIES; static { HashMap keyRequestProperties = new HashMap<>(); @@ -53,13 +50,12 @@ import java.util.UUID; private final String defaultUrl; private final Map keyRequestProperties; - public static TestMediaDrmCallback newWidevineInstance(String contentId, String provider) { - String defaultUrl = WIDEVINE_BASE_URL + "?video_id=" + contentId + "&provider=" + provider; + public static TestMediaDrmCallback newWidevineInstance(String defaultUrl) { return new TestMediaDrmCallback(defaultUrl, null); } - public static TestMediaDrmCallback newPlayReadyInstance() { - return new TestMediaDrmCallback(PLAYREADY_BASE_URL, PLAYREADY_KEY_REQUEST_PROPERTIES); + public static TestMediaDrmCallback newPlayReadyInstance(String defaultUrl) { + return new TestMediaDrmCallback(defaultUrl, PLAYREADY_KEY_REQUEST_PROPERTIES); } private TestMediaDrmCallback(String defaultUrl, Map keyRequestProperties) { diff --git a/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java b/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java index 781b4d7be3..4f91c966e3 100644 --- a/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java @@ -177,6 +177,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { private Format format; private MediaCodec codec; private DrmSession drmSession; + private DrmSession pendingDrmSession; private boolean codecIsAdaptive; private boolean codecNeedsDiscardToSpsWorkaround; private boolean codecNeedsFlushWorkaround; @@ -287,17 +288,11 @@ public abstract class MediaCodecRenderer extends BaseRenderer { return; } + drmSession = pendingDrmSession; String mimeType = format.sampleMimeType; MediaCrypto mediaCrypto = null; boolean drmSessionRequiresSecureDecoder = false; - if (format.drmInitData != null) { - if (drmSessionManager == null) { - throw ExoPlaybackException.createForRenderer( - new IllegalStateException("Media requires a DrmSessionManager"), getIndex()); - } - if (drmSession == null) { - drmSession = drmSessionManager.acquireSession(Looper.myLooper(), format.drmInitData); - } + if (drmSession != null) { int drmSessionState = drmSession.getState(); if (drmSessionState == DrmSession.STATE_ERROR) { throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex()); @@ -400,9 +395,19 @@ public abstract class MediaCodecRenderer extends BaseRenderer { try { releaseCodec(); } finally { - if (drmSession != null) { - drmSessionManager.releaseSession(drmSession); - drmSession = null; + try { + if (drmSession != null) { + drmSessionManager.releaseSession(drmSession); + } + } finally { + try { + if (pendingDrmSession != null && pendingDrmSession != drmSession) { + drmSessionManager.releaseSession(pendingDrmSession); + } + } finally { + drmSession = null; + pendingDrmSession = null; + } } } } @@ -439,6 +444,13 @@ public abstract class MediaCodecRenderer extends BaseRenderer { codec.release(); } finally { codec = null; + if (drmSession != null && pendingDrmSession != drmSession) { + try { + drmSessionManager.releaseSession(drmSession); + } finally { + drmSession = null; + } + } } } } @@ -700,7 +712,26 @@ public abstract class MediaCodecRenderer extends BaseRenderer { protected void onInputFormatChanged(Format newFormat) throws ExoPlaybackException { Format oldFormat = format; format = newFormat; - if (codec != null && canReconfigureCodec(codec, codecIsAdaptive, oldFormat, format)) { + + boolean drmInitDataChanged = !Util.areEqual(format.drmInitData, oldFormat == null ? null + : oldFormat.drmInitData); + if (drmInitDataChanged) { + if (format.drmInitData != null) { + if (drmSessionManager == null) { + throw ExoPlaybackException.createForRenderer( + new IllegalStateException("Media requires a DrmSessionManager"), getIndex()); + } + pendingDrmSession = drmSessionManager.acquireSession(Looper.myLooper(), format.drmInitData); + if (pendingDrmSession == drmSession) { + drmSessionManager.releaseSession(pendingDrmSession); + } + } else { + pendingDrmSession = null; + } + } + + if (pendingDrmSession == drmSession && codec != null + && canReconfigureCodec(codec, codecIsAdaptive, oldFormat, format)) { codecReconfigured = true; codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING; codecNeedsAdaptationWorkaroundBuffer = codecNeedsAdaptationWorkaround