diff --git a/demo/src/main/assets/media.exolist.json b/demo/src/main/assets/media.exolist.json index 4a519196574..59ae87ad5fd 100644 --- a/demo/src/main/assets/media.exolist.json +++ b/demo/src/main/assets/media.exolist.json @@ -138,28 +138,52 @@ "uri": "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears_uhd.mpd" }, { - "name": "WV: Secure SD & HD (MP4,H264)", + "name": "WV: Secure SD & HD (cenc,MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", "drm_scheme": "widevine", "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" }, { - "name": "WV: Secure SD (MP4,H264)", + "name": "WV: Secure SD (cenc,MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd", "drm_scheme": "widevine", "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" }, { - "name": "WV: Secure HD (MP4,H264)", + "name": "WV: Secure HD (cenc,MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_hd.mpd", "drm_scheme": "widevine", "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" }, { - "name": "WV: Secure UHD (MP4,H264)", + "name": "WV: Secure UHD (cenc,MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_uhd.mpd", "drm_scheme": "widevine", "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" + }, + { + "name": "WV: Secure SD & HD (cbc1,MP4,H264)", + "uri": "https://storage.googleapis.com/wvmedia/cbc1/h264/tears/tears_aes_cbc1.mpd", + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" + }, + { + "name": "WV: Secure SD (cbc1,MP4,H264)", + "uri": "https://storage.googleapis.com/wvmedia/cbc1/h264/tears/tears_aes_cbc1_sd.mpd", + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" + }, + { + "name": "WV: Secure HD (cbc1,MP4,H264)", + "uri": "https://storage.googleapis.com/wvmedia/cbc1/h264/tears/tears_aes_cbc1_hd.mpd", + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" + }, + { + "name": "WV: Secure UHD (cbc1,MP4,H264)", + "uri": "https://storage.googleapis.com/wvmedia/cbc1/h264/tears/tears_aes_cbc1_uhd.mpd", + "drm_scheme": "widevine", + "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" } ] }, diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java index 5d44e718807..cc3f3150141 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java @@ -1128,24 +1128,18 @@ private boolean readSample(ExtractorInput input) throws IOException, Interrupted sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs); } - @C.BufferFlags int sampleFlags = (fragment.definesEncryptionData ? C.BUFFER_FLAG_ENCRYPTED : 0) - | (fragment.sampleIsSyncFrameTable[sampleIndex] ? C.BUFFER_FLAG_KEY_FRAME : 0); + @C.BufferFlags int sampleFlags = fragment.sampleIsSyncFrameTable[sampleIndex] + ? C.BUFFER_FLAG_KEY_FRAME : 0; // Encryption data. TrackOutput.CryptoData cryptoData = null; - TrackEncryptionBox encryptionBox = null; if (fragment.definesEncryptionData) { - encryptionBox = fragment.trackEncryptionBox != null + sampleFlags |= C.BUFFER_FLAG_ENCRYPTED; + TrackEncryptionBox encryptionBox = fragment.trackEncryptionBox != null ? fragment.trackEncryptionBox : track.getSampleDescriptionEncryptionBox(fragment.header.sampleDescriptionIndex); - if (encryptionBox != currentTrackBundle.cachedEncryptionBox) { - cryptoData = new TrackOutput.CryptoData(C.CRYPTO_MODE_AES_CTR, encryptionBox.keyId); - } else { - cryptoData = currentTrackBundle.cachedCryptoData; - } + cryptoData = encryptionBox.cryptoData; } - currentTrackBundle.cachedCryptoData = cryptoData; - currentTrackBundle.cachedEncryptionBox = encryptionBox; output.sampleMetadata(sampleTimeUs, sampleFlags, sampleSize, 0, cryptoData); @@ -1301,10 +1295,6 @@ private static final class TrackBundle { public int currentSampleInTrackRun; public int currentTrackRunIndex; - // Auxiliary references. - public TrackOutput.CryptoData cachedCryptoData; - public TrackEncryptionBox cachedEncryptionBox; - public TrackBundle(TrackOutput output) { fragment = new TrackFragment(); this.output = output; @@ -1322,8 +1312,6 @@ public void reset() { currentSampleIndex = 0; currentTrackRunIndex = 0; currentSampleInTrackRun = 0; - cachedCryptoData = null; - cachedEncryptionBox = null; } public void updateDrmInitData(DrmInitData drmInitData) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/TrackEncryptionBox.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/TrackEncryptionBox.java index d56504f7806..6f33d2222f6 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/TrackEncryptionBox.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/TrackEncryptionBox.java @@ -16,6 +16,9 @@ package com.google.android.exoplayer2.extractor.mp4; import android.support.annotation.Nullable; +import android.util.Log; +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.extractor.TrackOutput; /** * Encapsulates information parsed from a track encryption (tenc) box or sample group description @@ -23,6 +26,8 @@ */ public final class TrackEncryptionBox { + private static final String TAG = "TrackEncryptionBox"; + /** * Indicates the encryption state of the samples in the sample group. */ @@ -34,27 +39,47 @@ public final class TrackEncryptionBox { @Nullable public final String schemeType; /** - * The initialization vector size in bytes for the samples in the corresponding sample group. + * A {@link TrackOutput.CryptoData} instance containing the encryption information from this + * {@link TrackEncryptionBox}. */ - public final int initializationVectorSize; + public final TrackOutput.CryptoData cryptoData; /** - * The key identifier for the samples in the corresponding sample group. + * The initialization vector size in bytes for the samples in the corresponding sample group. */ - public final byte[] keyId; + public final int initializationVectorSize; + /** * @param isEncrypted See {@link #isEncrypted}. * @param schemeType See {@link #schemeType}. * @param initializationVectorSize See {@link #initializationVectorSize}. - * @param keyId See {@link #keyId}. + * @param keyId See {@link TrackOutput.CryptoData#encryptionKey}. */ public TrackEncryptionBox(boolean isEncrypted, @Nullable String schemeType, int initializationVectorSize, byte[] keyId) { this.isEncrypted = isEncrypted; this.schemeType = schemeType; this.initializationVectorSize = initializationVectorSize; - this.keyId = keyId; + cryptoData = new TrackOutput.CryptoData(schemeToCryptoMode(schemeType), keyId); + } + + @C.CryptoMode + private static int schemeToCryptoMode(@Nullable String schemeType) { + if (schemeType == null) { + // If unknown, assume cenc. + return C.CRYPTO_MODE_AES_CTR; + } + switch (schemeType) { + case "cenc": + return C.CRYPTO_MODE_AES_CTR; + case "cbc1": + return C.CRYPTO_MODE_AES_CBC; + default: + Log.w(TAG, "Unsupported protection scheme type '" + schemeType + "'. Assuming AES-CTR " + + "crypto mode."); + return C.CRYPTO_MODE_AES_CTR; + } } }