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:
+ *
+ *
+ * - (1 byte) {@code encryption_signal_byte}: Most significant bit signals whether the
+ * encryption data contains subsample encryption data. The remaining bits contain {@code
+ * initialization_vector_size}.
+ *
- ({@code initialization_vector_size} bytes) Initialization vector.
+ *
- If subsample encryption data is present, as per {@code encryption_signal_byte}, the
+ * encryption data also contains:
+ *
+ * - (2 bytes) {@code subsample_encryption_data_length}.
+ *
- ({@code subsample_encryption_data_length} bytes) Subsample encryption data
+ * (repeated {@code subsample_encryption_data_length / 6} times:
+ *
+ * - (3 bytes) Size of a clear section in sample.
+ *
- (3 bytes) Size of an encryption section in sample.
+ *
+ *
+ *
+ */
+ 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);