From 7839955f314c95e73a347d7993d6a07b72058290 Mon Sep 17 00:00:00 2001 From: aquilescanta Date: Tue, 21 Apr 2020 17:06:52 +0100 Subject: [PATCH] Separate encryption data into a new TrackOutput method Allows media parser to populate crypto data. PiperOrigin-RevId: 307616083 --- .../exoplayer2/source/SampleQueue.java | 6 +- .../source/chunk/ChunkExtractorWrapper.java | 5 +- .../source/dash/PlayerEmsgHandler.java | 5 +- .../extractor/DummyTrackOutput.java | 6 +- .../exoplayer2/extractor/TrackOutput.java | 63 ++++++++++++++++++- .../extractor/mkv/MatroskaExtractor.java | 17 +++-- .../extractor/mp4/FragmentedMp4Extractor.java | 13 ++-- .../source/hls/HlsSampleStreamWrapper.java | 6 +- .../exoplayer2/testutil/FakeTrackOutput.java | 6 +- 9 files changed, 104 insertions(+), 23 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java index 484aca5def..4371e39a3d 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java @@ -477,13 +477,15 @@ public class SampleQueue implements TrackOutput { } @Override - public final int sampleData(DataReader input, int length, boolean allowEndOfInput) + public final int sampleData( + DataReader input, int length, boolean allowEndOfInput, @SampleDataPart int sampleDataPart) throws IOException { return sampleDataQueue.sampleData(input, length, allowEndOfInput); } @Override - public final void sampleData(ParsableByteArray buffer, int length) { + public final void sampleData( + ParsableByteArray buffer, int length, @SampleDataPart int sampleDataPart) { sampleDataQueue.sampleData(buffer, length); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkExtractorWrapper.java b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkExtractorWrapper.java index 76a4665d77..f2362f2eb1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkExtractorWrapper.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkExtractorWrapper.java @@ -203,13 +203,14 @@ public final class ChunkExtractorWrapper implements ExtractorOutput { } @Override - public int sampleData(DataReader input, int length, boolean allowEndOfInput) + public int sampleData( + DataReader input, int length, boolean allowEndOfInput, @SampleDataPart int sampleDataPart) throws IOException { return castNonNull(trackOutput).sampleData(input, length, allowEndOfInput); } @Override - public void sampleData(ParsableByteArray data, int length) { + public void sampleData(ParsableByteArray data, int length, @SampleDataPart int sampleDataPart) { castNonNull(trackOutput).sampleData(data, length); } diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/PlayerEmsgHandler.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/PlayerEmsgHandler.java index 504b2f4c27..365c05b3f4 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/PlayerEmsgHandler.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/PlayerEmsgHandler.java @@ -300,13 +300,14 @@ public final class PlayerEmsgHandler implements Handler.Callback { } @Override - public int sampleData(DataReader input, int length, boolean allowEndOfInput) + public int sampleData( + DataReader input, int length, boolean allowEndOfInput, @SampleDataPart int sampleDataPart) throws IOException { return sampleQueue.sampleData(input, length, allowEndOfInput); } @Override - public void sampleData(ParsableByteArray data, int length) { + public void sampleData(ParsableByteArray data, int length, @SampleDataPart int sampleDataPart) { sampleQueue.sampleData(data, length); } diff --git a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/DummyTrackOutput.java b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/DummyTrackOutput.java index 7ef308ef46..4700bbb480 100644 --- a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/DummyTrackOutput.java +++ b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/DummyTrackOutput.java @@ -43,7 +43,9 @@ public final class DummyTrackOutput implements TrackOutput { } @Override - public int sampleData(DataReader input, int length, boolean allowEndOfInput) throws IOException { + public int sampleData( + DataReader input, int length, boolean allowEndOfInput, @SampleDataPart int sampleDataPart) + throws IOException { int bytesToSkipByReading = Math.min(readBuffer.length, length); int bytesSkipped = input.read(readBuffer, /* offset= */ 0, bytesToSkipByReading); if (bytesSkipped == C.RESULT_END_OF_INPUT) { @@ -56,7 +58,7 @@ public final class DummyTrackOutput implements TrackOutput { } @Override - public void sampleData(ParsableByteArray data, int length) { + public void sampleData(ParsableByteArray data, int length, @SampleDataPart int sampleDataPart) { data.skipBytes(length); } diff --git a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/TrackOutput.java b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/TrackOutput.java index 3e95fab209..f1a9ac731a 100644 --- a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/TrackOutput.java +++ b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/TrackOutput.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.extractor; +import androidx.annotation.IntDef; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; @@ -22,6 +23,9 @@ import com.google.android.exoplayer2.upstream.DataReader; import com.google.android.exoplayer2.util.ParsableByteArray; import java.io.EOFException; import java.io.IOException; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Arrays; /** @@ -94,6 +98,41 @@ public interface TrackOutput { } + /** Defines the part of the sample data to which a call to {@link #sampleData} corresponds. */ + @Documented + @Retention(RetentionPolicy.SOURCE) + @IntDef({SAMPLE_DATA_PART_MAIN, SAMPLE_DATA_PART_ENCRYPTION, SAMPLE_DATA_PART_SUPPLEMENTAL}) + @interface SampleDataPart {} + + /** Main media sample data. */ + int SAMPLE_DATA_PART_MAIN = 0; + /** + * Sample encryption data. + * + *

The format for encryption information is: + * + *

+ */ + int SAMPLE_DATA_PART_ENCRYPTION = 1; + /** Sample supplemental data. */ + int SAMPLE_DATA_PART_SUPPLEMENTAL = 2; + /** * Called when the {@link Format} of the track has been extracted from the stream. * @@ -101,6 +140,22 @@ public interface TrackOutput { */ void format(Format format); + /** + * Equivalent to {@link #sampleData(DataReader, int, boolean, int) sampleData(input, length, + * allowEndOfInput, SAMPLE_DATA_PART_MAIN)}. + */ + default int sampleData(DataReader input, int length, boolean allowEndOfInput) throws IOException { + return sampleData(input, length, allowEndOfInput, SAMPLE_DATA_PART_MAIN); + } + + /** + * Equivalent to {@link #sampleData(ParsableByteArray, int, int)} sampleData(data, length, + * SAMPLE_DATA_PART_MAIN)}. + */ + default void sampleData(ParsableByteArray data, int length) { + sampleData(data, length, SAMPLE_DATA_PART_MAIN); + } + /** * Called to write sample data to the output. * @@ -109,18 +164,22 @@ public interface TrackOutput { * @param allowEndOfInput True if encountering the end of the input having read no data is * allowed, and should result in {@link C#RESULT_END_OF_INPUT} being returned. False if it * should be considered an error, causing an {@link EOFException} to be thrown. + * @param sampleDataPart The part of the sample data to which this call corresponds. * @return The number of bytes appended. * @throws IOException If an error occurred reading from the input. */ - int sampleData(DataReader input, int length, boolean allowEndOfInput) throws IOException; + int sampleData( + DataReader input, int length, boolean allowEndOfInput, @SampleDataPart int sampleDataPart) + throws IOException; /** * Called to write sample data to the output. * * @param data A {@link ParsableByteArray} from which to read the sample data. * @param length The number of bytes to read, starting from {@code data.getPosition()}. + * @param sampleDataPart The part of the sample data to which this call corresponds. */ - void sampleData(ParsableByteArray data, int length); + void sampleData(ParsableByteArray data, int length, @SampleDataPart int sampleDataPart); /** * Called when metadata associated with a sample has been extracted from the stream. diff --git a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java index 09704f49c9..4d24c4fb95 100644 --- a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java +++ b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java @@ -1281,7 +1281,8 @@ public class MatroskaExtractor implements Extractor { } else { // Append supplemental data. int blockAdditionalSize = blockAdditionalData.limit(); - track.output.sampleData(blockAdditionalData, blockAdditionalSize); + track.output.sampleData( + blockAdditionalData, blockAdditionalSize, TrackOutput.SAMPLE_DATA_PART_SUPPLEMENTAL); size += blockAdditionalSize; } } @@ -1350,11 +1351,14 @@ public class MatroskaExtractor implements Extractor { // Write the signal byte, containing the IV size and the subsample encryption flag. scratch.data[0] = (byte) (ENCRYPTION_IV_SIZE | (hasSubsampleEncryption ? 0x80 : 0x00)); scratch.setPosition(0); - output.sampleData(scratch, 1); + output.sampleData(scratch, 1, TrackOutput.SAMPLE_DATA_PART_ENCRYPTION); sampleBytesWritten++; // Write the IV. encryptionInitializationVector.setPosition(0); - output.sampleData(encryptionInitializationVector, ENCRYPTION_IV_SIZE); + output.sampleData( + encryptionInitializationVector, + ENCRYPTION_IV_SIZE, + TrackOutput.SAMPLE_DATA_PART_ENCRYPTION); sampleBytesWritten += ENCRYPTION_IV_SIZE; } if (hasSubsampleEncryption) { @@ -1402,7 +1406,10 @@ public class MatroskaExtractor implements Extractor { encryptionSubsampleDataBuffer.putInt(0); } encryptionSubsampleData.reset(encryptionSubsampleDataBuffer.array(), subsampleDataSize); - output.sampleData(encryptionSubsampleData, subsampleDataSize); + output.sampleData( + encryptionSubsampleData, + subsampleDataSize, + TrackOutput.SAMPLE_DATA_PART_ENCRYPTION); sampleBytesWritten += subsampleDataSize; } } @@ -1421,7 +1428,7 @@ public class MatroskaExtractor implements Extractor { scratch.data[1] = (byte) ((size >> 16) & 0xFF); scratch.data[2] = (byte) ((size >> 8) & 0xFF); scratch.data[3] = (byte) (size & 0xFF); - output.sampleData(scratch, 4); + output.sampleData(scratch, 4, TrackOutput.SAMPLE_DATA_PART_SUPPLEMENTAL); sampleBytesWritten += 4; } diff --git a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java index 359ccc13dc..0cb409b79a 100644 --- a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java +++ b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java @@ -1611,9 +1611,10 @@ public class FragmentedMp4Extractor implements Extractor { encryptionSignalByte.data[0] = (byte) (vectorSize | (writeSubsampleEncryptionData ? 0x80 : 0)); encryptionSignalByte.setPosition(0); - output.sampleData(encryptionSignalByte, 1); + output.sampleData(encryptionSignalByte, 1, TrackOutput.SAMPLE_DATA_PART_ENCRYPTION); // Write the vector. - output.sampleData(initializationVectorData, vectorSize); + output.sampleData( + initializationVectorData, vectorSize, TrackOutput.SAMPLE_DATA_PART_ENCRYPTION); if (!writeSubsampleEncryptionData) { return 1 + vectorSize; @@ -1635,7 +1636,10 @@ public class FragmentedMp4Extractor implements Extractor { scratch.data[5] = (byte) ((sampleSize >> 16) & 0xFF); scratch.data[6] = (byte) ((sampleSize >> 8) & 0xFF); scratch.data[7] = (byte) (sampleSize & 0xFF); - output.sampleData(scratch, SINGLE_SUBSAMPLE_ENCRYPTION_DATA_LENGTH); + output.sampleData( + scratch, + SINGLE_SUBSAMPLE_ENCRYPTION_DATA_LENGTH, + TrackOutput.SAMPLE_DATA_PART_ENCRYPTION); return 1 + vectorSize + SINGLE_SUBSAMPLE_ENCRYPTION_DATA_LENGTH; } @@ -1658,7 +1662,8 @@ public class FragmentedMp4Extractor implements Extractor { subsampleEncryptionData = scratch; } - output.sampleData(subsampleEncryptionData, subsampleDataLength); + output.sampleData( + subsampleEncryptionData, subsampleDataLength, TrackOutput.SAMPLE_DATA_PART_ENCRYPTION); return 1 + vectorSize + subsampleDataLength; } diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index 41dc652e51..49a0a5d10b 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -1521,7 +1521,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; } @Override - public int sampleData(DataReader input, int length, boolean allowEndOfInput) + public int sampleData( + DataReader input, int length, boolean allowEndOfInput, @SampleDataPart int sampleDataPart) throws IOException { ensureBufferCapacity(bufferPosition + length); int numBytesRead = input.read(buffer, bufferPosition, length); @@ -1537,7 +1538,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; } @Override - public void sampleData(ParsableByteArray buffer, int length) { + public void sampleData( + ParsableByteArray buffer, int length, @SampleDataPart int sampleDataPart) { ensureBufferCapacity(bufferPosition + length); buffer.readBytes(this.buffer, bufferPosition, length); bufferPosition += length; diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTrackOutput.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTrackOutput.java index b168ebc093..47674fb787 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTrackOutput.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTrackOutput.java @@ -75,7 +75,9 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable { } @Override - public int sampleData(DataReader input, int length, boolean allowEndOfInput) throws IOException { + public int sampleData( + DataReader input, int length, boolean allowEndOfInput, @SampleDataPart int sampleDataPart) + throws IOException { byte[] newData = new byte[length]; int bytesAppended = input.read(newData, 0, length); if (bytesAppended == C.RESULT_END_OF_INPUT) { @@ -90,7 +92,7 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable { } @Override - public void sampleData(ParsableByteArray data, int length) { + public void sampleData(ParsableByteArray data, int length, @SampleDataPart int sampleDataPart) { byte[] newData = new byte[length]; data.readBytes(newData, 0, length); sampleData = TestUtil.joinByteArrays(sampleData, newData);