Add support for cbc1 encryption scheme

Issue:#1661
Issue:#1989
Issue:#2089

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=159553419
This commit is contained in:
aquilescanta 2017-06-20 06:32:12 -07:00 committed by Oliver Woodman
parent 1c8f14b5fd
commit 8d74ba4850
3 changed files with 64 additions and 27 deletions

View File

@ -138,28 +138,52 @@
"uri": "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears_uhd.mpd" "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", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
"drm_scheme": "widevine", "drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" "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", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd",
"drm_scheme": "widevine", "drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" "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", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_hd.mpd",
"drm_scheme": "widevine", "drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" "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", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_uhd.mpd",
"drm_scheme": "widevine", "drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" "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"
} }
] ]
}, },

View File

@ -1128,24 +1128,18 @@ public final class FragmentedMp4Extractor implements Extractor {
sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs); sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs);
} }
@C.BufferFlags int sampleFlags = (fragment.definesEncryptionData ? C.BUFFER_FLAG_ENCRYPTED : 0) @C.BufferFlags int sampleFlags = fragment.sampleIsSyncFrameTable[sampleIndex]
| (fragment.sampleIsSyncFrameTable[sampleIndex] ? C.BUFFER_FLAG_KEY_FRAME : 0); ? C.BUFFER_FLAG_KEY_FRAME : 0;
// Encryption data. // Encryption data.
TrackOutput.CryptoData cryptoData = null; TrackOutput.CryptoData cryptoData = null;
TrackEncryptionBox encryptionBox = null;
if (fragment.definesEncryptionData) { if (fragment.definesEncryptionData) {
encryptionBox = fragment.trackEncryptionBox != null sampleFlags |= C.BUFFER_FLAG_ENCRYPTED;
TrackEncryptionBox encryptionBox = fragment.trackEncryptionBox != null
? fragment.trackEncryptionBox ? fragment.trackEncryptionBox
: track.getSampleDescriptionEncryptionBox(fragment.header.sampleDescriptionIndex); : track.getSampleDescriptionEncryptionBox(fragment.header.sampleDescriptionIndex);
if (encryptionBox != currentTrackBundle.cachedEncryptionBox) { cryptoData = encryptionBox.cryptoData;
cryptoData = new TrackOutput.CryptoData(C.CRYPTO_MODE_AES_CTR, encryptionBox.keyId);
} else {
cryptoData = currentTrackBundle.cachedCryptoData;
}
} }
currentTrackBundle.cachedCryptoData = cryptoData;
currentTrackBundle.cachedEncryptionBox = encryptionBox;
output.sampleMetadata(sampleTimeUs, sampleFlags, sampleSize, 0, cryptoData); output.sampleMetadata(sampleTimeUs, sampleFlags, sampleSize, 0, cryptoData);
@ -1301,10 +1295,6 @@ public final class FragmentedMp4Extractor implements Extractor {
public int currentSampleInTrackRun; public int currentSampleInTrackRun;
public int currentTrackRunIndex; public int currentTrackRunIndex;
// Auxiliary references.
public TrackOutput.CryptoData cachedCryptoData;
public TrackEncryptionBox cachedEncryptionBox;
public TrackBundle(TrackOutput output) { public TrackBundle(TrackOutput output) {
fragment = new TrackFragment(); fragment = new TrackFragment();
this.output = output; this.output = output;
@ -1322,8 +1312,6 @@ public final class FragmentedMp4Extractor implements Extractor {
currentSampleIndex = 0; currentSampleIndex = 0;
currentTrackRunIndex = 0; currentTrackRunIndex = 0;
currentSampleInTrackRun = 0; currentSampleInTrackRun = 0;
cachedCryptoData = null;
cachedEncryptionBox = null;
} }
public void updateDrmInitData(DrmInitData drmInitData) { public void updateDrmInitData(DrmInitData drmInitData) {

View File

@ -16,6 +16,9 @@
package com.google.android.exoplayer2.extractor.mp4; package com.google.android.exoplayer2.extractor.mp4;
import android.support.annotation.Nullable; 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 * Encapsulates information parsed from a track encryption (tenc) box or sample group description
@ -23,6 +26,8 @@ import android.support.annotation.Nullable;
*/ */
public final class TrackEncryptionBox { public final class TrackEncryptionBox {
private static final String TAG = "TrackEncryptionBox";
/** /**
* Indicates the encryption state of the samples in the sample group. * Indicates the encryption state of the samples in the sample group.
*/ */
@ -33,28 +38,48 @@ public final class TrackEncryptionBox {
*/ */
@Nullable public final String schemeType; @Nullable public final String schemeType;
/**
* A {@link TrackOutput.CryptoData} instance containing the encryption information from this
* {@link TrackEncryptionBox}.
*/
public final TrackOutput.CryptoData cryptoData;
/** /**
* The initialization vector size in bytes for the samples in the corresponding sample group. * The initialization vector size in bytes for the samples in the corresponding sample group.
*/ */
public final int initializationVectorSize; public final int initializationVectorSize;
/**
* The key identifier for the samples in the corresponding sample group.
*/
public final byte[] keyId;
/** /**
* @param isEncrypted See {@link #isEncrypted}. * @param isEncrypted See {@link #isEncrypted}.
* @param schemeType See {@link #schemeType}. * @param schemeType See {@link #schemeType}.
* @param initializationVectorSize See {@link #initializationVectorSize}. * @param initializationVectorSize See {@link #initializationVectorSize}.
* @param keyId See {@link #keyId}. * @param keyId See {@link TrackOutput.CryptoData#encryptionKey}.
*/ */
public TrackEncryptionBox(boolean isEncrypted, @Nullable String schemeType, public TrackEncryptionBox(boolean isEncrypted, @Nullable String schemeType,
int initializationVectorSize, byte[] keyId) { int initializationVectorSize, byte[] keyId) {
this.isEncrypted = isEncrypted; this.isEncrypted = isEncrypted;
this.schemeType = schemeType; this.schemeType = schemeType;
this.initializationVectorSize = initializationVectorSize; 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;
}
} }
} }