From 56a509d8e43b459bdefbd115b85aa7103c16770c Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Tue, 10 Mar 2015 21:44:20 +0000 Subject: [PATCH] Clean up handling of encrypted samples in fmp4/webm extractors. - The fmp4 extractor was reading from sampleEncryptionData even for not-encrypted samples, which I'm pretty sure isn't right. Fixed this. For all encrypted content I've seen, this change will be a no-op because isEncrypted is always true if there's an encryptionBox present. - Made webm extractor only set cryptoInfo if isEncrypted is true. - Align variable naming in the two extractors, for clarity. --- .../parser/mp4/FragmentedMp4Extractor.java | 12 ++++---- .../chunk/parser/webm/WebmExtractor.java | 29 ++++++++++--------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/parser/mp4/FragmentedMp4Extractor.java b/library/src/main/java/com/google/android/exoplayer/chunk/parser/mp4/FragmentedMp4Extractor.java index a6a95cd8d7..3febb381c5 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/parser/mp4/FragmentedMp4Extractor.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/parser/mp4/FragmentedMp4Extractor.java @@ -799,8 +799,11 @@ public final class FragmentedMp4Extractor implements Extractor { private void readSampleEncryptionData(ParsableByteArray sampleEncryptionData, SampleHolder out) { TrackEncryptionBox encryptionBox = track.sampleDescriptionEncryptionBoxes[fragmentRun.sampleDescriptionIndex]; + if (!encryptionBox.isEncrypted) { + return; + } + byte[] keyId = encryptionBox.keyId; - boolean isEncrypted = encryptionBox.isEncrypted; int vectorSize = encryptionBox.initializationVectorSize; boolean subsampleEncryption = fragmentRun.sampleHasSubsampleEncryptionTable[sampleIndex]; @@ -828,11 +831,10 @@ public final class FragmentedMp4Extractor implements Extractor { clearDataSizes[0] = 0; encryptedDataSizes[0] = fragmentRun.sampleSizeTable[sampleIndex]; } + out.cryptoInfo.set(subsampleCount, clearDataSizes, encryptedDataSizes, keyId, vector, - isEncrypted ? MediaCodec.CRYPTO_MODE_AES_CTR : MediaCodec.CRYPTO_MODE_UNENCRYPTED); - if (isEncrypted) { - out.flags |= MediaExtractor.SAMPLE_FLAG_ENCRYPTED; - } + MediaCodec.CRYPTO_MODE_AES_CTR); + out.flags |= MediaExtractor.SAMPLE_FLAG_ENCRYPTED; } } diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/parser/webm/WebmExtractor.java b/library/src/main/java/com/google/android/exoplayer/chunk/parser/webm/WebmExtractor.java index cb6c765708..0141a4144b 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/parser/webm/WebmExtractor.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/parser/webm/WebmExtractor.java @@ -486,29 +486,30 @@ public final class WebmExtractor implements Extractor { throw new ParserException("Extension bit is set in signal byte"); } boolean isEncrypted = (signalByte[0] & 0x01) == 0x01; - byte[] iv = null; if (isEncrypted) { + byte[] iv = null; iv = sampleHolder.cryptoInfo.iv; if (iv == null || iv.length != BLOCK_COUNTER_SIZE) { iv = new byte[BLOCK_COUNTER_SIZE]; } reader.readBytes(inputStream, iv, 8); // The container has only 8 bytes of IV. sampleHolder.size -= 8; + + int[] clearDataSizes = sampleHolder.cryptoInfo.numBytesOfClearData; + if (clearDataSizes == null || clearDataSizes.length < 1) { + clearDataSizes = new int[1]; + } + int[] encryptedDataSizes = sampleHolder.cryptoInfo.numBytesOfEncryptedData; + if (encryptedDataSizes == null || encryptedDataSizes.length < 1) { + encryptedDataSizes = new int[1]; + } + clearDataSizes[0] = 0; + encryptedDataSizes[0] = sampleHolder.size; + + sampleHolder.cryptoInfo.set(1, clearDataSizes, encryptedDataSizes, + encryptionKeyId, iv, MediaCodec.CRYPTO_MODE_AES_CTR); sampleHolder.flags |= MediaExtractor.SAMPLE_FLAG_ENCRYPTED; } - int[] numBytesOfClearData = sampleHolder.cryptoInfo.numBytesOfClearData; - if (numBytesOfClearData == null || numBytesOfClearData.length != 1) { - numBytesOfClearData = new int[1]; - } - numBytesOfClearData[0] = isEncrypted ? 0 : sampleHolder.size; - int[] numBytesOfEncryptedData = sampleHolder.cryptoInfo.numBytesOfEncryptedData; - if (numBytesOfEncryptedData == null || numBytesOfEncryptedData.length != 1) { - numBytesOfEncryptedData = new int[1]; - } - numBytesOfEncryptedData[0] = isEncrypted ? sampleHolder.size : 0; - sampleHolder.cryptoInfo.set( - 1, numBytesOfClearData, numBytesOfEncryptedData, encryptionKeyId, iv, - isEncrypted ? MediaCodec.CRYPTO_MODE_AES_CTR : MediaCodec.CRYPTO_MODE_UNENCRYPTED); } if (sampleHolder.data == null || sampleHolder.data.capacity() < sampleHolder.size) {