Introduce CryptoData parameter object

This will allow supporting more encryption schemes. Including some
that require more encryption data, like the encryption pattern.

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

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=155481889
This commit is contained in:
aquilescanta 2017-05-09 02:20:43 -07:00 committed by Oliver Woodman
parent 0302fd6b4d
commit 1f43fb1998
10 changed files with 114 additions and 55 deletions

View File

@ -30,5 +30,6 @@ track 1:
time = 0 time = 0
flags = 1073741824 flags = 1073741824
data = length 39, hash B7FE77F4 data = length 39, hash B7FE77F4
crypto mode = 1
encryption key = length 16, hash 4CE944CF encryption key = length 16, hash 4CE944CF
tracksEnded = true tracksEnded = true

View File

@ -30,5 +30,6 @@ track 1:
time = 0 time = 0
flags = 1073741824 flags = 1073741824
data = length 24, hash E58668B1 data = length 24, hash E58668B1
crypto mode = 1
encryption key = length 16, hash 4CE944CF encryption key = length 16, hash 4CE944CF
tracksEnded = true tracksEnded = true

View File

@ -83,12 +83,12 @@ public final class C {
public static final String UTF16_NAME = "UTF-16"; public static final String UTF16_NAME = "UTF-16";
/** /**
* * The name of the serif font family. * The name of the serif font family.
*/ */
public static final String SERIF_NAME = "serif"; public static final String SERIF_NAME = "serif";
/** /**
* * The name of the sans-serif font family. * The name of the sans-serif font family.
*/ */
public static final String SANS_SERIF_NAME = "sans-serif"; public static final String SANS_SERIF_NAME = "sans-serif";

View File

@ -366,8 +366,9 @@ public final class DefaultTrackOutput implements TrackOutput {
} }
// Populate the cryptoInfo. // Populate the cryptoInfo.
CryptoData cryptoData = extrasHolder.cryptoData;
buffer.cryptoInfo.set(subsampleCount, clearDataSizes, encryptedDataSizes, buffer.cryptoInfo.set(subsampleCount, clearDataSizes, encryptedDataSizes,
extrasHolder.encryptionKeyId, buffer.cryptoInfo.iv, C.CRYPTO_MODE_AES_CTR); cryptoData.encryptionKey, buffer.cryptoInfo.iv, cryptoData.cryptoMode);
// Adjust the offset and size to take into account the bytes read. // Adjust the offset and size to take into account the bytes read.
int bytesRead = (int) (offset - extrasHolder.offset); int bytesRead = (int) (offset - extrasHolder.offset);
@ -516,7 +517,7 @@ public final class DefaultTrackOutput implements TrackOutput {
@Override @Override
public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset, public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
byte[] encryptionKey) { CryptoData cryptoData) {
if (pendingFormatAdjustment) { if (pendingFormatAdjustment) {
format(lastUnadjustedFormat); format(lastUnadjustedFormat);
} }
@ -533,7 +534,7 @@ public final class DefaultTrackOutput implements TrackOutput {
} }
timeUs += sampleOffsetUs; timeUs += sampleOffsetUs;
long absoluteOffset = totalBytesWritten - size - offset; long absoluteOffset = totalBytesWritten - size - offset;
infoQueue.commitSample(timeUs, flags, absoluteOffset, size, encryptionKey); infoQueue.commitSample(timeUs, flags, absoluteOffset, size, cryptoData);
} finally { } finally {
endWriteOperation(); endWriteOperation();
} }
@ -606,7 +607,7 @@ public final class DefaultTrackOutput implements TrackOutput {
private int[] sizes; private int[] sizes;
private int[] flags; private int[] flags;
private long[] timesUs; private long[] timesUs;
private byte[][] encryptionKeys; private CryptoData[] cryptoDatas;
private Format[] formats; private Format[] formats;
private int queueSize; private int queueSize;
@ -628,7 +629,7 @@ public final class DefaultTrackOutput implements TrackOutput {
timesUs = new long[capacity]; timesUs = new long[capacity];
flags = new int[capacity]; flags = new int[capacity];
sizes = new int[capacity]; sizes = new int[capacity];
encryptionKeys = new byte[capacity][]; cryptoDatas = new CryptoData[capacity];
formats = new Format[capacity]; formats = new Format[capacity];
largestDequeuedTimestampUs = Long.MIN_VALUE; largestDequeuedTimestampUs = Long.MIN_VALUE;
largestQueuedTimestampUs = Long.MIN_VALUE; largestQueuedTimestampUs = Long.MIN_VALUE;
@ -792,7 +793,7 @@ public final class DefaultTrackOutput implements TrackOutput {
buffer.setFlags(flags[relativeReadIndex]); buffer.setFlags(flags[relativeReadIndex]);
extrasHolder.size = sizes[relativeReadIndex]; extrasHolder.size = sizes[relativeReadIndex];
extrasHolder.offset = offsets[relativeReadIndex]; extrasHolder.offset = offsets[relativeReadIndex];
extrasHolder.encryptionKeyId = encryptionKeys[relativeReadIndex]; extrasHolder.cryptoData = cryptoDatas[relativeReadIndex];
largestDequeuedTimestampUs = Math.max(largestDequeuedTimestampUs, buffer.timeUs); largestDequeuedTimestampUs = Math.max(largestDequeuedTimestampUs, buffer.timeUs);
queueSize--; queueSize--;
@ -892,7 +893,7 @@ public final class DefaultTrackOutput implements TrackOutput {
} }
public synchronized void commitSample(long timeUs, @C.BufferFlags int sampleFlags, long offset, public synchronized void commitSample(long timeUs, @C.BufferFlags int sampleFlags, long offset,
int size, byte[] encryptionKey) { int size, CryptoData cryptoData) {
if (upstreamKeyframeRequired) { if (upstreamKeyframeRequired) {
if ((sampleFlags & C.BUFFER_FLAG_KEY_FRAME) == 0) { if ((sampleFlags & C.BUFFER_FLAG_KEY_FRAME) == 0) {
return; return;
@ -905,7 +906,7 @@ public final class DefaultTrackOutput implements TrackOutput {
offsets[relativeWriteIndex] = offset; offsets[relativeWriteIndex] = offset;
sizes[relativeWriteIndex] = size; sizes[relativeWriteIndex] = size;
flags[relativeWriteIndex] = sampleFlags; flags[relativeWriteIndex] = sampleFlags;
encryptionKeys[relativeWriteIndex] = encryptionKey; cryptoDatas[relativeWriteIndex] = cryptoData;
formats[relativeWriteIndex] = upstreamFormat; formats[relativeWriteIndex] = upstreamFormat;
sourceIds[relativeWriteIndex] = upstreamSourceId; sourceIds[relativeWriteIndex] = upstreamSourceId;
// Increment the write index. // Increment the write index.
@ -918,14 +919,14 @@ public final class DefaultTrackOutput implements TrackOutput {
long[] newTimesUs = new long[newCapacity]; long[] newTimesUs = new long[newCapacity];
int[] newFlags = new int[newCapacity]; int[] newFlags = new int[newCapacity];
int[] newSizes = new int[newCapacity]; int[] newSizes = new int[newCapacity];
byte[][] newEncryptionKeys = new byte[newCapacity][]; CryptoData[] newCryptoDatas = new CryptoData[newCapacity];
Format[] newFormats = new Format[newCapacity]; Format[] newFormats = new Format[newCapacity];
int beforeWrap = capacity - relativeReadIndex; int beforeWrap = capacity - relativeReadIndex;
System.arraycopy(offsets, relativeReadIndex, newOffsets, 0, beforeWrap); System.arraycopy(offsets, relativeReadIndex, newOffsets, 0, beforeWrap);
System.arraycopy(timesUs, relativeReadIndex, newTimesUs, 0, beforeWrap); System.arraycopy(timesUs, relativeReadIndex, newTimesUs, 0, beforeWrap);
System.arraycopy(flags, relativeReadIndex, newFlags, 0, beforeWrap); System.arraycopy(flags, relativeReadIndex, newFlags, 0, beforeWrap);
System.arraycopy(sizes, relativeReadIndex, newSizes, 0, beforeWrap); System.arraycopy(sizes, relativeReadIndex, newSizes, 0, beforeWrap);
System.arraycopy(encryptionKeys, relativeReadIndex, newEncryptionKeys, 0, beforeWrap); System.arraycopy(cryptoDatas, relativeReadIndex, newCryptoDatas, 0, beforeWrap);
System.arraycopy(formats, relativeReadIndex, newFormats, 0, beforeWrap); System.arraycopy(formats, relativeReadIndex, newFormats, 0, beforeWrap);
System.arraycopy(sourceIds, relativeReadIndex, newSourceIds, 0, beforeWrap); System.arraycopy(sourceIds, relativeReadIndex, newSourceIds, 0, beforeWrap);
int afterWrap = relativeReadIndex; int afterWrap = relativeReadIndex;
@ -933,14 +934,14 @@ public final class DefaultTrackOutput implements TrackOutput {
System.arraycopy(timesUs, 0, newTimesUs, beforeWrap, afterWrap); System.arraycopy(timesUs, 0, newTimesUs, beforeWrap, afterWrap);
System.arraycopy(flags, 0, newFlags, beforeWrap, afterWrap); System.arraycopy(flags, 0, newFlags, beforeWrap, afterWrap);
System.arraycopy(sizes, 0, newSizes, beforeWrap, afterWrap); System.arraycopy(sizes, 0, newSizes, beforeWrap, afterWrap);
System.arraycopy(encryptionKeys, 0, newEncryptionKeys, beforeWrap, afterWrap); System.arraycopy(cryptoDatas, 0, newCryptoDatas, beforeWrap, afterWrap);
System.arraycopy(formats, 0, newFormats, beforeWrap, afterWrap); System.arraycopy(formats, 0, newFormats, beforeWrap, afterWrap);
System.arraycopy(sourceIds, 0, newSourceIds, beforeWrap, afterWrap); System.arraycopy(sourceIds, 0, newSourceIds, beforeWrap, afterWrap);
offsets = newOffsets; offsets = newOffsets;
timesUs = newTimesUs; timesUs = newTimesUs;
flags = newFlags; flags = newFlags;
sizes = newSizes; sizes = newSizes;
encryptionKeys = newEncryptionKeys; cryptoDatas = newCryptoDatas;
formats = newFormats; formats = newFormats;
sourceIds = newSourceIds; sourceIds = newSourceIds;
relativeReadIndex = 0; relativeReadIndex = 0;
@ -990,7 +991,7 @@ public final class DefaultTrackOutput implements TrackOutput {
public int size; public int size;
public long offset; public long offset;
public long nextOffset; public long nextOffset;
public byte[] encryptionKeyId; public CryptoData cryptoData;
} }

View File

@ -51,7 +51,7 @@ public final class DummyTrackOutput implements TrackOutput {
@Override @Override
public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset, public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
byte[] encryptionKey) { CryptoData cryptoData) {
// Do nothing. // Do nothing.
} }

View File

@ -20,12 +20,54 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
/** /**
* Receives track level data extracted by an {@link Extractor}. * Receives track level data extracted by an {@link Extractor}.
*/ */
public interface TrackOutput { public interface TrackOutput {
/**
* Holds data required to decrypt a sample.
*/
final class CryptoData {
/**
* The encryption mode used for the sample.
*/
@C.CryptoMode public final int cryptoMode;
/**
* The encryption key associated with the sample. Its contents must not be modified.
*/
public final byte[] encryptionKey;
public CryptoData(@C.CryptoMode int cryptoMode, byte[] encryptionKey) {
this.cryptoMode = cryptoMode;
this.encryptionKey = encryptionKey;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
CryptoData other = (CryptoData) obj;
return cryptoMode == other.cryptoMode && Arrays.equals(encryptionKey, other.encryptionKey);
}
@Override
public int hashCode() {
int result = cryptoMode;
result = 31 * result + Arrays.hashCode(encryptionKey);
return result;
}
}
/** /**
* Called when the {@link Format} of the track has been extracted from the stream. * Called when the {@link Format} of the track has been extracted from the stream.
* *
@ -70,9 +112,9 @@ public interface TrackOutput {
* {@link #sampleData(ExtractorInput, int, boolean)} or * {@link #sampleData(ExtractorInput, int, boolean)} or
* {@link #sampleData(ParsableByteArray, int)} since the last byte belonging to the sample * {@link #sampleData(ParsableByteArray, int)} since the last byte belonging to the sample
* whose metadata is being passed. * whose metadata is being passed.
* @param encryptionKey The encryption key associated with the sample. May be null. * @param encryptionData The encryption data required to decrypt the sample. May be null.
*/ */
void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset, void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
byte[] encryptionKey); CryptoData encryptionData);
} }

View File

@ -580,11 +580,11 @@ public final class MatroskaExtractor implements Extractor {
break; break;
case ID_CONTENT_ENCODING: case ID_CONTENT_ENCODING:
if (currentTrack.hasContentEncryption) { if (currentTrack.hasContentEncryption) {
if (currentTrack.encryptionKeyId == null) { if (currentTrack.cryptoData == null) {
throw new ParserException("Encrypted Track found but ContentEncKeyID was not found"); throw new ParserException("Encrypted Track found but ContentEncKeyID was not found");
} }
currentTrack.drmInitData = new DrmInitData( currentTrack.drmInitData = new DrmInitData(new SchemeData(C.UUID_NIL,
new SchemeData(C.UUID_NIL, MimeTypes.VIDEO_WEBM, currentTrack.encryptionKeyId)); MimeTypes.VIDEO_WEBM, currentTrack.cryptoData.encryptionKey));
} }
break; break;
case ID_CONTENT_ENCODINGS: case ID_CONTENT_ENCODINGS:
@ -888,8 +888,9 @@ public final class MatroskaExtractor implements Extractor {
input.readFully(currentTrack.sampleStrippedBytes, 0, contentSize); input.readFully(currentTrack.sampleStrippedBytes, 0, contentSize);
break; break;
case ID_CONTENT_ENCRYPTION_KEY_ID: case ID_CONTENT_ENCRYPTION_KEY_ID:
currentTrack.encryptionKeyId = new byte[contentSize]; byte[] encryptionKey = new byte[contentSize];
input.readFully(currentTrack.encryptionKeyId, 0, contentSize); input.readFully(encryptionKey, 0, contentSize);
currentTrack.cryptoData = new TrackOutput.CryptoData(C.CRYPTO_MODE_AES_CTR, encryptionKey);
break; break;
case ID_SIMPLE_BLOCK: case ID_SIMPLE_BLOCK:
case ID_BLOCK: case ID_BLOCK:
@ -1033,7 +1034,7 @@ public final class MatroskaExtractor implements Extractor {
if (CODEC_ID_SUBRIP.equals(track.codecId)) { if (CODEC_ID_SUBRIP.equals(track.codecId)) {
writeSubripSample(track); writeSubripSample(track);
} }
track.output.sampleMetadata(timeUs, blockFlags, sampleBytesWritten, 0, track.encryptionKeyId); track.output.sampleMetadata(timeUs, blockFlags, sampleBytesWritten, 0, track.cryptoData);
sampleRead = true; sampleRead = true;
resetSample(); resetSample();
} }
@ -1470,7 +1471,7 @@ public final class MatroskaExtractor implements Extractor {
public int defaultSampleDurationNs; public int defaultSampleDurationNs;
public boolean hasContentEncryption; public boolean hasContentEncryption;
public byte[] sampleStrippedBytes; public byte[] sampleStrippedBytes;
public byte[] encryptionKeyId; public TrackOutput.CryptoData cryptoData;
public byte[] codecPrivate; public byte[] codecPrivate;
public DrmInitData drmInitData; public DrmInitData drmInitData;

View File

@ -1122,19 +1122,30 @@ public final class FragmentedMp4Extractor implements Extractor {
} }
long sampleTimeUs = fragment.getSamplePresentationTime(sampleIndex) * 1000L; long sampleTimeUs = fragment.getSamplePresentationTime(sampleIndex) * 1000L;
@C.BufferFlags int sampleFlags = (fragment.definesEncryptionData ? C.BUFFER_FLAG_ENCRYPTED : 0)
| (fragment.sampleIsSyncFrameTable[sampleIndex] ? C.BUFFER_FLAG_KEY_FRAME : 0);
int sampleDescriptionIndex = fragment.header.sampleDescriptionIndex;
byte[] encryptionKey = null;
if (fragment.definesEncryptionData) {
encryptionKey = fragment.trackEncryptionBox != null
? fragment.trackEncryptionBox.keyId
: track.sampleDescriptionEncryptionBoxes[sampleDescriptionIndex].keyId;
}
if (timestampAdjuster != null) { if (timestampAdjuster != null) {
sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs); sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs);
} }
output.sampleMetadata(sampleTimeUs, sampleFlags, sampleSize, 0, encryptionKey);
@C.BufferFlags int sampleFlags = (fragment.definesEncryptionData ? C.BUFFER_FLAG_ENCRYPTED : 0)
| (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
? fragment.trackEncryptionBox
: track.sampleDescriptionEncryptionBoxes[fragment.header.sampleDescriptionIndex];
if (encryptionBox != currentTrackBundle.cachedEncryptionBox) {
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);
while (!pendingMetadataSampleInfos.isEmpty()) { while (!pendingMetadataSampleInfos.isEmpty()) {
MetadataSampleInfo sampleInfo = pendingMetadataSampleInfos.removeFirst(); MetadataSampleInfo sampleInfo = pendingMetadataSampleInfos.removeFirst();
@ -1288,6 +1299,10 @@ 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;
@ -1305,6 +1320,8 @@ 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

@ -186,8 +186,8 @@ public final class ChunkExtractorWrapper implements ExtractorOutput {
@Override @Override
public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset, public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
byte[] encryptionKey) { CryptoData cryptoData) {
trackOutput.sampleMetadata(timeUs, flags, size, offset, encryptionKey); trackOutput.sampleMetadata(timeUs, flags, size, offset, cryptoData);
} }
} }

View File

@ -36,7 +36,7 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
private final ArrayList<Integer> sampleFlags; private final ArrayList<Integer> sampleFlags;
private final ArrayList<Integer> sampleStartOffsets; private final ArrayList<Integer> sampleStartOffsets;
private final ArrayList<Integer> sampleEndOffsets; private final ArrayList<Integer> sampleEndOffsets;
private final ArrayList<byte[]> sampleEncryptionKeys; private final ArrayList<CryptoData> cryptoDatas;
private byte[] sampleData; private byte[] sampleData;
public Format format; public Format format;
@ -47,7 +47,7 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
sampleFlags = new ArrayList<>(); sampleFlags = new ArrayList<>();
sampleStartOffsets = new ArrayList<>(); sampleStartOffsets = new ArrayList<>();
sampleEndOffsets = new ArrayList<>(); sampleEndOffsets = new ArrayList<>();
sampleEncryptionKeys = new ArrayList<>(); cryptoDatas = new ArrayList<>();
} }
public void clear() { public void clear() {
@ -56,7 +56,7 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
sampleFlags.clear(); sampleFlags.clear();
sampleStartOffsets.clear(); sampleStartOffsets.clear();
sampleEndOffsets.clear(); sampleEndOffsets.clear();
sampleEncryptionKeys.clear(); cryptoDatas.clear();
} }
@Override @Override
@ -89,29 +89,24 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
@Override @Override
public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset, public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
byte[] encryptionKey) { CryptoData cryptoData) {
sampleTimesUs.add(timeUs); sampleTimesUs.add(timeUs);
sampleFlags.add(flags); sampleFlags.add(flags);
sampleStartOffsets.add(sampleData.length - offset - size); sampleStartOffsets.add(sampleData.length - offset - size);
sampleEndOffsets.add(sampleData.length - offset); sampleEndOffsets.add(sampleData.length - offset);
sampleEncryptionKeys.add(encryptionKey); cryptoDatas.add(cryptoData);
} }
public void assertSampleCount(int count) { public void assertSampleCount(int count) {
Assert.assertEquals(count, sampleTimesUs.size()); Assert.assertEquals(count, sampleTimesUs.size());
} }
public void assertSample(int index, byte[] data, long timeUs, int flags, byte[] encryptionKey) { public void assertSample(int index, byte[] data, long timeUs, int flags, CryptoData cryptoData) {
byte[] actualData = getSampleData(index); byte[] actualData = getSampleData(index);
MoreAsserts.assertEquals(data, actualData); MoreAsserts.assertEquals(data, actualData);
Assert.assertEquals(timeUs, (long) sampleTimesUs.get(index)); Assert.assertEquals(timeUs, (long) sampleTimesUs.get(index));
Assert.assertEquals(flags, (int) sampleFlags.get(index)); Assert.assertEquals(flags, (int) sampleFlags.get(index));
byte[] sampleEncryptionKey = sampleEncryptionKeys.get(index); Assert.assertEquals(cryptoData, cryptoDatas.get(index));
if (encryptionKey == null) {
Assert.assertEquals(null, sampleEncryptionKey);
} else {
MoreAsserts.assertEquals(encryptionKey, sampleEncryptionKey);
}
} }
public byte[] getSampleData(int index) { public byte[] getSampleData(int index) {
@ -128,10 +123,10 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
Assert.assertEquals(expected.sampleFlags.get(i), sampleFlags.get(i)); Assert.assertEquals(expected.sampleFlags.get(i), sampleFlags.get(i));
Assert.assertEquals(expected.sampleStartOffsets.get(i), sampleStartOffsets.get(i)); Assert.assertEquals(expected.sampleStartOffsets.get(i), sampleStartOffsets.get(i));
Assert.assertEquals(expected.sampleEndOffsets.get(i), sampleEndOffsets.get(i)); Assert.assertEquals(expected.sampleEndOffsets.get(i), sampleEndOffsets.get(i));
if (expected.sampleEncryptionKeys.get(i) == null) { if (expected.cryptoDatas.get(i) == null) {
Assert.assertNull(sampleEncryptionKeys.get(i)); Assert.assertNull(cryptoDatas.get(i));
} else { } else {
MoreAsserts.assertEquals(expected.sampleEncryptionKeys.get(i), sampleEncryptionKeys.get(i)); Assert.assertEquals(expected.cryptoDatas.get(i), cryptoDatas.get(i));
} }
} }
} }
@ -172,9 +167,10 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
.add("time", sampleTimesUs.get(i)) .add("time", sampleTimesUs.get(i))
.add("flags", sampleFlags.get(i)) .add("flags", sampleFlags.get(i))
.add("data", getSampleData(i)); .add("data", getSampleData(i));
byte[] key = sampleEncryptionKeys.get(i); CryptoData cryptoData = cryptoDatas.get(i);
if (key != null) { if (cryptoData != null) {
dumper.add("encryption key", key); dumper.add("crypto mode", cryptoData.cryptoMode);
dumper.add("encryption key", cryptoData.encryptionKey);
} }
dumper.endBlock(); dumper.endBlock();
} }